@@ -462,7 +462,7 @@ fn full_res(tcx: TyCtxt<'_>, (base, assoc_item): (Res, Option<DefId>)) -> Res {
462462}
463463
464464/// Given a primitive type, try to resolve an associated item.
465- fn resolve_primitive_associated_item < ' tcx > (
465+ fn resolve_primitive_inherent_assoc_item < ' tcx > (
466466 tcx : TyCtxt < ' tcx > ,
467467 prim_ty : PrimitiveType ,
468468 ns : Namespace ,
@@ -597,33 +597,30 @@ fn resolve_associated_item<'tcx>(
597597 let item_ident = Ident :: with_dummy_span ( item_name) ;
598598
599599 match root_res {
600- Res :: Primitive ( prim) => {
601- let items = resolve_primitive_associated_item ( tcx, prim, ns, item_ident) ;
602- if !items. is_empty ( ) {
603- items
604- // Inherent associated items take precedence over items that come from trait impls.
605- } else {
606- primitive_type_to_ty ( tcx, prim)
607- . map ( |ty| {
608- resolve_associated_trait_item ( ty, module_id, item_ident, ns, tcx)
609- . iter ( )
610- . map ( |item| ( root_res, item. def_id ) )
611- . collect :: < Vec < _ > > ( )
612- } )
613- . unwrap_or_default ( )
614- }
615- }
616- Res :: Def ( DefKind :: TyAlias , did) => {
600+ Res :: Def ( DefKind :: TyAlias , alias_did) => {
617601 // Resolve the link on the type the alias points to.
618602 // FIXME: if the associated item is defined directly on the type alias,
619603 // it will show up on its documentation page, we should link there instead.
620- let Some ( res) = ty_to_res ( tcx, tcx. type_of ( did) . instantiate_identity ( ) ) else {
621- return Vec :: new ( ) ;
604+ let Some ( aliased_res) = ty_to_res ( tcx, tcx. type_of ( alias_did) . instantiate_identity ( ) )
605+ else {
606+ return vec ! [ ] ;
622607 } ;
623- resolve_associated_item ( tcx, res, item_name, ns, disambiguator, module_id)
608+ let aliased_items =
609+ resolve_associated_item ( tcx, aliased_res, item_name, ns, disambiguator, module_id) ;
610+ aliased_items
611+ . into_iter ( )
612+ . map ( |( res, assoc_did) | {
613+ if is_assoc_item_on_alias_page ( tcx, assoc_did) {
614+ ( root_res, assoc_did)
615+ } else {
616+ ( res, assoc_did)
617+ }
618+ } )
619+ . collect ( )
624620 }
621+ Res :: Primitive ( prim) => resolve_assoc_on_primitive ( tcx, prim, ns, item_ident, module_id) ,
625622 Res :: Def ( DefKind :: Struct | DefKind :: Union | DefKind :: Enum , did) => {
626- resolve_assoc_on_adt ( tcx, did, item_name , ns, disambiguator, module_id)
623+ resolve_assoc_on_adt ( tcx, did, item_ident , ns, disambiguator, module_id)
627624 }
628625 Res :: Def ( DefKind :: ForeignTy , did) => {
629626 resolve_assoc_on_simple_type ( tcx, did, item_ident, ns, module_id)
@@ -640,23 +637,56 @@ fn resolve_associated_item<'tcx>(
640637 }
641638}
642639
640+ // FIXME: make this fully complete by also including ALL inherent impls
641+ // and trait impls BUT ONLY if on alias directly
642+ fn is_assoc_item_on_alias_page < ' tcx > ( tcx : TyCtxt < ' tcx > , assoc_did : DefId ) -> bool {
643+ match tcx. def_kind ( assoc_did) {
644+ // Variants and fields always have docs on the alias page.
645+ DefKind :: Variant | DefKind :: Field => true ,
646+ _ => false ,
647+ }
648+ }
649+
650+ fn resolve_assoc_on_primitive < ' tcx > (
651+ tcx : TyCtxt < ' tcx > ,
652+ prim : PrimitiveType ,
653+ ns : Namespace ,
654+ item_ident : Ident ,
655+ module_id : DefId ,
656+ ) -> Vec < ( Res , DefId ) > {
657+ let root_res = Res :: Primitive ( prim) ;
658+ let items = resolve_primitive_inherent_assoc_item ( tcx, prim, ns, item_ident) ;
659+ if !items. is_empty ( ) {
660+ items
661+ // Inherent associated items take precedence over items that come from trait impls.
662+ } else {
663+ primitive_type_to_ty ( tcx, prim)
664+ . map ( |ty| {
665+ resolve_associated_trait_item ( ty, module_id, item_ident, ns, tcx)
666+ . iter ( )
667+ . map ( |item| ( root_res, item. def_id ) )
668+ . collect :: < Vec < _ > > ( )
669+ } )
670+ . unwrap_or_default ( )
671+ }
672+ }
673+
643674fn resolve_assoc_on_adt < ' tcx > (
644675 tcx : TyCtxt < ' tcx > ,
645676 adt_def_id : DefId ,
646- item_name : Symbol ,
677+ item_ident : Ident ,
647678 ns : Namespace ,
648679 disambiguator : Option < Disambiguator > ,
649680 module_id : DefId ,
650681) -> Vec < ( Res , DefId ) > {
651- debug ! ( "looking for associated item named {item_name } for item {adt_def_id:?}" ) ;
682+ debug ! ( "looking for associated item named {item_ident } for item {adt_def_id:?}" ) ;
652683 let root_res = Res :: from_def_id ( tcx, adt_def_id) ;
653684 let adt_ty = tcx. type_of ( adt_def_id) . instantiate_identity ( ) ;
654685 let adt_def = adt_ty. ty_adt_def ( ) . expect ( "must be ADT" ) ;
655- let item_ident = Ident :: with_dummy_span ( item_name) ;
656686 // Checks if item_name is a variant of the `SomeItem` enum
657687 if ns == TypeNS && adt_def. is_enum ( ) {
658688 for variant in adt_def. variants ( ) {
659- if variant. name == item_name {
689+ if variant. name == item_ident . name {
660690 return vec ! [ ( root_res, variant. def_id) ] ;
661691 }
662692 }
@@ -665,7 +695,7 @@ fn resolve_assoc_on_adt<'tcx>(
665695 if let Some ( Disambiguator :: Kind ( DefKind :: Field ) ) = disambiguator
666696 && ( adt_def. is_struct ( ) || adt_def. is_union ( ) )
667697 {
668- return resolve_structfield ( adt_def, item_name )
698+ return resolve_structfield ( adt_def, item_ident . name )
669699 . into_iter ( )
670700 . map ( |did| ( root_res, did) )
671701 . collect ( ) ;
@@ -677,7 +707,7 @@ fn resolve_assoc_on_adt<'tcx>(
677707 }
678708
679709 if ns == Namespace :: ValueNS && ( adt_def. is_struct ( ) || adt_def. is_union ( ) ) {
680- return resolve_structfield ( adt_def, item_name )
710+ return resolve_structfield ( adt_def, item_ident . name )
681711 . into_iter ( )
682712 . map ( |did| ( root_res, did) )
683713 . collect ( ) ;
0 commit comments