@@ -31,7 +31,7 @@ use std::cell::Cell;
31
31
use std:: mem;
32
32
use std:: ops:: Range ;
33
33
34
- use crate :: clean:: { self , Crate , GetDefId , Import , Item , ItemLink , PrimitiveType } ;
34
+ use crate :: clean:: { self , Crate , GetDefId , Item , ItemLink , PrimitiveType } ;
35
35
use crate :: core:: DocContext ;
36
36
use crate :: fold:: DocFolder ;
37
37
use crate :: html:: markdown:: markdown_links;
@@ -195,7 +195,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
195
195
fn variant_field (
196
196
& self ,
197
197
path_str : & ' path str ,
198
- current_item : & Option < String > ,
199
198
module_id : DefId ,
200
199
) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
201
200
let cx = self . cx ;
@@ -218,14 +217,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
218
217
split. next ( ) . map ( |f| ( f, Symbol :: intern ( f) ) ) . ok_or_else ( no_res) ?;
219
218
let path = split
220
219
. next ( )
221
- . map ( |f| {
222
- if f == "self" || f == "Self" {
223
- if let Some ( name) = current_item. as_ref ( ) {
224
- return name. clone ( ) ;
225
- }
226
- }
227
- f. to_owned ( )
228
- } )
220
+ . map ( |f| f. to_owned ( ) )
229
221
// If there's no third component, we saw `[a::b]` before and it failed to resolve.
230
222
// So there's no partial res.
231
223
. ok_or_else ( no_res) ?;
@@ -405,8 +397,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
405
397
& self ,
406
398
path_str : & ' path str ,
407
399
ns : Namespace ,
408
- // FIXME(#76467): This is for `Self`, and it's wrong.
409
- current_item : & Option < String > ,
410
400
module_id : DefId ,
411
401
extra_fragment : & Option < String > ,
412
402
) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
@@ -449,14 +439,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
449
439
let ( item_str, item_name) = split. next ( ) . map ( |i| ( i, Symbol :: intern ( i) ) ) . unwrap ( ) ;
450
440
let path_root = split
451
441
. next ( )
452
- . map ( |f| {
453
- if f == "self" || f == "Self" {
454
- if let Some ( name) = current_item. as_ref ( ) {
455
- return name. clone ( ) ;
456
- }
457
- }
458
- f. to_owned ( )
459
- } )
442
+ . map ( |f| f. to_owned ( ) )
460
443
// If there's no `::`, it's not an associated item.
461
444
// So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
462
445
. ok_or_else ( || {
@@ -477,7 +460,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
477
460
} else {
478
461
// FIXME: this is duplicated on the end of this function.
479
462
return if ns == Namespace :: ValueNS {
480
- self . variant_field ( path_str, current_item , module_id)
463
+ self . variant_field ( path_str, module_id)
481
464
} else {
482
465
Err ( ResolutionFailure :: NotResolved {
483
466
module_id,
@@ -617,7 +600,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
617
600
} ;
618
601
res. unwrap_or_else ( || {
619
602
if ns == Namespace :: ValueNS {
620
- self . variant_field ( path_str, current_item , module_id)
603
+ self . variant_field ( path_str, module_id)
621
604
} else {
622
605
Err ( ResolutionFailure :: NotResolved {
623
606
module_id,
@@ -640,15 +623,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
640
623
ns : Namespace ,
641
624
path_str : & str ,
642
625
module_id : DefId ,
643
- current_item : & Option < String > ,
644
626
extra_fragment : & Option < String > ,
645
627
) -> Option < Res > {
646
628
// resolve() can't be used for macro namespace
647
629
let result = match ns {
648
630
Namespace :: MacroNS => self . resolve_macro ( path_str, module_id) . map_err ( ErrorKind :: from) ,
649
- Namespace :: TypeNS | Namespace :: ValueNS => self
650
- . resolve ( path_str, ns, current_item , module_id, extra_fragment)
651
- . map ( | ( res , _ ) | res ) ,
631
+ Namespace :: TypeNS | Namespace :: ValueNS => {
632
+ self . resolve ( path_str, ns, module_id, extra_fragment) . map ( | ( res , _ ) | res )
633
+ }
652
634
} ;
653
635
654
636
let res = match result {
@@ -839,77 +821,55 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
839
821
trace ! ( "got parent node for {:?} {:?}, id {:?}" , item. type_( ) , item. name, item. def_id) ;
840
822
}
841
823
842
- let current_item = match item. kind {
843
- clean:: ModuleItem ( ..) => {
844
- if item. attrs . inner_docs {
845
- if item. def_id . is_top_level_module ( ) { item. name . clone ( ) } else { None }
846
- } else {
847
- match parent_node. or ( self . mod_ids . last ( ) . copied ( ) ) {
848
- Some ( parent) if !parent. is_top_level_module ( ) => {
849
- Some ( self . cx . tcx . item_name ( parent) . to_string ( ) )
850
- }
851
- _ => None ,
852
- }
853
- }
854
- }
855
- clean:: ImplItem ( clean:: Impl { ref for_, .. } ) => {
856
- for_. def_id ( ) . map ( |did| self . cx . tcx . item_name ( did) . to_string ( ) )
857
- }
858
- // we don't display docs on `extern crate` items anyway, so don't process them.
859
- clean:: ExternCrateItem ( ..) => {
860
- debug ! ( "ignoring extern crate item {:?}" , item. def_id) ;
861
- return Some ( self . fold_item_recur ( item) ) ;
862
- }
863
- clean:: ImportItem ( Import { kind : clean:: ImportKind :: Simple ( ref name, ..) , .. } ) => {
864
- Some ( name. clone ( ) )
865
- }
866
- clean:: MacroItem ( ..) => None ,
867
- _ => item. name . clone ( ) ,
824
+ // find item's parent to resolve `Self` in item's docs below
825
+ debug ! ( "looking for the `Self` type" ) ;
826
+ let self_id = if item. is_fake ( ) {
827
+ None
828
+ } else if matches ! (
829
+ self . cx. tcx. def_kind( item. def_id) ,
830
+ DefKind :: AssocConst
831
+ | DefKind :: AssocFn
832
+ | DefKind :: AssocTy
833
+ | DefKind :: Variant
834
+ | DefKind :: Field
835
+ ) {
836
+ self . cx . tcx . parent ( item. def_id )
837
+ // HACK(jynelson): `clean` marks associated types as `TypedefItem`, not as `AssocTypeItem`.
838
+ // Fixing this breaks `fn render_deref_methods`.
839
+ // As a workaround, see if the parent of the item is an `impl`; if so this must be an associated item,
840
+ // regardless of what rustdoc wants to call it.
841
+ } else if let Some ( parent) = self . cx . tcx . parent ( item. def_id ) {
842
+ let parent_kind = self . cx . tcx . def_kind ( parent) ;
843
+ Some ( if parent_kind == DefKind :: Impl { parent } else { item. def_id } )
844
+ } else {
845
+ Some ( item. def_id )
868
846
} ;
869
847
848
+ // FIXME(jynelson): this shouldn't go through stringification, rustdoc should just use the DefId directly
849
+ let self_name = self_id. and_then ( |self_id| {
850
+ use ty:: TyKind ;
851
+ if matches ! ( self . cx. tcx. def_kind( self_id) , DefKind :: Impl ) {
852
+ // using `ty.to_string()` directly has issues with shortening paths
853
+ // FIXME: this is a hack, isn't there a better way?
854
+ let ty = self . cx . tcx . type_of ( self_id) ;
855
+ let name = match ty. kind ( ) {
856
+ TyKind :: Adt ( def, _) => Some ( self . cx . tcx . item_name ( def. did ) . to_string ( ) ) ,
857
+ other if other. is_primitive ( ) => Some ( ty. to_string ( ) ) ,
858
+ _ => None ,
859
+ } ;
860
+ debug ! ( "using type_of(): {:?}" , name) ;
861
+ name
862
+ } else {
863
+ let name = self . cx . tcx . opt_item_name ( self_id) . map ( |sym| sym. to_string ( ) ) ;
864
+ debug ! ( "using item_name(): {:?}" , name) ;
865
+ name
866
+ }
867
+ } ) ;
868
+
870
869
if item. is_mod ( ) && item. attrs . inner_docs {
871
870
self . mod_ids . push ( item. def_id ) ;
872
871
}
873
872
874
- // find item's parent to resolve `Self` in item's docs below
875
- // FIXME(#76467, #75809): this is a mess and doesn't handle cross-crate
876
- // re-exports
877
- let parent_name = self . cx . as_local_hir_id ( item. def_id ) . and_then ( |item_hir| {
878
- let parent_hir = self . cx . tcx . hir ( ) . get_parent_item ( item_hir) ;
879
- let item_parent = self . cx . tcx . hir ( ) . find ( parent_hir) ;
880
- match item_parent {
881
- Some ( hir:: Node :: Item ( hir:: Item {
882
- kind :
883
- hir:: ItemKind :: Impl {
884
- self_ty :
885
- hir:: Ty {
886
- kind :
887
- hir:: TyKind :: Path ( hir:: QPath :: Resolved (
888
- _,
889
- hir:: Path { segments, .. } ,
890
- ) ) ,
891
- ..
892
- } ,
893
- ..
894
- } ,
895
- ..
896
- } ) ) => segments. first ( ) . map ( |seg| seg. ident . to_string ( ) ) ,
897
- Some ( hir:: Node :: Item ( hir:: Item {
898
- ident, kind : hir:: ItemKind :: Enum ( ..) , ..
899
- } ) )
900
- | Some ( hir:: Node :: Item ( hir:: Item {
901
- ident, kind : hir:: ItemKind :: Struct ( ..) , ..
902
- } ) )
903
- | Some ( hir:: Node :: Item ( hir:: Item {
904
- ident, kind : hir:: ItemKind :: Union ( ..) , ..
905
- } ) )
906
- | Some ( hir:: Node :: Item ( hir:: Item {
907
- ident, kind : hir:: ItemKind :: Trait ( ..) , ..
908
- } ) ) => Some ( ident. to_string ( ) ) ,
909
- _ => None ,
910
- }
911
- } ) ;
912
-
913
873
// We want to resolve in the lexical scope of the documentation.
914
874
// In the presence of re-exports, this is not the same as the module of the item.
915
875
// Rather than merging all documentation into one, resolve it one attribute at a time
@@ -945,9 +905,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
945
905
let link = self . resolve_link (
946
906
& item,
947
907
& combined_docs,
948
- & current_item ,
908
+ & self_name ,
949
909
parent_node,
950
- & parent_name,
951
910
krate,
952
911
ori_link,
953
912
link_range,
@@ -980,9 +939,8 @@ impl LinkCollector<'_, '_> {
980
939
& self ,
981
940
item : & Item ,
982
941
dox : & str ,
983
- current_item : & Option < String > ,
942
+ self_name : & Option < String > ,
984
943
parent_node : Option < DefId > ,
985
- parent_name : & Option < String > ,
986
944
krate : CrateNum ,
987
945
ori_link : String ,
988
946
link_range : Option < Range < usize > > ,
@@ -1069,7 +1027,7 @@ impl LinkCollector<'_, '_> {
1069
1027
let resolved_self;
1070
1028
// replace `Self` with suitable item's parent name
1071
1029
if path_str. starts_with ( "Self::" ) {
1072
- if let Some ( ref name) = parent_name {
1030
+ if let Some ( ref name) = self_name {
1073
1031
resolved_self = format ! ( "{}::{}" , name, & path_str[ 6 ..] ) ;
1074
1032
path_str = & resolved_self;
1075
1033
}
@@ -1122,7 +1080,6 @@ impl LinkCollector<'_, '_> {
1122
1080
item,
1123
1081
dox,
1124
1082
path_str,
1125
- current_item,
1126
1083
module_id,
1127
1084
extra_fragment,
1128
1085
& ori_link,
@@ -1243,15 +1200,14 @@ impl LinkCollector<'_, '_> {
1243
1200
item : & Item ,
1244
1201
dox : & str ,
1245
1202
path_str : & str ,
1246
- current_item : & Option < String > ,
1247
1203
base_node : DefId ,
1248
1204
extra_fragment : Option < String > ,
1249
1205
ori_link : & str ,
1250
1206
link_range : Option < Range < usize > > ,
1251
1207
) -> Option < ( Res , Option < String > ) > {
1252
1208
match disambiguator. map ( Disambiguator :: ns) {
1253
1209
Some ( ns @ ( ValueNS | TypeNS ) ) => {
1254
- match self . resolve ( path_str, ns, & current_item , base_node, & extra_fragment) {
1210
+ match self . resolve ( path_str, ns, base_node, & extra_fragment) {
1255
1211
Ok ( res) => Some ( res) ,
1256
1212
Err ( ErrorKind :: Resolve ( box mut kind) ) => {
1257
1213
// We only looked in one namespace. Try to give a better error if possible.
@@ -1264,7 +1220,6 @@ impl LinkCollector<'_, '_> {
1264
1220
new_ns,
1265
1221
path_str,
1266
1222
base_node,
1267
- & current_item,
1268
1223
& extra_fragment,
1269
1224
) {
1270
1225
kind = ResolutionFailure :: WrongNamespace ( res, ns) ;
@@ -1298,13 +1253,7 @@ impl LinkCollector<'_, '_> {
1298
1253
macro_ns : self
1299
1254
. resolve_macro ( path_str, base_node)
1300
1255
. map ( |res| ( res, extra_fragment. clone ( ) ) ) ,
1301
- type_ns : match self . resolve (
1302
- path_str,
1303
- TypeNS ,
1304
- & current_item,
1305
- base_node,
1306
- & extra_fragment,
1307
- ) {
1256
+ type_ns : match self . resolve ( path_str, TypeNS , base_node, & extra_fragment) {
1308
1257
Ok ( res) => {
1309
1258
debug ! ( "got res in TypeNS: {:?}" , res) ;
1310
1259
Ok ( res)
@@ -1315,13 +1264,7 @@ impl LinkCollector<'_, '_> {
1315
1264
}
1316
1265
Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1317
1266
} ,
1318
- value_ns : match self . resolve (
1319
- path_str,
1320
- ValueNS ,
1321
- & current_item,
1322
- base_node,
1323
- & extra_fragment,
1324
- ) {
1267
+ value_ns : match self . resolve ( path_str, ValueNS , base_node, & extra_fragment) {
1325
1268
Ok ( res) => Ok ( res) ,
1326
1269
Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1327
1270
anchor_failure ( self . cx , & item, ori_link, dox, link_range, msg) ;
@@ -1389,13 +1332,9 @@ impl LinkCollector<'_, '_> {
1389
1332
Err ( mut kind) => {
1390
1333
// `resolve_macro` only looks in the macro namespace. Try to give a better error if possible.
1391
1334
for & ns in & [ TypeNS , ValueNS ] {
1392
- if let Some ( res) = self . check_full_res (
1393
- ns,
1394
- path_str,
1395
- base_node,
1396
- & current_item,
1397
- & extra_fragment,
1398
- ) {
1335
+ if let Some ( res) =
1336
+ self . check_full_res ( ns, path_str, base_node, & extra_fragment)
1337
+ {
1399
1338
kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
1400
1339
break ;
1401
1340
}
@@ -1734,7 +1673,7 @@ fn resolution_failure(
1734
1673
name = start;
1735
1674
for & ns in & [ TypeNS , ValueNS , MacroNS ] {
1736
1675
if let Some ( res) =
1737
- collector. check_full_res ( ns, & start, module_id, & None , & None )
1676
+ collector. check_full_res ( ns, & start, module_id, & None )
1738
1677
{
1739
1678
debug ! ( "found partial_res={:?}" , res) ;
1740
1679
* partial_res = Some ( res) ;
@@ -2131,7 +2070,7 @@ fn strip_generics_from_path(path_str: &str) -> Result<String, ResolutionFailure<
2131
2070
}
2132
2071
_ => segment. push ( chr) ,
2133
2072
}
2134
- debug ! ( "raw segment: {:?}" , segment) ;
2073
+ trace ! ( "raw segment: {:?}" , segment) ;
2135
2074
}
2136
2075
2137
2076
if !segment. is_empty ( ) {
0 commit comments