@@ -10,7 +10,7 @@ use rustc_hir::def::{
10
10
PerNS , Res ,
11
11
} ;
12
12
use rustc_hir:: def_id:: DefId ;
13
- use rustc_middle:: ty:: { self , TyCtxt } ;
13
+ use rustc_middle:: ty;
14
14
use rustc_resolve:: ParentScope ;
15
15
use rustc_session:: lint;
16
16
use rustc_span:: hygiene:: MacroKind ;
@@ -327,7 +327,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
327
327
// To handle that properly resolve() would have to support
328
328
// something like [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
329
329
. or_else ( || {
330
- let kind = resolve_associated_trait_item ( did, item_name, ns, & self . cx ) ;
330
+ let kind = resolve_associated_trait_item (
331
+ did, module_id, item_name, ns, & self . cx ,
332
+ ) ;
331
333
debug ! ( "got associated item kind {:?}" , kind) ;
332
334
kind
333
335
} ) ;
@@ -440,6 +442,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
440
442
441
443
fn resolve_associated_trait_item (
442
444
did : DefId ,
445
+ module : DefId ,
443
446
item_name : Symbol ,
444
447
ns : Namespace ,
445
448
cx : & DocContext < ' _ > ,
@@ -504,8 +507,7 @@ fn resolve_associated_trait_item(
504
507
// Next consider explicit impls: `impl MyTrait for MyType`
505
508
// Give precedence to inherent impls.
506
509
if candidates. is_empty ( ) {
507
- let mut cache = cx. type_trait_cache . borrow_mut ( ) ;
508
- let traits = cache. entry ( did) . or_insert_with ( || traits_implemented_by ( cx. tcx , did) ) ;
510
+ let traits = traits_implemented_by ( cx, did, module) ;
509
511
debug ! ( "considering traits {:?}" , traits) ;
510
512
candidates. extend ( traits. iter ( ) . filter_map ( |& trait_| {
511
513
cx. tcx
@@ -519,27 +521,30 @@ fn resolve_associated_trait_item(
519
521
candidates. pop ( ) . map ( |( _, kind) | kind)
520
522
}
521
523
522
- /// Given a type, return all traits implemented by that type.
524
+ /// Given a type, return all traits in scope in `module` implemented by that type.
523
525
///
524
526
/// NOTE: this cannot be a query because more traits could be available when more crates are compiled!
525
527
/// So it is not stable to serialize cross-crate.
526
- /// FIXME: this should only search traits in scope
527
- fn traits_implemented_by < ' a > ( tcx : TyCtxt < ' a > , type_ : DefId ) -> FxHashSet < DefId > {
528
- use rustc_hir:: def_id:: LOCAL_CRATE ;
528
+ fn traits_implemented_by ( cx : & DocContext < ' _ > , type_ : DefId , module : DefId ) -> FxHashSet < DefId > {
529
+ let mut cache = cx. module_trait_cache . borrow_mut ( ) ;
530
+ let in_scope_traits = cache. entry ( module) . or_insert_with ( || {
531
+ cx. enter_resolver ( |resolver| {
532
+ resolver. traits_in_scope ( module) . into_iter ( ) . map ( |candidate| candidate. def_id ) . collect ( )
533
+ } )
534
+ } ) ;
529
535
530
- let all_traits = tcx. all_traits ( LOCAL_CRATE ) . iter ( ) . copied ( ) ;
531
- let ty = tcx. type_of ( type_) ;
532
- let iter = all_traits. flat_map ( |trait_| {
536
+ let ty = cx. tcx . type_of ( type_) ;
537
+ let iter = in_scope_traits. iter ( ) . flat_map ( |& trait_| {
533
538
trace ! ( "considering explicit impl for trait {:?}" , trait_) ;
534
539
let mut saw_impl = false ;
535
540
// Look at each trait implementation to see if it's an impl for `did`
536
- tcx. for_each_relevant_impl ( trait_, ty, |impl_| {
541
+ cx . tcx . for_each_relevant_impl ( trait_, ty, |impl_| {
537
542
// FIXME: this is inefficient, find a way to short-circuit for_each_* so this doesn't take as long
538
543
if saw_impl {
539
544
return ;
540
545
}
541
546
542
- let trait_ref = tcx. impl_trait_ref ( impl_) . expect ( "this is not an inherent impl" ) ;
547
+ let trait_ref = cx . tcx . impl_trait_ref ( impl_) . expect ( "this is not an inherent impl" ) ;
543
548
// Check if these are the same type.
544
549
let impl_type = trait_ref. self_ty ( ) ;
545
550
debug ! (
0 commit comments