Skip to content

Commit 28d3ddd

Browse files
Move lints for check-cfg to attribute parsing
1 parent b657298 commit 28d3ddd

File tree

18 files changed

+96
-118
lines changed

18 files changed

+96
-118
lines changed

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 22 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,16 @@ pub(crate) mod check_cfg;
22

33
use rustc_ast::token::Delimiter;
44
use rustc_ast::tokenstream::DelimSpan;
5-
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, NodeId, ast, token};
5+
use rustc_ast::{AttrItem, Attribute, CRATE_NODE_ID, LitKind, ast, token};
66
use rustc_errors::{Applicability, PResult};
77
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate, Features, template};
88
use rustc_hir::attrs::CfgEntry;
9+
use rustc_hir::lints::AttributeLintKind;
910
use rustc_hir::{AttrPath, RustcVersion};
1011
use rustc_parse::parser::{ForceCollect, Parser};
1112
use rustc_parse::{exp, parse_in};
1213
use rustc_session::Session;
1314
use rustc_session::config::ExpectedValues;
14-
use rustc_session::lint::BuiltinLintDiag;
15-
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
1615
use rustc_session::parse::{ParseSess, feature_err};
1716
use rustc_span::{ErrorGuaranteed, Span, Symbol, sym};
1817
use thin_vec::ThinVec;
@@ -23,10 +22,7 @@ use crate::session_diagnostics::{
2322
AttributeParseError, AttributeParseErrorReason, CfgAttrBadDelim, MetaBadDelimSugg,
2423
ParsedDescription,
2524
};
26-
use crate::{
27-
AttributeParser, CfgMatchesLintEmitter, fluent_generated, parse_version, session_diagnostics,
28-
try_gate_cfg,
29-
};
25+
use crate::{AttributeParser, fluent_generated, parse_version, session_diagnostics, try_gate_cfg};
3026

3127
pub const CFG_TEMPLATE: AttributeTemplate = template!(
3228
List: &["predicate"],
@@ -195,43 +191,40 @@ fn parse_name_value<S: Stage>(
195191
}
196192
};
197193

194+
match cx.sess.psess.check_config.expecteds.get(&name) {
195+
Some(ExpectedValues::Some(values)) if !values.contains(&value.map(|(v, _)| v)) => {
196+
cx.emit_lint(AttributeLintKind::UnexpectedCfgValue { name, name_span, value }, span);
197+
}
198+
None if cx.sess.psess.check_config.exhaustive_names => {
199+
cx.emit_lint(AttributeLintKind::UnexpectedCfgName { name, name_span, value }, span);
200+
}
201+
_ => { /* not unexpected */ }
202+
}
203+
198204
Ok(CfgEntry::NameValue { name, name_span, value, span })
199205
}
200206

201-
pub fn eval_config_entry(
202-
sess: &Session,
203-
cfg_entry: &CfgEntry,
204-
id: NodeId,
205-
emit_lints: ShouldEmit,
206-
) -> EvalConfigResult {
207+
pub fn eval_config_entry(sess: &Session, cfg_entry: &CfgEntry) -> EvalConfigResult {
207208
match cfg_entry {
208209
CfgEntry::All(subs, ..) => {
209-
let mut all = None;
210210
for sub in subs {
211-
let res = eval_config_entry(sess, sub, id, emit_lints);
212-
// We cannot short-circuit because `eval_config_entry` emits some lints
211+
let res = eval_config_entry(sess, sub);
213212
if !res.as_bool() {
214-
all.get_or_insert(res);
213+
return res;
215214
}
216215
}
217-
all.unwrap_or_else(|| EvalConfigResult::True)
216+
EvalConfigResult::True
218217
}
219218
CfgEntry::Any(subs, span) => {
220-
let mut any = None;
221219
for sub in subs {
222-
let res = eval_config_entry(sess, sub, id, emit_lints);
223-
// We cannot short-circuit because `eval_config_entry` emits some lints
224-
if res.as_bool() {
225-
any.get_or_insert(res);
220+
if eval_config_entry(sess, sub).as_bool() {
221+
return EvalConfigResult::True;
226222
}
227223
}
228-
any.unwrap_or_else(|| EvalConfigResult::False {
229-
reason: cfg_entry.clone(),
230-
reason_span: *span,
231-
})
224+
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
232225
}
233226
CfgEntry::Not(sub, span) => {
234-
if eval_config_entry(sess, sub, id, emit_lints).as_bool() {
227+
if eval_config_entry(sess, sub).as_bool() {
235228
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
236229
} else {
237230
EvalConfigResult::True
@@ -244,31 +237,7 @@ pub fn eval_config_entry(
244237
EvalConfigResult::False { reason: cfg_entry.clone(), reason_span: *span }
245238
}
246239
}
247-
CfgEntry::NameValue { name, name_span, value, span } => {
248-
if let ShouldEmit::ErrorsAndLints = emit_lints {
249-
match sess.psess.check_config.expecteds.get(name) {
250-
Some(ExpectedValues::Some(values))
251-
if !values.contains(&value.map(|(v, _)| v)) =>
252-
{
253-
id.emit_span_lint(
254-
sess,
255-
UNEXPECTED_CFGS,
256-
*span,
257-
BuiltinLintDiag::UnexpectedCfgValue((*name, *name_span), *value),
258-
);
259-
}
260-
None if sess.psess.check_config.exhaustive_names => {
261-
id.emit_span_lint(
262-
sess,
263-
UNEXPECTED_CFGS,
264-
*span,
265-
BuiltinLintDiag::UnexpectedCfgName((*name, *name_span), *value),
266-
);
267-
}
268-
_ => { /* not unexpected */ }
269-
}
270-
}
271-
240+
CfgEntry::NameValue { name, name_span: _, value, span } => {
272241
if sess.psess.config.contains(&(*name, value.map(|(v, _)| v))) {
273242
EvalConfigResult::True
274243
} else {

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ impl<'sess> AttributeParser<'sess, Early> {
115115
OmitDoc::Skip,
116116
std::convert::identity,
117117
|lint| {
118-
crate::lints::emit_attribute_lint(&lint, sess);
118+
crate::lints::emit_attribute_lint(&lint, sess, sess);
119119
},
120120
)
121121
}
@@ -187,7 +187,7 @@ impl<'sess> AttributeParser<'sess, Early> {
187187
target_span,
188188
target_id: target_node_id,
189189
emit_lint: &mut |lint| {
190-
crate::lints::emit_attribute_lint(&lint, sess);
190+
crate::lints::emit_attribute_lint(&lint, sess, sess);
191191
},
192192
},
193193
attr_span,

compiler/rustc_attr_parsing/src/lints.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@ use std::borrow::Cow;
33
use rustc_errors::{DiagArgValue, LintEmitter};
44
use rustc_hir::Target;
55
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
6+
use rustc_session::Session;
67
use rustc_span::sym;
78

8-
use crate::session_diagnostics;
9+
use crate::{session_diagnostics, unexpected_cfg_name, unexpected_cfg_value};
910

10-
pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emitter: L) {
11+
//tcx: TyCtxt<'_>
12+
pub fn emit_attribute_lint<L: LintEmitter>(
13+
lint: &AttributeLint<L::Id>,
14+
lint_emitter: L,
15+
sess: &Session,
16+
) {
1117
let AttributeLint { id, span, kind } = lint;
1218

1319
match kind {
@@ -98,5 +104,19 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<L::Id>, lint_emi
98104
},
99105
)
100106
}
107+
&AttributeLintKind::UnexpectedCfgName { name, name_span, value } => lint_emitter
108+
.emit_node_span_lint(
109+
rustc_session::lint::builtin::UNEXPECTED_CFGS,
110+
*id,
111+
*span,
112+
unexpected_cfg_name(sess, None, (name, name_span), value),
113+
),
114+
&AttributeLintKind::UnexpectedCfgValue { name, name_span, value } => lint_emitter
115+
.emit_node_span_lint(
116+
rustc_session::lint::builtin::UNEXPECTED_CFGS,
117+
*id,
118+
*span,
119+
unexpected_cfg_value(sess, None, (name, name_span), value),
120+
),
101121
}
102122
}

compiler/rustc_builtin_macros/src/cfg.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,7 @@ pub(crate) fn expand_cfg(
2626

2727
ExpandResult::Ready(match parse_cfg(cx, sp, tts) {
2828
Ok(cfg) => {
29-
let matches_cfg = attr::eval_config_entry(
30-
cx.sess,
31-
&cfg,
32-
cx.current_expansion.lint_node_id,
33-
ShouldEmit::ErrorsAndLints,
34-
)
35-
.as_bool();
29+
let matches_cfg = attr::eval_config_entry(cx.sess, &cfg).as_bool();
3630

3731
MacEager::expr(cx.expr_bool(sp, matches_cfg))
3832
}

compiler/rustc_builtin_macros/src/cfg_select.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@ use crate::errors::{CfgSelectNoMatches, CfgSelectUnreachable};
1111
/// Selects the first arm whose predicate evaluates to true.
1212
fn select_arm(ecx: &ExtCtxt<'_>, branches: CfgSelectBranches) -> Option<(TokenStream, Span)> {
1313
for (cfg, tt, arm_span) in branches.reachable {
14-
if let EvalConfigResult::True = attr::eval_config_entry(
15-
&ecx.sess,
16-
&cfg,
17-
ecx.current_expansion.lint_node_id,
18-
ShouldEmit::ErrorsAndLints,
19-
) {
14+
if let EvalConfigResult::True = attr::eval_config_entry(&ecx.sess, &cfg) {
2015
return Some((tt, arm_span));
2116
}
2217
}

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ use find_msvc_tools;
1313
use itertools::Itertools;
1414
use regex::Regex;
1515
use rustc_arena::TypedArena;
16-
use rustc_ast::CRATE_NODE_ID;
17-
use rustc_attr_parsing::{ShouldEmit, eval_config_entry};
16+
use rustc_attr_parsing::eval_config_entry;
1817
use rustc_data_structures::fx::FxIndexSet;
1918
use rustc_data_structures::memmap::Mmap;
2019
use rustc_data_structures::temp_dir::MaybeTempDir;
@@ -3033,9 +3032,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
30333032

30343033
fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
30353034
match lib.cfg {
3036-
Some(ref cfg) => {
3037-
eval_config_entry(sess, cfg, CRATE_NODE_ID, ShouldEmit::ErrorsAndLints).as_bool()
3038-
}
3035+
Some(ref cfg) => eval_config_entry(sess, cfg).as_bool(),
30393036
None => true,
30403037
}
30413038
}

compiler/rustc_expand/src/config.rs

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,7 @@ pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec
165165
.iter()
166166
.flat_map(|attr| strip_unconfigured.process_cfg_attr(attr))
167167
.take_while(|attr| {
168-
!is_cfg(attr)
169-
|| strip_unconfigured
170-
.cfg_true(attr, strip_unconfigured.lint_node_id, ShouldEmit::Nothing)
171-
.as_bool()
168+
!is_cfg(attr) || strip_unconfigured.cfg_true(attr, ShouldEmit::Nothing).as_bool()
172169
})
173170
.collect()
174171
}
@@ -318,14 +315,7 @@ impl<'a> StripUnconfigured<'a> {
318315
);
319316
}
320317

321-
if !attr::eval_config_entry(
322-
self.sess,
323-
&cfg_predicate,
324-
ast::CRATE_NODE_ID,
325-
ShouldEmit::ErrorsAndLints,
326-
)
327-
.as_bool()
328-
{
318+
if !attr::eval_config_entry(self.sess, &cfg_predicate).as_bool() {
329319
return vec![trace_attr];
330320
}
331321

@@ -409,18 +399,12 @@ impl<'a> StripUnconfigured<'a> {
409399

410400
/// Determines if a node with the given attributes should be included in this configuration.
411401
fn in_cfg(&self, attrs: &[Attribute]) -> bool {
412-
attrs.iter().all(|attr| {
413-
!is_cfg(attr)
414-
|| self.cfg_true(attr, self.lint_node_id, ShouldEmit::ErrorsAndLints).as_bool()
415-
})
402+
attrs
403+
.iter()
404+
.all(|attr| !is_cfg(attr) || self.cfg_true(attr, ShouldEmit::ErrorsAndLints).as_bool())
416405
}
417406

418-
pub(crate) fn cfg_true(
419-
&self,
420-
attr: &Attribute,
421-
node: NodeId,
422-
emit_errors: ShouldEmit,
423-
) -> EvalConfigResult {
407+
pub(crate) fn cfg_true(&self, attr: &Attribute, emit_errors: ShouldEmit) -> EvalConfigResult {
424408
// Unsafety check needs to be done explicitly here because this attribute will be removed before the normal check
425409
deny_builtin_meta_unsafety(
426410
self.sess.dcx(),
@@ -432,7 +416,7 @@ impl<'a> StripUnconfigured<'a> {
432416
self.sess,
433417
attr,
434418
attr.span,
435-
node,
419+
self.lint_node_id,
436420
self.features,
437421
emit_errors,
438422
parse_cfg,
@@ -442,7 +426,7 @@ impl<'a> StripUnconfigured<'a> {
442426
return EvalConfigResult::True;
443427
};
444428

445-
eval_config_entry(self.sess, &cfg, self.lint_node_id, emit_errors)
429+
eval_config_entry(self.sess, &cfg)
446430
}
447431

448432
/// If attributes are not allowed on expressions, emit an error for `attr`

compiler/rustc_expand/src/expand.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,11 +2213,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
22132213

22142214
fn expand_cfg_true(
22152215
&mut self,
2216-
node: &mut (impl HasAttrs + HasNodeId),
2216+
node: &mut impl HasAttrs,
22172217
attr: ast::Attribute,
22182218
pos: usize,
22192219
) -> EvalConfigResult {
2220-
let res = self.cfg().cfg_true(&attr, node.node_id(), ShouldEmit::ErrorsAndLints);
2220+
let res = self.cfg().cfg_true(&attr, ShouldEmit::ErrorsAndLints);
22212221
if res.as_bool() {
22222222
// A trace attribute left in AST in place of the original `cfg` attribute.
22232223
// It can later be used by lints or other diagnostics.

compiler/rustc_hir/src/lints.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_data_structures::fingerprint::Fingerprint;
22
use rustc_macros::HashStable_Generic;
3-
use rustc_span::Span;
3+
use rustc_span::{Span, Symbol};
44

55
use crate::{AttrPath, HirId, Target};
66

@@ -62,4 +62,14 @@ pub enum AttributeLintKind {
6262
target: Target,
6363
target_span: Span,
6464
},
65+
UnexpectedCfgName {
66+
name: Symbol,
67+
name_span: Span,
68+
value: Option<(Symbol, Span)>,
69+
},
70+
UnexpectedCfgValue {
71+
name: Symbol,
72+
name_span: Span,
73+
value: Option<(Symbol, Span)>,
74+
},
6575
}

compiler/rustc_hir_analysis/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ pub fn provide(providers: &mut Providers) {
158158
fn emit_delayed_lint(lint: &DelayedLint, tcx: TyCtxt<'_>) {
159159
match lint {
160160
DelayedLint::AttributeParsing(attribute_lint) => {
161-
rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx)
161+
rustc_attr_parsing::emit_attribute_lint(attribute_lint, tcx, tcx.sess)
162162
}
163163
}
164164
}

0 commit comments

Comments
 (0)