@@ -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,29 @@ 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 ( ) ) else {
605+ return vec ! [ ] ;
622606 } ;
623- resolve_associated_item ( tcx, res, item_name, ns, disambiguator, module_id)
607+ let aliased_items =
608+ resolve_associated_item ( tcx, aliased_res, item_name, ns, disambiguator, module_id) ;
609+ aliased_items
610+ . into_iter ( )
611+ . map ( |( res, assoc_did) | {
612+ if is_assoc_item_on_alias_page ( tcx, assoc_did) {
613+ ( root_res, assoc_did)
614+ } else {
615+ ( res, assoc_did)
616+ }
617+ } )
618+ . collect ( )
624619 }
620+ Res :: Primitive ( prim) => resolve_assoc_on_primitive ( tcx, prim, ns, item_ident, module_id) ,
625621 Res :: Def ( DefKind :: Struct | DefKind :: Union | DefKind :: Enum , did) => {
626- resolve_assoc_on_adt ( tcx, did, item_name , ns, disambiguator, module_id)
622+ resolve_assoc_on_adt ( tcx, did, item_ident , ns, disambiguator, module_id)
627623 }
628624 Res :: Def ( DefKind :: ForeignTy , did) => {
629625 resolve_assoc_on_simple_type ( tcx, did, item_ident, ns, module_id)
@@ -640,23 +636,56 @@ fn resolve_associated_item<'tcx>(
640636 }
641637}
642638
639+ // FIXME: make this fully complete by also including ALL inherent impls
640+ // and trait impls BUT ONLY if on alias directly
641+ fn is_assoc_item_on_alias_page < ' tcx > ( tcx : TyCtxt < ' tcx > , assoc_did : DefId ) -> bool {
642+ match tcx. def_kind ( assoc_did) {
643+ // Variants and fields always have docs on the alias page.
644+ DefKind :: Variant | DefKind :: Field => true ,
645+ _ => false ,
646+ }
647+ }
648+
649+ fn resolve_assoc_on_primitive < ' tcx > (
650+ tcx : TyCtxt < ' tcx > ,
651+ prim : PrimitiveType ,
652+ ns : Namespace ,
653+ item_ident : Ident ,
654+ module_id : DefId ,
655+ ) -> Vec < ( Res , DefId ) > {
656+ let root_res = Res :: Primitive ( prim) ;
657+ let items = resolve_primitive_inherent_assoc_item ( tcx, prim, ns, item_ident) ;
658+ if !items. is_empty ( ) {
659+ items
660+ // Inherent associated items take precedence over items that come from trait impls.
661+ } else {
662+ primitive_type_to_ty ( tcx, prim)
663+ . map ( |ty| {
664+ resolve_associated_trait_item ( ty, module_id, item_ident, ns, tcx)
665+ . iter ( )
666+ . map ( |item| ( root_res, item. def_id ) )
667+ . collect :: < Vec < _ > > ( )
668+ } )
669+ . unwrap_or_default ( )
670+ }
671+ }
672+
643673fn resolve_assoc_on_adt < ' tcx > (
644674 tcx : TyCtxt < ' tcx > ,
645675 adt_def_id : DefId ,
646- item_name : Symbol ,
676+ item_ident : Ident ,
647677 ns : Namespace ,
648678 disambiguator : Option < Disambiguator > ,
649679 module_id : DefId ,
650680) -> Vec < ( Res , DefId ) > {
651- debug ! ( "looking for associated item named {item_name } for item {adt_def_id:?}" ) ;
681+ debug ! ( "looking for associated item named {item_ident } for item {adt_def_id:?}" ) ;
652682 let root_res = Res :: from_def_id ( tcx, adt_def_id) ;
653683 let adt_ty = tcx. type_of ( adt_def_id) . instantiate_identity ( ) ;
654684 let adt_def = adt_ty. ty_adt_def ( ) . expect ( "must be ADT" ) ;
655- let item_ident = Ident :: with_dummy_span ( item_name) ;
656685 // Checks if item_name is a variant of the `SomeItem` enum
657686 if ns == TypeNS && adt_def. is_enum ( ) {
658687 for variant in adt_def. variants ( ) {
659- if variant. name == item_name {
688+ if variant. name == item_ident . name {
660689 return vec ! [ ( root_res, variant. def_id) ] ;
661690 }
662691 }
@@ -665,7 +694,7 @@ fn resolve_assoc_on_adt<'tcx>(
665694 if let Some ( Disambiguator :: Kind ( DefKind :: Field ) ) = disambiguator
666695 && ( adt_def. is_struct ( ) || adt_def. is_union ( ) )
667696 {
668- return resolve_structfield ( adt_def, item_name )
697+ return resolve_structfield ( adt_def, item_ident . name )
669698 . into_iter ( )
670699 . map ( |did| ( root_res, did) )
671700 . collect ( ) ;
@@ -677,7 +706,7 @@ fn resolve_assoc_on_adt<'tcx>(
677706 }
678707
679708 if ns == Namespace :: ValueNS && ( adt_def. is_struct ( ) || adt_def. is_union ( ) ) {
680- return resolve_structfield ( adt_def, item_name )
709+ return resolve_structfield ( adt_def, item_ident . name )
681710 . into_iter ( )
682711 . map ( |did| ( root_res, did) )
683712 . collect ( ) ;
0 commit comments