@@ -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- }
616600 Res :: Def ( DefKind :: TyAlias , 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 ( 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, def_id) | {
612+ if is_assoc_item_on_alias_page ( tcx, def_id) {
613+ ( root_res, def_id)
614+ } else {
615+ ( res, def_id)
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,55 @@ 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 > , def_id : DefId ) -> bool {
642+ match tcx. def_kind ( def_id) {
643+ DefKind :: Variant | DefKind :: Field => true ,
644+ _ => false ,
645+ }
646+ }
647+
648+ fn resolve_assoc_on_primitive < ' tcx > (
649+ tcx : TyCtxt < ' tcx > ,
650+ prim : PrimitiveType ,
651+ ns : Namespace ,
652+ item_ident : Ident ,
653+ module_id : DefId ,
654+ ) -> Vec < ( Res , DefId ) > {
655+ let root_res = Res :: Primitive ( prim) ;
656+ let items = resolve_primitive_inherent_assoc_item ( tcx, prim, ns, item_ident) ;
657+ if !items. is_empty ( ) {
658+ items
659+ // Inherent associated items take precedence over items that come from trait impls.
660+ } else {
661+ primitive_type_to_ty ( tcx, prim)
662+ . map ( |ty| {
663+ resolve_associated_trait_item ( ty, module_id, item_ident, ns, tcx)
664+ . iter ( )
665+ . map ( |item| ( root_res, item. def_id ) )
666+ . collect :: < Vec < _ > > ( )
667+ } )
668+ . unwrap_or_default ( )
669+ }
670+ }
671+
643672fn resolve_assoc_on_adt < ' tcx > (
644673 tcx : TyCtxt < ' tcx > ,
645674 adt_def_id : DefId ,
646- item_name : Symbol ,
675+ item_ident : Ident ,
647676 ns : Namespace ,
648677 disambiguator : Option < Disambiguator > ,
649678 module_id : DefId ,
650679) -> Vec < ( Res , DefId ) > {
651- debug ! ( "looking for associated item named {item_name } for item {adt_def_id:?}" ) ;
680+ debug ! ( "looking for associated item named {item_ident } for item {adt_def_id:?}" ) ;
652681 let root_res = Res :: from_def_id ( tcx, adt_def_id) ;
653682 let adt_ty = tcx. type_of ( adt_def_id) . instantiate_identity ( ) ;
654683 let adt_def = adt_ty. ty_adt_def ( ) . expect ( "must be ADT" ) ;
655- let item_ident = Ident :: with_dummy_span ( item_name) ;
656684 // Checks if item_name is a variant of the `SomeItem` enum
657685 if ns == TypeNS && adt_def. is_enum ( ) {
658686 for variant in adt_def. variants ( ) {
659- if variant. name == item_name {
687+ if variant. name == item_ident . name {
660688 return vec ! [ ( root_res, variant. def_id) ] ;
661689 }
662690 }
@@ -665,7 +693,7 @@ fn resolve_assoc_on_adt<'tcx>(
665693 if let Some ( Disambiguator :: Kind ( DefKind :: Field ) ) = disambiguator
666694 && ( adt_def. is_struct ( ) || adt_def. is_union ( ) )
667695 {
668- return resolve_structfield ( adt_def, item_name )
696+ return resolve_structfield ( adt_def, item_ident . name )
669697 . into_iter ( )
670698 . map ( |did| ( root_res, did) )
671699 . collect ( ) ;
@@ -677,7 +705,7 @@ fn resolve_assoc_on_adt<'tcx>(
677705 }
678706
679707 if ns == Namespace :: ValueNS && ( adt_def. is_struct ( ) || adt_def. is_union ( ) ) {
680- return resolve_structfield ( adt_def, item_name )
708+ return resolve_structfield ( adt_def, item_ident . name )
681709 . into_iter ( )
682710 . map ( |did| ( root_res, did) )
683711 . collect ( ) ;
0 commit comments