@@ -8,7 +8,7 @@ use rustc_hir::def::{
88 Namespace :: { self , * } ,
99 PerNS , Res ,
1010} ;
11- use rustc_hir:: def_id:: { DefId , LocalDefId } ;
11+ use rustc_hir:: def_id:: DefId ;
1212use rustc_middle:: ty;
1313use rustc_resolve:: ParentScope ;
1414use rustc_session:: lint;
@@ -50,7 +50,8 @@ enum ErrorKind {
5050
5151struct LinkCollector < ' a , ' tcx > {
5252 cx : & ' a DocContext < ' tcx > ,
53- mod_ids : Vec < hir:: HirId > ,
53+ // NOTE: this may not necessarily be a module in the current crate
54+ mod_ids : Vec < DefId > ,
5455}
5556
5657impl < ' a , ' tcx > LinkCollector < ' a , ' tcx > {
@@ -62,7 +63,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
6263 & self ,
6364 path_str : & str ,
6465 current_item : & Option < String > ,
65- module_id : LocalDefId ,
66+ module_id : DefId ,
6667 ) -> Result < ( Res , Option < String > ) , ErrorKind > {
6768 let cx = self . cx ;
6869
@@ -124,7 +125,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
124125 }
125126
126127 /// Resolves a string as a macro.
127- fn macro_resolve ( & self , path_str : & str , parent_id : Option < hir :: HirId > ) -> Option < Res > {
128+ fn macro_resolve ( & self , path_str : & str , parent_id : Option < DefId > ) -> Option < Res > {
128129 let cx = self . cx ;
129130 let path = ast:: Path :: from_ident ( Ident :: from_str ( path_str) ) ;
130131 cx. enter_resolver ( |resolver| {
@@ -142,8 +143,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
142143 if let Some ( res) = resolver. all_macros ( ) . get ( & Symbol :: intern ( path_str) ) {
143144 return Some ( res. map_id ( |_| panic ! ( "unexpected id" ) ) ) ;
144145 }
145- if let Some ( module_id) = parent_id. or ( self . mod_ids . last ( ) . cloned ( ) ) {
146- let module_id = cx. tcx . hir ( ) . local_def_id ( module_id) ;
146+ if let Some ( module_id) = parent_id {
147147 if let Ok ( ( _, res) ) =
148148 resolver. resolve_str_path_error ( DUMMY_SP , path_str, MacroNS , module_id)
149149 {
@@ -167,15 +167,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
167167 disambiguator : Option < & str > ,
168168 ns : Namespace ,
169169 current_item : & Option < String > ,
170- parent_id : Option < hir :: HirId > ,
170+ parent_id : Option < DefId > ,
171171 extra_fragment : & Option < String > ,
172172 item_opt : Option < & Item > ,
173173 ) -> Result < ( Res , Option < String > ) , ErrorKind > {
174174 let cx = self . cx ;
175175
176176 // In case we're in a module, try to resolve the relative path.
177- if let Some ( module_id) = parent_id. or ( self . mod_ids . last ( ) . cloned ( ) ) {
178- let module_id = cx. tcx . hir ( ) . local_def_id ( module_id) ;
177+ if let Some ( module_id) = parent_id {
179178 let result = cx. enter_resolver ( |resolver| {
180179 resolver. resolve_str_path_error ( DUMMY_SP , & path_str, ns, module_id)
181180 } ) ;
@@ -445,40 +444,40 @@ fn is_derive_trait_collision<T>(ns: &PerNS<Option<(Res, T)>>) -> bool {
445444
446445impl < ' a , ' tcx > DocFolder for LinkCollector < ' a , ' tcx > {
447446 fn fold_item ( & mut self , mut item : Item ) -> Option < Item > {
448- let item_hir_id = if item. is_mod ( ) {
449- if let Some ( def_id) = item. def_id . as_local ( ) {
450- Some ( self . cx . tcx . hir ( ) . as_local_hir_id ( def_id) )
451- } else {
452- debug ! ( "attempting to fold on a non-local item: {:?}" , item) ;
453- return self . fold_item_recur ( item) ;
454- }
455- } else {
456- None
457- } ;
447+ use rustc_middle:: ty:: DefIdTree ;
458448
459- // FIXME: get the resolver to work with non-local resolve scopes.
460- let parent_node = self . cx . as_local_hir_id ( item. def_id ) . and_then ( |hir_id| {
461- // FIXME: this fails hard for impls in non-module scope, but is necessary for the
462- // current `resolve()` implementation.
463- match self . cx . as_local_hir_id ( self . cx . tcx . parent_module ( hir_id) . to_def_id ( ) ) . unwrap ( ) {
464- id if id != hir_id => Some ( id) ,
465- _ => None ,
449+ let parent_node = if item. is_fake ( ) {
450+ // FIXME: is this correct?
451+ None
452+ } else {
453+ let mut current = item. def_id ;
454+ // The immediate parent might not always be a module.
455+ // Find the first parent which is.
456+ loop {
457+ if let Some ( parent) = self . cx . tcx . parent ( current) {
458+ if self . cx . tcx . def_kind ( parent) == DefKind :: Mod {
459+ break Some ( parent) ;
460+ }
461+ current = parent;
462+ } else {
463+ break None ;
464+ }
466465 }
467- } ) ;
466+ } ;
468467
469468 if parent_node. is_some ( ) {
470- debug ! ( "got parent node for {:?} {:?}, id {:?}" , item. type_( ) , item. name, item. def_id) ;
469+ trace ! ( "got parent node for {:?} {:?}, id {:?}" , item. type_( ) , item. name, item. def_id) ;
471470 }
472471
473472 let current_item = match item. inner {
474473 ModuleItem ( ..) => {
475474 if item. attrs . inner_docs {
476- if item_hir_id . unwrap ( ) != hir :: CRATE_HIR_ID { item. name . clone ( ) } else { None }
475+ if item . def_id . is_top_level_module ( ) { item. name . clone ( ) } else { None }
477476 } else {
478- match parent_node. or ( self . mod_ids . last ( ) . cloned ( ) ) {
479- Some ( parent) if parent != hir :: CRATE_HIR_ID => {
477+ match parent_node. or ( self . mod_ids . last ( ) . copied ( ) ) {
478+ Some ( parent) if !parent . is_top_level_module ( ) => {
480479 // FIXME: can we pull the parent module's name from elsewhere?
481- Some ( self . cx . tcx . hir ( ) . name ( parent) . to_string ( ) )
480+ Some ( self . cx . tcx . item_name ( parent) . to_string ( ) )
482481 }
483482 _ => None ,
484483 }
@@ -488,18 +487,22 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
488487 for_. def_id ( ) . map ( |did| self . cx . tcx . item_name ( did) . to_string ( ) )
489488 }
490489 // we don't display docs on `extern crate` items anyway, so don't process them.
491- ExternCrateItem ( ..) => return self . fold_item_recur ( item) ,
490+ ExternCrateItem ( ..) => {
491+ debug ! ( "ignoring extern crate item {:?}" , item. def_id) ;
492+ return self . fold_item_recur ( item) ;
493+ }
492494 ImportItem ( Import :: Simple ( ref name, ..) ) => Some ( name. clone ( ) ) ,
493495 MacroItem ( ..) => None ,
494496 _ => item. name . clone ( ) ,
495497 } ;
496498
497499 if item. is_mod ( ) && item. attrs . inner_docs {
498- self . mod_ids . push ( item_hir_id . unwrap ( ) ) ;
500+ self . mod_ids . push ( item . def_id ) ;
499501 }
500502
501503 let cx = self . cx ;
502504 let dox = item. attrs . collapsed_doc_value ( ) . unwrap_or_else ( String :: new) ;
505+ trace ! ( "got documentation '{}'" , dox) ;
503506
504507 look_for_tests ( & cx, & dox, & item, true ) ;
505508
@@ -541,6 +544,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
541544 } ) ;
542545
543546 for ( ori_link, link_range) in markdown_links ( & dox) {
547+ trace ! ( "considering link '{}'" , ori_link) ;
548+
544549 // Bail early for real links.
545550 if ori_link. contains ( '/' ) {
546551 continue ;
@@ -641,8 +646,11 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
641646 // we've already pushed this node onto the resolution stack but
642647 // for outer comments we explicitly try and resolve against the
643648 // parent_node first.
644- let base_node =
645- if item. is_mod ( ) && item. attrs . inner_docs { None } else { parent_node } ;
649+ let base_node = if item. is_mod ( ) && item. attrs . inner_docs {
650+ self . mod_ids . last ( ) . copied ( )
651+ } else {
652+ parent_node
653+ } ;
646654
647655 // replace `Self` with suitable item's parent name
648656 if path_str. starts_with ( "Self::" ) {
@@ -826,7 +834,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
826834 }
827835
828836 if item. is_mod ( ) && !item. attrs . inner_docs {
829- self . mod_ids . push ( item_hir_id . unwrap ( ) ) ;
837+ self . mod_ids . push ( item . def_id ) ;
830838 }
831839
832840 if item. is_mod ( ) {
@@ -864,6 +872,7 @@ fn build_diagnostic(
864872 Some ( hir_id) => hir_id,
865873 None => {
866874 // If non-local, no need to check anything.
875+ info ! ( "ignoring warning from parent crate: {}" , err_msg) ;
867876 return ;
868877 }
869878 } ;
0 commit comments