@@ -8,9 +8,8 @@ use arrayvec::ArrayVec;
8
8
use base_db:: { CrateId , Edition } ;
9
9
use chalk_ir:: { cast:: Cast , Mutability , UniverseIndex } ;
10
10
use 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 ,
14
13
} ;
15
14
use hir_expand:: name:: Name ;
16
15
use rustc_hash:: { FxHashMap , FxHashSet } ;
@@ -21,7 +20,7 @@ use crate::{
21
20
db:: HirDatabase ,
22
21
from_foreign_def_id,
23
22
infer:: { unify:: InferenceTable , Adjust , Adjustment , AutoBorrow , OverloadedDeref , PointerCast } ,
24
- primitive:: { self , FloatTy , IntTy , UintTy } ,
23
+ primitive:: { FloatTy , IntTy , UintTy } ,
25
24
static_lifetime,
26
25
utils:: all_super_traits,
27
26
AdtId , Canonical , CanonicalVarKinds , DebruijnIndex , ForeignDefId , InEnvironment , Interner ,
@@ -337,6 +336,30 @@ impl InherentImpls {
337
336
}
338
337
}
339
338
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
+
340
363
fn collect_unnamed_consts < ' a > (
341
364
db : & ' a dyn HirDatabase ,
342
365
scope : & ' a ItemScope ,
@@ -370,63 +393,30 @@ pub fn def_crates(
370
393
ty : & Ty ,
371
394
cur_crate : CrateId ,
372
395
) -> 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
-
385
396
let mod_to_crate_ids = |module : ModuleId | Some ( iter:: once ( module. krate ( ) ) . collect ( ) ) ;
386
397
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 ( ) ) ) ,
391
402
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 ( ) ) )
405
404
}
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" ) ) )
418
417
}
419
418
_ => 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
+ }
430
420
}
431
421
432
422
/// Look up the method with the given name.
0 commit comments