@@ -9,11 +9,9 @@ use crate::def_collector::collect_definitions;
9
9
use crate :: imports:: { Import , ImportKind } ;
10
10
use crate :: macros:: { MacroRulesBinding , MacroRulesScope , MacroRulesScopeRef } ;
11
11
use crate :: Namespace :: { self , MacroNS , TypeNS , ValueNS } ;
12
- use crate :: { CrateLint , Determinacy , PathResult , ResolutionError , VisResolutionError } ;
13
- use crate :: {
14
- ExternPreludeEntry , ModuleOrUniformRoot , ParentScope , PerNS , Resolver , ResolverArenas ,
15
- } ;
16
- use crate :: { Module , ModuleData , ModuleKind , NameBinding , NameBindingKind , Segment , ToNameBinding } ;
12
+ use crate :: { CrateLint , Determinacy , ExternPreludeEntry , Module , ModuleKind , ModuleOrUniformRoot } ;
13
+ use crate :: { NameBinding , NameBindingKind , ParentScope , PathResult , PerNS , ResolutionError } ;
14
+ use crate :: { Resolver , ResolverArenas , Segment , ToNameBinding , VisResolutionError } ;
17
15
18
16
use rustc_ast:: visit:: { self , AssocCtxt , Visitor } ;
19
17
use rustc_ast:: { self as ast, AssocItem , AssocItemKind , MetaItemKind , StmtKind } ;
@@ -95,100 +93,93 @@ impl<'a> Resolver<'a> {
95
93
}
96
94
97
95
/// Walks up the tree of definitions starting at `def_id`,
98
- /// stopping at the first `DefKind::Mod` encountered
99
- fn nearest_parent_mod ( & mut self , def_id : DefId ) -> Module < ' a > {
100
- let def_key = self . cstore ( ) . def_key ( def_id) ;
101
-
102
- let mut parent_id = DefId {
103
- krate : def_id. krate ,
104
- index : def_key. parent . expect ( "failed to get parent for module" ) ,
105
- } ;
106
- // The immediate parent may not be a module
107
- // (e.g. `const _: () = { #[path = "foo.rs"] mod foo; };`)
108
- // Walk up the tree until we hit a module or the crate root.
109
- while parent_id. index != CRATE_DEF_INDEX
110
- && self . cstore ( ) . def_kind ( parent_id) != DefKind :: Mod
111
- {
112
- let parent_def_key = self . cstore ( ) . def_key ( parent_id) ;
113
- parent_id. index = parent_def_key. parent . expect ( "failed to get parent for module" ) ;
96
+ /// stopping at the first encountered module.
97
+ /// Parent block modules for arbitrary def-ids are not recorded for the local crate,
98
+ /// and are not preserved in metadata for foreign crates, so block modules are never
99
+ /// returned by this function.
100
+ ///
101
+ /// For the local crate ignoring block modules may be incorrect, so use this method with care.
102
+ ///
103
+ /// For foreign crates block modules can be ignored without introducing observable differences,
104
+ /// moreover they has to be ignored right now because they are not kept in metadata.
105
+ /// Foreign parent modules are used for resolving names used by foreign macros with def-site
106
+ /// hygiene, therefore block module ignorability relies on macros with def-site hygiene and
107
+ /// block module parents being unreachable from other crates.
108
+ /// Reachable macros with block module parents exist due to `#[macro_export] macro_rules!`,
109
+ /// but they cannot use def-site hygiene, so the assumption holds
110
+ /// (<https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508>).
111
+ fn get_nearest_non_block_module ( & mut self , mut def_id : DefId ) -> Module < ' a > {
112
+ loop {
113
+ match self . get_module ( def_id) {
114
+ Some ( module) => return module,
115
+ None => {
116
+ def_id. index =
117
+ self . def_key ( def_id) . parent . expect ( "non-root `DefId` without parent" )
118
+ }
119
+ }
114
120
}
115
- self . get_module ( parent_id)
116
121
}
117
122
118
- pub fn get_module ( & mut self , def_id : DefId ) -> Module < ' a > {
119
- // If this is a local module, it will be in `module_map`, no need to recalculate it.
120
- if let Some ( def_id) = def_id. as_local ( ) {
121
- return self . module_map [ & def_id] ;
122
- }
123
+ pub fn expect_module ( & mut self , def_id : DefId ) -> Module < ' a > {
124
+ self . get_module ( def_id) . expect ( "argument `DefId` is not a module" )
125
+ }
123
126
124
- // Cache module resolution
125
- if let Some ( & module) = self . extern_module_map . get ( & def_id) {
126
- return module;
127
+ /// If `def_id` refers to a module (in resolver's sense, i.e. a module item, crate root, enum,
128
+ /// or trait), then this function returns that module's resolver representation, otherwise it
129
+ /// returns `None`.
130
+ /// FIXME: `Module`s for local enums and traits are not currently found.
131
+ crate fn get_module ( & mut self , def_id : DefId ) -> Option < Module < ' a > > {
132
+ if let module @ Some ( ..) = self . module_map . get ( & def_id) {
133
+ return module. copied ( ) ;
127
134
}
128
135
129
- let ( name, parent) = if def_id. index == CRATE_DEF_INDEX {
130
- // This is the crate root
131
- ( self . cstore ( ) . crate_name ( def_id. krate ) , None )
132
- } else {
133
- let def_key = self . cstore ( ) . def_key ( def_id) ;
134
- let name = def_key
135
- . disambiguated_data
136
- . data
137
- . get_opt_name ( )
138
- . expect ( "given a DefId that wasn't a module" ) ;
139
-
140
- let parent = Some ( self . nearest_parent_mod ( def_id) ) ;
141
- ( name, parent)
142
- } ;
136
+ if !def_id. is_local ( ) {
137
+ let def_kind = self . cstore ( ) . def_kind ( def_id) ;
138
+ match def_kind {
139
+ DefKind :: Mod | DefKind :: Enum | DefKind :: Trait => {
140
+ let def_key = self . cstore ( ) . def_key ( def_id) ;
141
+ let parent = def_key. parent . map ( |index| {
142
+ self . get_nearest_non_block_module ( DefId { index, krate : def_id. krate } )
143
+ } ) ;
144
+ let name = if def_id. index == CRATE_DEF_INDEX {
145
+ self . cstore ( ) . crate_name ( def_id. krate )
146
+ } else {
147
+ def_key. disambiguated_data . data . get_opt_name ( ) . expect ( "module without name" )
148
+ } ;
143
149
144
- // Allocate and return a new module with the information we found
145
- let kind = ModuleKind :: Def ( DefKind :: Mod , def_id, name) ;
146
- let module = self . arenas . alloc_module ( ModuleData :: new (
147
- parent,
148
- kind,
149
- def_id,
150
- self . cstore ( ) . module_expansion_untracked ( def_id, & self . session ) ,
151
- self . cstore ( ) . get_span_untracked ( def_id, & self . session ) ,
152
- ) ) ;
153
- self . extern_module_map . insert ( def_id, module) ;
154
- module
150
+ let module = self . arenas . new_module (
151
+ parent,
152
+ ModuleKind :: Def ( def_kind, def_id, name) ,
153
+ self . cstore ( ) . module_expansion_untracked ( def_id, & self . session ) ,
154
+ self . cstore ( ) . get_span_untracked ( def_id, & self . session ) ,
155
+ // FIXME: Account for `#[no_implicit_prelude]` attributes.
156
+ parent. map_or ( false , |module| module. no_implicit_prelude ) ,
157
+ ) ;
158
+ self . module_map . insert ( def_id, module) ;
159
+ Some ( module)
160
+ }
161
+ _ => None ,
162
+ }
163
+ } else {
164
+ None
165
+ }
155
166
}
156
167
157
- crate fn macro_def_scope ( & mut self , expn_id : ExpnId ) -> Module < ' a > {
158
- let def_id = match expn_id. expn_data ( ) . macro_def_id {
159
- Some ( def_id) => def_id,
160
- None => {
161
- return expn_id
162
- . as_local ( )
163
- . and_then ( |expn_id| self . ast_transform_scopes . get ( & expn_id) )
164
- . unwrap_or ( & self . graph_root ) ;
165
- }
166
- } ;
167
- self . macro_def_scope_from_def_id ( def_id)
168
+ crate fn expn_def_scope ( & mut self , expn_id : ExpnId ) -> Module < ' a > {
169
+ match expn_id. expn_data ( ) . macro_def_id {
170
+ Some ( def_id) => self . macro_def_scope ( def_id) ,
171
+ None => expn_id
172
+ . as_local ( )
173
+ . and_then ( |expn_id| self . ast_transform_scopes . get ( & expn_id) )
174
+ . unwrap_or ( & self . graph_root ) ,
175
+ }
168
176
}
169
177
170
- crate fn macro_def_scope_from_def_id ( & mut self , def_id : DefId ) -> Module < ' a > {
178
+ crate fn macro_def_scope ( & mut self , def_id : DefId ) -> Module < ' a > {
171
179
if let Some ( id) = def_id. as_local ( ) {
172
180
self . local_macro_def_scopes [ & id]
173
181
} else {
174
- // This is not entirely correct - a `macro_rules!` macro may occur
175
- // inside a 'block' module:
176
- //
177
- // ```rust
178
- // const _: () = {
179
- // #[macro_export]
180
- // macro_rules! my_macro {
181
- // () => {};
182
- // }
183
- // `
184
- // We don't record this information for external crates, so
185
- // the module we compute here will be the closest 'mod' item
186
- // (not necesssarily the actual parent of the `macro_rules!`
187
- // macro). `macro_rules!` macros can't use def-site hygiene,
188
- // so this hopefully won't be a problem.
189
- //
190
- // See https://github.com/rust-lang/rust/pull/77984#issuecomment-712445508
191
- self . nearest_parent_mod ( def_id)
182
+ self . get_nearest_non_block_module ( def_id)
192
183
}
193
184
}
194
185
@@ -274,7 +265,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
274
265
self . r . visibilities [ & def_id. expect_local ( ) ]
275
266
}
276
267
// Otherwise, the visibility is restricted to the nearest parent `mod` item.
277
- _ => ty:: Visibility :: Restricted ( self . parent_scope . module . nearest_parent_mod ) ,
268
+ _ => ty:: Visibility :: Restricted ( self . parent_scope . module . nearest_parent_mod ( ) ) ,
278
269
} )
279
270
}
280
271
ast:: VisibilityKind :: Restricted { ref path, id, .. } => {
@@ -717,7 +708,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
717
708
local_def_id,
718
709
) ;
719
710
self . r . extern_crate_map . insert ( local_def_id, crate_id) ;
720
- self . r . get_module ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } )
711
+ self . r . expect_module ( crate_id. as_def_id ( ) )
721
712
} ;
722
713
723
714
let used = self . process_macro_use_imports ( item, module) ;
@@ -768,21 +759,16 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
768
759
}
769
760
770
761
ItemKind :: Mod ( ..) => {
771
- let module_kind = ModuleKind :: Def ( DefKind :: Mod , def_id, ident. name ) ;
772
- let module = self . r . arenas . alloc_module ( ModuleData {
773
- no_implicit_prelude : parent. no_implicit_prelude || {
774
- self . r . session . contains_name ( & item. attrs , sym:: no_implicit_prelude)
775
- } ,
776
- ..ModuleData :: new (
777
- Some ( parent) ,
778
- module_kind,
779
- def_id,
780
- expansion. to_expn_id ( ) ,
781
- item. span ,
782
- )
783
- } ) ;
762
+ let module = self . r . arenas . new_module (
763
+ Some ( parent) ,
764
+ ModuleKind :: Def ( DefKind :: Mod , def_id, ident. name ) ,
765
+ expansion. to_expn_id ( ) ,
766
+ item. span ,
767
+ parent. no_implicit_prelude
768
+ || self . r . session . contains_name ( & item. attrs , sym:: no_implicit_prelude) ,
769
+ ) ;
784
770
self . r . define ( parent, ident, TypeNS , ( module, vis, sp, expansion) ) ;
785
- self . r . module_map . insert ( local_def_id , module) ;
771
+ self . r . module_map . insert ( def_id , module) ;
786
772
787
773
// Descend into the module.
788
774
self . parent_scope . module = module;
@@ -813,13 +799,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
813
799
}
814
800
815
801
ItemKind :: Enum ( _, _) => {
816
- let module_kind = ModuleKind :: Def ( DefKind :: Enum , def_id, ident. name ) ;
817
- let module = self . r . new_module (
818
- parent,
819
- module_kind,
820
- parent. nearest_parent_mod ,
802
+ let module = self . r . arenas . new_module (
803
+ Some ( parent) ,
804
+ ModuleKind :: Def ( DefKind :: Enum , def_id, ident. name ) ,
821
805
expansion. to_expn_id ( ) ,
822
806
item. span ,
807
+ parent. no_implicit_prelude ,
823
808
) ;
824
809
self . r . define ( parent, ident, TypeNS , ( module, vis, sp, expansion) ) ;
825
810
self . parent_scope . module = module;
@@ -888,13 +873,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
888
873
889
874
ItemKind :: Trait ( ..) => {
890
875
// Add all the items within to a new module.
891
- let module_kind = ModuleKind :: Def ( DefKind :: Trait , def_id, ident. name ) ;
892
- let module = self . r . new_module (
893
- parent,
894
- module_kind,
895
- parent. nearest_parent_mod ,
876
+ let module = self . r . arenas . new_module (
877
+ Some ( parent) ,
878
+ ModuleKind :: Def ( DefKind :: Trait , def_id, ident. name ) ,
896
879
expansion. to_expn_id ( ) ,
897
880
item. span ,
881
+ parent. no_implicit_prelude ,
898
882
) ;
899
883
self . r . define ( parent, ident, TypeNS , ( module, vis, sp, expansion) ) ;
900
884
self . parent_scope . module = module;
@@ -932,12 +916,12 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
932
916
let parent = self . parent_scope . module ;
933
917
let expansion = self . parent_scope . expansion ;
934
918
if self . block_needs_anonymous_module ( block) {
935
- let module = self . r . new_module (
936
- parent,
919
+ let module = self . r . arenas . new_module (
920
+ Some ( parent) ,
937
921
ModuleKind :: Block ( block. id ) ,
938
- parent. nearest_parent_mod ,
939
922
expansion. to_expn_id ( ) ,
940
923
block. span ,
924
+ parent. no_implicit_prelude ,
941
925
) ;
942
926
self . r . block_map . insert ( block. id , module) ;
943
927
self . parent_scope . module = module; // Descend into the block.
@@ -953,12 +937,13 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
953
937
// Record primary definitions.
954
938
match res {
955
939
Res :: Def ( kind @ ( DefKind :: Mod | DefKind :: Enum | DefKind :: Trait ) , def_id) => {
956
- let module = self . r . new_module (
957
- parent,
940
+ let module = self . r . arenas . new_module (
941
+ Some ( parent) ,
958
942
ModuleKind :: Def ( kind, def_id, ident. name ) ,
959
- def_id,
960
943
expansion. to_expn_id ( ) ,
961
944
span,
945
+ // FIXME: Account for `#[no_implicit_prelude]` attributes.
946
+ parent. no_implicit_prelude ,
962
947
) ;
963
948
self . r . define ( parent, ident, TypeNS , ( module, vis, span, expansion) ) ;
964
949
}
0 commit comments