aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_completion/src/context.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-06-20 17:32:45 +0100
committerAleksey Kladov <[email protected]>2021-06-20 17:37:58 +0100
commit9a3eae8755f99f4cfb8c2abb0885ec500b946218 (patch)
tree040844f1a7cbd829586a883e292f3fa5f090e3cb /crates/ide_completion/src/context.rs
parentf1097c2d26b68741612ecd3411fe41dc13fb005a (diff)
fix: don't add duplicate `&` during completion
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 e49e434fa..7b76600df 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -385,14 +385,19 @@ impl<'a> CompletionContext<'a> {
385 (ty, name) 385 (ty, name)
386 }, 386 },
387 ast::ArgList(_it) => { 387 ast::ArgList(_it) => {
388 cov_mark::hit!(expected_type_fn_param_with_leading_char); 388 cov_mark::hit!(expected_type_fn_param);
389 cov_mark::hit!(expected_type_fn_param_without_leading_char);
390 ActiveParameter::at_token( 389 ActiveParameter::at_token(
391 &self.sema, 390 &self.sema,
392 self.token.clone(), 391 self.token.clone(),
393 ).map(|ap| { 392 ).map(|ap| {
394 let name = ap.ident().map(NameOrNameRef::Name); 393 let name = ap.ident().map(NameOrNameRef::Name);
395 (Some(ap.ty), name) 394 let ty = if has_ref(&self.token) {
395 cov_mark::hit!(expected_type_fn_param_ref);
396 ap.ty.remove_ref()
397 } else {
398 Some(ap.ty)
399 };
400 (ty, name)
396 }) 401 })
397 .unwrap_or((None, None)) 402 .unwrap_or((None, None))
398 }, 403 },
@@ -697,6 +702,19 @@ fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
697 use_tree.path().zip(Some(true)) 702 use_tree.path().zip(Some(true))
698} 703}
699 704
705fn has_ref(token: &SyntaxToken) -> bool {
706 let mut token = token.clone();
707 for skip in [WHITESPACE, IDENT, T![mut]] {
708 if token.kind() == skip {
709 token = match token.prev_token() {
710 Some(it) => it,
711 None => return false,
712 }
713 }
714 }
715 token.kind() == T![&]
716}
717
700#[cfg(test)] 718#[cfg(test)]
701mod tests { 719mod tests {
702 use expect_test::{expect, Expect}; 720 use expect_test::{expect, Expect};
@@ -769,14 +787,18 @@ fn foo() {
769 } 787 }
770 788
771 #[test] 789 #[test]
772 fn expected_type_fn_param_without_leading_char() { 790 fn expected_type_fn_param() {
773 cov_mark::check!(expected_type_fn_param_without_leading_char); 791 cov_mark::check!(expected_type_fn_param);
774 check_expected_type_and_name( 792 check_expected_type_and_name(
775 r#" 793 r#"
776fn foo() { 794fn foo() { bar($0); }
777 bar($0); 795fn bar(x: u32) {}
778} 796"#,
779 797 expect![[r#"ty: u32, name: x"#]],
798 );
799 check_expected_type_and_name(
800 r#"
801fn foo() { bar(c$0); }
780fn bar(x: u32) {} 802fn bar(x: u32) {}
781"#, 803"#,
782 expect![[r#"ty: u32, name: x"#]], 804 expect![[r#"ty: u32, name: x"#]],
@@ -784,18 +806,29 @@ fn bar(x: u32) {}
784 } 806 }
785 807
786 #[test] 808 #[test]
787 fn expected_type_fn_param_with_leading_char() { 809 fn expected_type_fn_param_ref() {
788 cov_mark::check!(expected_type_fn_param_with_leading_char); 810 cov_mark::check!(expected_type_fn_param_ref);
789 check_expected_type_and_name( 811 check_expected_type_and_name(
790 r#" 812 r#"
791fn foo() { 813fn foo() { bar(&$0); }
792 bar(c$0); 814fn bar(x: &u32) {}
793}
794
795fn bar(x: u32) {}
796"#, 815"#,
797 expect![[r#"ty: u32, name: x"#]], 816 expect![[r#"ty: u32, name: x"#]],
798 ); 817 );
818 check_expected_type_and_name(
819 r#"
820fn foo() { bar(&mut $0); }
821fn bar(x: &mut u32) {}
822"#,
823 expect![[r#"ty: u32, name: x"#]],
824 );
825 check_expected_type_and_name(
826 r#"
827fn foo() { bar(&c$0); }
828fn bar(x: &u32) {}
829 "#,
830 expect![[r#"ty: u32, name: x"#]],
831 );
799 } 832 }
800 833
801 #[test] 834 #[test]