Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/context/analysis.rs')
| -rw-r--r-- | crates/ide-completion/src/context/analysis.rs | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index faeb97f93f..b2ee94d49c 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -641,13 +641,23 @@ fn expected_type_and_name<'db>( } for _ in refs_level..0 { cov_mark::hit!(expected_type_fn_param_deref); - ty = ty.add_reference(hir::Mutability::Shared); + ty = ty.add_reference(sema.db, hir::Mutability::Shared); } ty } _ => ty, }; + let mut generic_def = None; + let mut rebase_ty = { + let node = node.clone(); + move |ty: hir::Type<'db>| { + let def = *generic_def + .get_or_insert_with(|| sema.scope(&node).and_then(|scope| scope.generic_def())); + def.and_then(|def| ty.try_rebase_into_owner(sema.db, def)) + .unwrap_or_else(|| ty.instantiate_with_errors()) + } + }; let (ty, name) = loop { break match_ast! { match node { @@ -791,26 +801,22 @@ fn expected_type_and_name<'db>( (ty, None) }, ast::TupleStructPat(it) => { - let fields = it.path().and_then(|path| match sema.resolve_path(&path)? { - hir::PathResolution::Def(hir::ModuleDef::Adt(adt)) => Some(adt.as_struct()?.fields(sema.db)), - hir::PathResolution::Def(hir::ModuleDef::EnumVariant(variant)) => Some(variant.fields(sema.db)), - _ => None, - }); + let fields = sema.resolve_tuple_struct_pat_fields(&it); let nr = it.fields().take_while(|it| it.syntax().text_range().end() <= token.text_range().start()).count(); - let ty = fields.and_then(|fields| Some(fields.get(nr)?.ty(sema.db).to_type(sema.db))); + let ty = fields.and_then(|fields| Some(rebase_ty(fields.get(nr)?.1.clone()))); (ty, None) }, ast::Fn(it) => { cov_mark::hit!(expected_type_fn_ret_with_leading_char); cov_mark::hit!(expected_type_fn_ret_without_leading_char); let def = sema.to_def(&it); - (def.map(|def| def.ret_type(sema.db)), None) + (def.map(|def| rebase_ty(def.ret_type(sema.db))), None) }, ast::ReturnExpr(it) => { let fn_ = sema.ancestors_with_macros(it.syntax().clone()) .find_map(Either::<ast::Fn, ast::ClosureExpr>::cast); let ty = fn_.and_then(|f| match f { - Either::Left(f) => Some(sema.to_def(&f)?.ret_type(sema.db)), + Either::Left(f) => Some(rebase_ty(sema.to_def(&f)?.ret_type(sema.db))), Either::Right(f) => { let ty = sema.type_of_expr(&f.into())?.original.as_callable(sema.db)?; Some(ty.return_type()) |