about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2021-12-22 00:18:39 +0100
committerLukas Wirth <lukastw97@gmail.com>2021-12-22 00:18:39 +0100
commit276687a6eeefbbc0721ded81980f88edd2178ebe (patch)
tree1777ba4e14367998f2f2e0e995a2b44f78ec9acd
parent60dfe8ceed39f7c89c1153655e17a5c6c0f56155 (diff)
downloadrust-276687a6eeefbbc0721ded81980f88edd2178ebe.tar.gz
rust-276687a6eeefbbc0721ded81980f88edd2178ebe.zip
internal: Directly use self param in completions instead of searching
-rw-r--r--crates/hir/src/lib.rs13
-rw-r--r--crates/ide_completion/src/completions/dot.rs33
2 files changed, 28 insertions, 18 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 526e90bd0b4..0ced029b84d 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1483,6 +1483,19 @@ impl SelfParam {
             .and_then(|params| params.self_param())
             .map(|value| InFile { file_id, value })
     }
+
+    pub fn ty(&self, db: &dyn HirDatabase) -> Type {
+        let resolver = self.func.resolver(db.upcast());
+        let krate = self.func.lookup(db.upcast()).container.module(db.upcast()).krate();
+        let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
+        let environment = db.trait_environment(self.func.into());
+
+        Type {
+            krate,
+            env: environment.clone(),
+            ty: ctx.lower_ty(&db.function_data(self.func).params[0].1),
+        }
+    }
 }
 
 impl HasVisibility for Function {
diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs
index e7371270fbf..e08a70ac7eb 100644
--- a/crates/ide_completion/src/completions/dot.rs
+++ b/crates/ide_completion/src/completions/dot.rs
@@ -1,7 +1,6 @@
 //! Completes references after dot (fields and method calls).
 
 use either::Either;
-use hir::ScopeDef;
 use rustc_hash::FxHashSet;
 
 use crate::{context::CompletionContext, patterns::ImmediateLocation, Completions};
@@ -36,24 +35,22 @@ fn complete_undotted_self(acc: &mut Completions, ctx: &CompletionContext) {
     if !ctx.is_trivial_path() || ctx.is_path_disallowed() || !ctx.expects_expression() {
         return;
     }
-    ctx.scope.process_all_names(&mut |name, def| {
-        if let ScopeDef::Local(local) = &def {
-            if local.is_self(ctx.db) {
-                let ty = local.ty(ctx.db);
-                complete_fields(ctx, &ty, |field, ty| match field {
-                    either::Either::Left(field) => {
-                        acc.add_field(ctx, Some(name.clone()), field, &ty)
-                    }
-                    either::Either::Right(tuple_idx) => {
-                        acc.add_tuple_field(ctx, Some(name.clone()), tuple_idx, &ty)
-                    }
-                });
-                complete_methods(ctx, &ty, |func| {
-                    acc.add_method(ctx, func, Some(name.clone()), None)
-                });
-            }
+    if let Some(func) = ctx.function_def.as_ref().and_then(|fn_| ctx.sema.to_def(fn_)) {
+        if let Some(self_) = func.self_param(ctx.db) {
+            let ty = self_.ty(ctx.db);
+            complete_fields(ctx, &ty, |field, ty| match field {
+                either::Either::Left(field) => {
+                    acc.add_field(ctx, Some(hir::known::SELF_PARAM), field, &ty)
+                }
+                either::Either::Right(tuple_idx) => {
+                    acc.add_tuple_field(ctx, Some(hir::known::SELF_PARAM), tuple_idx, &ty)
+                }
+            });
+            complete_methods(ctx, &ty, |func| {
+                acc.add_method(ctx, func, Some(hir::known::SELF_PARAM), None)
+            });
         }
-    });
+    }
 }
 
 fn complete_fields(