@@ -14,7 +14,7 @@ use rustc_hir::def::{
1414} ;
1515use rustc_hir:: def_id:: { CrateNum , DefId } ;
1616use rustc_middle:: ty:: TyCtxt ;
17- use rustc_middle:: { bug, ty} ;
17+ use rustc_middle:: { bug, span_bug , ty} ;
1818use rustc_resolve:: ParentScope ;
1919use rustc_session:: lint:: Lint ;
2020use rustc_span:: hygiene:: { MacroKind , SyntaxContext } ;
@@ -98,14 +98,10 @@ impl Res {
9898 }
9999 }
100100
101- fn def_id ( self ) -> DefId {
102- self . opt_def_id ( ) . expect ( "called def_id() on a primitive" )
103- }
104-
105- fn opt_def_id ( self ) -> Option < DefId > {
101+ fn def_id ( self , tcx : TyCtxt < ' _ > ) -> DefId {
106102 match self {
107- Res :: Def ( _, id) => Some ( id ) ,
108- Res :: Primitive ( _ ) => None ,
103+ Res :: Def ( _, id) => id ,
104+ Res :: Primitive ( prim ) => * PrimitiveType :: primitive_locations ( tcx ) . get ( & prim ) . unwrap ( ) ,
109105 }
110106 }
111107
@@ -237,10 +233,7 @@ enum AnchorFailure {
237233 /// link, Rustdoc disallows having a user-specified anchor.
238234 ///
239235 /// Most of the time this is fine, because you can just link to the page of
240- /// the item if you want to provide your own anchor. For primitives, though,
241- /// rustdoc uses the anchor as a side channel to know which page to link to;
242- /// it doesn't show up in the generated link. Ideally, rustdoc would remove
243- /// this limitation, allowing you to link to subheaders on primitives.
236+ /// the item if you want to provide your own anchor.
244237 RustdocAnchorConflict ( Res ) ,
245238}
246239
@@ -388,7 +381,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
388381 ty:: AssocKind :: Const => "associatedconstant" ,
389382 ty:: AssocKind :: Type => "associatedtype" ,
390383 } ;
391- let fragment = format ! ( "{}#{} .{}" , prim_ty . as_sym ( ) , out, item_name) ;
384+ let fragment = format ! ( "{}.{}" , out, item_name) ;
392385 ( Res :: Primitive ( prim_ty) , fragment, Some ( ( kind. as_def_kind ( ) , item. def_id ) ) )
393386 } )
394387 } )
@@ -475,14 +468,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
475468 return handle_variant ( self . cx , res, extra_fragment) ;
476469 }
477470 // Not a trait item; just return what we found.
478- Res :: Primitive ( ty) => {
479- if extra_fragment. is_some ( ) {
480- return Err ( ErrorKind :: AnchorFailure (
481- AnchorFailure :: RustdocAnchorConflict ( res) ,
482- ) ) ;
483- }
484- return Ok ( ( res, Some ( ty. as_sym ( ) . to_string ( ) ) ) ) ;
485- }
486471 _ => return Ok ( ( res, extra_fragment. clone ( ) ) ) ,
487472 }
488473 }
@@ -517,6 +502,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
517502 let ( res, fragment, side_channel) =
518503 self . resolve_associated_item ( ty_res, item_name, ns, module_id) ?;
519504 let result = if extra_fragment. is_some ( ) {
505+ // NOTE: can never be a primitive since `side_channel.is_none()` only when `res`
506+ // is a trait (and the side channel DefId is always an associated item).
520507 let diag_res = side_channel. map_or ( res, |( k, r) | Res :: Def ( k, r) ) ;
521508 Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( diag_res) ) )
522509 } else {
@@ -1152,7 +1139,7 @@ impl LinkCollector<'_, '_> {
11521139 module_id = DefId { krate, index : CRATE_DEF_INDEX } ;
11531140 }
11541141
1155- let ( mut res, mut fragment) = self . resolve_with_disambiguator_cached (
1142+ let ( mut res, fragment) = self . resolve_with_disambiguator_cached (
11561143 ResolutionInfo {
11571144 module_id,
11581145 dis : disambiguator,
@@ -1174,16 +1161,7 @@ impl LinkCollector<'_, '_> {
11741161 if let Some ( prim) = resolve_primitive ( path_str, TypeNS ) {
11751162 // `prim@char`
11761163 if matches ! ( disambiguator, Some ( Disambiguator :: Primitive ) ) {
1177- if fragment. is_some ( ) {
1178- anchor_failure (
1179- self . cx ,
1180- diag_info,
1181- AnchorFailure :: RustdocAnchorConflict ( prim) ,
1182- ) ;
1183- return None ;
1184- }
11851164 res = prim;
1186- fragment = Some ( prim. name ( self . cx . tcx ) . to_string ( ) ) ;
11871165 } else {
11881166 // `[char]` when a `char` module is in scope
11891167 let candidates = vec ! [ res, prim] ;
@@ -1303,12 +1281,17 @@ impl LinkCollector<'_, '_> {
13031281 }
13041282 }
13051283
1306- Some ( ItemLink { link : ori_link. link , link_text, did : None , fragment } )
1284+ Some ( ItemLink {
1285+ link : ori_link. link ,
1286+ link_text,
1287+ did : res. def_id ( self . cx . tcx ) ,
1288+ fragment,
1289+ } )
13071290 }
13081291 Res :: Def ( kind, id) => {
13091292 verify ( kind, id) ?;
13101293 let id = clean:: register_res ( self . cx , rustc_hir:: def:: Res :: Def ( kind, id) ) ;
1311- Some ( ItemLink { link : ori_link. link , link_text, did : Some ( id ) , fragment } )
1294+ Some ( ItemLink { link : ori_link. link , link_text, did : id , fragment } )
13121295 }
13131296 }
13141297 }
@@ -2069,8 +2052,11 @@ fn anchor_failure(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, failure: A
20692052 diag. span_label ( sp, "invalid anchor" ) ;
20702053 }
20712054 if let AnchorFailure :: RustdocAnchorConflict ( Res :: Primitive ( _) ) = failure {
2072- diag. note ( "this restriction may be lifted in a future release" ) ;
2073- diag. note ( "see https://github.com/rust-lang/rust/issues/83083 for more information" ) ;
2055+ if let Some ( sp) = sp {
2056+ span_bug ! ( sp, "anchors should be allowed now" ) ;
2057+ } else {
2058+ bug ! ( "anchors should be allowed now" ) ;
2059+ }
20742060 }
20752061 } ) ;
20762062}
@@ -2198,10 +2184,11 @@ fn handle_variant(
21982184 use rustc_middle:: ty:: DefIdTree ;
21992185
22002186 if extra_fragment. is_some ( ) {
2187+ // NOTE: `res` can never be a primitive since this function is only called when `tcx.def_kind(res) == DefKind::Variant`.
22012188 return Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( res) ) ) ;
22022189 }
22032190 cx. tcx
2204- . parent ( res. def_id ( ) )
2191+ . parent ( res. def_id ( cx . tcx ) )
22052192 . map ( |parent| {
22062193 let parent_def = Res :: Def ( DefKind :: Enum , parent) ;
22072194 let variant = cx. tcx . expect_variant_res ( res. as_hir_res ( ) . unwrap ( ) ) ;
0 commit comments