|
1 | 1 | use std::cmp;
|
2 | 2 |
|
3 | 3 | use rustc_data_structures::fx::FxHashMap;
|
4 |
| -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; |
5 | 4 | use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, MultiSpan};
|
6 | 5 | use rustc_hir::HirId;
|
7 |
| -use rustc_index::vec::IndexVec; |
8 |
| -use rustc_query_system::ich::StableHashingContext; |
9 | 6 | use rustc_session::lint::{
|
10 | 7 | builtin::{self, FORBIDDEN_LINT_GROUPS},
|
11 |
| - FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, |
| 8 | + FutureIncompatibilityReason, Level, Lint, LintId, |
12 | 9 | };
|
13 | 10 | use rustc_session::Session;
|
14 | 11 | use rustc_span::hygiene::MacroKind;
|
@@ -59,159 +56,51 @@ impl LintLevelSource {
|
59 | 56 | /// A tuple of a lint level and its source.
|
60 | 57 | pub type LevelAndSource = (Level, LintLevelSource);
|
61 | 58 |
|
62 |
| -#[derive(Debug, HashStable)] |
63 |
| -pub struct LintLevelSets { |
64 |
| - pub list: IndexVec<LintStackIndex, LintSet>, |
65 |
| -} |
66 |
| - |
67 |
| -rustc_index::newtype_index! { |
68 |
| - #[derive(HashStable)] |
69 |
| - pub struct LintStackIndex { |
70 |
| - const COMMAND_LINE = 0, |
71 |
| - } |
72 |
| -} |
73 |
| - |
74 |
| -#[derive(Debug, HashStable)] |
75 |
| -pub struct LintSet { |
76 |
| - // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which |
77 |
| - // flag. |
78 |
| - pub specs: FxHashMap<LintId, LevelAndSource>, |
79 |
| - |
80 |
| - pub parent: LintStackIndex, |
81 |
| -} |
82 |
| - |
83 |
| -impl LintLevelSets { |
84 |
| - pub fn new() -> Self { |
85 |
| - LintLevelSets { list: IndexVec::new() } |
86 |
| - } |
87 |
| - |
88 |
| - pub fn actual_level( |
89 |
| - level: Option<Level>, |
90 |
| - src: &mut LintLevelSource, |
91 |
| - sess: &Session, |
92 |
| - lint: &'static Lint, |
93 |
| - get_lint_id_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource), |
94 |
| - ) -> Level { |
95 |
| - // If `level` is none then we actually assume the default level for this |
96 |
| - // lint. |
97 |
| - let mut level = level.unwrap_or_else(|| lint.default_level(sess.edition())); |
98 |
| - |
99 |
| - // If we're about to issue a warning, check at the last minute for any |
100 |
| - // directives against the warnings "lint". If, for example, there's an |
101 |
| - // `allow(warnings)` in scope then we want to respect that instead. |
102 |
| - // |
103 |
| - // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically |
104 |
| - // triggers in cases (like #80988) where you have `forbid(warnings)`, |
105 |
| - // and so if we turned that into an error, it'd defeat the purpose of the |
106 |
| - // future compatibility warning. |
107 |
| - if level == Level::Warn && LintId::of(lint) != LintId::of(FORBIDDEN_LINT_GROUPS) { |
108 |
| - let (warnings_level, warnings_src) = get_lint_id_level(LintId::of(builtin::WARNINGS)); |
109 |
| - if let Some(configured_warning_level) = warnings_level { |
110 |
| - if configured_warning_level != Level::Warn { |
111 |
| - level = configured_warning_level; |
112 |
| - *src = warnings_src; |
113 |
| - } |
| 59 | +pub fn reveal_actual_level( |
| 60 | + level: Option<Level>, |
| 61 | + src: &mut LintLevelSource, |
| 62 | + sess: &Session, |
| 63 | + lint: LintId, |
| 64 | + get_lint_id_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource), |
| 65 | +) -> Level { |
| 66 | + // If `level` is none then we actually assume the default level for this |
| 67 | + // lint. |
| 68 | + let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition())); |
| 69 | + |
| 70 | + // If we're about to issue a warning, check at the last minute for any |
| 71 | + // directives against the warnings "lint". If, for example, there's an |
| 72 | + // `allow(warnings)` in scope then we want to respect that instead. |
| 73 | + // |
| 74 | + // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically |
| 75 | + // triggers in cases (like #80988) where you have `forbid(warnings)`, |
| 76 | + // and so if we turned that into an error, it'd defeat the purpose of the |
| 77 | + // future compatibility warning. |
| 78 | + if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) { |
| 79 | + let (warnings_level, warnings_src) = get_lint_id_level(LintId::of(builtin::WARNINGS)); |
| 80 | + if let Some(configured_warning_level) = warnings_level { |
| 81 | + if configured_warning_level != Level::Warn { |
| 82 | + level = configured_warning_level; |
| 83 | + *src = warnings_src; |
114 | 84 | }
|
115 | 85 | }
|
116 |
| - |
117 |
| - // Ensure that we never exceed the `--cap-lints` argument |
118 |
| - // unless the source is a --force-warn |
119 |
| - level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src { |
120 |
| - level |
121 |
| - } else { |
122 |
| - cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid)) |
123 |
| - }; |
124 |
| - |
125 |
| - if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) { |
126 |
| - // Ensure that we never exceed driver level. |
127 |
| - level = cmp::min(*driver_level, level); |
128 |
| - } |
129 |
| - |
130 |
| - level |
131 | 86 | }
|
132 | 87 |
|
133 |
| - pub fn get_lint_level( |
134 |
| - &self, |
135 |
| - lint: &'static Lint, |
136 |
| - idx: LintStackIndex, |
137 |
| - aux: Option<&FxHashMap<LintId, LevelAndSource>>, |
138 |
| - sess: &Session, |
139 |
| - ) -> LevelAndSource { |
140 |
| - let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux); |
141 |
| - |
142 |
| - let level = Self::actual_level(level, &mut src, sess, lint, |id| { |
143 |
| - self.get_lint_id_level(id, idx, aux) |
144 |
| - }); |
145 |
| - |
146 |
| - (level, src) |
147 |
| - } |
| 88 | + // Ensure that we never exceed the `--cap-lints` argument |
| 89 | + // unless the source is a --force-warn |
| 90 | + level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src { |
| 91 | + level |
| 92 | + } else { |
| 93 | + cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid)) |
| 94 | + }; |
148 | 95 |
|
149 |
| - pub fn get_lint_id_level( |
150 |
| - &self, |
151 |
| - id: LintId, |
152 |
| - mut idx: LintStackIndex, |
153 |
| - aux: Option<&FxHashMap<LintId, LevelAndSource>>, |
154 |
| - ) -> (Option<Level>, LintLevelSource) { |
155 |
| - if let Some(specs) = aux { |
156 |
| - if let Some(&(level, src)) = specs.get(&id) { |
157 |
| - return (Some(level), src); |
158 |
| - } |
159 |
| - } |
160 |
| - loop { |
161 |
| - let LintSet { ref specs, parent } = self.list[idx]; |
162 |
| - if let Some(&(level, src)) = specs.get(&id) { |
163 |
| - return (Some(level), src); |
164 |
| - } |
165 |
| - if idx == COMMAND_LINE { |
166 |
| - return (None, LintLevelSource::Default); |
167 |
| - } |
168 |
| - idx = parent; |
169 |
| - } |
| 96 | + if let Some(driver_level) = sess.driver_lint_caps.get(&lint) { |
| 97 | + // Ensure that we never exceed driver level. |
| 98 | + level = cmp::min(*driver_level, level); |
170 | 99 | }
|
171 |
| -} |
172 |
| - |
173 |
| -#[derive(Debug)] |
174 |
| -pub struct LintLevelMap { |
175 |
| - /// This is a collection of lint expectations as described in RFC 2383, that |
176 |
| - /// can be fulfilled during this compilation session. This means that at least |
177 |
| - /// one expected lint is currently registered in the lint store. |
178 |
| - /// |
179 |
| - /// The [`LintExpectationId`] is stored as a part of the [`Expect`](Level::Expect) |
180 |
| - /// lint level. |
181 |
| - pub lint_expectations: Vec<(LintExpectationId, LintExpectation)>, |
182 |
| - pub sets: LintLevelSets, |
183 |
| - pub id_to_set: FxHashMap<HirId, LintStackIndex>, |
184 |
| -} |
185 | 100 |
|
186 |
| -impl LintLevelMap { |
187 |
| - /// If the `id` was previously registered with `register_id` when building |
188 |
| - /// this `LintLevelMap` this returns the corresponding lint level and source |
189 |
| - /// of the lint level for the lint provided. |
190 |
| - /// |
191 |
| - /// If the `id` was not previously registered, returns `None`. If `None` is |
192 |
| - /// returned then the parent of `id` should be acquired and this function |
193 |
| - /// should be called again. |
194 |
| - pub fn level_and_source( |
195 |
| - &self, |
196 |
| - lint: &'static Lint, |
197 |
| - id: HirId, |
198 |
| - session: &Session, |
199 |
| - ) -> Option<LevelAndSource> { |
200 |
| - self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session)) |
201 |
| - } |
| 101 | + level |
202 | 102 | }
|
203 | 103 |
|
204 |
| -impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap { |
205 |
| - #[inline] |
206 |
| - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { |
207 |
| - let LintLevelMap { ref sets, ref id_to_set, ref lint_expectations } = *self; |
208 |
| - |
209 |
| - id_to_set.hash_stable(hcx, hasher); |
210 |
| - lint_expectations.hash_stable(hcx, hasher); |
211 |
| - |
212 |
| - hcx.while_hashing_spans(true, |hcx| sets.hash_stable(hcx, hasher)) |
213 |
| - } |
214 |
| -} |
215 | 104 | pub struct LintLevelQueryMap<'tcx> {
|
216 | 105 | pub tcx: TyCtxt<'tcx>,
|
217 | 106 | pub cur: HirId,
|
@@ -258,7 +147,7 @@ impl<'tcx> LintLevelQueryMap<'tcx> {
|
258 | 147 | specs: &FxHashMap<LintId, LevelAndSource>,
|
259 | 148 | ) -> (Level, LintLevelSource) {
|
260 | 149 | let (level, mut src) = Self::get_lint_id_level(id, cur, tcx, specs);
|
261 |
| - let level = LintLevelSets::actual_level(level, &mut src, tcx.sess, id.lint, |id| { |
| 150 | + let level = reveal_actual_level(level, &mut src, tcx.sess, id, |id| { |
262 | 151 | Self::get_lint_id_level(id, cur, tcx, specs)
|
263 | 152 | });
|
264 | 153 | (level, src)
|
|
0 commit comments