@@ -377,7 +377,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
377377 ns : Namespace ,
378378 module_id : DefId ,
379379 item_name : Symbol ,
380- item_str : & ' path str ,
381380 ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
382381 let tcx = self . cx . tcx ;
383382
@@ -399,7 +398,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
399398 . map ( |out| {
400399 (
401400 Res :: Primitive ( prim_ty) ,
402- Some ( format ! ( "{}#{}.{}" , prim_ty. as_str( ) , out, item_str ) ) ,
401+ Some ( format ! ( "{}#{}.{}" , prim_ty. as_str( ) , out, item_name ) ) ,
403402 )
404403 } )
405404 } )
@@ -413,7 +412,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
413412 ResolutionFailure :: NotResolved {
414413 module_id,
415414 partial_res : Some ( Res :: Primitive ( prim_ty) ) ,
416- unresolved : item_str . into ( ) ,
415+ unresolved : item_name . to_string ( ) . into ( ) ,
417416 }
418417 . into ( )
419418 } )
@@ -490,8 +489,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
490489 module_id : DefId ,
491490 extra_fragment : & Option < String > ,
492491 ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
493- let tcx = self . cx . tcx ;
494-
495492 if let Some ( res) = self . resolve_path ( path_str, ns, module_id) {
496493 match res {
497494 // FIXME(#76467): make this fallthrough to lookup the associated
@@ -534,29 +531,44 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
534531 }
535532 } ) ?;
536533
537- // FIXME: are these both necessary?
538- let ty_res = if let Some ( ty_res) = resolve_primitive ( & path_root, TypeNS )
534+ // FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support
535+ // links to primitives when `#[doc(primitive)]` is present. It should give an ambiguity
536+ // error instead and special case *only* modules with `#[doc(primitive)]`, not all
537+ // primitives.
538+ resolve_primitive ( & path_root, TypeNS )
539539 . or_else ( || self . resolve_path ( & path_root, TypeNS , module_id) )
540- {
541- ty_res
542- } else {
543- // FIXME: this is duplicated on the end of this function.
544- return if ns == Namespace :: ValueNS {
545- self . variant_field ( path_str, module_id)
546- } else {
547- Err ( ResolutionFailure :: NotResolved {
548- module_id,
549- partial_res : None ,
550- unresolved : path_root. into ( ) ,
540+ . and_then ( |ty_res| {
541+ self . resolve_associated_item ( ty_res, item_name, ns, module_id, extra_fragment)
542+ } )
543+ . unwrap_or_else ( || {
544+ if ns == Namespace :: ValueNS {
545+ self . variant_field ( path_str, module_id)
546+ } else {
547+ Err ( ResolutionFailure :: NotResolved {
548+ module_id,
549+ partial_res : None ,
550+ unresolved : path_root. into ( ) ,
551+ }
552+ . into ( ) )
551553 }
552- . into ( ) )
553- } ;
554- } ;
554+ } )
555+ }
556+
557+ fn resolve_associated_item (
558+ & mut self ,
559+ root_res : Res ,
560+ item_name : Symbol ,
561+ ns : Namespace ,
562+ module_id : DefId ,
563+ extra_fragment : & Option < String > ,
564+ // lol this is so bad
565+ ) -> Option < Result < ( Res , Option < String > ) , ErrorKind < ' static > > > {
566+ let tcx = self . cx . tcx ;
555567
556- let res = match ty_res {
557- Res :: Primitive ( prim) => Some (
558- self . resolve_primitive_associated_item ( prim, ns, module_id, item_name, item_str ) ,
559- ) ,
568+ match root_res {
569+ Res :: Primitive ( prim) => {
570+ Some ( self . resolve_primitive_associated_item ( prim, ns, module_id, item_name) )
571+ }
560572 Res :: Def (
561573 DefKind :: Struct
562574 | DefKind :: Union
@@ -600,13 +612,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
600612 ty:: AssocKind :: Type => "associatedtype" ,
601613 } ;
602614 Some ( if extra_fragment. is_some ( ) {
603- Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( ty_res) ) )
615+ Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict (
616+ root_res,
617+ ) ) )
604618 } else {
605619 // HACK(jynelson): `clean` expects the type, not the associated item
606620 // but the disambiguator logic expects the associated item.
607621 // Store the kind in a side channel so that only the disambiguator logic looks at it.
608622 self . kind_side_channel . set ( Some ( ( kind. as_def_kind ( ) , id) ) ) ;
609- Ok ( ( ty_res , Some ( format ! ( "{}.{}" , out, item_str ) ) ) )
623+ Ok ( ( root_res , Some ( format ! ( "{}.{}" , out, item_name ) ) ) )
610624 } )
611625 } else if ns == Namespace :: ValueNS {
612626 debug ! ( "looking for variants or fields named {} for {:?}" , item_name, did) ;
@@ -637,7 +651,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
637651 ) )
638652 } else {
639653 Ok ( (
640- ty_res ,
654+ root_res ,
641655 Some ( format ! (
642656 "{}.{}" ,
643657 if def. is_enum( ) { "variant" } else { "structfield" } ,
@@ -670,26 +684,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
670684 } ;
671685
672686 if extra_fragment. is_some ( ) {
673- Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( ty_res) ) )
687+ Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict (
688+ root_res,
689+ ) ) )
674690 } else {
675691 let res = Res :: Def ( item. kind . as_def_kind ( ) , item. def_id ) ;
676- Ok ( ( res, Some ( format ! ( "{}.{}" , kind, item_str ) ) ) )
692+ Ok ( ( res, Some ( format ! ( "{}.{}" , kind, item_name ) ) ) )
677693 }
678694 } ) ,
679695 _ => None ,
680- } ;
681- res. unwrap_or_else ( || {
682- if ns == Namespace :: ValueNS {
683- self . variant_field ( path_str, module_id)
684- } else {
685- Err ( ResolutionFailure :: NotResolved {
686- module_id,
687- partial_res : Some ( ty_res) ,
688- unresolved : item_str. into ( ) ,
689- }
690- . into ( ) )
691- }
692- } )
696+ }
693697 }
694698
695699 /// Used for reporting better errors.
0 commit comments