@@ -102,7 +102,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
102102 fn variant_field (
103103 & self ,
104104 path_str : & ' path str ,
105- current_item : & Option < String > ,
106105 module_id : DefId ,
107106 ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
108107 let cx = self . cx ;
@@ -125,14 +124,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
125124 split. next ( ) . map ( |f| ( f, Symbol :: intern ( f) ) ) . ok_or_else ( no_res) ?;
126125 let path = split
127126 . next ( )
128- . map ( |f| {
129- if f == "self" || f == "Self" {
130- if let Some ( name) = current_item. as_ref ( ) {
131- return name. clone ( ) ;
132- }
133- }
134- f. to_owned ( )
135- } )
127+ . map ( |f| f. to_owned ( ) )
136128 // If there's no third component, we saw `[a::b]` before and it failed to resolve.
137129 // So there's no partial res.
138130 . ok_or_else ( no_res) ?;
@@ -237,7 +229,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
237229 & self ,
238230 path_str : & ' path str ,
239231 ns : Namespace ,
240- current_item : & Option < String > ,
241232 module_id : DefId ,
242233 extra_fragment : & Option < String > ,
243234 ) -> Result < ( Res , Option < String > ) , ErrorKind < ' path > > {
@@ -296,14 +287,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
296287 let ( item_str, item_name) = split. next ( ) . map ( |i| ( i, Symbol :: intern ( i) ) ) . unwrap ( ) ;
297288 let path_root = split
298289 . next ( )
299- . map ( |f| {
300- if f == "self" || f == "Self" {
301- if let Some ( name) = current_item. as_ref ( ) {
302- return name. clone ( ) ;
303- }
304- }
305- f. to_owned ( )
306- } )
290+ . map ( |f| f. to_owned ( ) )
307291 // If there's no `::`, it's not an associated item.
308292 // So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
309293 . ok_or_else ( || {
@@ -365,7 +349,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
365349 let ty_res = match ty_res {
366350 Err ( ( ) ) | Ok ( Res :: Err ) => {
367351 return if ns == Namespace :: ValueNS {
368- self . variant_field ( path_str, current_item , module_id)
352+ self . variant_field ( path_str, module_id)
369353 } else {
370354 Err ( ResolutionFailure :: NotResolved {
371355 module_id,
@@ -501,7 +485,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
501485 } ;
502486 res. unwrap_or_else ( || {
503487 if ns == Namespace :: ValueNS {
504- self . variant_field ( path_str, current_item , module_id)
488+ self . variant_field ( path_str, module_id)
505489 } else {
506490 Err ( ResolutionFailure :: NotResolved {
507491 module_id,
@@ -524,7 +508,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
524508 ns : Namespace ,
525509 path_str : & str ,
526510 module_id : DefId ,
527- current_item : & Option < String > ,
528511 extra_fragment : & Option < String > ,
529512 ) -> Option < Res > {
530513 let check_full_res_inner = |this : & Self , result : Result < Res , ErrorKind < ' _ > > | {
@@ -540,7 +523,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
540523 } ;
541524 // cannot be used for macro namespace
542525 let check_full_res = |this : & Self , ns| {
543- let result = this. resolve ( path_str, ns, current_item , module_id, extra_fragment) ;
526+ let result = this. resolve ( path_str, ns, module_id, extra_fragment) ;
544527 check_full_res_inner ( this, result. map ( |( res, _) | res) )
545528 } ;
546529 let check_full_res_macro = |this : & Self | {
@@ -736,32 +719,40 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
736719 trace ! ( "got parent node for {:?} {:?}, id {:?}" , item. type_( ) , item. name, item. def_id) ;
737720 }
738721
739- let current_item = match item. inner {
740- ModuleItem ( ..) => {
741- if item. attrs . inner_docs {
742- if item. def_id . is_top_level_module ( ) { item. name . clone ( ) } else { None }
743- } else {
744- match parent_node. or ( self . mod_ids . last ( ) . copied ( ) ) {
745- Some ( parent) if !parent. is_top_level_module ( ) => {
746- // FIXME: can we pull the parent module's name from elsewhere?
747- Some ( self . cx . tcx . item_name ( parent) . to_string ( ) )
748- }
749- _ => None ,
750- }
751- }
752- }
753- ImplItem ( Impl { ref for_, .. } ) => {
754- for_. def_id ( ) . map ( |did| self . cx . tcx . item_name ( did) . to_string ( ) )
755- }
756- // we don't display docs on `extern crate` items anyway, so don't process them.
757- ExternCrateItem ( ..) => {
758- debug ! ( "ignoring extern crate item {:?}" , item. def_id) ;
759- return self . fold_item_recur ( item) ;
760- }
761- ImportItem ( Import :: Simple ( ref name, ..) ) => Some ( name. clone ( ) ) ,
762- MacroItem ( ..) => None ,
763- _ => item. name . clone ( ) ,
722+ // find item's parent to resolve `Self` in item's docs below
723+ debug ! ( "looking for the `Self` type" ) ;
724+ let self_id = if item. is_fake ( ) {
725+ None
726+ } else if matches ! (
727+ self . cx. tcx. def_kind( item. def_id) ,
728+ DefKind :: AssocConst
729+ | DefKind :: AssocFn
730+ | DefKind :: AssocTy
731+ | DefKind :: Variant
732+ | DefKind :: Field
733+ ) {
734+ self . cx . tcx . parent ( item. def_id )
735+ // HACK(jynelson): `clean` marks associated types as `TypedefItem`, not as `AssocTypeItem`.
736+ // Fixing this breaks `fn render_deref_methods`.
737+ // As a workaround, see if the parent of the item is an `impl`; if so this must be an associated item,
738+ // regardless of what rustdoc wants to call it.
739+ } else if let Some ( parent) = self . cx . tcx . parent ( item. def_id ) {
740+ let parent_kind = self . cx . tcx . def_kind ( parent) ;
741+ Some ( if parent_kind == DefKind :: Impl { parent } else { item. def_id } )
742+ } else {
743+ // FIXME: this should really be `Some(item.def_id)`, but for some reason that panics in `opt_item_name`
744+ None
764745 } ;
746+ let self_name = self_id. and_then ( |self_id| {
747+ if matches ! ( self . cx. tcx. def_kind( self_id) , DefKind :: Impl ) {
748+ debug ! ( "using type_of()" ) ;
749+ // NOTE: uses Debug to avoid shortening paths
750+ Some ( format ! ( "{:?}" , self . cx. tcx. type_of( self_id) ) )
751+ } else {
752+ debug ! ( "using item_name()" ) ;
753+ self . cx . tcx . opt_item_name ( self_id) . map ( |sym| sym. to_string ( ) )
754+ }
755+ } ) ;
765756
766757 if item. is_mod ( ) && item. attrs . inner_docs {
767758 self . mod_ids . push ( item. def_id ) ;
@@ -770,53 +761,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
770761 let dox = item. attrs . collapsed_doc_value ( ) . unwrap_or_else ( String :: new) ;
771762 trace ! ( "got documentation '{}'" , dox) ;
772763
773- // find item's parent to resolve `Self` in item's docs below
774- let parent_name = self . cx . as_local_hir_id ( item. def_id ) . and_then ( |item_hir| {
775- let parent_hir = self . cx . tcx . hir ( ) . get_parent_item ( item_hir) ;
776- let item_parent = self . cx . tcx . hir ( ) . find ( parent_hir) ;
777- match item_parent {
778- Some ( hir:: Node :: Item ( hir:: Item {
779- kind :
780- hir:: ItemKind :: Impl {
781- self_ty :
782- hir:: Ty {
783- kind :
784- hir:: TyKind :: Path ( hir:: QPath :: Resolved (
785- _,
786- hir:: Path { segments, .. } ,
787- ) ) ,
788- ..
789- } ,
790- ..
791- } ,
792- ..
793- } ) ) => segments. first ( ) . map ( |seg| seg. ident . to_string ( ) ) ,
794- Some ( hir:: Node :: Item ( hir:: Item {
795- ident, kind : hir:: ItemKind :: Enum ( ..) , ..
796- } ) )
797- | Some ( hir:: Node :: Item ( hir:: Item {
798- ident, kind : hir:: ItemKind :: Struct ( ..) , ..
799- } ) )
800- | Some ( hir:: Node :: Item ( hir:: Item {
801- ident, kind : hir:: ItemKind :: Union ( ..) , ..
802- } ) )
803- | Some ( hir:: Node :: Item ( hir:: Item {
804- ident, kind : hir:: ItemKind :: Trait ( ..) , ..
805- } ) ) => Some ( ident. to_string ( ) ) ,
806- _ => None ,
807- }
808- } ) ;
809-
810764 for ( ori_link, link_range) in markdown_links ( & dox) {
811- self . resolve_link (
812- & mut item,
813- & dox,
814- & current_item,
815- parent_node,
816- & parent_name,
817- ori_link,
818- link_range,
819- ) ;
765+ self . resolve_link ( & mut item, & dox, & self_name, parent_node, ori_link, link_range) ;
820766 }
821767
822768 if item. is_mod ( ) && !item. attrs . inner_docs {
@@ -840,9 +786,8 @@ impl LinkCollector<'_, '_> {
840786 & self ,
841787 item : & mut Item ,
842788 dox : & str ,
843- current_item : & Option < String > ,
789+ self_name : & Option < String > ,
844790 parent_node : Option < DefId > ,
845- parent_name : & Option < String > ,
846791 ori_link : String ,
847792 link_range : Option < Range < usize > > ,
848793 ) {
@@ -933,8 +878,10 @@ impl LinkCollector<'_, '_> {
933878
934879 // replace `Self` with suitable item's parent name
935880 if path_str. starts_with ( "Self::" ) {
936- if let Some ( ref name) = parent_name {
881+ if let Some ( ref name) = self_name {
882+ debug ! ( "replacing Self with {}" , name) ;
937883 resolved_self = format ! ( "{}::{}" , name, & path_str[ 6 ..] ) ;
884+ // FIXME: this overwrites the link text in both error messages and the link body
938885 path_str = & resolved_self;
939886 }
940887 } else if path_str. starts_with ( "crate::" ) {
@@ -955,7 +902,6 @@ impl LinkCollector<'_, '_> {
955902 item,
956903 dox,
957904 path_str,
958- current_item,
959905 module_id,
960906 extra_fragment,
961907 & ori_link,
@@ -1083,15 +1029,14 @@ impl LinkCollector<'_, '_> {
10831029 item : & mut Item ,
10841030 dox : & str ,
10851031 path_str : & str ,
1086- current_item : & Option < String > ,
10871032 base_node : DefId ,
10881033 extra_fragment : Option < String > ,
10891034 ori_link : & str ,
10901035 link_range : Option < Range < usize > > ,
10911036 ) -> Option < ( Res , Option < String > ) > {
10921037 match disambiguator. map ( Disambiguator :: ns) {
10931038 Some ( ns @ ( ValueNS | TypeNS ) ) => {
1094- match self . resolve ( path_str, ns, & current_item , base_node, & extra_fragment) {
1039+ match self . resolve ( path_str, ns, base_node, & extra_fragment) {
10951040 Ok ( res) => Some ( res) ,
10961041 Err ( ErrorKind :: Resolve ( box mut kind) ) => {
10971042 // We only looked in one namespace. Try to give a better error if possible.
@@ -1104,7 +1049,6 @@ impl LinkCollector<'_, '_> {
11041049 new_ns,
11051050 path_str,
11061051 base_node,
1107- & current_item,
11081052 & extra_fragment,
11091053 ) {
11101054 kind = ResolutionFailure :: WrongNamespace ( res, ns) ;
@@ -1138,13 +1082,7 @@ impl LinkCollector<'_, '_> {
11381082 macro_ns : self
11391083 . macro_resolve ( path_str, base_node)
11401084 . map ( |res| ( res, extra_fragment. clone ( ) ) ) ,
1141- type_ns : match self . resolve (
1142- path_str,
1143- TypeNS ,
1144- & current_item,
1145- base_node,
1146- & extra_fragment,
1147- ) {
1085+ type_ns : match self . resolve ( path_str, TypeNS , base_node, & extra_fragment) {
11481086 Ok ( res) => {
11491087 debug ! ( "got res in TypeNS: {:?}" , res) ;
11501088 Ok ( res)
@@ -1155,13 +1093,7 @@ impl LinkCollector<'_, '_> {
11551093 }
11561094 Err ( ErrorKind :: Resolve ( box kind) ) => Err ( kind) ,
11571095 } ,
1158- value_ns : match self . resolve (
1159- path_str,
1160- ValueNS ,
1161- & current_item,
1162- base_node,
1163- & extra_fragment,
1164- ) {
1096+ value_ns : match self . resolve ( path_str, ValueNS , base_node, & extra_fragment) {
11651097 Ok ( res) => Ok ( res) ,
11661098 Err ( ErrorKind :: AnchorFailure ( msg) ) => {
11671099 anchor_failure ( self . cx , & item, ori_link, dox, link_range, msg) ;
@@ -1229,13 +1161,9 @@ impl LinkCollector<'_, '_> {
12291161 Err ( mut kind) => {
12301162 // `macro_resolve` only looks in the macro namespace. Try to give a better error if possible.
12311163 for & ns in & [ TypeNS , ValueNS ] {
1232- if let Some ( res) = self . check_full_res (
1233- ns,
1234- path_str,
1235- base_node,
1236- & current_item,
1237- & extra_fragment,
1238- ) {
1164+ if let Some ( res) =
1165+ self . check_full_res ( ns, path_str, base_node, & extra_fragment)
1166+ {
12391167 kind = ResolutionFailure :: WrongNamespace ( res, MacroNS ) ;
12401168 break ;
12411169 }
@@ -1558,7 +1486,7 @@ fn resolution_failure(
15581486 name = start;
15591487 for & ns in & [ TypeNS , ValueNS , MacroNS ] {
15601488 if let Some ( res) =
1561- collector. check_full_res ( ns, & start, module_id, & None , & None )
1489+ collector. check_full_res ( ns, & start, module_id, & None )
15621490 {
15631491 debug ! ( "found partial_res={:?}" , res) ;
15641492 * partial_res = Some ( res) ;
0 commit comments