@@ -13,7 +13,7 @@ use rustc_hir::def::{
13
13
PerNS ,
14
14
} ;
15
15
use rustc_hir:: def_id:: { CrateNum , DefId } ;
16
- use rustc_middle:: ty:: { Ty , TyCtxt } ;
16
+ use rustc_middle:: ty:: { DefIdTree , Ty , TyCtxt } ;
17
17
use rustc_middle:: { bug, span_bug, ty} ;
18
18
use rustc_resolve:: ParentScope ;
19
19
use rustc_session:: lint:: Lint ;
@@ -27,6 +27,7 @@ use pulldown_cmark::LinkType;
27
27
use std:: borrow:: Cow ;
28
28
use std:: cell:: Cell ;
29
29
use std:: convert:: { TryFrom , TryInto } ;
30
+ use std:: fmt:: Write ;
30
31
use std:: mem;
31
32
use std:: ops:: Range ;
32
33
@@ -240,53 +241,61 @@ enum AnchorFailure {
240
241
241
242
#[ derive( Clone , Debug , Hash , PartialEq , Eq ) ]
242
243
crate enum UrlFragment {
243
- Method ( Symbol ) ,
244
- TyMethod ( Symbol ) ,
245
- AssociatedConstant ( Symbol ) ,
246
- AssociatedType ( Symbol ) ,
244
+ Def ( FragmentKind , DefId ) ,
245
+ UserWritten ( String ) ,
246
+ }
247
247
248
- StructField ( Symbol ) ,
249
- Variant ( Symbol ) ,
250
- VariantField { variant : Symbol , field : Symbol } ,
248
+ #[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
249
+ crate enum FragmentKind {
250
+ Method ,
251
+ TyMethod ,
252
+ AssociatedConstant ,
253
+ AssociatedType ,
251
254
252
- UserWritten ( String ) ,
255
+ StructField ,
256
+ Variant ,
257
+ VariantField ,
253
258
}
254
259
255
260
impl UrlFragment {
256
261
/// Create a fragment for an associated item.
257
262
///
258
263
/// `is_prototype` is whether this associated item is a trait method
259
264
/// without a default definition.
260
- fn from_assoc_item ( name : Symbol , kind : ty:: AssocKind , is_prototype : bool ) -> Self {
265
+ fn from_assoc_item ( def_id : DefId , kind : ty:: AssocKind , is_prototype : bool ) -> Self {
261
266
match kind {
262
267
ty:: AssocKind :: Fn => {
263
268
if is_prototype {
264
- UrlFragment :: TyMethod ( name )
269
+ UrlFragment :: Def ( FragmentKind :: TyMethod , def_id )
265
270
} else {
266
- UrlFragment :: Method ( name )
271
+ UrlFragment :: Def ( FragmentKind :: Method , def_id )
267
272
}
268
273
}
269
- ty:: AssocKind :: Const => UrlFragment :: AssociatedConstant ( name ) ,
270
- ty:: AssocKind :: Type => UrlFragment :: AssociatedType ( name ) ,
274
+ ty:: AssocKind :: Const => UrlFragment :: Def ( FragmentKind :: AssociatedConstant , def_id ) ,
275
+ ty:: AssocKind :: Type => UrlFragment :: Def ( FragmentKind :: AssociatedType , def_id ) ,
271
276
}
272
277
}
273
- }
274
278
275
- /// Render the fragment, including the leading `#`.
276
- impl std:: fmt:: Display for UrlFragment {
277
- fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
278
- write ! ( f, "#" ) ?;
279
- match self {
280
- UrlFragment :: Method ( name) => write ! ( f, "method.{}" , name) ,
281
- UrlFragment :: TyMethod ( name) => write ! ( f, "tymethod.{}" , name) ,
282
- UrlFragment :: AssociatedConstant ( name) => write ! ( f, "associatedconstant.{}" , name) ,
283
- UrlFragment :: AssociatedType ( name) => write ! ( f, "associatedtype.{}" , name) ,
284
- UrlFragment :: StructField ( name) => write ! ( f, "structfield.{}" , name) ,
285
- UrlFragment :: Variant ( name) => write ! ( f, "variant.{}" , name) ,
286
- UrlFragment :: VariantField { variant, field } => {
287
- write ! ( f, "variant.{}.field.{}" , variant, field)
279
+ /// Render the fragment, including the leading `#`.
280
+ crate fn render ( & self , s : & mut String , tcx : TyCtxt < ' _ > ) -> std:: fmt:: Result {
281
+ write ! ( s, "#" ) ?;
282
+ match * self {
283
+ UrlFragment :: Def ( kind, def_id) => {
284
+ let name = tcx. item_name ( def_id) ;
285
+ match kind {
286
+ FragmentKind :: Method => write ! ( s, "method.{}" , name) ,
287
+ FragmentKind :: TyMethod => write ! ( s, "tymethod.{}" , name) ,
288
+ FragmentKind :: AssociatedConstant => write ! ( s, "associatedconstant.{}" , name) ,
289
+ FragmentKind :: AssociatedType => write ! ( s, "associatedtype.{}" , name) ,
290
+ FragmentKind :: StructField => write ! ( s, "structfield.{}" , name) ,
291
+ FragmentKind :: Variant => write ! ( s, "variant.{}" , name) ,
292
+ FragmentKind :: VariantField => {
293
+ let variant = tcx. item_name ( tcx. parent ( def_id) . unwrap ( ) ) ;
294
+ write ! ( s, "variant.{}.field.{}" , variant, name)
295
+ }
296
+ }
288
297
}
289
- UrlFragment :: UserWritten ( raw) => write ! ( f , "{}" , raw) ,
298
+ UrlFragment :: UserWritten ( ref raw) => write ! ( s , "{}" , raw) ,
290
299
}
291
300
}
292
301
}
@@ -387,13 +396,12 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
387
396
}
388
397
match tcx. type_of ( did) . kind ( ) {
389
398
ty:: Adt ( def, _) if def. is_enum ( ) => {
390
- if def. all_fields ( ) . any ( |item| item. ident . name == variant_field_name) {
399
+ if let Some ( field) =
400
+ def. all_fields ( ) . find ( |f| f. ident . name == variant_field_name)
401
+ {
391
402
Ok ( (
392
403
ty_res,
393
- Some ( UrlFragment :: VariantField {
394
- variant : variant_name,
395
- field : variant_field_name,
396
- } ) ,
404
+ Some ( UrlFragment :: Def ( FragmentKind :: VariantField , field. did ) ) ,
397
405
) )
398
406
} else {
399
407
Err ( ResolutionFailure :: NotResolved {
@@ -430,7 +438,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
430
438
. find_by_name_and_namespace ( tcx, Ident :: with_dummy_span ( item_name) , ns, impl_)
431
439
. map ( |item| {
432
440
let kind = item. kind ;
433
- let fragment = UrlFragment :: from_assoc_item ( item_name , kind, false ) ;
441
+ let fragment = UrlFragment :: from_assoc_item ( item . def_id , kind, false ) ;
434
442
( Res :: Primitive ( prim_ty) , fragment, Some ( ( kind. as_def_kind ( ) , item. def_id ) ) )
435
443
} )
436
444
} )
@@ -683,7 +691,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
683
691
684
692
assoc_item. map ( |item| {
685
693
let kind = item. kind ;
686
- let fragment = UrlFragment :: from_assoc_item ( item_name , kind, false ) ;
694
+ let fragment = UrlFragment :: from_assoc_item ( item . def_id , kind, false ) ;
687
695
// HACK(jynelson): `clean` expects the type, not the associated item
688
696
// but the disambiguator logic expects the associated item.
689
697
// Store the kind in a side channel so that only the disambiguator logic looks at it.
@@ -737,7 +745,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
737
745
738
746
if let Some ( item) = assoc_item {
739
747
let kind = item. kind ;
740
- let fragment = UrlFragment :: from_assoc_item ( item_name , kind, false ) ;
748
+ let fragment = UrlFragment :: from_assoc_item ( item . def_id , kind, false ) ;
741
749
// HACK(jynelson): `clean` expects the type, not the associated item
742
750
// but the disambiguator logic expects the associated item.
743
751
// Store the kind in a side channel so that only the disambiguator logic looks at it.
@@ -774,7 +782,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
774
782
. find ( |item| item. ident . name == item_name) ?;
775
783
Some ( (
776
784
root_res,
777
- UrlFragment :: StructField ( field. ident . name ) ,
785
+ UrlFragment :: Def ( FragmentKind :: StructField , field. did ) ,
778
786
Some ( ( DefKind :: Field , field. did ) ) ,
779
787
) )
780
788
}
@@ -783,7 +791,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
783
791
. find_by_name_and_namespace ( tcx, Ident :: with_dummy_span ( item_name) , ns, did)
784
792
. map ( |item| {
785
793
let fragment = UrlFragment :: from_assoc_item (
786
- item_name ,
794
+ item . def_id ,
787
795
item. kind ,
788
796
!item. defaultness . has_value ( ) ,
789
797
) ;
@@ -919,8 +927,6 @@ fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure<'_
919
927
920
928
impl < ' a , ' tcx > DocVisitor for LinkCollector < ' a , ' tcx > {
921
929
fn visit_item ( & mut self , item : & Item ) {
922
- use rustc_middle:: ty:: DefIdTree ;
923
-
924
930
let parent_node =
925
931
item. def_id . as_def_id ( ) . and_then ( |did| find_nearest_parent_module ( self . cx . tcx , did) ) ;
926
932
if parent_node. is_some ( ) {
@@ -2280,14 +2286,12 @@ fn handle_variant(
2280
2286
cx : & DocContext < ' _ > ,
2281
2287
res : Res ,
2282
2288
) -> Result < ( Res , Option < UrlFragment > ) , ErrorKind < ' static > > {
2283
- use rustc_middle:: ty:: DefIdTree ;
2284
-
2285
2289
cx. tcx
2286
2290
. parent ( res. def_id ( cx. tcx ) )
2287
2291
. map ( |parent| {
2288
2292
let parent_def = Res :: Def ( DefKind :: Enum , parent) ;
2289
2293
let variant = cx. tcx . expect_variant_res ( res. as_hir_res ( ) . unwrap ( ) ) ;
2290
- ( parent_def, Some ( UrlFragment :: Variant ( variant. ident . name ) ) )
2294
+ ( parent_def, Some ( UrlFragment :: Def ( FragmentKind :: Variant , variant. def_id ) ) )
2291
2295
} )
2292
2296
. ok_or_else ( || ResolutionFailure :: NoParentItem . into ( ) )
2293
2297
}
0 commit comments