Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/dot.rs')
-rw-r--r--crates/ide-completion/src/completions/dot.rs108
1 files changed, 102 insertions, 6 deletions
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs
index 9c2e0dcf1c..18cfa53f8e 100644
--- a/crates/ide-completion/src/completions/dot.rs
+++ b/crates/ide-completion/src/completions/dot.rs
@@ -4,6 +4,7 @@ use std::ops::ControlFlow;
use hir::{Complete, Function, HasContainer, ItemContainer, MethodCandidateCallback};
use ide_db::FxHashSet;
+use itertools::Either;
use syntax::SmolStr;
use crate::{
@@ -146,11 +147,14 @@ pub(crate) fn complete_undotted_self(
_ => return,
};
- let ty = self_param.ty(ctx.db);
+ let (param_name, ty) = match self_param {
+ Either::Left(self_param) => ("self", &self_param.ty(ctx.db)),
+ Either::Right(this_param) => ("this", this_param.ty()),
+ };
complete_fields(
acc,
ctx,
- &ty,
+ ty,
|acc, field, ty| {
acc.add_field(
ctx,
@@ -163,15 +167,17 @@ pub(crate) fn complete_undotted_self(
in_breakable: expr_ctx.in_breakable,
},
},
- Some(SmolStr::new_static("self")),
+ Some(SmolStr::new_static(param_name)),
field,
&ty,
)
},
- |acc, field, ty| acc.add_tuple_field(ctx, Some(SmolStr::new_static("self")), field, &ty),
+ |acc, field, ty| {
+ acc.add_tuple_field(ctx, Some(SmolStr::new_static(param_name)), field, &ty)
+ },
false,
);
- complete_methods(ctx, &ty, &ctx.traits_in_scope(), |func| {
+ complete_methods(ctx, ty, &ctx.traits_in_scope(), |func| {
acc.add_method(
ctx,
&DotAccess {
@@ -184,7 +190,7 @@ pub(crate) fn complete_undotted_self(
},
},
func,
- Some(SmolStr::new_static("self")),
+ Some(SmolStr::new_static(param_name)),
None,
)
});
@@ -1074,6 +1080,96 @@ impl Foo { fn foo(&mut self) { $0 } }"#,
}
#[test]
+ fn completes_bare_fields_and_methods_in_this_closure() {
+ check_no_kw(
+ r#"
+//- minicore: fn
+struct Foo { field: i32 }
+
+impl Foo { fn foo(&mut self) { let _: fn(&mut Self) = |this| { $0 } } }"#,
+ expect![[r#"
+ fd this.field i32
+ me this.foo() fn(&mut self)
+ lc self &mut Foo
+ lc this &mut Foo
+ md core
+ sp Self Foo
+ st Foo Foo
+ tt Fn
+ tt FnMut
+ tt FnOnce
+ bt u32 u32
+ "#]],
+ );
+ }
+
+ #[test]
+ fn completes_bare_fields_and_methods_in_other_closure() {
+ check_no_kw(
+ r#"
+//- minicore: fn
+struct Foo { field: i32 }
+
+impl Foo { fn foo(&self) { let _: fn(&Self) = |foo| { $0 } } }"#,
+ expect![[r#"
+ fd self.field i32
+ me self.foo() fn(&self)
+ lc foo &Foo
+ lc self &Foo
+ md core
+ sp Self Foo
+ st Foo Foo
+ tt Fn
+ tt FnMut
+ tt FnOnce
+ bt u32 u32
+ "#]],
+ );
+
+ check_no_kw(
+ r#"
+//- minicore: fn
+struct Foo { field: i32 }
+
+impl Foo { fn foo(&self) { let _: fn(&Self) = || { $0 } } }"#,
+ expect![[r#"
+ fd self.field i32
+ me self.foo() fn(&self)
+ lc self &Foo
+ md core
+ sp Self Foo
+ st Foo Foo
+ tt Fn
+ tt FnMut
+ tt FnOnce
+ bt u32 u32
+ "#]],
+ );
+
+ check_no_kw(
+ r#"
+//- minicore: fn
+struct Foo { field: i32 }
+
+impl Foo { fn foo(&self) { let _: fn(&Self, &Self) = |foo, other| { $0 } } }"#,
+ expect![[r#"
+ fd self.field i32
+ me self.foo() fn(&self)
+ lc foo &Foo
+ lc other &Foo
+ lc self &Foo
+ md core
+ sp Self Foo
+ st Foo Foo
+ tt Fn
+ tt FnMut
+ tt FnOnce
+ bt u32 u32
+ "#]],
+ );
+ }
+
+ #[test]
fn macro_completion_after_dot() {
check_no_kw(
r#"