Accept arbitrary expressions in key-value attributes at parse time

This commit is contained in:
Vadim Petrochenkov 2020-11-07 16:09:40 +03:00
parent fa55f668e5
commit 31d72c2658
24 changed files with 145 additions and 210 deletions

View File

@ -24,7 +24,7 @@ pub use UnsafeSource::*;
use crate::ptr::P;
use crate::token::{self, CommentKind, DelimToken};
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::stack::ensure_sufficient_stack;
@ -39,7 +39,6 @@ use rustc_span::{Span, DUMMY_SP};
use std::cmp::Ordering;
use std::convert::TryFrom;
use std::fmt;
use std::iter;
#[cfg(test)]
mod tests;
@ -1514,20 +1513,6 @@ impl MacArgs {
}
}
/// Tokens together with the delimiters or `=`.
/// Use of this method generally means that something suboptimal or hacky is happening.
pub fn outer_tokens(&self) -> TokenStream {
match *self {
MacArgs::Empty => TokenStream::default(),
MacArgs::Delimited(dspan, delim, ref tokens) => {
TokenTree::Delimited(dspan, delim.to_token(), tokens.clone()).into()
}
MacArgs::Eq(eq_span, ref tokens) => {
iter::once(TokenTree::token(token::Eq, eq_span)).chain(tokens.trees()).collect()
}
}
}
/// Whether a macro with these arguments needs a semicolon
/// when used as a standalone item or statement.
pub fn need_semicolon(&self) -> bool {

View File

@ -371,20 +371,15 @@ pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) {
// The value in `#[key = VALUE]` must be visited as an expression for backward
// compatibility, so that macros can be expanded in that position.
if !vis.token_visiting_enabled() {
if let Some(TokenTree::Token(token)) = tokens.trees_ref().next() {
if let token::Interpolated(..) = token.kind {
// ^^ Do not `make_mut` unless we have to.
match Lrc::make_mut(&mut tokens.0).get_mut(0) {
Some((TokenTree::Token(token), _spacing)) => match &mut token.kind {
token::Interpolated(nt) => match Lrc::make_mut(nt) {
token::NtExpr(expr) => vis.visit_expr(expr),
t => panic!("unexpected token in key-value attribute: {:?}", t),
},
t => panic!("unexpected token in key-value attribute: {:?}", t),
},
match Lrc::make_mut(&mut tokens.0).get_mut(0) {
Some((TokenTree::Token(token), _spacing)) => match &mut token.kind {
token::Interpolated(nt) => match Lrc::make_mut(nt) {
token::NtExpr(expr) => vis.visit_expr(expr),
t => panic!("unexpected token in key-value attribute: {:?}", t),
}
}
},
t => panic!("unexpected token in key-value attribute: {:?}", t),
},
t => panic!("unexpected token in key-value attribute: {:?}", t),
}
}
}

View File

@ -906,7 +906,6 @@ pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) {
token::NtExpr(expr) => visitor.visit_expr(expr),
t => panic!("unexpected token in key-value attribute: {:?}", t),
},
token::Literal(..) | token::Ident(..) => {}
t => panic!("unexpected token in key-value attribute: {:?}", t),
},
t => panic!("unexpected token in key-value attribute: {:?}", t),

View File

@ -630,6 +630,10 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
gate_all!(const_trait_impl, "const trait impls are experimental");
gate_all!(half_open_range_patterns, "half-open range patterns are unstable");
gate_all!(inline_const, "inline-const is experimental");
gate_all!(
extended_key_value_attributes,
"arbitrary expressions in key-value attributes are unstable"
);
if sess.parse_sess.span_diagnostic.err_count() == 0 {
// Errors for `destructuring_assignment` can get quite noisy, especially where `_` is
// involved, so we only emit errors where there are no other parsing errors.

View File

@ -620,6 +620,9 @@ declare_features! (
/// Allows capturing disjoint fields in a closure/generator (RFC 2229).
(active, capture_disjoint_fields, "1.49.0", Some(53488), None),
/// Allows arbitrary expressions in key-value attributes at parse time.
(active, extended_key_value_attributes, "1.50.0", Some(78835), None),
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------

View File

@ -23,6 +23,7 @@ use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, CrateSugar, E
use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacDelimiter, Mutability, StrLit};
use rustc_ast::{Visibility, VisibilityKind};
use rustc_ast_pretty::pprust;
use rustc_data_structures::sync::Lrc;
use rustc_errors::PResult;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, FatalError};
use rustc_session::parse::ParseSess;
@ -935,16 +936,24 @@ impl<'a> Parser<'a> {
is_interpolated_expr = true;
}
}
let token_tree = if is_interpolated_expr {
// We need to accept arbitrary interpolated expressions to continue
// supporting things like `doc = $expr` that work on stable.
// Non-literal interpolated expressions are rejected after expansion.
self.parse_token_tree()
} else {
self.parse_unsuffixed_lit()?.token_tree()
};
MacArgs::Eq(eq_span, token_tree.into())
// The value here is never passed to macros as tokens by itself (not as a part
// of the whole attribute), so we don't collect tokens here. If this changes,
// then token will need to be collected. One catch here is that we are using
// a nonterminal for keeping the expression, but this nonterminal should not
// be wrapped into a group when converting to token stream.
let expr = self.parse_expr()?;
let span = expr.span;
match &expr.kind {
// Not gated to supporte things like `doc = $expr` that work on stable.
_ if is_interpolated_expr => {}
ExprKind::Lit(lit) if lit.kind.is_unsuffixed() => {}
_ => self.sess.gated_spans.gate(sym::extended_key_value_attributes, span),
}
let token = token::Interpolated(Lrc::new(token::NtExpr(expr)));
MacArgs::Eq(eq_span, TokenTree::token(token, span).into())
} else {
MacArgs::Empty
}

View File

@ -496,6 +496,7 @@ symbols! {
expf64,
export_name,
expr,
extended_key_value_attributes,
extern_absolute_paths,
extern_crate_item_prelude,
extern_crate_self,

View File

@ -1,4 +1,5 @@
#![feature(external_doc)]
#![feature(extended_key_value_attributes)]
// @has external_doc/struct.CanHasDocs.html
// @has - '//h1' 'External Docs'
@ -6,3 +7,18 @@
#[doc(include = "auxiliary/external-doc.md")]
/// ## Inline Docs
pub struct CanHasDocs;
// @has external_doc/struct.IncludeStrDocs.html
// @has - '//h1' 'External Docs'
// @has - '//h2' 'Inline Docs'
#[doc = include_str!("auxiliary/external-doc.md")]
/// ## Inline Docs
pub struct IncludeStrDocs;
macro_rules! dir { () => { "auxiliary" } }
// @has external_doc/struct.EagerExpansion.html
// @has - '//h1' 'External Docs'
#[doc = include_str!(concat!(dir!(), "/external-doc.md"))]
/// ## Inline Docs
pub struct EagerExpansion;

View File

@ -1 +1 @@
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":null}]}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}

View File

@ -1 +1 @@
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}
{"module":{"inner":{"lo":0,"hi":0},"unsafety":"No","items":[{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"prelude_import","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"","span":{"lo":0,"hi":0}},"kind":{"variant":"Use","fields":[{"prefix":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"{{root}}","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"std","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"prelude","span":{"lo":0,"hi":0}},"id":0,"args":null},{"ident":{"name":"v1","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"kind":"Glob","span":{"lo":0,"hi":0}}]},"tokens":null},{"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"macro_use","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":"Empty","tokens":null},null]},"id":null,"style":"Outer","span":{"lo":0,"hi":0}}],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"std","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null},{"attrs":[],"id":0,"span":{"lo":0,"hi":0},"vis":{"kind":"Inherited","span":{"lo":0,"hi":0},"tokens":null},"ident":{"name":"core","span":{"lo":0,"hi":0}},"kind":{"variant":"ExternCrate","fields":[null]},"tokens":null}],"inline":true},"attrs":[{"kind":{"variant":"Normal","fields":[{"path":{"span":{"lo":0,"hi":0},"segments":[{"ident":{"name":"crate_type","span":{"lo":0,"hi":0}},"id":0,"args":null}],"tokens":null},"args":{"variant":"Eq","fields":[{"lo":0,"hi":0},{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Interpolated","fields":[{"variant":"NtExpr","fields":[{"id":0,"kind":{"variant":"Lit","fields":[{"token":{"kind":"Str","symbol":"lib","suffix":null},"kind":{"variant":"Str","fields":["lib","Cooked"]},"span":{"lo":0,"hi":0}}]},"span":{"lo":0,"hi":0},"attrs":{"0":null},"tokens":null}]}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"tokens":null},{"0":[[{"variant":"Token","fields":[{"kind":"Pound","span":{"lo":0,"hi":0}}]},"Joint"],[{"variant":"Token","fields":[{"kind":"Not","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Delimited","fields":[{"open":{"lo":0,"hi":0},"close":{"lo":0,"hi":0}},"Bracket",{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Ident","fields":["crate_type",false]},"span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":"Eq","span":{"lo":0,"hi":0}}]},"Alone"],[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}]},"Alone"]]}]},"id":null,"style":"Inner","span":{"lo":0,"hi":0}}],"span":{"lo":0,"hi":0},"proc_macros":[]}

View File

@ -1,2 +1,2 @@
#[my_attr = !] //~ ERROR unexpected token: `!`
#[my_attr = !] //~ ERROR expected expression, found `]`
fn main() {}

View File

@ -1,8 +1,8 @@
error: unexpected token: `!`
--> $DIR/attr-eq-token-tree.rs:1:13
error: expected expression, found `]`
--> $DIR/attr-eq-token-tree.rs:1:14
|
LL | #[my_attr = !]
| ^
| ^ expected expression
error: aborting due to previous error

View File

@ -12,23 +12,22 @@ extern crate key_value_expansion;
macro_rules! bug {
($expr:expr) => {
#[rustc_dummy = $expr] // Any key-value attribute, not necessarily `doc`
//~^ ERROR unexpected token: `(7u32)`
struct S;
};
}
// Any expressions containing macro call `X` that's more complex than `X` itself.
// Parentheses will work.
bug!((column!()));
bug!((column!())); //~ ERROR unexpected token: `(7u32)`
// Original test case.
macro_rules! bug {
() => {
bug!("bug" + stringify!(found));
bug!("bug" + stringify!(found)); //~ ERROR unexpected token: `"bug" + "found"`
};
($test:expr) => {
#[doc = $test] //~ ERROR unexpected token: `"bug" + "found"`
#[doc = $test]
struct Test {}
};
}
@ -39,7 +38,7 @@ bug!();
macro_rules! doc_comment {
($x:expr) => {
#[doc = $x] //~ ERROR unexpected token: `{
#[doc = $x]
extern {}
};
}
@ -47,6 +46,7 @@ macro_rules! doc_comment {
macro_rules! some_macro {
($t1: ty) => {
doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}
//~^ ERROR unexpected token: `{
};
}

View File

@ -1,19 +1,14 @@
error: unexpected token: `(7u32)`
--> $DIR/key-value-expansion.rs:14:25
--> $DIR/key-value-expansion.rs:21:6
|
LL | #[rustc_dummy = $expr] // Any key-value attribute, not necessarily `doc`
| ^^^^^
...
LL | bug!((column!()));
| ------------------ in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
| ^^^^^^^^^^^
error: unexpected token: `"bug" + "found"`
--> $DIR/key-value-expansion.rs:31:17
--> $DIR/key-value-expansion.rs:27:14
|
LL | #[doc = $test]
| ^^^^^
LL | bug!("bug" + stringify!(found));
| ^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | bug!();
| ------- in this macro invocation
@ -30,10 +25,10 @@ error: unexpected token: `{
}));
res
}.as_str()`
--> $DIR/key-value-expansion.rs:42:17
--> $DIR/key-value-expansion.rs:48:23
|
LL | #[doc = $x]
| ^^
LL | doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
LL | some_macro!(u8);
| ---------------- in this macro invocation

View File

@ -0,0 +1,8 @@
#[cfg(FALSE)]
#[attr = multi::segment::path] //~ ERROR arbitrary expressions in key-value attributes are unstable
#[attr = macro_call!()] //~ ERROR arbitrary expressions in key-value attributes are unstable
#[attr = 1 + 2] //~ ERROR arbitrary expressions in key-value attributes are unstable
#[attr = what?] //~ ERROR arbitrary expressions in key-value attributes are unstable
struct S;
fn main() {}

View File

@ -0,0 +1,39 @@
error[E0658]: arbitrary expressions in key-value attributes are unstable
--> $DIR/feature-gate-extended_key_value_attributes.rs:2:10
|
LL | #[attr = multi::segment::path]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #78835 <https://github.com/rust-lang/rust/issues/78835> for more information
= help: add `#![feature(extended_key_value_attributes)]` to the crate attributes to enable
error[E0658]: arbitrary expressions in key-value attributes are unstable
--> $DIR/feature-gate-extended_key_value_attributes.rs:3:10
|
LL | #[attr = macro_call!()]
| ^^^^^^^^^^^^^
|
= note: see issue #78835 <https://github.com/rust-lang/rust/issues/78835> for more information
= help: add `#![feature(extended_key_value_attributes)]` to the crate attributes to enable
error[E0658]: arbitrary expressions in key-value attributes are unstable
--> $DIR/feature-gate-extended_key_value_attributes.rs:4:10
|
LL | #[attr = 1 + 2]
| ^^^^^
|
= note: see issue #78835 <https://github.com/rust-lang/rust/issues/78835> for more information
= help: add `#![feature(extended_key_value_attributes)]` to the crate attributes to enable
error[E0658]: arbitrary expressions in key-value attributes are unstable
--> $DIR/feature-gate-extended_key_value_attributes.rs:5:10
|
LL | #[attr = what?]
| ^^^^^
|
= note: see issue #78835 <https://github.com/rust-lang/rust/issues/78835> for more information
= help: add `#![feature(extended_key_value_attributes)]` to the crate attributes to enable
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,2 +1,2 @@
#[doc = $not_there] //~ ERROR unexpected token: `$`
#[doc = $not_there] //~ ERROR expected expression, found `$`
fn main() { }

View File

@ -1,8 +1,8 @@
error: unexpected token: `$`
error: expected expression, found `$`
--> $DIR/macro-attribute.rs:1:9
|
LL | #[doc = $not_there]
| ^
| ^ expected expression
error: aborting due to previous error

View File

@ -2,8 +2,7 @@
macro_rules! check {
($expr: expr) => (
#[rustc_dummy = $expr] //~ ERROR unexpected token: `-0`
//~| ERROR unexpected token: `0 + 0`
#[rustc_dummy = $expr]
use main as _;
);
}
@ -11,7 +10,7 @@ macro_rules! check {
check!("0"); // OK
check!(0); // OK
check!(0u8); //~ ERROR suffixed literals are not allowed in attributes
check!(-0); // ERROR, see above
check!(0 + 0); // ERROR, see above
check!(-0); //~ ERROR unexpected token: `-0`
check!(0 + 0); //~ ERROR unexpected token: `0 + 0`
fn main() {}

View File

@ -1,5 +1,5 @@
error: suffixed literals are not allowed in attributes
--> $DIR/malformed-interpolated.rs:13:8
--> $DIR/malformed-interpolated.rs:12:8
|
LL | check!(0u8);
| ^^^
@ -7,26 +7,16 @@ LL | check!(0u8);
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: unexpected token: `-0`
--> $DIR/malformed-interpolated.rs:5:25
--> $DIR/malformed-interpolated.rs:13:8
|
LL | #[rustc_dummy = $expr]
| ^^^^^
...
LL | check!(-0); // ERROR, see above
| ----------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
LL | check!(-0);
| ^^
error: unexpected token: `0 + 0`
--> $DIR/malformed-interpolated.rs:5:25
--> $DIR/malformed-interpolated.rs:14:8
|
LL | #[rustc_dummy = $expr]
| ^^^^^
...
LL | check!(0 + 0); // ERROR, see above
| -------------- in this macro invocation
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
LL | check!(0 + 0);
| ^^^^^
error: aborting due to 3 previous errors

View File

@ -1,2 +1,2 @@
#[path =] //~ ERROR unexpected token: `]`
#[path =] //~ ERROR expected expression, found `]`
mod m {}

View File

@ -1,8 +1,8 @@
error: unexpected token: `]`
error: expected expression, found `]`
--> $DIR/attr-bad-meta-2.rs:1:9
|
LL | #[path =]
| ^
| ^ expected expression
error: aborting due to previous error

View File

@ -1,27 +1,15 @@
#![feature(rustc_attrs)]
#![feature(rustc_attrs, extended_key_value_attributes)]
#[rustc_dummy = 1usize] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1u8] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1u16] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1u32] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1u64] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1isize] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1i8] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1i16] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1i32] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1i64] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1.0f32] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
#[rustc_dummy = 1.0f64] //~ ERROR: suffixed literals are not allowed in attributes
//~| ERROR: suffixed literals are not allowed in attributes
fn main() {}

View File

@ -7,119 +7,23 @@ LL | #[rustc_dummy = 1usize]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:5:17
--> $DIR/suffixed-literal-meta.rs:4:17
|
LL | #[rustc_dummy = 1u8]
| ^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:7:17
|
LL | #[rustc_dummy = 1u16]
| ^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:9:17
|
LL | #[rustc_dummy = 1u32]
| ^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:11:17
|
LL | #[rustc_dummy = 1u64]
| ^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:13:17
|
LL | #[rustc_dummy = 1isize]
| ^^^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:15:17
|
LL | #[rustc_dummy = 1i8]
| ^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:17:17
|
LL | #[rustc_dummy = 1i16]
| ^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:19:17
|
LL | #[rustc_dummy = 1i32]
| ^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:21:17
|
LL | #[rustc_dummy = 1i64]
| ^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:23:17
|
LL | #[rustc_dummy = 1.0f32]
| ^^^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:25:17
|
LL | #[rustc_dummy = 1.0f64]
| ^^^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:3:17
|
LL | #[rustc_dummy = 1usize]
| ^^^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:5:17
|
LL | #[rustc_dummy = 1u8]
| ^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:7:17
|
LL | #[rustc_dummy = 1u16]
| ^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:9:17
--> $DIR/suffixed-literal-meta.rs:6:17
|
LL | #[rustc_dummy = 1u32]
| ^^^^
@ -127,7 +31,7 @@ LL | #[rustc_dummy = 1u32]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:11:17
--> $DIR/suffixed-literal-meta.rs:7:17
|
LL | #[rustc_dummy = 1u64]
| ^^^^
@ -135,7 +39,7 @@ LL | #[rustc_dummy = 1u64]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:13:17
--> $DIR/suffixed-literal-meta.rs:8:17
|
LL | #[rustc_dummy = 1isize]
| ^^^^^^
@ -143,7 +47,7 @@ LL | #[rustc_dummy = 1isize]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:15:17
--> $DIR/suffixed-literal-meta.rs:9:17
|
LL | #[rustc_dummy = 1i8]
| ^^^
@ -151,7 +55,7 @@ LL | #[rustc_dummy = 1i8]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:17:17
--> $DIR/suffixed-literal-meta.rs:10:17
|
LL | #[rustc_dummy = 1i16]
| ^^^^
@ -159,7 +63,7 @@ LL | #[rustc_dummy = 1i16]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:19:17
--> $DIR/suffixed-literal-meta.rs:11:17
|
LL | #[rustc_dummy = 1i32]
| ^^^^
@ -167,7 +71,7 @@ LL | #[rustc_dummy = 1i32]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:21:17
--> $DIR/suffixed-literal-meta.rs:12:17
|
LL | #[rustc_dummy = 1i64]
| ^^^^
@ -175,7 +79,7 @@ LL | #[rustc_dummy = 1i64]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:23:17
--> $DIR/suffixed-literal-meta.rs:13:17
|
LL | #[rustc_dummy = 1.0f32]
| ^^^^^^
@ -183,12 +87,12 @@ LL | #[rustc_dummy = 1.0f32]
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: suffixed literals are not allowed in attributes
--> $DIR/suffixed-literal-meta.rs:25:17
--> $DIR/suffixed-literal-meta.rs:14:17
|
LL | #[rustc_dummy = 1.0f64]
| ^^^^^^
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
error: aborting due to 24 previous errors
error: aborting due to 12 previous errors