Skip to content

Commit 312da21

Browse files
Use the new attribute validation from rustc_attr_parsing
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
1 parent 1a56b22 commit 312da21

File tree

9 files changed

+45
-66
lines changed

9 files changed

+45
-66
lines changed

compiler/rustc_attr_parsing/src/attributes/stability.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,12 @@ pub(crate) fn parse_stability<S: Stage>(
247247
let mut feature = None;
248248
let mut since = None;
249249

250-
for param in args.list()?.mixed() {
250+
let ArgParser::List(list) = args else {
251+
cx.expected_list(cx.attr_span);
252+
return None;
253+
};
254+
255+
for param in list.mixed() {
251256
let param_span = param.span();
252257
let Some(param) = param.meta_item() else {
253258
cx.emit_err(session_diagnostics::UnsupportedLiteral {
@@ -322,7 +327,13 @@ pub(crate) fn parse_unstability<S: Stage>(
322327
let mut is_soft = false;
323328
let mut implied_by = None;
324329
let mut old_name = None;
325-
for param in args.list()?.mixed() {
330+
331+
let ArgParser::List(list) = args else {
332+
cx.expected_list(cx.attr_span);
333+
return None;
334+
};
335+
336+
for param in list.mixed() {
326337
let Some(param) = param.meta_item() else {
327338
cx.emit_err(session_diagnostics::UnsupportedLiteral {
328339
span: param.span(),

compiler/rustc_builtin_macros/src/cfg_accessible.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! Implementation of the `#[cfg_accessible(path)]` attribute macro.
22
33
use rustc_ast as ast;
4+
use rustc_attr_parsing::check_builtin_meta_item;
45
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier};
56
use rustc_feature::AttributeTemplate;
6-
use rustc_parse::validate_attr;
77
use rustc_span::{Span, sym};
88

99
use crate::errors;
@@ -45,13 +45,12 @@ impl MultiItemModifier for Expander {
4545
_is_derive_const: bool,
4646
) -> ExpandResult<Vec<Annotatable>, Annotatable> {
4747
let template = AttributeTemplate { list: Some("path"), ..Default::default() };
48-
validate_attr::check_builtin_meta_item(
49-
&ecx.sess.psess,
48+
check_builtin_meta_item(
49+
ecx.sess,
5050
meta_item,
5151
ast::AttrStyle::Outer,
5252
sym::cfg_accessible,
5353
template,
54-
true,
5554
);
5655

5756
let Some(path) = validate_input(ecx, meta_item) else {

compiler/rustc_builtin_macros/src/derive.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use rustc_ast as ast;
22
use rustc_ast::{GenericParamKind, ItemKind, MetaItemInner, MetaItemKind, StmtKind};
3+
use rustc_attr_parsing::check_builtin_meta_item;
34
use rustc_expand::base::{
45
Annotatable, DeriveResolution, ExpandResult, ExtCtxt, Indeterminate, MultiItemModifier,
56
};
67
use rustc_feature::AttributeTemplate;
7-
use rustc_parse::validate_attr;
88
use rustc_session::Session;
99
use rustc_span::{ErrorGuaranteed, Ident, Span, sym};
1010

@@ -36,13 +36,12 @@ impl MultiItemModifier for Expander {
3636
ecx.resolver.resolve_derives(ecx.current_expansion.id, ecx.force_mode, &|| {
3737
let template =
3838
AttributeTemplate { list: Some("Trait1, Trait2, ..."), ..Default::default() };
39-
validate_attr::check_builtin_meta_item(
40-
&sess.psess,
39+
check_builtin_meta_item(
40+
sess,
4141
meta_item,
4242
ast::AttrStyle::Outer,
4343
sym::derive,
4444
template,
45-
true,
4645
);
4746

4847
let mut resolutions = match &meta_item.kind {

compiler/rustc_builtin_macros/src/util.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
use rustc_ast::ptr::P;
22
use rustc_ast::tokenstream::TokenStream;
33
use rustc_ast::{self as ast, AttrStyle, Attribute, MetaItem, attr, token};
4+
use rustc_attr_parsing::check_builtin_meta_item;
45
use rustc_errors::{Applicability, Diag, ErrorGuaranteed};
56
use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt};
67
use rustc_expand::expand::AstFragment;
78
use rustc_feature::AttributeTemplate;
89
use rustc_lint_defs::BuiltinLintDiag;
910
use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES;
10-
use rustc_parse::{exp, parser, validate_attr};
11+
use rustc_parse::{exp, parser};
1112
use rustc_session::errors::report_lit_error;
1213
use rustc_span::{BytePos, Span, Symbol};
1314

@@ -16,14 +17,7 @@ use crate::errors;
1617
pub(crate) fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) {
1718
// All the built-in macro attributes are "words" at the moment.
1819
let template = AttributeTemplate { word: true, ..Default::default() };
19-
validate_attr::check_builtin_meta_item(
20-
&ecx.sess.psess,
21-
meta_item,
22-
AttrStyle::Outer,
23-
name,
24-
template,
25-
true,
26-
);
20+
check_builtin_meta_item(ecx.sess, meta_item, AttrStyle::Outer, name, template);
2721
}
2822

2923
/// Emit a warning if the item is annotated with the given attribute. This is used to diagnose when

compiler/rustc_expand/src/config.rs

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,15 @@ use rustc_ast::{
1212
};
1313
use rustc_attr_parsing as attr;
1414
use rustc_attr_parsing::{
15-
AttributeParser, CFG_TEMPLATE, EvalConfigResult, ShouldEmit, eval_config_entry, parse_cfg_attr,
15+
AttributeParser, CFG_TEMPLATE, Early, EvalConfigResult, ShouldEmit, check_attribute_safety,
16+
eval_config_entry, parse_cfg_attr,
1617
};
1718
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1819
use rustc_feature::{
19-
ACCEPTED_LANG_FEATURES, AttributeSafety, EnabledLangFeature, EnabledLibFeature, Features,
20-
REMOVED_LANG_FEATURES, UNSTABLE_LANG_FEATURES,
20+
ACCEPTED_LANG_FEATURES, EnabledLangFeature, EnabledLibFeature, Features, REMOVED_LANG_FEATURES,
21+
UNSTABLE_LANG_FEATURES,
2122
};
2223
use rustc_lint_defs::BuiltinLintDiag;
23-
use rustc_parse::validate_attr;
24-
use rustc_parse::validate_attr::deny_builtin_meta_unsafety;
2524
use rustc_session::Session;
2625
use rustc_session::parse::feature_err;
2726
use rustc_span::{STDLIB_STABLE_CRATES, Span, Symbol, sym};
@@ -292,12 +291,7 @@ impl<'a> StripUnconfigured<'a> {
292291
/// is in the original source file. Gives a compiler error if the syntax of
293292
/// the attribute is incorrect.
294293
pub(crate) fn expand_cfg_attr(&self, cfg_attr: &Attribute, recursive: bool) -> Vec<Attribute> {
295-
validate_attr::check_attribute_safety(
296-
&self.sess.psess,
297-
Some(AttributeSafety::Normal),
298-
&cfg_attr,
299-
ast::CRATE_NODE_ID,
300-
);
294+
check_attribute_safety::<Early>(self.sess, &cfg_attr, ast::CRATE_NODE_ID, &mut |_| {});
301295

302296
// A trace attribute left in AST in place of the original `cfg_attr` attribute.
303297
// It can later be used by lints or other diagnostics.
@@ -415,23 +409,10 @@ impl<'a> StripUnconfigured<'a> {
415409
node: NodeId,
416410
emit_errors: ShouldEmit,
417411
) -> EvalConfigResult {
418-
// We need to run this to do basic validation of the attribute, such as that lits are valid, etc
419-
// FIXME(jdonszelmann) this should not be necessary in the future
420-
match validate_attr::parse_meta(&self.sess.psess, attr) {
421-
Ok(_) => {}
422-
Err(err) => {
423-
err.emit();
424-
return EvalConfigResult::True;
425-
}
412+
if !AttributeParser::validate_attribute_early(self.sess, attr, node) {
413+
return EvalConfigResult::True;
426414
}
427415

428-
// Unsafety check needs to be done explicitly here because this attribute will be removed before the normal check
429-
deny_builtin_meta_unsafety(
430-
self.sess.dcx(),
431-
attr.get_normal_item().unsafety,
432-
&rustc_ast::Path::from_ident(attr.ident().unwrap()),
433-
);
434-
435416
let Some(cfg) = AttributeParser::parse_single(
436417
self.sess,
437418
attr,

compiler/rustc_expand/src/expand.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_ast::{
1313
MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind, token,
1414
};
1515
use rustc_ast_pretty::pprust;
16-
use rustc_attr_parsing::{EvalConfigResult, ShouldEmit};
16+
use rustc_attr_parsing::{AttributeParser, EvalConfigResult, ShouldEmit};
1717
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1818
use rustc_errors::PResult;
1919
use rustc_feature::Features;
@@ -2119,17 +2119,15 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
21192119

21202120
// Detect use of feature-gated or invalid attributes on macro invocations
21212121
// since they will not be detected after macro expansion.
2122-
fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall) {
2122+
fn check_attributes(&self, attrs: &[ast::Attribute], call: &ast::MacCall, call_id: NodeId) {
21232123
let features = self.cx.ecfg.features;
21242124
let mut attrs = attrs.iter().peekable();
21252125
let mut span: Option<Span> = None;
21262126
while let Some(attr) = attrs.next() {
2127+
// Attributes on a macro call will not be checked during late parsing since we'll remove them
2128+
// We do some basic checks now, but we don't fully parse them
21272129
rustc_ast_passes::feature_gate::check_attribute(attr, self.cx.sess, features);
2128-
validate_attr::check_attr(
2129-
&self.cx.sess.psess,
2130-
attr,
2131-
self.cx.current_expansion.lint_node_id,
2132-
);
2130+
AttributeParser::validate_attribute_early(self.cx.sess, attr, call_id);
21332131

21342132
let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
21352133
span = Some(current_span);
@@ -2228,8 +2226,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
22282226
}
22292227
},
22302228
None if node.is_mac_call() => {
2229+
let mac_node_id = node.node_id();
22312230
let (mac, attrs, add_semicolon) = node.take_mac_call();
2232-
self.check_attributes(&attrs, &mac);
2231+
self.check_attributes(&attrs, &mac, mac_node_id);
22332232
let mut res = self.collect_bang(mac, Node::KIND).make_ast::<Node>();
22342233
Node::post_flat_map_node_collect_bang(&mut res, add_semicolon);
22352234
res
@@ -2315,7 +2314,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
23152314
None if node.is_mac_call() => {
23162315
let n = mem::replace(node, Node::dummy());
23172316
let (mac, attrs, _) = n.take_mac_call();
2318-
self.check_attributes(&attrs, &mac);
2317+
self.check_attributes(&attrs, &mac, node.node_id());
23192318

23202319
*node = self.collect_bang(mac, Node::KIND).make_ast::<Node>().into()
23212320
}

compiler/rustc_expand/src/module.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use std::path::{self, Path, PathBuf};
33

44
use rustc_ast::ptr::P;
55
use rustc_ast::{AttrVec, Attribute, Inline, Item, ModSpans};
6+
use rustc_attr_parsing::emit_fatal_malformed_builtin_attribute;
67
use rustc_errors::{Diag, ErrorGuaranteed};
7-
use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal, validate_attr};
8+
use rustc_parse::{exp, new_parser_from_file, unwrap_or_emit_fatal};
89
use rustc_session::Session;
910
use rustc_session::parse::ParseSess;
1011
use rustc_span::{Ident, Span, sym};
@@ -190,7 +191,7 @@ pub(crate) fn mod_file_path_from_attr(
190191
// Usually bad forms are checked during semantic analysis via
191192
// `TyCtxt::check_mod_attrs`), but by the time that runs the macro
192193
// is expanded, and it doesn't give an error.
193-
validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, first_path, sym::path);
194+
emit_fatal_malformed_builtin_attribute(sess, first_path, sym::path);
194195
};
195196

196197
let path_str = path_sym.as_str();

compiler/rustc_interface/src/passes.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use std::sync::{Arc, LazyLock, OnceLock};
66
use std::{env, fs, iter};
77

88
use rustc_ast as ast;
9+
use rustc_attr_parsing::emit_fatal_malformed_builtin_attribute;
910
use rustc_codegen_ssa::traits::CodegenBackend;
1011
use rustc_data_structures::jobserver::Proxy;
1112
use rustc_data_structures::steal::Steal;
@@ -25,9 +26,7 @@ use rustc_middle::arena::Arena;
2526
use rustc_middle::dep_graph::DepsType;
2627
use rustc_middle::ty::{self, CurrentGcx, GlobalCtxt, RegisteredTools, TyCtxt};
2728
use rustc_middle::util::Providers;
28-
use rustc_parse::{
29-
new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal, validate_attr,
30-
};
29+
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
3130
use rustc_passes::{abi_test, input_stats, layout_test};
3231
use rustc_resolve::Resolver;
3332
use rustc_session::config::{CrateType, Input, OutFileName, OutputFilenames, OutputType};
@@ -1304,7 +1303,7 @@ fn validate_and_find_value_str_builtin_attr(
13041303
// Validate *all* relevant attributes, not just the first occurrence.
13051304
for attr in ast::attr::filter_by_name(krate_attrs, name) {
13061305
let Some(value) = attr.value_str() else {
1307-
validate_attr::emit_fatal_malformed_builtin_attribute(&sess.psess, attr, name)
1306+
emit_fatal_malformed_builtin_attribute(sess, attr, name)
13081307
};
13091308
// Choose the first occurrence as our result.
13101309
result.get_or_insert((value, attr.span));

compiler/rustc_interface/src/util.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ use std::sync::{Arc, OnceLock};
55
use std::{env, thread};
66

77
use rustc_ast as ast;
8+
use rustc_attr_parsing::emit_fatal_malformed_builtin_attribute;
89
use rustc_codegen_ssa::traits::CodegenBackend;
910
use rustc_data_structures::jobserver::Proxy;
1011
use rustc_data_structures::sync;
1112
use rustc_metadata::{DylibError, load_symbol_from_dylib};
1213
use rustc_middle::ty::CurrentGcx;
13-
use rustc_parse::validate_attr;
1414
use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple};
1515
use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
1616
use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
@@ -477,11 +477,7 @@ pub(crate) fn check_attr_crate_type(
477477
// caught during semantic analysis via `TyCtxt::check_mod_attrs`,
478478
// but by the time that runs the macro is expanded, and it doesn't
479479
// give an error.
480-
validate_attr::emit_fatal_malformed_builtin_attribute(
481-
&sess.psess,
482-
a,
483-
sym::crate_type,
484-
);
480+
emit_fatal_malformed_builtin_attribute(sess, a, sym::crate_type);
485481
}
486482
}
487483
}

0 commit comments

Comments
 (0)