Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide/src/goto_definition.rs')
| -rw-r--r-- | crates/ide/src/goto_definition.rs | 46 |
1 files changed, 43 insertions, 3 deletions
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 2c6c6e6e6c..99d0d6af71 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -141,15 +141,35 @@ fn find_definition_for_known_blanket_dual_impls( let method_call = ast::MethodCallExpr::cast(original_token.parent()?.parent()?)?; let callable = sema.resolve_method_call_as_callable(&method_call)?; let CallableKind::Function(f) = callable.kind() else { return None }; - let t = f.as_assoc_item(sema.db)?.container_trait(sema.db)?; + let assoc = f.as_assoc_item(sema.db)?; let return_type = callable.return_type(); let fd = FamousDefs(sema, return_type.krate(sema.db)); + + let t = match assoc.container(sema.db) { + hir::AssocItemContainer::Trait(t) => t, + hir::AssocItemContainer::Impl(impl_) + if impl_.self_ty(sema.db).is_str() && f.name(sema.db) == sym::parse => + { + let t = fd.core_convert_FromStr()?; + let t_f = t.function(sema.db, &sym::from_str)?; + return sema + .resolve_trait_impl_method( + return_type.clone(), + t, + t_f, + [return_type.type_arguments().next()?], + ) + .map(|f| def_to_nav(sema.db, f.into())); + } + hir::AssocItemContainer::Impl(_) => return None, + }; + let fn_name = f.name(sema.db); let f = if fn_name == sym::into && fd.core_convert_Into() == Some(t) { let dual = fd.core_convert_From()?; let dual_f = dual.function(sema.db, &sym::from)?; - sema.resolve_impl_method( + sema.resolve_trait_impl_method( return_type.clone(), dual, dual_f, @@ -158,7 +178,7 @@ fn find_definition_for_known_blanket_dual_impls( } else if fn_name == sym::try_into && fd.core_convert_TryInto() == Some(t) { let dual = fd.core_convert_TryFrom()?; let dual_f = dual.function(sema.db, &sym::try_from)?; - sema.resolve_impl_method( + sema.resolve_trait_impl_method( return_type.clone(), dual, dual_f, @@ -3195,4 +3215,24 @@ fn f() { "#, ); } + + #[test] + fn parse_call_to_from_str_definition() { + check( + r#" +//- minicore: from, str +struct A; +impl FromStr for A { + type Error = String; + fn from_str(value: &str) -> Result<Self, Self::Error> { + //^^^^^^^^ + Ok(A) + } +} +fn f() { + let a: Result<A, _> = "aaaaaa".parse$0(); +} + "#, + ); + } } |