@@ -5,11 +5,10 @@ use crate::{
55 navigation_target:: { self , ToNav } ,
66 FilePosition , NavigationTarget , RangeInfo , TryToNav , UpmappingResult ,
77} ;
8- use hir:: { AsAssocItem , AssocItem , FileRange , Impl , InFile , MacroFileIdExt , ModuleDef , Semantics } ;
8+ use hir:: { AsAssocItem , AssocItem , FileRange , InFile , MacroFileIdExt , ModuleDef , Semantics } ;
99use ide_db:: {
1010 base_db:: { AnchoredPath , FileLoader , SourceDatabase } ,
1111 defs:: { Definition , IdentClass } ,
12- famous_defs:: FamousDefs ,
1312 helpers:: pick_best_token,
1413 RootDatabase , SymbolKind ,
1514} ;
@@ -82,8 +81,7 @@ pub(crate) fn goto_definition(
8281 return Some ( RangeInfo :: new ( original_token. text_range ( ) , navs) ) ;
8382 }
8483
85- if let Some ( navs) = find_definition_for_known_blanket_dual_impls ( sema, file_id, & original_token)
86- {
84+ if let Some ( navs) = find_definition_for_known_blanket_dual_impls ( sema, & original_token) {
8785 return Some ( RangeInfo :: new ( original_token. text_range ( ) , navs) ) ;
8886 }
8987
@@ -134,58 +132,13 @@ pub(crate) fn goto_definition(
134132// If the token is into(), try_into(), parse(), search the definition of From, TryFrom, FromStr.
135133fn find_definition_for_known_blanket_dual_impls (
136134 sema : & Semantics < ' _ , RootDatabase > ,
137- file_id : FileId ,
138135 original_token : & SyntaxToken ,
139136) -> Option < Vec < NavigationTarget > > {
140- let db = sema. db ;
141- let krate = sema. file_to_module_def ( file_id) ?. krate ( ) ;
142-
143- // e.g. if the method call is let b = a.into(),
144- // - receiver_type is A (type of a)
145- // - return_type is B (type of b)
146- // We will find the definition of B::from(a: A).
147137 let method_call = ast:: MethodCallExpr :: cast ( original_token. parent ( ) ?. parent ( ) ?) ?;
148- let callable = sema. resolve_method_call_as_callable ( & method_call) ?;
149- let ( _, receiver_type) = callable. receiver_param ( db) ?;
150- let return_type = callable. return_type ( ) ;
151-
152- let ( search_method, search_trait, return_type) = match method_call. name_ref ( ) ?. text ( ) . as_str ( ) {
153- "into" => ( "from" , FamousDefs ( sema, krate) . core_convert_From ( ) ?, return_type) ,
154- // If the method is try_into() or parse(), return_type is Result<T, Error>.
155- // Get T from type arguments of Result<T, Error>.
156- "try_into" => (
157- "try_from" ,
158- FamousDefs ( sema, krate) . core_convert_TryFrom ( ) ?,
159- return_type. type_arguments ( ) . next ( ) ?,
160- ) ,
161- "parse" => (
162- "from_str" ,
163- FamousDefs ( sema, krate) . core_str_FromStr ( ) ?,
164- return_type. type_arguments ( ) . next ( ) ?,
165- ) ,
166- _ => return None ,
167- } ;
168-
169- let from_impls = Impl :: all_for_type ( db, return_type)
170- . into_iter ( )
171- . filter ( |impl_| impl_. trait_ ( db) . is_some_and ( |trait_| trait_ == search_trait) ) ;
172- let from_methods = from_impls. flat_map ( |impl_| impl_. items ( db) ) . filter_map ( |item| match item {
173- AssocItem :: Function ( function) if function. name ( db) . as_str ( ) == search_method => {
174- Some ( function)
175- }
176- _ => None ,
177- } ) ;
178- let target_method = from_methods. into_iter ( ) . find ( |method| {
179- let args = method. assoc_fn_params ( db) ;
180-
181- // FIXME: This condition does not work for complicated cases such as
182- // receiver_type: Vec<i64>
183- // arg.ty(): T: IntoIterator<Item = i64>
184- args. first ( ) . is_some_and ( |arg| receiver_type. could_coerce_to ( db, arg. ty ( ) ) )
185- } ) ?;
138+ let target_method = sema. resolve_known_blanket_dual_impls ( & method_call) ?;
186139
187140 let def = Definition :: from ( target_method) ;
188- Some ( def_to_nav ( db, def) )
141+ Some ( def_to_nav ( sema . db , def) )
189142}
190143
191144fn try_lookup_include_path (
0 commit comments