@@ -31,7 +31,7 @@ use std::cell::Cell;
3131use std:: mem;
3232use std:: ops:: Range ;
3333
34- use crate :: clean:: { self , Crate , GetDefId , Import , Item , ItemLink , PrimitiveType } ;
34+ use crate :: clean:: { self , Crate , GetDefId , Item , ItemLink , PrimitiveType } ;
3535use crate :: core:: DocContext ;
3636use crate :: fold:: DocFolder ;
3737use crate :: html:: markdown:: markdown_links;
@@ -195,7 +195,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
195195 fn variant_field (
196196 & self ,
197197 path_str : & ' path str ,
198- current_item : & Option < String > ,
199198 module_id : DefId ,
200199 ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
201200 let cx = self . cx ;
@@ -218,14 +217,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
218217 split. next ( ) . map ( |f| ( f, Symbol :: intern ( f) ) ) . ok_or_else ( no_res) ?;
219218 let path = split
220219 . 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 ( ) )
229221 // If there's no third component, we saw `[a::b]` before and it failed to resolve.
230222 // So there's no partial res.
231223 . ok_or_else ( no_res) ?;
@@ -405,8 +397,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
405397 & self ,
406398 path_str : & ' path str ,
407399 ns : Namespace ,
408- // FIXME(#76467): This is for `Self`, and it's wrong.
409- current_item : & Option < String > ,
410400 module_id : DefId ,
411401 extra_fragment : & Option < String > ,
412402 ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
@@ -449,14 +439,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
449439 let ( item_str, item_name) = split. next ( ) . map ( |i| ( i, Symbol :: intern ( i) ) ) . unwrap ( ) ;
450440 let path_root = split
451441 . 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 ( ) )
460443 // If there's no `::`, it's not an associated item.
461444 // So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
462445 . ok_or_else ( || {
@@ -477,7 +460,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
477460 } else {
478461 // FIXME: this is duplicated on the end of this function.
479462 return if ns == Namespace :: ValueNS {
480- self . variant_field ( path_str, current_item , module_id)
463+ self . variant_field ( path_str, module_id)
481464 } else {
482465 Err ( ResolutionFailure :: NotResolved {
483466 module_id,
@@ -617,7 +600,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
617600 } ;
618601 res. unwrap_or_else ( || {
619602 if ns == Namespace :: ValueNS {
620- self . variant_field ( path_str, current_item , module_id)
603+ self . variant_field ( path_str, module_id)
621604 } else {
622605 Err ( ResolutionFailure :: NotResolved {
623606 module_id,
@@ -640,15 +623,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
640623 ns : Namespace ,
641624 path_str : & str ,
642625 module_id : DefId ,
643- current_item : & Option < String > ,
644626 extra_fragment : & Option < String > ,
645627 ) -> Option < Res > {
646628 // resolve() can't be used for macro namespace
647629 let result = match ns {
648630 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+ }
652634 } ;
653635
654636 let res = match result {
@@ -839,77 +821,49 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
839821 trace ! ( "got parent node for {:?} {:?}, id {:?}" , item. type_( ) , item. name, item. def_id) ;
840822 }
841823
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 )
868846 } ;
869847
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+
870863 if item. is_mod ( ) && item. attrs . inner_docs {
871864 self . mod_ids . push ( item. def_id ) ;
872865 }
873866
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-
913867 // We want to resolve in the lexical scope of the documentation.
914868 // In the presence of re-exports, this is not the same as the module of the item.
915869 // 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> {
945899 let link = self . resolve_link (
946900 & item,
947901 & combined_docs,
948- & current_item ,
902+ & self_name ,
949903 parent_node,
950- & parent_name,
951904 krate,
952905 ori_link,
953906 link_range,
@@ -980,9 +933,8 @@ impl LinkCollector<'_, '_> {
980933 & self ,
981934 item : & Item ,
982935 dox : & str ,
983- current_item : & Option < String > ,
936+ self_name : & Option < String > ,
984937 parent_node : Option < DefId > ,
985- parent_name : & Option < String > ,
986938 krate : CrateNum ,
987939 ori_link : String ,
988940 link_range : Option < Range < usize > > ,
@@ -1069,7 +1021,7 @@ impl LinkCollector<'_, '_> {
10691021 let resolved_self;
10701022 // replace `Self` with suitable item's parent name
10711023 if path_str. starts_with ( "Self::" ) {
1072- if let Some ( ref name) = parent_name {
1024+ if let Some ( ref name) = self_name {
10731025 resolved_self = format ! ( "{}::{}" , name, & path_str[ 6 ..] ) ;
10741026 path_str = & resolved_self;
10751027 }
@@ -1122,7 +1074,6 @@ impl LinkCollector<'_, '_> {
11221074 item,
11231075 dox,
11241076 path_str,
1125- current_item,
11261077 module_id,
11271078 extra_fragment,
11281079 & ori_link,
@@ -1243,15 +1194,14 @@ impl LinkCollector<'_, '_> {
12431194 item : & Item ,
12441195 dox : & str ,
12451196 path_str : & str ,
1246- current_item : & Option < String > ,
12471197 base_node : DefId ,
12481198 extra_fragment : Option < String > ,
12491199 ori_link : & str ,
12501200 link_range : Option < Range < usize > > ,
12511201 ) -> Option < ( Res , Option < String > ) > {
12521202 match disambiguator. map ( Disambiguator :: ns) {
12531203 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) {
12551205 Ok ( res) => Some ( res) ,
12561206 Err ( ErrorKind :: Resolve ( box mut kind) ) => {
12571207 // We only looked in one namespace. Try to give a better error if possible.
@@ -1264,7 +1214,6 @@ impl LinkCollector<'_, '_> {
12641214 new_ns,
12651215 path_str,
12661216 base_node,
1267- & current_item,
12681217 & extra_fragment,
12691218 ) {
12701219 kind = ResolutionFailure :: WrongNamespace ( res, ns) ;
@@ -1298,13 +1247,7 @@ impl LinkCollector<'_, '_> {
12981247 macro_ns : self
12991248 . resolve_macro ( path_str, base_node)
13001249 . 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) {
13081251 Ok ( res) => {
13091252 debug ! ( "got res in TypeNS: {:?}" , res) ;
13101253 Ok ( res)
@@ -1315,13 +1258,7 @@ impl LinkCollector<'_, '_> {
13151258 }
13161259 Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
13171260 } ,
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) {
13251262 Ok ( res) => Ok ( res) ,
13261263 Err ( ErrorKind :: AnchorFailure ( msg) ) => {
13271264 anchor_failure ( self . cx , & item, ori_link, dox, link_range, msg) ;
@@ -1389,13 +1326,9 @@ impl LinkCollector<'_, '_> {
13891326 Err ( mut kind) => {
13901327 // `resolve_macro` only looks in the macro namespace. Try to give a better error if possible.
13911328 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+ {
13991332 kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
14001333 break ;
14011334 }
@@ -1734,7 +1667,7 @@ fn resolution_failure(
17341667 name = start;
17351668 for & ns in & [ TypeNS , ValueNS , MacroNS ] {
17361669 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 )
17381671 {
17391672 debug ! ( "found partial_res={:?}" , res) ;
17401673 * partial_res = Some ( res) ;
@@ -2131,7 +2064,7 @@ fn strip_generics_from_path(path_str: &str) -> Result<String, ResolutionFailure<
21312064 }
21322065 _ => segment. push ( chr) ,
21332066 }
2134- debug ! ( "raw segment: {:?}" , segment) ;
2067+ trace ! ( "raw segment: {:?}" , segment) ;
21352068 }
21362069
21372070 if !segment. is_empty ( ) {
0 commit comments