@@ -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,49 @@ 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
+ if matches ! ( self . cx. tcx. def_kind( self_id) , DefKind :: Impl ) {
851
+ // using `ty.to_string()` directly has issues with shortening paths
852
+ let ty = self . cx . tcx . type_of ( self_id) ;
853
+ let name = ty:: print:: with_crate_prefix ( || ty. to_string ( ) ) ;
854
+ debug ! ( "using type_of(): {}" , name) ;
855
+ Some ( name)
856
+ } else {
857
+ let name = self . cx . tcx . opt_item_name ( self_id) . map ( |sym| sym. to_string ( ) ) ;
858
+ debug ! ( "using item_name(): {:?}" , name) ;
859
+ name
860
+ }
861
+ } ) ;
862
+
870
863
if item. is_mod ( ) && item. attrs . inner_docs {
871
864
self . mod_ids . push ( item. def_id ) ;
872
865
}
873
866
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
867
// We want to resolve in the lexical scope of the documentation.
914
868
// In the presence of re-exports, this is not the same as the module of the item.
915
869
// Rather than merging all documentation into one, resolve it one attribute at a time
@@ -945,9 +899,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
945
899
let link = self . resolve_link (
946
900
& item,
947
901
& combined_docs,
948
- & current_item ,
902
+ & self_name ,
949
903
parent_node,
950
- & parent_name,
951
904
krate,
952
905
ori_link,
953
906
link_range,
@@ -980,9 +933,8 @@ impl LinkCollector<'_, '_> {
980
933
& self ,
981
934
item : & Item ,
982
935
dox : & str ,
983
- current_item : & Option < String > ,
936
+ self_name : & Option < String > ,
984
937
parent_node : Option < DefId > ,
985
- parent_name : & Option < String > ,
986
938
krate : CrateNum ,
987
939
ori_link : String ,
988
940
link_range : Option < Range < usize > > ,
@@ -1069,7 +1021,7 @@ impl LinkCollector<'_, '_> {
1069
1021
let resolved_self;
1070
1022
// replace `Self` with suitable item's parent name
1071
1023
if path_str. starts_with ( "Self::" ) {
1072
- if let Some ( ref name) = parent_name {
1024
+ if let Some ( ref name) = self_name {
1073
1025
resolved_self = format ! ( "{}::{}" , name, & path_str[ 6 ..] ) ;
1074
1026
path_str = & resolved_self;
1075
1027
}
@@ -1122,7 +1074,6 @@ impl LinkCollector<'_, '_> {
1122
1074
item,
1123
1075
dox,
1124
1076
path_str,
1125
- current_item,
1126
1077
module_id,
1127
1078
extra_fragment,
1128
1079
& ori_link,
@@ -1243,15 +1194,14 @@ impl LinkCollector<'_, '_> {
1243
1194
item : & Item ,
1244
1195
dox : & str ,
1245
1196
path_str : & str ,
1246
- current_item : & Option < String > ,
1247
1197
base_node : DefId ,
1248
1198
extra_fragment : Option < String > ,
1249
1199
ori_link : & str ,
1250
1200
link_range : Option < Range < usize > > ,
1251
1201
) -> Option < ( Res , Option < String > ) > {
1252
1202
match disambiguator. map ( Disambiguator :: ns) {
1253
1203
Some ( ns @ ( ValueNS | TypeNS ) ) => {
1254
- match self . resolve ( path_str, ns, & current_item , base_node, & extra_fragment) {
1204
+ match self . resolve ( path_str, ns, base_node, & extra_fragment) {
1255
1205
Ok ( res) => Some ( res) ,
1256
1206
Err ( ErrorKind :: Resolve ( box mut kind) ) => {
1257
1207
// We only looked in one namespace. Try to give a better error if possible.
@@ -1264,7 +1214,6 @@ impl LinkCollector<'_, '_> {
1264
1214
new_ns,
1265
1215
path_str,
1266
1216
base_node,
1267
- & current_item,
1268
1217
& extra_fragment,
1269
1218
) {
1270
1219
kind = ResolutionFailure :: WrongNamespace ( res, ns) ;
@@ -1298,13 +1247,7 @@ impl LinkCollector<'_, '_> {
1298
1247
macro_ns : self
1299
1248
. resolve_macro ( path_str, base_node)
1300
1249
. 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
- ) {
1250
+ type_ns : match self . resolve ( path_str, TypeNS , base_node, & extra_fragment) {
1308
1251
Ok ( res) => {
1309
1252
debug ! ( "got res in TypeNS: {:?}" , res) ;
1310
1253
Ok ( res)
@@ -1315,13 +1258,7 @@ impl LinkCollector<'_, '_> {
1315
1258
}
1316
1259
Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
1317
1260
} ,
1318
- value_ns : match self . resolve (
1319
- path_str,
1320
- ValueNS ,
1321
- & current_item,
1322
- base_node,
1323
- & extra_fragment,
1324
- ) {
1261
+ value_ns : match self . resolve ( path_str, ValueNS , base_node, & extra_fragment) {
1325
1262
Ok ( res) => Ok ( res) ,
1326
1263
Err ( ErrorKind :: AnchorFailure ( msg) ) => {
1327
1264
anchor_failure ( self . cx , & item, ori_link, dox, link_range, msg) ;
@@ -1389,13 +1326,9 @@ impl LinkCollector<'_, '_> {
1389
1326
Err ( mut kind) => {
1390
1327
// `resolve_macro` only looks in the macro namespace. Try to give a better error if possible.
1391
1328
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
- ) {
1329
+ if let Some ( res) =
1330
+ self . check_full_res ( ns, path_str, base_node, & extra_fragment)
1331
+ {
1399
1332
kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
1400
1333
break ;
1401
1334
}
@@ -1734,7 +1667,7 @@ fn resolution_failure(
1734
1667
name = start;
1735
1668
for & ns in & [ TypeNS , ValueNS , MacroNS ] {
1736
1669
if let Some ( res) =
1737
- collector. check_full_res ( ns, & start, module_id, & None , & None )
1670
+ collector. check_full_res ( ns, & start, module_id, & None )
1738
1671
{
1739
1672
debug ! ( "found partial_res={:?}" , res) ;
1740
1673
* partial_res = Some ( res) ;
@@ -2131,7 +2064,7 @@ fn strip_generics_from_path(path_str: &str) -> Result<String, ResolutionFailure<
2131
2064
}
2132
2065
_ => segment. push ( chr) ,
2133
2066
}
2134
- debug ! ( "raw segment: {:?}" , segment) ;
2067
+ trace ! ( "raw segment: {:?}" , segment) ;
2135
2068
}
2136
2069
2137
2070
if !segment. is_empty ( ) {
0 commit comments