@@ -513,7 +513,31 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
513513 path_str : & ' path str ,
514514 ns : Namespace ,
515515 module_id : DefId ,
516- extra_fragment : & Option < UrlFragment > ,
516+ user_fragment : & Option < UrlFragment > ,
517+ ) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' path > > {
518+ let ( res, rustdoc_fragment) = self . resolve_inner ( path_str, ns, module_id) ?;
519+ let chosen_fragment = match ( user_fragment, rustdoc_fragment) {
520+ ( Some ( _) , Some ( r_frag) ) => {
521+ let diag_res = match r_frag {
522+ UrlFragment :: Def ( _, did) => Res :: Def ( self . cx . tcx . def_kind ( did) , did) ,
523+ // FIXME: eliminate this branch somehow
524+ UrlFragment :: UserWritten ( _) => unreachable ! ( ) ,
525+ } ;
526+ let failure = AnchorFailure :: RustdocAnchorConflict ( diag_res) ;
527+ return Err ( ErrorKind :: AnchorFailure ( failure) ) ;
528+ }
529+ ( Some ( u_frag) , None ) => Some ( u_frag. clone ( ) ) ,
530+ ( None , Some ( r_frag) ) => Some ( r_frag) ,
531+ ( None , None ) => None ,
532+ } ;
533+ Ok ( ( res, chosen_fragment) )
534+ }
535+
536+ fn resolve_inner < ' path > (
537+ & mut self ,
538+ path_str : & ' path str ,
539+ ns : Namespace ,
540+ module_id : DefId ,
517541 ) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' path > > {
518542 if let Some ( res) = self . resolve_path ( path_str, ns, module_id) {
519543 match res {
@@ -522,17 +546,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
522546 Res :: Def ( DefKind :: AssocFn | DefKind :: AssocConst , _) => assert_eq ! ( ns, ValueNS ) ,
523547 Res :: Def ( DefKind :: AssocTy , _) => assert_eq ! ( ns, TypeNS ) ,
524548 Res :: Def ( DefKind :: Variant , _) => {
525- if extra_fragment. is_some ( ) {
526- // NOTE: `res` can never be a primitive since this match arm means
527- // `tcx.def_kind(res) == DefKind::Variant`.
528- return Err ( ErrorKind :: AnchorFailure (
529- AnchorFailure :: RustdocAnchorConflict ( res) ,
530- ) ) ;
531- }
532549 return handle_variant ( self . cx , res) ;
533550 }
534551 // Not a trait item; just return what we found.
535- _ => return Ok ( ( res, extra_fragment . clone ( ) ) ) ,
552+ _ => return Ok ( ( res, None ) ) ,
536553 }
537554 }
538555
@@ -565,21 +582,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
565582 . and_then ( |ty_res| {
566583 let ( res, fragment, side_channel) =
567584 self . resolve_associated_item ( ty_res, item_name, ns, module_id) ?;
568- let result = if extra_fragment. is_some ( ) {
569- // NOTE: can never be a primitive since `side_channel.is_none()` only when `res`
570- // is a trait (and the side channel DefId is always an associated item).
571- let diag_res = side_channel. map_or ( res, |( k, r) | Res :: Def ( k, r) ) ;
572- Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( diag_res) ) )
573- } else {
574- // HACK(jynelson): `clean` expects the type, not the associated item
575- // but the disambiguator logic expects the associated item.
576- // Store the kind in a side channel so that only the disambiguator logic looks at it.
577- if let Some ( ( kind, id) ) = side_channel {
578- self . kind_side_channel . set ( Some ( ( kind, id) ) ) ;
579- }
580- Ok ( ( res, Some ( fragment) ) )
581- } ;
582- Some ( result)
585+
586+ // HACK(jynelson): `clean` expects the type, not the associated item
587+ // but the disambiguator logic expects the associated item.
588+ // Store the kind in a side channel so that only the disambiguator logic looks at it.
589+ if let Some ( ( kind, id) ) = side_channel {
590+ self . kind_side_channel . set ( Some ( ( kind, id) ) ) ;
591+ }
592+ Some ( Ok ( ( res, Some ( fragment) ) ) )
583593 } )
584594 . unwrap_or_else ( || {
585595 if ns == Namespace :: ValueNS {
0 commit comments