@@ -6,10 +6,11 @@ use rustc_data_structures::fx::FxHashMap;
6
6
use rustc_errors:: { Applicability , Diagnostic , LintDiagnosticBuilder , MultiSpan } ;
7
7
use rustc_hir as hir;
8
8
use rustc_hir:: { intravisit, HirId } ;
9
+ use rustc_index:: vec:: IndexVec ;
9
10
use rustc_middle:: hir:: nested_filter;
10
11
use rustc_middle:: lint:: {
11
- struct_lint_level, LevelAndSource , LintExpectation , LintLevelQueryMap , LintLevelSets ,
12
- LintLevelSource , LintSet , LintStackIndex , COMMAND_LINE ,
12
+ reveal_actual_level , struct_lint_level, LevelAndSource , LintExpectation , LintLevelSource ,
13
+ ShallowLintLevelMap ,
13
14
} ;
14
15
use rustc_middle:: ty:: query:: Providers ;
15
16
use rustc_middle:: ty:: { RegisteredTools , TyCtxt } ;
@@ -27,13 +28,80 @@ use crate::errors::{
27
28
UnknownToolInScopedLint ,
28
29
} ;
29
30
31
+ #[ derive( Debug ) ]
32
+ struct LintLevelSets {
33
+ list : IndexVec < LintStackIndex , LintSet > ,
34
+ }
35
+
36
+ rustc_index:: newtype_index! {
37
+ struct LintStackIndex {
38
+ ENCODABLE = custom, // we don't need encoding
39
+ const COMMAND_LINE = 0 ,
40
+ }
41
+ }
42
+
43
+ #[ derive( Debug ) ]
44
+ struct LintSet {
45
+ // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which
46
+ // flag.
47
+ specs : FxHashMap < LintId , LevelAndSource > ,
48
+
49
+ parent : LintStackIndex ,
50
+ }
51
+
52
+ impl LintLevelSets {
53
+ fn new ( ) -> Self {
54
+ LintLevelSets { list : IndexVec :: new ( ) }
55
+ }
56
+
57
+ fn get_lint_level (
58
+ & self ,
59
+ lint : & ' static Lint ,
60
+ idx : LintStackIndex ,
61
+ aux : Option < & FxHashMap < LintId , LevelAndSource > > ,
62
+ sess : & Session ,
63
+ ) -> LevelAndSource {
64
+ let lint = LintId :: of ( lint) ;
65
+ let ( level, mut src) = self . raw_lint_id_level ( lint, idx, aux) ;
66
+ let level = reveal_actual_level ( level, & mut src, sess, lint, |id| {
67
+ self . raw_lint_id_level ( id, idx, aux)
68
+ } ) ;
69
+ ( level, src)
70
+ }
71
+
72
+ fn raw_lint_id_level (
73
+ & self ,
74
+ id : LintId ,
75
+ mut idx : LintStackIndex ,
76
+ aux : Option < & FxHashMap < LintId , LevelAndSource > > ,
77
+ ) -> ( Option < Level > , LintLevelSource ) {
78
+ if let Some ( specs) = aux {
79
+ if let Some ( & ( level, src) ) = specs. get ( & id) {
80
+ return ( Some ( level) , src) ;
81
+ }
82
+ }
83
+ loop {
84
+ let LintSet { ref specs, parent } = self . list [ idx] ;
85
+ if let Some ( & ( level, src) ) = specs. get ( & id) {
86
+ return ( Some ( level) , src) ;
87
+ }
88
+ if idx == COMMAND_LINE {
89
+ return ( None , LintLevelSource :: Default ) ;
90
+ }
91
+ idx = parent;
92
+ }
93
+ }
94
+ }
95
+
30
96
fn lint_expectations ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> Vec < ( LintExpectationId , LintExpectation ) > {
31
97
let store = unerased_lint_store ( tcx) ;
32
98
33
99
let mut builder = LintLevelsBuilder {
34
100
sess : tcx. sess ,
35
101
provider : QueryMapExpectationsWrapper {
36
- map : LintLevelQueryMap { tcx, cur : hir:: CRATE_HIR_ID , specs : FxHashMap :: default ( ) } ,
102
+ tcx,
103
+ cur : hir:: CRATE_HIR_ID ,
104
+ specs : ShallowLintLevelMap :: default ( ) ,
37
105
expectations : Vec :: new ( ) ,
38
106
unstable_to_stable_ids : FxHashMap :: default ( ) ,
39
107
} ,
@@ -51,12 +119,12 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
51
119
builder. provider . expectations
52
120
}
53
121
54
- fn lint_levels_on ( tcx : TyCtxt < ' _ > , hir_id : HirId ) -> FxHashMap < LintId , LevelAndSource > {
122
+ fn shallow_lint_levels_on ( tcx : TyCtxt < ' _ > , hir_id : HirId ) -> ShallowLintLevelMap {
55
123
let store = unerased_lint_store ( tcx) ;
56
124
57
125
let mut levels = LintLevelsBuilder {
58
126
sess : tcx. sess ,
59
- provider : LintLevelQueryMap { tcx, cur : hir_id, specs : FxHashMap :: default ( ) } ,
127
+ provider : LintLevelQueryMap { tcx, cur : hir_id, specs : ShallowLintLevelMap :: default ( ) } ,
60
128
warn_about_weird_lints : false ,
61
129
store,
62
130
registered_tools : & tcx. resolutions ( ( ) ) . registered_tools ,
@@ -77,12 +145,6 @@ pub struct TopDown {
77
145
cur : LintStackIndex ,
78
146
}
79
147
80
- pub struct QueryMapExpectationsWrapper < ' tcx > {
81
- map : LintLevelQueryMap < ' tcx > ,
82
- expectations : Vec < ( LintExpectationId , LintExpectation ) > ,
83
- unstable_to_stable_ids : FxHashMap < LintExpectationId , LintExpectationId > ,
84
- }
85
-
86
148
pub trait LintLevelsProvider {
87
149
fn current_specs ( & self ) -> & FxHashMap < LintId , LevelAndSource > ;
88
150
fn current_specs_mut ( & mut self ) -> & mut FxHashMap < LintId , LevelAndSource > ;
@@ -104,28 +166,42 @@ impl LintLevelsProvider for TopDown {
104
166
}
105
167
}
106
168
169
+ struct LintLevelQueryMap < ' tcx > {
170
+ tcx : TyCtxt < ' tcx > ,
171
+ cur : HirId ,
172
+ specs : ShallowLintLevelMap ,
173
+ }
174
+
107
175
impl LintLevelsProvider for LintLevelQueryMap < ' _ > {
108
176
fn current_specs ( & self ) -> & FxHashMap < LintId , LevelAndSource > {
109
- & self . specs
177
+ & self . specs . specs
110
178
}
111
179
fn current_specs_mut ( & mut self ) -> & mut FxHashMap < LintId , LevelAndSource > {
112
- & mut self . specs
180
+ & mut self . specs . specs
113
181
}
114
182
fn get_lint_level ( & self , lint : & ' static Lint , _: & Session ) -> LevelAndSource {
115
- self . lint_level ( lint)
183
+ self . specs . lint_level_id_at_node ( self . tcx , LintId :: of ( lint) , self . cur )
116
184
}
117
185
}
118
186
187
+ struct QueryMapExpectationsWrapper < ' tcx > {
188
+ tcx : TyCtxt < ' tcx > ,
189
+ cur : HirId ,
190
+ specs : ShallowLintLevelMap ,
191
+ expectations : Vec < ( LintExpectationId , LintExpectation ) > ,
192
+ unstable_to_stable_ids : FxHashMap < LintExpectationId , LintExpectationId > ,
193
+ }
194
+
119
195
impl LintLevelsProvider for QueryMapExpectationsWrapper < ' _ > {
120
196
fn current_specs ( & self ) -> & FxHashMap < LintId , LevelAndSource > {
121
- & self . map . specs
197
+ & self . specs . specs
122
198
}
123
199
fn current_specs_mut ( & mut self ) -> & mut FxHashMap < LintId , LevelAndSource > {
124
- self . map . specs . clear ( ) ;
125
- & mut self . map . specs
200
+ self . specs . specs . clear ( ) ;
201
+ & mut self . specs . specs
126
202
}
127
203
fn get_lint_level ( & self , lint : & ' static Lint , _: & Session ) -> LevelAndSource {
128
- self . map . lint_level ( lint)
204
+ self . specs . lint_level_id_at_node ( self . tcx , LintId :: of ( lint) , self . cur )
129
205
}
130
206
fn push_expectation ( & mut self , id : LintExpectationId , expectation : LintExpectation ) {
131
207
let LintExpectationId :: Stable { attr_id : Some ( attr_id) , hir_id, attr_index, .. } = id else { bug ! ( "unstable expectation id should already be mapped" ) } ;
@@ -144,19 +220,15 @@ impl LintLevelsProvider for QueryMapExpectationsWrapper<'_> {
144
220
145
221
impl < ' tcx > LintLevelsBuilder < ' _ , QueryMapExpectationsWrapper < ' tcx > > {
146
222
fn add_id ( & mut self , hir_id : HirId ) {
147
- self . add (
148
- self . provider . map . tcx . hir ( ) . attrs ( hir_id) ,
149
- hir_id == hir:: CRATE_HIR_ID ,
150
- Some ( hir_id) ,
151
- ) ;
223
+ self . add ( self . provider . tcx . hir ( ) . attrs ( hir_id) , hir_id == hir:: CRATE_HIR_ID , Some ( hir_id) ) ;
152
224
}
153
225
}
154
226
155
227
impl < ' tcx > intravisit:: Visitor < ' tcx > for LintLevelsBuilder < ' _ , QueryMapExpectationsWrapper < ' tcx > > {
156
228
type NestedFilter = nested_filter:: All ;
157
229
158
230
fn nested_visit_map ( & mut self ) -> Self :: Map {
159
- self . provider . map . tcx . hir ( )
231
+ self . provider . tcx . hir ( )
160
232
}
161
233
162
234
fn visit_param ( & mut self , param : & ' tcx hir:: Param < ' tcx > ) {
@@ -225,13 +297,12 @@ pub struct LintLevelsBuilder<'s, P> {
225
297
registered_tools : & ' s RegisteredTools ,
226
298
}
227
299
228
- pub struct BuilderPush {
300
+ pub ( crate ) struct BuilderPush {
229
301
prev : LintStackIndex ,
230
- pub changed : bool ,
231
302
}
232
303
233
304
impl < ' s > LintLevelsBuilder < ' s , TopDown > {
234
- pub fn new (
305
+ pub ( crate ) fn new (
235
306
sess : & ' s Session ,
236
307
warn_about_weird_lints : bool ,
237
308
store : & ' s LintStore ,
@@ -289,11 +360,11 @@ impl<'s> LintLevelsBuilder<'s, TopDown> {
289
360
self . provider . cur = prev;
290
361
}
291
362
292
- BuilderPush { prev, changed : prev != self . provider . cur }
363
+ BuilderPush { prev }
293
364
}
294
365
295
366
/// Called after `push` when the scope of a set of attributes are exited.
296
- pub fn pop ( & mut self , push : BuilderPush ) {
367
+ pub ( crate ) fn pop ( & mut self , push : BuilderPush ) {
297
368
self . provider . cur = push. prev ;
298
369
}
299
370
}
@@ -855,7 +926,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
855
926
856
927
/// Used to emit a lint-related diagnostic based on the current state of
857
928
/// this lint context.
858
- pub fn struct_lint (
929
+ pub ( crate ) fn struct_lint (
859
930
& self ,
860
931
lint : & ' static Lint ,
861
932
span : Option < MultiSpan > ,
@@ -866,6 +937,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
866
937
}
867
938
}
868
939
869
- pub fn provide ( providers : & mut Providers ) {
870
- * providers = Providers { lint_levels_on , lint_expectations, ..* providers } ;
940
+ pub ( crate ) fn provide ( providers : & mut Providers ) {
941
+ * providers = Providers { shallow_lint_levels_on , lint_expectations, ..* providers } ;
871
942
}
0 commit comments