@@ -14,7 +14,7 @@ use rustc_hir::def::{
14
14
} ;
15
15
use rustc_hir:: def_id:: { CrateNum , DefId } ;
16
16
use rustc_middle:: ty:: TyCtxt ;
17
- use rustc_middle:: { bug, ty} ;
17
+ use rustc_middle:: { bug, span_bug , ty} ;
18
18
use rustc_resolve:: ParentScope ;
19
19
use rustc_session:: lint:: Lint ;
20
20
use rustc_span:: hygiene:: { MacroKind , SyntaxContext } ;
@@ -98,14 +98,10 @@ impl Res {
98
98
}
99
99
}
100
100
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 {
106
102
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 ( ) ,
109
105
}
110
106
}
111
107
@@ -237,10 +233,7 @@ enum AnchorFailure {
237
233
/// link, Rustdoc disallows having a user-specified anchor.
238
234
///
239
235
/// 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.
244
237
RustdocAnchorConflict ( Res ) ,
245
238
}
246
239
@@ -388,7 +381,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
388
381
ty:: AssocKind :: Const => "associatedconstant" ,
389
382
ty:: AssocKind :: Type => "associatedtype" ,
390
383
} ;
391
- let fragment = format ! ( "{}#{} .{}" , prim_ty . as_sym ( ) , out, item_name) ;
384
+ let fragment = format ! ( "{}.{}" , out, item_name) ;
392
385
( Res :: Primitive ( prim_ty) , fragment, Some ( ( kind. as_def_kind ( ) , item. def_id ) ) )
393
386
} )
394
387
} )
@@ -475,14 +468,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
475
468
return handle_variant ( self . cx , res, extra_fragment) ;
476
469
}
477
470
// 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
- }
486
471
_ => return Ok ( ( res, extra_fragment. clone ( ) ) ) ,
487
472
}
488
473
}
@@ -517,6 +502,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
517
502
let ( res, fragment, side_channel) =
518
503
self . resolve_associated_item ( ty_res, item_name, ns, module_id) ?;
519
504
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).
520
507
let diag_res = side_channel. map_or ( res, |( k, r) | Res :: Def ( k, r) ) ;
521
508
Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( diag_res) ) )
522
509
} else {
@@ -1152,7 +1139,7 @@ impl LinkCollector<'_, '_> {
1152
1139
module_id = DefId { krate, index : CRATE_DEF_INDEX } ;
1153
1140
}
1154
1141
1155
- let ( mut res, mut fragment) = self . resolve_with_disambiguator_cached (
1142
+ let ( mut res, fragment) = self . resolve_with_disambiguator_cached (
1156
1143
ResolutionInfo {
1157
1144
module_id,
1158
1145
dis : disambiguator,
@@ -1174,16 +1161,7 @@ impl LinkCollector<'_, '_> {
1174
1161
if let Some ( prim) = resolve_primitive ( path_str, TypeNS ) {
1175
1162
// `prim@char`
1176
1163
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
- }
1185
1164
res = prim;
1186
- fragment = Some ( prim. name ( self . cx . tcx ) . to_string ( ) ) ;
1187
1165
} else {
1188
1166
// `[char]` when a `char` module is in scope
1189
1167
let candidates = vec ! [ res, prim] ;
@@ -1303,12 +1281,17 @@ impl LinkCollector<'_, '_> {
1303
1281
}
1304
1282
}
1305
1283
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
+ } )
1307
1290
}
1308
1291
Res :: Def ( kind, id) => {
1309
1292
verify ( kind, id) ?;
1310
1293
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 } )
1312
1295
}
1313
1296
}
1314
1297
}
@@ -2069,8 +2052,11 @@ fn anchor_failure(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, failure: A
2069
2052
diag. span_label ( sp, "invalid anchor" ) ;
2070
2053
}
2071
2054
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
+ }
2074
2060
}
2075
2061
} ) ;
2076
2062
}
@@ -2198,10 +2184,11 @@ fn handle_variant(
2198
2184
use rustc_middle:: ty:: DefIdTree ;
2199
2185
2200
2186
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`.
2201
2188
return Err ( ErrorKind :: AnchorFailure ( AnchorFailure :: RustdocAnchorConflict ( res) ) ) ;
2202
2189
}
2203
2190
cx. tcx
2204
- . parent ( res. def_id ( ) )
2191
+ . parent ( res. def_id ( cx . tcx ) )
2205
2192
. map ( |parent| {
2206
2193
let parent_def = Res :: Def ( DefKind :: Enum , parent) ;
2207
2194
let variant = cx. tcx . expect_variant_res ( res. as_hir_res ( ) . unwrap ( ) ) ;
0 commit comments