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 | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index 4fb8248e78..7aec6f7e8f 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -648,6 +648,16 @@ fn expected_type_and_name<'db>( _ => 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 { @@ -793,20 +803,20 @@ fn expected_type_and_name<'db>( ast::TupleStructPat(it) => { let fields = sema.type_of_pat(&it.clone().into()).map(|ty| ty.original.fields(sema.db)); 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)?.1.clone())); + 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()) |