Skip to content

Commit acc46aa

Browse files
Auto merge of #144689 - JonathanBrouwer:share_parse_path, r=<try>
Rewrite the new attribute parser
2 parents e5e79f8 + 7b3bb12 commit acc46aa

39 files changed

+477
-470
lines changed

Cargo.lock

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3458,7 +3458,6 @@ dependencies = [
34583458
"rustc_feature",
34593459
"rustc_fluent_macro",
34603460
"rustc_macros",
3461-
"rustc_parse",
34623461
"rustc_session",
34633462
"rustc_span",
34643463
"rustc_target",
@@ -3504,6 +3503,7 @@ dependencies = [
35043503
"rustc_hir",
35053504
"rustc_lexer",
35063505
"rustc_macros",
3506+
"rustc_parse",
35073507
"rustc_session",
35083508
"rustc_span",
35093509
"thin-vec",
@@ -4374,7 +4374,6 @@ dependencies = [
43744374
"rustc-literal-escaper",
43754375
"rustc_ast",
43764376
"rustc_ast_pretty",
4377-
"rustc_attr_parsing",
43784377
"rustc_data_structures",
43794378
"rustc_errors",
43804379
"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
@@ -26,10 +26,10 @@ use rustc_ast::ptr::P;
2626
use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, walk_list};
2727
use rustc_ast::*;
2828
use rustc_ast_pretty::pprust::{self, State};
29+
use rustc_attr_parsing::validate_attr;
2930
use rustc_data_structures::fx::FxIndexMap;
3031
use rustc_errors::DiagCtxtHandle;
3132
use rustc_feature::Features;
32-
use rustc_parse::validate_attr;
3333
use rustc_session::Session;
3434
use rustc_session::lint::builtin::{
3535
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
@@ -15,6 +15,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1515
rustc_hir = { path = "../rustc_hir" }
1616
rustc_lexer = { path = "../rustc_lexer" }
1717
rustc_macros = { path = "../rustc_macros" }
18+
rustc_parse = { path = "../rustc_parse" }
1819
rustc_session = { path = "../rustc_session" }
1920
rustc_span = { path = "../rustc_span" }
2021
thin-vec = "0.2.12"

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,21 @@ attr_parsing_unused_multiple =
161161
162162
-attr_parsing_previously_accepted =
163163
this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
164+
165+
attr_parsing_meta_bad_delim = wrong meta list delimiters
166+
attr_parsing_meta_bad_delim_suggestion = the delimiters should be `(` and `)`
167+
168+
attr_parsing_unsafe_attr_outside_unsafe = unsafe attribute used without unsafe
169+
.label = usage of unsafe attribute
170+
attr_parsing_unsafe_attr_outside_unsafe_suggestion = wrap the attribute in `unsafe(...)`
171+
172+
attr_parsing_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
173+
.label = this is not an unsafe attribute
174+
.suggestion = remove the `unsafe(...)`
175+
.note = extraneous unsafe is not allowed in attributes
176+
177+
attr_parsing_invalid_meta_item = expected unsuffixed literal, found {$descr}
178+
.quote_ident_sugg = surround the identifier with quotation marks to make it into a string literal
179+
180+
attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes
181+
.help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::borrow::Cow;
12
use std::cell::RefCell;
23
use std::collections::BTreeMap;
34
use std::ops::{Deref, DerefMut};
@@ -213,7 +214,6 @@ mod private {
213214
#[allow(private_interfaces)]
214215
pub trait Stage: Sized + 'static + Sealed {
215216
type Id: Copy;
216-
const SHOULD_EMIT_LINTS: bool;
217217

218218
fn parsers() -> &'static group_type!(Self);
219219

@@ -222,13 +222,14 @@ pub trait Stage: Sized + 'static + Sealed {
222222
sess: &'sess Session,
223223
diag: impl for<'x> Diagnostic<'x>,
224224
) -> ErrorGuaranteed;
225+
226+
fn should_emit(&self) -> ShouldEmit;
225227
}
226228

227229
// allow because it's a sealed trait
228230
#[allow(private_interfaces)]
229231
impl Stage for Early {
230232
type Id = NodeId;
231-
const SHOULD_EMIT_LINTS: bool = false;
232233

233234
fn parsers() -> &'static group_type!(Self) {
234235
&early::ATTRIBUTE_PARSERS
@@ -244,13 +245,16 @@ impl Stage for Early {
244245
sess.dcx().create_err(diag).delay_as_bug()
245246
}
246247
}
248+
249+
fn should_emit(&self) -> ShouldEmit {
250+
self.emit_errors
251+
}
247252
}
248253

249254
// allow because it's a sealed trait
250255
#[allow(private_interfaces)]
251256
impl Stage for Late {
252257
type Id = HirId;
253-
const SHOULD_EMIT_LINTS: bool = true;
254258

255259
fn parsers() -> &'static group_type!(Self) {
256260
&late::ATTRIBUTE_PARSERS
@@ -262,6 +266,10 @@ impl Stage for Late {
262266
) -> ErrorGuaranteed {
263267
tcx.dcx().emit_err(diag)
264268
}
269+
270+
fn should_emit(&self) -> ShouldEmit {
271+
ShouldEmit::ErrorsAndLints
272+
}
265273
}
266274

267275
/// used when parsing attributes for miscellaneous things *before* ast lowering
@@ -300,7 +308,7 @@ impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
300308
/// must be delayed until after HIR is built. This method will take care of the details of
301309
/// that.
302310
pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) {
303-
if !S::SHOULD_EMIT_LINTS {
311+
if !self.stage.should_emit().should_emit() {
304312
return;
305313
}
306314
let id = self.target_id;
@@ -686,9 +694,9 @@ impl<'sess> AttributeParser<'sess, Early> {
686694
target_node_id: NodeId,
687695
features: Option<&'sess Features>,
688696
emit_errors: ShouldEmit,
689-
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> T,
697+
parse_fn: fn(cx: &mut AcceptContext<'_, '_, Early>, item: &ArgParser<'_>) -> Option<T>,
690698
template: &AttributeTemplate,
691-
) -> T {
699+
) -> Option<T> {
692700
let mut parser = Self {
693701
features,
694702
tools: Vec::new(),
@@ -699,7 +707,7 @@ impl<'sess> AttributeParser<'sess, Early> {
699707
let ast::AttrKind::Normal(normal_attr) = &attr.kind else {
700708
panic!("parse_single called on a doc attr")
701709
};
702-
let meta_parser = MetaItemParser::from_attr(normal_attr, parser.dcx());
710+
let meta_parser = MetaItemParser::from_attr(normal_attr, &sess.psess, emit_errors)?;
703711
let path = meta_parser.path();
704712
let args = meta_parser.args();
705713
let mut cx: AcceptContext<'_, 'sess, Early> = AcceptContext {
@@ -804,14 +812,22 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
804812
// }))
805813
// }
806814
ast::AttrKind::Normal(n) => {
807-
attr_paths.push(PathParser::Ast(&n.item.path));
815+
attr_paths.push(PathParser(Cow::Borrowed(&n.item.path)));
808816

809-
let parser = MetaItemParser::from_attr(n, self.dcx());
810-
let path = parser.path();
811-
let args = parser.args();
812-
let parts = path.segments().map(|i| i.name).collect::<Vec<_>>();
817+
let parts =
818+
n.item.path.segments.iter().map(|seg| seg.ident.name).collect::<Vec<_>>();
813819

814820
if let Some(accepts) = S::parsers().0.get(parts.as_slice()) {
821+
let Some(parser) = MetaItemParser::from_attr(
822+
n,
823+
&self.sess.psess,
824+
self.stage.should_emit(),
825+
) else {
826+
continue;
827+
};
828+
let path = parser.path();
829+
let args = parser.args();
830+
815831
for (template, accept) in accepts {
816832
let mut cx: AcceptContext<'_, 'sess, S> = AcceptContext {
817833
shared: SharedContext {

compiler/rustc_attr_parsing/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ pub(crate) mod context;
8989
mod lints;
9090
pub mod parser;
9191
mod session_diagnostics;
92+
pub mod validate_attr;
9293

9394
pub use attributes::cfg::{CFG_TEMPLATE, EvalConfigResult, eval_config_entry, parse_cfg_attr};
9495
pub use attributes::cfg_old::*;

0 commit comments

Comments
 (0)