@@ -8,7 +8,7 @@ use rustc_hir::def::{
8
8
Namespace :: { self , * } ,
9
9
PerNS , Res ,
10
10
} ;
11
- use rustc_hir:: def_id:: { DefId , LocalDefId } ;
11
+ use rustc_hir:: def_id:: DefId ;
12
12
use rustc_middle:: ty;
13
13
use rustc_resolve:: ParentScope ;
14
14
use rustc_session:: lint;
@@ -50,7 +50,8 @@ enum ErrorKind {
50
50
51
51
struct LinkCollector < ' a , ' tcx > {
52
52
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 > ,
54
55
}
55
56
56
57
impl < ' a , ' tcx > LinkCollector < ' a , ' tcx > {
@@ -62,7 +63,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
62
63
& self ,
63
64
path_str : & str ,
64
65
current_item : & Option < String > ,
65
- module_id : LocalDefId ,
66
+ module_id : DefId ,
66
67
) -> Result < ( Res , Option < String > ) , ErrorKind > {
67
68
let cx = self . cx ;
68
69
@@ -124,7 +125,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
124
125
}
125
126
126
127
/// 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 > {
128
129
let cx = self . cx ;
129
130
let path = ast:: Path :: from_ident ( Ident :: from_str ( path_str) ) ;
130
131
cx. enter_resolver ( |resolver| {
@@ -142,8 +143,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
142
143
if let Some ( res) = resolver. all_macros ( ) . get ( & Symbol :: intern ( path_str) ) {
143
144
return Some ( res. map_id ( |_| panic ! ( "unexpected id" ) ) ) ;
144
145
}
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 {
147
147
if let Ok ( ( _, res) ) =
148
148
resolver. resolve_str_path_error ( DUMMY_SP , path_str, MacroNS , module_id)
149
149
{
@@ -167,15 +167,14 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
167
167
disambiguator : Option < & str > ,
168
168
ns : Namespace ,
169
169
current_item : & Option < String > ,
170
- parent_id : Option < hir :: HirId > ,
170
+ parent_id : Option < DefId > ,
171
171
extra_fragment : & Option < String > ,
172
172
item_opt : Option < & Item > ,
173
173
) -> Result < ( Res , Option < String > ) , ErrorKind > {
174
174
let cx = self . cx ;
175
175
176
176
// 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 {
179
178
let result = cx. enter_resolver ( |resolver| {
180
179
resolver. resolve_str_path_error ( DUMMY_SP , & path_str, ns, module_id)
181
180
} ) ;
@@ -445,40 +444,40 @@ fn is_derive_trait_collision<T>(ns: &PerNS<Option<(Res, T)>>) -> bool {
445
444
446
445
impl < ' a , ' tcx > DocFolder for LinkCollector < ' a , ' tcx > {
447
446
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 ;
458
448
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
+ }
466
465
}
467
- } ) ;
466
+ } ;
468
467
469
468
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) ;
471
470
}
472
471
473
472
let current_item = match item. inner {
474
473
ModuleItem ( ..) => {
475
474
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 }
477
476
} 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 ( ) => {
480
479
// 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 ( ) )
482
481
}
483
482
_ => None ,
484
483
}
@@ -488,18 +487,22 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
488
487
for_. def_id ( ) . map ( |did| self . cx . tcx . item_name ( did) . to_string ( ) )
489
488
}
490
489
// 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
+ }
492
494
ImportItem ( Import :: Simple ( ref name, ..) ) => Some ( name. clone ( ) ) ,
493
495
MacroItem ( ..) => None ,
494
496
_ => item. name . clone ( ) ,
495
497
} ;
496
498
497
499
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 ) ;
499
501
}
500
502
501
503
let cx = self . cx ;
502
504
let dox = item. attrs . collapsed_doc_value ( ) . unwrap_or_else ( String :: new) ;
505
+ trace ! ( "got documentation '{}'" , dox) ;
503
506
504
507
look_for_tests ( & cx, & dox, & item, true ) ;
505
508
@@ -541,6 +544,8 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
541
544
} ) ;
542
545
543
546
for ( ori_link, link_range) in markdown_links ( & dox) {
547
+ trace ! ( "considering link '{}'" , ori_link) ;
548
+
544
549
// Bail early for real links.
545
550
if ori_link. contains ( '/' ) {
546
551
continue ;
@@ -641,8 +646,11 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
641
646
// we've already pushed this node onto the resolution stack but
642
647
// for outer comments we explicitly try and resolve against the
643
648
// 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
+ } ;
646
654
647
655
// replace `Self` with suitable item's parent name
648
656
if path_str. starts_with ( "Self::" ) {
@@ -826,7 +834,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
826
834
}
827
835
828
836
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 ) ;
830
838
}
831
839
832
840
if item. is_mod ( ) {
@@ -864,6 +872,7 @@ fn build_diagnostic(
864
872
Some ( hir_id) => hir_id,
865
873
None => {
866
874
// If non-local, no need to check anything.
875
+ info ! ( "ignoring warning from parent crate: {}" , err_msg) ;
867
876
return ;
868
877
}
869
878
} ;
0 commit comments