Skip to content

Commit 17e34f6

Browse files
Use the new attribute parser throughout the codebase
1 parent 549314b commit 17e34f6

File tree

4 files changed

+71
-41
lines changed

4 files changed

+71
-41
lines changed

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::borrow::Cow;
2+
13
use rustc_ast as ast;
24
use rustc_ast::NodeId;
35
use rustc_errors::DiagCtxtHandle;
@@ -49,27 +51,44 @@ impl<'sess> AttributeParser<'sess, Early> {
4951
target_node_id: NodeId,
5052
features: Option<&'sess Features>,
5153
) -> Option<Attribute> {
52-
let mut p = Self {
53-
features,
54-
tools: Vec::new(),
55-
parse_only: Some(sym),
54+
let mut parsed = Self::parse_limited_all(
5655
sess,
57-
stage: Early { emit_errors: ShouldEmit::Nothing },
58-
};
59-
let mut parsed = p.parse_attribute_list(
6056
attrs,
57+
Some(sym),
58+
Target::Crate, // Does not matter, we're not going to emit errors anyways
6159
target_span,
6260
target_node_id,
63-
Target::Crate, // Does not matter, we're not going to emit errors anyways
61+
features,
62+
ShouldEmit::Nothing,
63+
);
64+
assert!(parsed.len() <= 1);
65+
parsed.pop()
66+
}
67+
68+
pub fn parse_limited_all(
69+
sess: &'sess Session,
70+
attrs: &[ast::Attribute],
71+
parse_only: Option<Symbol>,
72+
target: Target,
73+
target_span: Span,
74+
target_node_id: NodeId,
75+
features: Option<&'sess Features>,
76+
emit_errors: ShouldEmit,
77+
) -> Vec<Attribute> {
78+
let mut p =
79+
Self { features, tools: Vec::new(), parse_only, sess, stage: Early { emit_errors } };
80+
p.parse_attribute_list(
81+
attrs,
82+
target_span,
83+
target_node_id,
84+
target,
6485
OmitDoc::Skip,
6586
std::convert::identity,
6687
|_lint| {
67-
panic!("can't emit lints here for now (nothing uses this atm)");
88+
// FIXME: Can't emit lints here for now
89+
// This branch can be hit when an attribute produces a warning during early parsing (such as attributes on macro calls)
6890
},
69-
);
70-
assert!(parsed.len() <= 1);
71-
72-
parsed.pop()
91+
)
7392
}
7493

7594
pub fn parse_single<T>(
@@ -79,9 +98,9 @@ impl<'sess> AttributeParser<'sess, Early> {
7998
target_node_id: NodeId,
8099
features: Option<&'sess Features>,
81100
emit_errors: ShouldEmit,
82-
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> T,
101+
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> Option<T>,
83102
template: &AttributeTemplate,
84-
) -> T {
103+
) -> Option<T> {
85104
let mut parser = Self {
86105
features,
87106
tools: Vec::new(),
@@ -92,7 +111,9 @@ impl<'sess> AttributeParser<'sess, Early> {
92111
let ast::AttrKind::Normal(normal_attr) = &attr.kind else {
93112
panic!("parse_single called on a doc attr")
94113
};
95-
let meta_parser = MetaItemParser::from_attr(normal_attr, parser.dcx());
114+
let parts =
115+
normal_attr.item.path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>();
116+
let meta_parser = MetaItemParser::from_attr(normal_attr, &parts, &sess.psess, emit_errors)?;
96117
let path = meta_parser.path();
97118
let args = meta_parser.args();
98119
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
@@ -199,14 +220,22 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
199220
// }))
200221
// }
201222
ast::AttrKind::Normal(n) => {
202-
attr_paths.push(PathParser::Ast(&n.item.path));
223+
attr_paths.push(PathParser(Cow::Borrowed(&n.item.path)));
203224

204-
let parser = MetaItemParser::from_attr(n, self.dcx());
205-
let path = parser.path();
206-
let args = parser.args();
207-
let path_parts = path.segments().map(|i| i.name).collect::<Vec<_>>();
225+
let parts =
226+
n.item.path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>();
208227

209-
if let Some(accepts) = S::parsers().accepters.get(path_parts.as_slice()) {
228+
if let Some(accepts) = S::parsers().accepters.get(parts.as_slice()) {
229+
let Some(parser) = MetaItemParser::from_attr(
230+
n,
231+
&parts,
232+
&self.sess.psess,
233+
self.stage.should_emit(),
234+
) else {
235+
continue;
236+
};
237+
let path = parser.path();
238+
let args = parser.args();
210239
for accept in accepts {
211240
let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext {
212241
shared: SharedContext {

compiler/rustc_attr_parsing/src/validate_attr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute, id: NodeId) {
3333
// Check input tokens for built-in and key-value attributes.
3434
match builtin_attr_info {
3535
// `rustc_dummy` doesn't have any restrictions specific to built-in attributes.
36-
Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => {
36+
Some(BuiltinAttribute { name, template, .. }) => {
37+
if AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(&name)) {
38+
return;
39+
}
3740
match parse_meta(psess, attr) {
3841
// Don't check safety again, we just did that
3942
Ok(meta) => {
@@ -259,9 +262,6 @@ pub fn check_builtin_meta_item(
259262
) {
260263
if !is_attr_template_compatible(&template, &meta.kind) {
261264
// attrs with new parsers are locally validated so excluded here
262-
if AttributeParser::<Late>::is_parsed_attribute(slice::from_ref(&name)) {
263-
return;
264-
}
265265
emit_malformed_attribute(psess, style, meta.span, name, template);
266266
}
267267

compiler/rustc_expand/src/config.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -415,16 +415,6 @@ impl<'a> StripUnconfigured<'a> {
415415
node: NodeId,
416416
emit_errors: ShouldEmit,
417417
) -> 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-
}
426-
}
427-
428418
// Unsafety check needs to be done explicitly here because this attribute will be removed before the normal check
429419
deny_builtin_meta_unsafety(
430420
self.sess.dcx(),

compiler/rustc_expand/src/expand.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
use std::path::PathBuf;
22
use std::rc::Rc;
33
use std::sync::Arc;
4-
use std::{iter, mem};
4+
use std::{iter, mem, slice};
55

66
use rustc_ast::mut_visit::*;
77
use rustc_ast::tokenstream::TokenStream;
88
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
99
use rustc_ast::{
10-
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, DUMMY_NODE_ID,
11-
ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner,
12-
MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind, token,
10+
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, CRATE_NODE_ID,
11+
DUMMY_NODE_ID, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, ItemKind, MacStmtStyle,
12+
MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind, TyKind, token,
1313
};
1414
use rustc_ast_pretty::pprust;
15-
use rustc_attr_parsing::{EvalConfigResult, ShouldEmit, validate_attr};
15+
use rustc_attr_parsing::{AttributeParser, EvalConfigResult, ShouldEmit, validate_attr};
1616
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
1717
use rustc_errors::PResult;
1818
use rustc_feature::Features;
19+
use rustc_hir::Target;
1920
use rustc_hir::def::MacroKinds;
2021
use rustc_parse::parser::{
2122
AttemptLocalParseRecovery, CommaRecoveryMode, ForceCollect, Parser, RecoverColon, RecoverComma,
@@ -2157,6 +2158,16 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
21572158
attr,
21582159
self.cx.current_expansion.lint_node_id,
21592160
);
2161+
AttributeParser::parse_limited_all(
2162+
self.cx.sess,
2163+
slice::from_ref(attr),
2164+
None,
2165+
Target::MacroCall,
2166+
call.span(),
2167+
CRATE_NODE_ID,
2168+
Some(self.cx.ecfg.features),
2169+
ShouldEmit::ErrorsAndLints,
2170+
);
21602171

21612172
let current_span = if let Some(sp) = span { sp.to(attr.span) } else { attr.span };
21622173
span = Some(current_span);

0 commit comments

Comments
 (0)