diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 526e90bd0b..0ced029b84 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 e7371270fb..e08a70ac7e 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(