@@ -8,9 +8,8 @@ use arrayvec::ArrayVec;
88use base_db:: { CrateId , Edition } ;
99use chalk_ir:: { cast:: Cast , Mutability , UniverseIndex } ;
1010use hir_def:: {
11- item_scope:: ItemScope , lang_item:: LangItemTarget , nameres:: DefMap , AssocItemId , BlockId ,
12- ConstId , FunctionId , GenericDefId , HasModule , ImplId , ItemContainerId , Lookup , ModuleDefId ,
13- ModuleId , TraitId ,
11+ item_scope:: ItemScope , nameres:: DefMap , AssocItemId , BlockId , ConstId , FunctionId ,
12+ GenericDefId , HasModule , ImplId , ItemContainerId , Lookup , ModuleDefId , ModuleId , TraitId ,
1413} ;
1514use hir_expand:: name:: Name ;
1615use rustc_hash:: { FxHashMap , FxHashSet } ;
@@ -21,7 +20,7 @@ use crate::{
2120 db:: HirDatabase ,
2221 from_foreign_def_id,
2322 infer:: { unify:: InferenceTable , Adjust , Adjustment , AutoBorrow , OverloadedDeref , PointerCast } ,
24- primitive:: { self , FloatTy , IntTy , UintTy } ,
23+ primitive:: { FloatTy , IntTy , UintTy } ,
2524 static_lifetime,
2625 utils:: all_super_traits,
2726 AdtId , Canonical , CanonicalVarKinds , DebruijnIndex , ForeignDefId , InEnvironment , Interner ,
@@ -337,6 +336,30 @@ impl InherentImpls {
337336 }
338337}
339338
339+ pub fn inherent_impl_crates_query (
340+ db : & dyn HirDatabase ,
341+ krate : CrateId ,
342+ fp : TyFingerprint ,
343+ ) -> ArrayVec < CrateId , 2 > {
344+ let _p = profile:: span ( "inherent_impl_crates_query" ) ;
345+ let mut res = ArrayVec :: new ( ) ;
346+ let crate_graph = db. crate_graph ( ) ;
347+
348+ for krate in crate_graph. transitive_deps ( krate) {
349+ if res. is_full ( ) {
350+ // we don't currently look for or store more than two crates here,
351+ // so don't needlessly look at more crates than necessary.
352+ break ;
353+ }
354+ let impls = db. inherent_impls_in_crate ( krate) ;
355+ if impls. map . get ( & fp) . map_or ( false , |v| !v. is_empty ( ) ) {
356+ res. push ( krate) ;
357+ }
358+ }
359+
360+ res
361+ }
362+
340363fn collect_unnamed_consts < ' a > (
341364 db : & ' a dyn HirDatabase ,
342365 scope : & ' a ItemScope ,
@@ -370,63 +393,30 @@ pub fn def_crates(
370393 ty : & Ty ,
371394 cur_crate : CrateId ,
372395) -> Option < ArrayVec < CrateId , 2 > > {
373- // Types like slice can have inherent impls in several crates, (core and alloc).
374- // The corresponding impls are marked with lang items, so we can use them to find the required crates.
375- macro_rules! lang_item_crate {
376- ( $( $name: expr) ,+ $( , ) ?) => { {
377- let mut v = ArrayVec :: <LangItemTarget , 2 >:: new( ) ;
378- $(
379- v. extend( db. lang_item( cur_crate, $name. into( ) ) ) ;
380- ) +
381- v
382- } } ;
383- }
384-
385396 let mod_to_crate_ids = |module : ModuleId | Some ( iter:: once ( module. krate ( ) ) . collect ( ) ) ;
386397
387- let lang_item_targets = match ty . kind ( Interner ) {
388- TyKind :: Adt ( AdtId ( def_id ) , _ ) => {
389- return mod_to_crate_ids ( def_id . module ( db . upcast ( ) ) ) ;
390- }
398+ let fp = TyFingerprint :: for_inherent_impl ( ty ) ;
399+
400+ match ty . kind ( Interner ) {
401+ TyKind :: Adt ( AdtId ( def_id ) , _ ) => mod_to_crate_ids ( def_id . module ( db . upcast ( ) ) ) ,
391402 TyKind :: Foreign ( id) => {
392- return mod_to_crate_ids (
393- from_foreign_def_id ( * id) . lookup ( db. upcast ( ) ) . module ( db. upcast ( ) ) ,
394- ) ;
395- }
396- TyKind :: Scalar ( Scalar :: Bool ) => lang_item_crate ! ( "bool" ) ,
397- TyKind :: Scalar ( Scalar :: Char ) => lang_item_crate ! ( "char" ) ,
398- TyKind :: Scalar ( Scalar :: Float ( f) ) => match f {
399- // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
400- FloatTy :: F32 => lang_item_crate ! ( "f32" , "f32_runtime" ) ,
401- FloatTy :: F64 => lang_item_crate ! ( "f64" , "f64_runtime" ) ,
402- } ,
403- & TyKind :: Scalar ( Scalar :: Int ( t) ) => {
404- lang_item_crate ! ( primitive:: int_ty_to_string( t) )
403+ mod_to_crate_ids ( from_foreign_def_id ( * id) . lookup ( db. upcast ( ) ) . module ( db. upcast ( ) ) )
405404 }
406- & TyKind :: Scalar ( Scalar :: Uint ( t ) ) => {
407- lang_item_crate ! ( primitive :: uint_ty_to_string ( t ) )
408- }
409- TyKind :: Str => lang_item_crate ! ( "str_alloc" , "str" ) ,
410- TyKind :: Slice ( _ ) => lang_item_crate ! ( "slice_alloc" , "slice" ) ,
411- TyKind :: Array ( .. ) => lang_item_crate ! ( "array" ) ,
412- TyKind :: Raw ( Mutability :: Not , _ ) => lang_item_crate ! ( "const_ptr" ) ,
413- TyKind :: Raw ( Mutability :: Mut , _ ) => lang_item_crate ! ( "mut_ptr" ) ,
414- TyKind :: Dyn ( _) => {
415- return ty . dyn_trait ( ) . and_then ( |trait_| {
416- mod_to_crate_ids ( GenericDefId :: TraitId ( trait_ ) . module ( db . upcast ( ) ) )
417- } ) ;
405+ TyKind :: Dyn ( _ ) => ty
406+ . dyn_trait ( )
407+ . and_then ( |trait_| mod_to_crate_ids ( GenericDefId :: TraitId ( trait_ ) . module ( db . upcast ( ) ) ) ) ,
408+ // for primitives, there may be impls in various places (core and alloc
409+ // mostly). We just check the whole crate graph for crates with impls
410+ // (cached behind a query).
411+ TyKind :: Scalar ( _ )
412+ | TyKind :: Str
413+ | TyKind :: Slice ( _)
414+ | TyKind :: Array ( .. )
415+ | TyKind :: Raw ( .. ) => {
416+ Some ( db . inherent_impl_crates ( cur_crate , fp . expect ( "fingerprint for primitive" ) ) )
418417 }
419418 _ => return None ,
420- } ;
421- let res = lang_item_targets
422- . into_iter ( )
423- . filter_map ( |it| match it {
424- LangItemTarget :: ImplDefId ( it) => Some ( it) ,
425- _ => None ,
426- } )
427- . map ( |it| it. lookup ( db. upcast ( ) ) . container . krate ( ) )
428- . collect ( ) ;
429- Some ( res)
419+ }
430420}
431421
432422/// Look up the method with the given name.
0 commit comments