@@ -10,7 +10,7 @@ use rustc_hir::def::{
1010 PerNS , Res ,
1111} ;
1212use rustc_hir:: def_id:: DefId ;
13- use rustc_middle:: ty:: { self , TyCtxt } ;
13+ use rustc_middle:: ty;
1414use rustc_resolve:: ParentScope ;
1515use rustc_session:: lint;
1616use rustc_span:: hygiene:: MacroKind ;
@@ -327,7 +327,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
327327 // To handle that properly resolve() would have to support
328328 // something like [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
329329 . 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+ ) ;
331333 debug ! ( "got associated item kind {:?}" , kind) ;
332334 kind
333335 } ) ;
@@ -440,6 +442,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
440442
441443fn resolve_associated_trait_item (
442444 did : DefId ,
445+ module : DefId ,
443446 item_name : Symbol ,
444447 ns : Namespace ,
445448 cx : & DocContext < ' _ > ,
@@ -504,8 +507,7 @@ fn resolve_associated_trait_item(
504507 // Next consider explicit impls: `impl MyTrait for MyType`
505508 // Give precedence to inherent impls.
506509 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) ;
509511 debug ! ( "considering traits {:?}" , traits) ;
510512 candidates. extend ( traits. iter ( ) . filter_map ( |& trait_| {
511513 cx. tcx
@@ -519,27 +521,30 @@ fn resolve_associated_trait_item(
519521 candidates. pop ( ) . map ( |( _, kind) | kind)
520522}
521523
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.
523525///
524526/// NOTE: this cannot be a query because more traits could be available when more crates are compiled!
525527/// 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+ } ) ;
529535
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_| {
533538 trace ! ( "considering explicit impl for trait {:?}" , trait_) ;
534539 let mut saw_impl = false ;
535540 // 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_| {
537542 // FIXME: this is inefficient, find a way to short-circuit for_each_* so this doesn't take as long
538543 if saw_impl {
539544 return ;
540545 }
541546
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" ) ;
543548 // Check if these are the same type.
544549 let impl_type = trait_ref. self_ty ( ) ;
545550 debug ! (
0 commit comments