@@ -236,10 +236,23 @@ enum AnchorFailure {
236236
237237#[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
238238crate enum UrlFragment {
239- Def ( FragmentKind , DefId ) ,
239+ Item ( ItemFragment ) ,
240240 UserWritten ( String ) ,
241241}
242242
243+ impl UrlFragment {
244+ /// Render the fragment, including the leading `#`.
245+ crate fn render ( & self , s : & mut String , tcx : TyCtxt < ' _ > ) -> std:: fmt:: Result {
246+ match self {
247+ UrlFragment :: Item ( frag) => frag. render ( s, tcx) ,
248+ UrlFragment :: UserWritten ( raw) => write ! ( s, "#{}" , raw) ,
249+ }
250+ }
251+ }
252+
253+ #[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
254+ crate struct ItemFragment ( FragmentKind , DefId ) ;
255+
243256#[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
244257crate enum FragmentKind {
245258 Method ,
@@ -252,7 +265,7 @@ crate enum FragmentKind {
252265 VariantField ,
253266}
254267
255- impl UrlFragment {
268+ impl ItemFragment {
256269 /// Create a fragment for an associated item.
257270 ///
258271 /// `is_prototype` is whether this associated item is a trait method
@@ -261,21 +274,21 @@ impl UrlFragment {
261274 match kind {
262275 ty:: AssocKind :: Fn => {
263276 if is_prototype {
264- UrlFragment :: Def ( FragmentKind :: TyMethod , def_id)
277+ ItemFragment ( FragmentKind :: TyMethod , def_id)
265278 } else {
266- UrlFragment :: Def ( FragmentKind :: Method , def_id)
279+ ItemFragment ( FragmentKind :: Method , def_id)
267280 }
268281 }
269- ty:: AssocKind :: Const => UrlFragment :: Def ( FragmentKind :: AssociatedConstant , def_id) ,
270- ty:: AssocKind :: Type => UrlFragment :: Def ( FragmentKind :: AssociatedType , def_id) ,
282+ ty:: AssocKind :: Const => ItemFragment ( FragmentKind :: AssociatedConstant , def_id) ,
283+ ty:: AssocKind :: Type => ItemFragment ( FragmentKind :: AssociatedType , def_id) ,
271284 }
272285 }
273286
274287 /// Render the fragment, including the leading `#`.
275288 crate fn render ( & self , s : & mut String , tcx : TyCtxt < ' _ > ) -> std:: fmt:: Result {
276289 write ! ( s, "#" ) ?;
277290 match * self {
278- UrlFragment :: Def ( kind, def_id) => {
291+ ItemFragment ( kind, def_id) => {
279292 let name = tcx. item_name ( def_id) ;
280293 match kind {
281294 FragmentKind :: Method => write ! ( s, "method.{}" , name) ,
@@ -290,7 +303,6 @@ impl UrlFragment {
290303 }
291304 }
292305 }
293- UrlFragment :: UserWritten ( ref raw) => write ! ( s, "{}" , raw) ,
294306 }
295307 }
296308}
@@ -300,7 +312,7 @@ struct ResolutionInfo {
300312 module_id : DefId ,
301313 dis : Option < Disambiguator > ,
302314 path_str : String ,
303- extra_fragment : Option < UrlFragment > ,
315+ extra_fragment : Option < String > ,
304316}
305317
306318#[ derive( Clone ) ]
@@ -339,7 +351,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
339351 & self ,
340352 path_str : & ' path str ,
341353 module_id : DefId ,
342- ) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' path > > {
354+ ) -> Result < ( Res , Option < ItemFragment > ) , ErrorKind < ' path > > {
343355 let tcx = self . cx . tcx ;
344356 let no_res = || ResolutionFailure :: NotResolved {
345357 module_id,
@@ -389,10 +401,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
389401 if let Some ( field) =
390402 def. all_fields ( ) . find ( |f| f. ident . name == variant_field_name)
391403 {
392- Ok ( (
393- ty_res,
394- Some ( UrlFragment :: Def ( FragmentKind :: VariantField , field. did ) ) ,
395- ) )
404+ Ok ( ( ty_res, Some ( ItemFragment ( FragmentKind :: VariantField , field. did ) ) ) )
396405 } else {
397406 Err ( ResolutionFailure :: NotResolved {
398407 module_id,
@@ -420,15 +429,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
420429 prim_ty : PrimitiveType ,
421430 ns : Namespace ,
422431 item_name : Symbol ,
423- ) -> Option < ( Res , UrlFragment ) > {
432+ ) -> Option < ( Res , ItemFragment ) > {
424433 let tcx = self . cx . tcx ;
425434
426435 prim_ty. impls ( tcx) . into_iter ( ) . find_map ( |& impl_| {
427436 tcx. associated_items ( impl_)
428437 . find_by_name_and_namespace ( tcx, Ident :: with_dummy_span ( item_name) , ns, impl_)
429438 . map ( |item| {
430439 let kind = item. kind ;
431- let fragment = UrlFragment :: from_assoc_item ( item. def_id , kind, false ) ;
440+ let fragment = ItemFragment :: from_assoc_item ( item. def_id , kind, false ) ;
432441 ( Res :: Primitive ( prim_ty) , fragment)
433442 } )
434443 } )
@@ -503,21 +512,19 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
503512 path_str : & ' path str ,
504513 ns : Namespace ,
505514 module_id : DefId ,
506- user_fragment : & Option < UrlFragment > ,
515+ user_fragment : & Option < String > ,
507516 ) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' path > > {
508517 let ( res, rustdoc_fragment) = self . resolve_inner ( path_str, ns, module_id) ?;
509518 let chosen_fragment = match ( user_fragment, rustdoc_fragment) {
510519 ( Some ( _) , Some ( r_frag) ) => {
511520 let diag_res = match r_frag {
512- UrlFragment :: Def ( _, did) => Res :: Def ( self . cx . tcx . def_kind ( did) , did) ,
513- // FIXME: eliminate this branch somehow
514- UrlFragment :: UserWritten ( _) => unreachable ! ( ) ,
521+ ItemFragment ( _, did) => Res :: Def ( self . cx . tcx . def_kind ( did) , did) ,
515522 } ;
516523 let failure = AnchorFailure :: RustdocAnchorConflict ( diag_res) ;
517524 return Err ( ErrorKind :: AnchorFailure ( failure) ) ;
518525 }
519- ( Some ( u_frag) , None ) => Some ( u_frag. clone ( ) ) ,
520- ( None , Some ( r_frag) ) => Some ( r_frag) ,
526+ ( Some ( u_frag) , None ) => Some ( UrlFragment :: UserWritten ( u_frag. clone ( ) ) ) ,
527+ ( None , Some ( r_frag) ) => Some ( UrlFragment :: Item ( r_frag) ) ,
521528 ( None , None ) => None ,
522529 } ;
523530 Ok ( ( res, chosen_fragment) )
@@ -528,7 +535,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
528535 path_str : & ' path str ,
529536 ns : Namespace ,
530537 module_id : DefId ,
531- ) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' path > > {
538+ ) -> Result < ( Res , Option < ItemFragment > ) , ErrorKind < ' path > > {
532539 if let Some ( res) = self . resolve_path ( path_str, ns, module_id) {
533540 match res {
534541 // FIXME(#76467): make this fallthrough to lookup the associated
@@ -670,7 +677,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
670677 item_name : Symbol ,
671678 ns : Namespace ,
672679 module_id : DefId ,
673- ) -> Option < ( Res , UrlFragment ) > {
680+ ) -> Option < ( Res , ItemFragment ) > {
674681 let tcx = self . cx . tcx ;
675682
676683 match root_res {
@@ -685,7 +692,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
685692
686693 assoc_item. map ( |item| {
687694 let kind = item. kind ;
688- let fragment = UrlFragment :: from_assoc_item ( item. def_id , kind, false ) ;
695+ let fragment = ItemFragment :: from_assoc_item ( item. def_id , kind, false ) ;
689696 ( root_res, fragment)
690697 } )
691698 } )
@@ -736,7 +743,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
736743
737744 if let Some ( item) = assoc_item {
738745 let kind = item. kind ;
739- let fragment = UrlFragment :: from_assoc_item ( item. def_id , kind, false ) ;
746+ let fragment = ItemFragment :: from_assoc_item ( item. def_id , kind, false ) ;
740747 return Some ( ( root_res, fragment) ) ;
741748 }
742749
@@ -768,13 +775,13 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
768775 . fields
769776 . iter ( )
770777 . find ( |item| item. ident . name == item_name) ?;
771- Some ( ( root_res, UrlFragment :: Def ( FragmentKind :: StructField , field. did ) ) )
778+ Some ( ( root_res, ItemFragment ( FragmentKind :: StructField , field. did ) ) )
772779 }
773780 Res :: Def ( DefKind :: Trait , did) => tcx
774781 . associated_items ( did)
775782 . find_by_name_and_namespace ( tcx, Ident :: with_dummy_span ( item_name) , ns, did)
776783 . map ( |item| {
777- let fragment = UrlFragment :: from_assoc_item (
784+ let fragment = ItemFragment :: from_assoc_item (
778785 item. def_id ,
779786 item. kind ,
780787 !item. defaultness . has_value ( ) ,
@@ -797,7 +804,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
797804 ns : Namespace ,
798805 path_str : & str ,
799806 module_id : DefId ,
800- extra_fragment : & Option < UrlFragment > ,
807+ extra_fragment : & Option < String > ,
801808 ) -> Option < Res > {
802809 // resolve() can't be used for macro namespace
803810 let result = match ns {
@@ -812,7 +819,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
812819
813820 let res = match result {
814821 Ok ( ( res, frag) ) => {
815- if let Some ( UrlFragment :: Def ( _, id) ) = frag {
822+ if let Some ( UrlFragment :: Item ( ItemFragment ( _, id) ) ) = frag {
816823 Some ( Res :: Def ( self . cx . tcx . def_kind ( id) , id) )
817824 } else {
818825 Some ( res)
@@ -1039,7 +1046,7 @@ impl From<AnchorFailure> for PreprocessingError<'_> {
10391046struct PreprocessingInfo {
10401047 path_str : String ,
10411048 disambiguator : Option < Disambiguator > ,
1042- extra_fragment : Option < UrlFragment > ,
1049+ extra_fragment : Option < String > ,
10431050 link_text : String ,
10441051}
10451052
@@ -1125,7 +1132,7 @@ fn preprocess_link<'a>(
11251132 Some ( Ok ( PreprocessingInfo {
11261133 path_str,
11271134 disambiguator,
1128- extra_fragment : extra_fragment. map ( |frag| UrlFragment :: UserWritten ( frag. to_owned ( ) ) ) ,
1135+ extra_fragment : extra_fragment. map ( |frag| frag. to_owned ( ) ) ,
11291136 link_text : link_text. to_owned ( ) ,
11301137 } ) )
11311138}
@@ -1292,7 +1299,7 @@ impl LinkCollector<'_, '_> {
12921299 } ;
12931300
12941301 let verify = |kind : DefKind , id : DefId | {
1295- let ( kind, id) = if let Some ( UrlFragment :: Def ( _, id) ) = fragment {
1302+ let ( kind, id) = if let Some ( UrlFragment :: Item ( ItemFragment ( _, id) ) ) = fragment {
12961303 ( self . cx . tcx . def_kind ( id) , id)
12971304 } else {
12981305 ( kind, id)
@@ -1340,7 +1347,7 @@ impl LinkCollector<'_, '_> {
13401347
13411348 match res {
13421349 Res :: Primitive ( prim) => {
1343- if let Some ( UrlFragment :: Def ( _, id) ) = fragment {
1350+ if let Some ( UrlFragment :: Item ( ItemFragment ( _, id) ) ) = fragment {
13441351 let kind = self . cx . tcx . def_kind ( id) ;
13451352
13461353 // We're actually resolving an associated item of a primitive, so we need to
@@ -1488,7 +1495,7 @@ impl LinkCollector<'_, '_> {
14881495 let mut candidates = PerNS {
14891496 macro_ns : self
14901497 . resolve_macro ( path_str, base_node)
1491- . map ( |res| ( res, extra_fragment. clone ( ) ) ) ,
1498+ . map ( |res| ( res, extra_fragment. clone ( ) . map ( UrlFragment :: UserWritten ) ) ) ,
14921499 type_ns : match self . resolve ( path_str, TypeNS , base_node, extra_fragment) {
14931500 Ok ( res) => {
14941501 debug ! ( "got res in TypeNS: {:?}" , res) ;
@@ -1520,7 +1527,10 @@ impl LinkCollector<'_, '_> {
15201527 // Shouldn't happen but who knows?
15211528 Ok ( ( res, Some ( fragment) ) )
15221529 }
1523- ( fragment, None ) | ( None , fragment) => Ok ( ( res, fragment) ) ,
1530+ ( fragment, None ) => Ok ( ( res, fragment) ) ,
1531+ ( None , fragment) => {
1532+ Ok ( ( res, fragment. map ( UrlFragment :: UserWritten ) ) )
1533+ }
15241534 }
15251535 }
15261536 }
@@ -1557,7 +1567,7 @@ impl LinkCollector<'_, '_> {
15571567 }
15581568 Some ( MacroNS ) => {
15591569 match self . resolve_macro ( path_str, base_node) {
1560- Ok ( res) => Some ( ( res, extra_fragment. clone ( ) ) ) ,
1570+ Ok ( res) => Some ( ( res, extra_fragment. clone ( ) . map ( UrlFragment :: UserWritten ) ) ) ,
15611571 Err ( mut kind) => {
15621572 // `resolve_macro` only looks in the macro namespace. Try to give a better error if possible.
15631573 for ns in [ TypeNS , ValueNS ] {
@@ -2276,13 +2286,13 @@ fn privacy_error(cx: &DocContext<'_>, diag_info: &DiagnosticInfo<'_>, path_str:
22762286fn handle_variant (
22772287 cx : & DocContext < ' _ > ,
22782288 res : Res ,
2279- ) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' static > > {
2289+ ) -> Result < ( Res , Option < ItemFragment > ) , ErrorKind < ' static > > {
22802290 cx. tcx
22812291 . parent ( res. def_id ( cx. tcx ) )
22822292 . map ( |parent| {
22832293 let parent_def = Res :: Def ( DefKind :: Enum , parent) ;
22842294 let variant = cx. tcx . expect_variant_res ( res. as_hir_res ( ) . unwrap ( ) ) ;
2285- ( parent_def, Some ( UrlFragment :: Def ( FragmentKind :: Variant , variant. def_id ) ) )
2295+ ( parent_def, Some ( ItemFragment ( FragmentKind :: Variant , variant. def_id ) ) )
22862296 } )
22872297 . ok_or_else ( || ResolutionFailure :: NoParentItem . into ( ) )
22882298}
0 commit comments