Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ impl MetaItem {
_span,
_spacing,
Delimiter::Invisible(InvisibleOrigin::MetaVar(
MetaVarKind::Meta { .. } | MetaVarKind::Path,
MetaVarKind::Meta | MetaVarKind::Path,
)),
_stream,
)) => {
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,7 @@ pub enum MetaVarKind {
Ident,
Lifetime,
Literal,
Meta {
/// Will `AttrItem::meta` succeed on this, if reparsed?
has_meta_form: bool,
},
Meta,
Path,
Vis,
TT,
Expand All @@ -87,7 +84,7 @@ impl fmt::Display for MetaVarKind {
MetaVarKind::Ident => sym::ident,
MetaVarKind::Lifetime => sym::lifetime,
MetaVarKind::Literal => sym::literal,
MetaVarKind::Meta { .. } => sym::meta,
MetaVarKind::Meta => sym::meta,
MetaVarKind::Path => sym::path,
MetaVarKind::Vis => sym::vis,
MetaVarKind::TT => sym::tt,
Expand Down Expand Up @@ -693,7 +690,7 @@ impl Token {
OpenInvisible(InvisibleOrigin::MetaVar(
MetaVarKind::Expr { .. } |
MetaVarKind::Literal |
MetaVarKind::Meta { .. } |
MetaVarKind::Meta |
MetaVarKind::Pat(_) |
MetaVarKind::Path |
MetaVarKind::Ty { .. }
Expand Down
25 changes: 12 additions & 13 deletions compiler/rustc_attr_parsing/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,19 +410,18 @@ impl<'a, 'sess> MetaItemListParserContext<'a, 'sess> {
}

fn parse_attr_item(&mut self) -> PResult<'sess, MetaItemParser<'static>> {
if let Some(MetaVarKind::Meta { has_meta_form }) = self.parser.token.is_metavar_seq() {
return if has_meta_form {
let attr_item = self
.parser
.eat_metavar_seq(MetaVarKind::Meta { has_meta_form: true }, |this| {
MetaItemListParserContext { parser: this, should_emit: self.should_emit }
.parse_attr_item()
})
.unwrap();
Ok(attr_item)
} else {
self.parser.unexpected_any()
};
if let Some(mv_kind @ (MetaVarKind::Meta | MetaVarKind::Expr { .. })) =
self.parser.token.is_metavar_seq()
{
return self
.parser
.eat_metavar_seq(mv_kind, |this| {
MetaItemListParserContext { parser: this, should_emit: self.should_emit }
.parse_attr_item()
})
.ok_or_else(|| {
self.parser.unexpected_any::<core::convert::Infallible>().unwrap_err()
});
}

let path = self.parser.parse_path(PathStyle::Mod)?;
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_expand/src/mbe/transcribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,12 +481,7 @@ fn transcribe_pnr<'tx>(
mk_delimited(ty.span, MetaVarKind::Ty { is_path }, TokenStream::from_ast(ty))
}
ParseNtResult::Meta(attr_item) => {
let has_meta_form = attr_item.meta_kind().is_some();
mk_delimited(
attr_item.span(),
MetaVarKind::Meta { has_meta_form },
TokenStream::from_ast(attr_item),
)
mk_delimited(attr_item.span(), MetaVarKind::Meta, TokenStream::from_ast(attr_item))
}
ParseNtResult::Path(path) => {
mk_delimited(path.span, MetaVarKind::Path, TokenStream::from_ast(path))
Expand Down
20 changes: 8 additions & 12 deletions compiler/rustc_parse/src/parser/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl<'a> Parser<'a> {
/// The delimiters or `=` are still put into the resulting token stream.
pub fn parse_attr_item(&mut self, force_collect: ForceCollect) -> PResult<'a, ast::AttrItem> {
if let Some(item) = self.eat_metavar_seq_with_matcher(
|mv_kind| matches!(mv_kind, MetaVarKind::Meta { .. }),
|mv_kind| matches!(mv_kind, MetaVarKind::Meta),
|this| this.parse_attr_item(force_collect),
) {
return Ok(item);
Expand Down Expand Up @@ -421,17 +421,13 @@ impl<'a> Parser<'a> {
&mut self,
unsafe_allowed: AllowLeadingUnsafe,
) -> PResult<'a, ast::MetaItem> {
if let Some(MetaVarKind::Meta { has_meta_form }) = self.token.is_metavar_seq() {
return if has_meta_form {
let attr_item = self
.eat_metavar_seq(MetaVarKind::Meta { has_meta_form: true }, |this| {
this.parse_attr_item(ForceCollect::No)
})
.unwrap();
Ok(attr_item.meta(attr_item.path.span).unwrap())
} else {
self.unexpected_any()
};
if let Some(mv_kind @ (MetaVarKind::Meta | MetaVarKind::Expr { .. })) =
self.token.is_metavar_seq()
{
return self
.eat_metavar_seq(mv_kind, |this| this.parse_attr_item(ForceCollect::No))
.map(|attr_item| attr_item.meta(attr_item.path.span).unwrap())
.ok_or_else(|| self.unexpected_any::<core::convert::Infallible>().unwrap_err());
}

let lo = self.token.span;
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/nonterminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl<'a> Parser<'a> {
| MetaVarKind::Expr { .. }
| MetaVarKind::Ty { .. }
| MetaVarKind::Literal // `true`, `false`
| MetaVarKind::Meta { .. }
| MetaVarKind::Meta
| MetaVarKind::Path => true,

MetaVarKind::Item
Expand Down Expand Up @@ -82,7 +82,7 @@ impl<'a> Parser<'a> {
MetaVarKind::Item
| MetaVarKind::Pat(_)
| MetaVarKind::Ty { .. }
| MetaVarKind::Meta { .. }
| MetaVarKind::Meta
| MetaVarKind::Path
| MetaVarKind::Vis => false,
MetaVarKind::Lifetime | MetaVarKind::Ident | MetaVarKind::TT => {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/attributes/nonterminal-expansion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
macro_rules! pass_nonterminal {
($n:expr) => {
#[repr(align($n))]
//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable
struct S;
fn foo() {}
};
}

Expand All @@ -15,5 +14,6 @@ macro_rules! n {
}

pass_nonterminal!(n!());
//~^ ERROR expected one of `(`, `::`, or `=`, found `!`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This error is surprisingly different from what you get when "inlining" the macro?

error: expected unsuffixed literal, found `!`
 --> src/main.rs:6:15
  |
6 | #[repr(align(n!()))]
  |               ^

https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=979f349ee4be2e88b300d4f97f5e1db9

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$expr effectively has parentheses around it, so the "inlined" version would look more like #[repr(align((n!())))].


fn main() {}
11 changes: 3 additions & 8 deletions tests/ui/attributes/nonterminal-expansion.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `expr` metavariable
--> $DIR/nonterminal-expansion.rs:7:22
error: expected one of `(`, `::`, or `=`, found `!`
--> $DIR/nonterminal-expansion.rs:16:20
|
LL | #[repr(align($n))]
| ^^
...
LL | pass_nonterminal!(n!());
| ----------------------- in this macro invocation
|
= note: this error originates in the macro `pass_nonterminal` (in Nightly builds, run with -Z macro-backtrace for more info)
| ^ expected one of `(`, `::`, or `=`

error: aborting due to 1 previous error

11 changes: 11 additions & 0 deletions tests/ui/macros/attr-expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
macro_rules! foo {
($e:expr) => {
#[$e]
//~^ ERROR expected identifier, found metavariable
fn foo() {}
}
}

foo!(inline);

fn main() {}
13 changes: 13 additions & 0 deletions tests/ui/macros/attr-expr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
error: expected identifier, found metavariable
--> $DIR/attr-expr.rs:3:11
|
LL | #[$e]
| ^^ expected identifier, found metavariable
...
LL | foo!(inline);
| ------------ in this macro invocation
|
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error

11 changes: 11 additions & 0 deletions tests/ui/macros/cfg_attr-expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
macro_rules! foo {
($e:expr) => {
#[cfg_attr(true, $e)]
//~^ ERROR expected identifier, found metavariable
fn foo() {}
}
}

foo!(inline);

fn main() {}
15 changes: 15 additions & 0 deletions tests/ui/macros/cfg_attr-expr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: expected identifier, found metavariable
--> $DIR/cfg_attr-expr.rs:3:26
|
LL | #[cfg_attr(true, $e)]
| ^^ expected identifier, found metavariable
...
LL | foo!(inline);
| ------------ in this macro invocation
|
= help: the valid syntax is `#[cfg_attr(condition, attribute, other_attribute, ...)]`
= note: for more information, visit <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>
= note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error

26 changes: 26 additions & 0 deletions tests/ui/macros/cfg_expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//@ run-pass

macro_rules! foo {
($e:expr, $n:ident) => {
#[cfg_attr($e, allow(non_snake_case))]
#[cfg($e)]
fn $n() {}

#[cfg_attr(not($e), allow(unused))]
#[cfg(not($e))]
fn $n() {
panic!()
}
}
}

foo!(true, BAR);
foo!(any(true, unix, target_pointer_width = "64"), baz);
foo!(target_pointer_width = "64", quux);

fn main() {
BAR();
baz();
#[cfg(target_pointer_width = "64")]
quux();
}
4 changes: 3 additions & 1 deletion tests/ui/parser/attribute/attr-bad-meta-4.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
macro_rules! mac {
($attr_item: meta) => {
#[cfg($attr_item)]
//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `meta` metavariable
struct S;
}
}

mac!(an(arbitrary token stream));
//~^ ERROR expected one of `(`, `)`, `,`, `::`, or `=`, found `token`
//~| ERROR expected one of `(`, `)`, `,`, `::`, or `=`, found `stream`
//~| ERROR [E0537]

#[cfg(feature = -1)]
//~^ ERROR expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-`
Expand Down
30 changes: 21 additions & 9 deletions tests/ui/parser/attribute/attr-bad-meta-4.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `-`
--> $DIR/attr-bad-meta-4.rs:11:17
--> $DIR/attr-bad-meta-4.rs:13:17
|
LL | #[cfg(feature = -1)]
| ^
Expand All @@ -10,16 +10,28 @@ LL - #[cfg(feature = -1)]
LL + #[cfg(feature = 1)]
|

error: expected a literal (`1u8`, `1.0f32`, `"string"`, etc.) here, found `meta` metavariable
--> $DIR/attr-bad-meta-4.rs:3:15
error: expected one of `(`, `)`, `,`, `::`, or `=`, found `token`
--> $DIR/attr-bad-meta-4.rs:8:19
|
LL | #[cfg($attr_item)]
| ^^^^^^^^^^
...
LL | mac!(an(arbitrary token stream));
| -------------------------------- in this macro invocation
| -^^^^^ expected one of `(`, `)`, `,`, `::`, or `=`
| |
| help: missing `,`

error: expected one of `(`, `)`, `,`, `::`, or `=`, found `stream`
--> $DIR/attr-bad-meta-4.rs:8:25
|
= note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
LL | mac!(an(arbitrary token stream));
| -^^^^^^ expected one of `(`, `)`, `,`, `::`, or `=`
| |
| help: missing `,`

error[E0537]: invalid predicate `an`
--> $DIR/attr-bad-meta-4.rs:8:6
|
LL | mac!(an(arbitrary token stream));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 2 previous errors
error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0537`.
Loading