Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f5703d5

Browse files
committed
Auto merge of #144689 - JonathanBrouwer:share_parse_path, r=jdonszelmann
Rewrite the new attribute argument parser Fixes #143940 This rewrites the parser, should improve performance and maintainability. This can be reviewed commit by commit
2 parents 831e291 + ec5b2cc commit f5703d5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+665
-519
lines changed

‎Cargo.lock‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3459,7 +3459,6 @@ dependencies = [
34593459
"rustc_feature",
34603460
"rustc_fluent_macro",
34613461
"rustc_macros",
3462-
"rustc_parse",
34633462
"rustc_session",
34643463
"rustc_span",
34653464
"rustc_target",
@@ -3490,6 +3489,7 @@ dependencies = [
34903489
"rustc_hir",
34913490
"rustc_lexer",
34923491
"rustc_macros",
3492+
"rustc_parse",
34933493
"rustc_session",
34943494
"rustc_span",
34953495
"thin-vec",
@@ -4355,7 +4355,6 @@ dependencies = [
43554355
"rustc-literal-escaper",
43564356
"rustc_ast",
43574357
"rustc_ast_pretty",
4358-
"rustc_attr_parsing",
43594358
"rustc_data_structures",
43604359
"rustc_errors",
43614360
"rustc_feature",

‎compiler/rustc_ast_passes/Cargo.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ rustc_errors = { path = "../rustc_errors" }
1515
rustc_feature = { path = "../rustc_feature" }
1616
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1717
rustc_macros = { path = "../rustc_macros" }
18-
rustc_parse = { path = "../rustc_parse" }
1918
rustc_session = { path = "../rustc_session" }
2019
rustc_span = { path = "../rustc_span" }
2120
rustc_target = { path = "../rustc_target" }

‎compiler/rustc_ast_passes/src/ast_validation.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ use rustc_abi::{CanonAbi, ExternAbi, InterruptKind};
2525
use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, walk_list};
2626
use rustc_ast::*;
2727
use rustc_ast_pretty::pprust::{self, State};
28+
use rustc_attr_parsing::validate_attr;
2829
use rustc_data_structures::fx::FxIndexMap;
2930
use rustc_errors::DiagCtxtHandle;
3031
use rustc_feature::Features;
31-
use rustc_parse::validate_attr;
3232
use rustc_session::Session;
3333
use rustc_session::lint::builtin::{
3434
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, MISSING_UNSAFE_ON_EXTERN,

‎compiler/rustc_attr_parsing/Cargo.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1414
rustc_hir = { path = "../rustc_hir" }
1515
rustc_lexer = { path = "../rustc_lexer" }
1616
rustc_macros = { path = "../rustc_macros" }
17+
rustc_parse = { path = "../rustc_parse" }
1718
rustc_session = { path = "../rustc_session" }
1819
rustc_span = { path = "../rustc_span" }
1920
thin-vec = "0.2.12"

‎compiler/rustc_attr_parsing/messages.ftl‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,3 +170,22 @@ attr_parsing_unused_multiple =
170170
171171
-attr_parsing_previously_accepted =
172172
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
173+
174+
attr_parsing_meta_bad_delim = wrong meta list delimiters
175+
attr_parsing_meta_bad_delim_suggestion = the delimiters should be `(` and `)`
176+
177+
attr_parsing_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
178+
.label = usage of unsafe attribute
179+
attr_parsing_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
180+
181+
attr_parsing_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
182+
.label = this is not an unsafe attribute
183+
.suggestion = remove the `unsafe(...)`
184+
.note = extraneous unsafe is not allowed in attributes
185+
186+
attr_parsing_invalid_meta_item = expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found {$descr}
187+
.remove_neg_sugg = negative numbers are not literals, try removing the `-` sign
188+
.quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal
189+
190+
attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes
191+
.help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)

‎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/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ pub mod parser;
102102
mod lints;
103103
mod session_diagnostics;
104104
mod target_checking;
105+
pub mod validate_attr;
105106

106107
pub use attributes::cfg::{CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg_attr};
107108
pub use attributes::cfg_old::*;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /