@@ -9,7 +9,7 @@ use rustc_ast_lowering::ResolverAstLowering;
9
9
use rustc_data_structures:: fx:: FxHashMap ;
10
10
use rustc_hir:: def:: Namespace :: * ;
11
11
use rustc_hir:: def:: { DefKind , Namespace , Res } ;
12
- use rustc_hir:: def_id:: { DefId , DefIdMap , DefIdSet , LocalDefId , CRATE_DEF_ID } ;
12
+ use rustc_hir:: def_id:: { DefId , DefIdMap , DefIdSet , CRATE_DEF_ID } ;
13
13
use rustc_hir:: TraitCandidate ;
14
14
use rustc_middle:: ty:: { DefIdTree , Visibility } ;
15
15
use rustc_resolve:: { ParentScope , Resolver } ;
@@ -27,10 +27,12 @@ crate fn early_resolve_intra_doc_links(
27
27
externs : Externs ,
28
28
document_private_items : bool ,
29
29
) -> ResolverCaches {
30
+ let parent_scope =
31
+ ParentScope :: module ( resolver. expect_module ( CRATE_DEF_ID . to_def_id ( ) ) , resolver) ;
30
32
let mut link_resolver = EarlyDocLinkResolver {
31
33
resolver,
32
34
sess,
33
- current_mod : CRATE_DEF_ID ,
35
+ parent_scope ,
34
36
visited_mods : Default :: default ( ) ,
35
37
markdown_links : Default :: default ( ) ,
36
38
doc_link_resolutions : Default :: default ( ) ,
@@ -52,7 +54,7 @@ crate fn early_resolve_intra_doc_links(
52
54
// DO NOT REMOVE THIS without first testing on the reproducer in
53
55
// https://github.com/jyn514/objr/commit/edcee7b8124abf0e4c63873e8422ff81beb11ebb
54
56
for ( extern_name, _) in externs. iter ( ) . filter ( |( _, entry) | entry. add_prelude ) {
55
- link_resolver. resolver . resolve_rustdoc_path ( extern_name, TypeNS , CRATE_DEF_ID . to_def_id ( ) ) ;
57
+ link_resolver. resolver . resolve_rustdoc_path ( extern_name, TypeNS , parent_scope ) ;
56
58
}
57
59
58
60
ResolverCaches {
@@ -72,7 +74,7 @@ fn doc_attrs<'a>(attrs: impl Iterator<Item = &'a ast::Attribute>) -> Attributes
72
74
struct EarlyDocLinkResolver < ' r , ' ra > {
73
75
resolver : & ' r mut Resolver < ' ra > ,
74
76
sess : & ' r Session ,
75
- current_mod : LocalDefId ,
77
+ parent_scope : ParentScope < ' ra > ,
76
78
visited_mods : DefIdSet ,
77
79
markdown_links : FxHashMap < String , Vec < PreprocessedMarkdownLink > > ,
78
80
doc_link_resolutions : FxHashMap < ( Symbol , Namespace , DefId ) , Option < Res < ast:: NodeId > > > ,
@@ -82,7 +84,7 @@ struct EarlyDocLinkResolver<'r, 'ra> {
82
84
document_private_items : bool ,
83
85
}
84
86
85
- impl EarlyDocLinkResolver < ' _ , ' _ > {
87
+ impl < ' ra > EarlyDocLinkResolver < ' _ , ' ra > {
86
88
fn add_traits_in_scope ( & mut self , def_id : DefId ) {
87
89
// Calls to `traits_in_scope` are expensive, so try to avoid them if only possible.
88
90
// Keys in the `traits_in_scope` cache are always module IDs.
@@ -205,20 +207,24 @@ impl EarlyDocLinkResolver<'_, '_> {
205
207
if !attrs. iter ( ) . any ( |attr| attr. may_have_doc_links ( ) ) {
206
208
return ;
207
209
}
208
- let module_id = self . current_mod . to_def_id ( ) ;
209
- self . resolve_doc_links ( doc_attrs ( attrs. iter ( ) ) , module_id) ;
210
+ self . resolve_doc_links ( doc_attrs ( attrs. iter ( ) ) , self . parent_scope ) ;
210
211
}
211
212
212
- fn resolve_and_cache ( & mut self , path_str : & str , ns : Namespace , module_id : DefId ) -> bool {
213
+ fn resolve_and_cache (
214
+ & mut self ,
215
+ path_str : & str ,
216
+ ns : Namespace ,
217
+ parent_scope : & ParentScope < ' ra > ,
218
+ ) -> bool {
213
219
self . doc_link_resolutions
214
- . entry ( ( Symbol :: intern ( path_str) , ns, module_id ) )
215
- . or_insert_with_key ( |( path, ns, module_id ) | {
216
- self . resolver . resolve_rustdoc_path ( path. as_str ( ) , * ns, * module_id )
220
+ . entry ( ( Symbol :: intern ( path_str) , ns, parent_scope . module . def_id ( ) ) )
221
+ . or_insert_with_key ( |( path, ns, _ ) | {
222
+ self . resolver . resolve_rustdoc_path ( path. as_str ( ) , * ns, * parent_scope )
217
223
} )
218
224
. is_some ( )
219
225
}
220
226
221
- fn resolve_doc_links ( & mut self , attrs : Attributes , module_id : DefId ) {
227
+ fn resolve_doc_links ( & mut self , attrs : Attributes , parent_scope : ParentScope < ' ra > ) {
222
228
let mut need_traits_in_scope = false ;
223
229
for ( doc_module, doc) in attrs. prepare_to_doc_link_resolution ( ) {
224
230
assert_eq ! ( doc_module, None ) ;
@@ -230,7 +236,7 @@ impl EarlyDocLinkResolver<'_, '_> {
230
236
// The logic here is a conservative approximation for path resolution in
231
237
// `resolve_with_disambiguator`.
232
238
if let Some ( ns) = pinfo. disambiguator . map ( Disambiguator :: ns) {
233
- if self . resolve_and_cache ( & pinfo. path_str , ns, module_id ) {
239
+ if self . resolve_and_cache ( & pinfo. path_str , ns, & parent_scope ) {
234
240
continue ;
235
241
}
236
242
}
@@ -239,7 +245,7 @@ impl EarlyDocLinkResolver<'_, '_> {
239
245
let mut any_resolved = false ;
240
246
let mut need_assoc = false ;
241
247
for ns in [ TypeNS , ValueNS , MacroNS ] {
242
- if self . resolve_and_cache ( & pinfo. path_str , ns, module_id ) {
248
+ if self . resolve_and_cache ( & pinfo. path_str , ns, & parent_scope ) {
243
249
any_resolved = true ;
244
250
} else if ns != MacroNS {
245
251
need_assoc = true ;
@@ -256,7 +262,7 @@ impl EarlyDocLinkResolver<'_, '_> {
256
262
}
257
263
258
264
if need_traits_in_scope {
259
- self . add_traits_in_scope ( module_id ) ;
265
+ self . add_traits_in_scope ( parent_scope . module . def_id ( ) ) ;
260
266
}
261
267
}
262
268
@@ -298,11 +304,13 @@ impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> {
298
304
fn visit_item ( & mut self , item : & ast:: Item ) {
299
305
self . resolve_doc_links_local ( & item. attrs ) ; // Outer attribute scope
300
306
if let ItemKind :: Mod ( ..) = item. kind {
301
- let old_mod = mem:: replace ( & mut self . current_mod , self . resolver . local_def_id ( item. id ) ) ;
307
+ let module_def_id = self . resolver . local_def_id ( item. id ) . to_def_id ( ) ;
308
+ let module = self . resolver . expect_module ( module_def_id) ;
309
+ let old_module = mem:: replace ( & mut self . parent_scope . module , module) ;
302
310
self . resolve_doc_links_local ( & item. attrs ) ; // Inner attribute scope
303
- self . process_module_children_or_reexports ( self . current_mod . to_def_id ( ) ) ;
311
+ self . process_module_children_or_reexports ( module_def_id ) ;
304
312
visit:: walk_item ( self , item) ;
305
- self . current_mod = old_mod ;
313
+ self . parent_scope . module = old_module ;
306
314
} else {
307
315
match item. kind {
308
316
ItemKind :: Trait ( ..) => {
0 commit comments