aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_completion/src/context.rs')
-rw-r--r--crates/ide_completion/src/context.rs65
1 files changed, 49 insertions, 16 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 4814bd64d..f0da98739 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -388,14 +388,19 @@ impl<'a> CompletionContext<'a> {
388 (ty, name) 388 (ty, name)
389 }, 389 },
390 ast::ArgList(_it) => { 390 ast::ArgList(_it) => {
391 cov_mark::hit!(expected_type_fn_param_with_leading_char); 391 cov_mark::hit!(expected_type_fn_param);
392 cov_mark::hit!(expected_type_fn_param_without_leading_char);
393 ActiveParameter::at_token( 392 ActiveParameter::at_token(
394 &self.sema, 393 &self.sema,
395 self.token.clone(), 394 self.token.clone(),
396 ).map(|ap| { 395 ).map(|ap| {
397 let name = ap.ident().map(NameOrNameRef::Name); 396 let name = ap.ident().map(NameOrNameRef::Name);
398 (Some(ap.ty), name) 397 let ty = if has_ref(&self.token) {
398 cov_mark::hit!(expected_type_fn_param_ref);
399 ap.ty.remove_ref()
400 } else {
401 Some(ap.ty)
402 };
403 (ty, name)
399 }) 404 })
400 .unwrap_or((None, None)) 405 .unwrap_or((None, None))
401 }, 406 },
@@ -700,6 +705,19 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
700 use_tree.path().zip(Some(true)) 705 use_tree.path().zip(Some(true))
701} 706}
702 707
708fn has_ref(token: &SyntaxToken) -> bool {
709 let mut token = token.clone();
710 for skip in [WHITESPACE, IDENT, T![mut]] {
711 if token.kind() == skip {
712 token = match token.prev_token() {
713 Some(it) => it,
714 None => return false,
715 }
716 }
717 }
718 token.kind() == T![&]
719}
720
703#[cfg(test)] 721#[cfg(test)]
704mod tests { 722mod tests {
705 use expect_test::{expect, Expect}; 723 use expect_test::{expect, Expect};
@@ -772,14 +790,18 @@ fn foo() {
772 } 790 }
773 791
774 #[test] 792 #[test]
775 fn expected_type_fn_param_without_leading_char() { 793 fn expected_type_fn_param() {
776 cov_mark::check!(expected_type_fn_param_without_leading_char); 794 cov_mark::check!(expected_type_fn_param);
777 check_expected_type_and_name( 795 check_expected_type_and_name(
778 r#" 796 r#"
779fn foo() { 797fn foo() { bar($0); }
780 bar($0); 798fn bar(x: u32) {}
781} 799"#,
782 800 expect![[r#"ty: u32, name: x"#]],
801 );
802 check_expected_type_and_name(
803 r#"
804fn foo() { bar(c$0); }
783fn bar(x: u32) {} 805fn bar(x: u32) {}
784"#, 806"#,
785 expect![[r#"ty: u32, name: x"#]], 807 expect![[r#"ty: u32, name: x"#]],
@@ -787,18 +809,29 @@ fn bar(x: u32) {}
787 } 809 }
788 810
789 #[test] 811 #[test]
790 fn expected_type_fn_param_with_leading_char() { 812 fn expected_type_fn_param_ref() {
791 cov_mark::check!(expected_type_fn_param_with_leading_char); 813 cov_mark::check!(expected_type_fn_param_ref);
792 check_expected_type_and_name( 814 check_expected_type_and_name(
793 r#" 815 r#"
794fn foo() { 816fn foo() { bar(&$0); }
795 bar(c$0); 817fn bar(x: &u32) {}
796}
797
798fn bar(x: u32) {}
799"#, 818"#,
800 expect![[r#"ty: u32, name: x"#]], 819 expect![[r#"ty: u32, name: x"#]],
801 ); 820 );
821 check_expected_type_and_name(
822 r#"
823fn foo() { bar(&mut $0); }
824fn bar(x: &mut u32) {}
825"#,
826 expect![[r#"ty: u32, name: x"#]],
827 );
828 check_expected_type_and_name(
829 r#"
830fn foo() { bar(&c$0); }
831fn bar(x: &u32) {}
832 "#,
833 expect![[r#"ty: u32, name: x"#]],
834 );
802 } 835 }
803 836
804 #[test] 837 #[test]