Auto merge of #96546 - nnethercote:overhaul-MacArgs, r=petrochenkov
Overhaul `MacArgs` Motivation: - Clarify some code that I found hard to understand. - Eliminate one use of three places where `TokenKind::Interpolated` values are created. r? `@petrochenkov`
This commit is contained in:
commit
4c60a0ea5b
@ -23,7 +23,7 @@
|
|||||||
pub use UnsafeSource::*;
|
pub use UnsafeSource::*;
|
||||||
|
|
||||||
use crate::ptr::P;
|
use crate::ptr::P;
|
||||||
use crate::token::{self, CommentKind, Delimiter, Token};
|
use crate::token::{self, CommentKind, Delimiter, Token, TokenKind};
|
||||||
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
|
use crate::tokenstream::{DelimSpan, LazyTokenStream, TokenStream, TokenTree};
|
||||||
|
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
@ -1532,7 +1532,7 @@ pub fn span(&self) -> Span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Arguments passed to an attribute or a function-like macro.
|
/// Arguments passed to an attribute or a function-like macro.
|
||||||
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
pub enum MacArgs {
|
pub enum MacArgs {
|
||||||
/// No arguments - `#[attr]`.
|
/// No arguments - `#[attr]`.
|
||||||
Empty,
|
Empty,
|
||||||
@ -1542,11 +1542,20 @@ pub enum MacArgs {
|
|||||||
Eq(
|
Eq(
|
||||||
/// Span of the `=` token.
|
/// Span of the `=` token.
|
||||||
Span,
|
Span,
|
||||||
/// "value" as a nonterminal token.
|
/// The "value".
|
||||||
Token,
|
MacArgsEq,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion
|
||||||
|
// is completed, all cases end up either as a literal, which is the form used
|
||||||
|
// after lowering to HIR, or as an error.
|
||||||
|
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||||
|
pub enum MacArgsEq {
|
||||||
|
Ast(P<Expr>),
|
||||||
|
Hir(Lit),
|
||||||
|
}
|
||||||
|
|
||||||
impl MacArgs {
|
impl MacArgs {
|
||||||
pub fn delim(&self) -> Option<Delimiter> {
|
pub fn delim(&self) -> Option<Delimiter> {
|
||||||
match self {
|
match self {
|
||||||
@ -1559,7 +1568,10 @@ pub fn span(&self) -> Option<Span> {
|
|||||||
match self {
|
match self {
|
||||||
MacArgs::Empty => None,
|
MacArgs::Empty => None,
|
||||||
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
|
MacArgs::Delimited(dspan, ..) => Some(dspan.entire()),
|
||||||
MacArgs::Eq(eq_span, token) => Some(eq_span.to(token.span)),
|
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)),
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||||
|
unreachable!("in literal form when getting span: {:?}", lit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1569,7 +1581,23 @@ pub fn inner_tokens(&self) -> TokenStream {
|
|||||||
match self {
|
match self {
|
||||||
MacArgs::Empty => TokenStream::default(),
|
MacArgs::Empty => TokenStream::default(),
|
||||||
MacArgs::Delimited(.., tokens) => tokens.clone(),
|
MacArgs::Delimited(.., tokens) => tokens.clone(),
|
||||||
MacArgs::Eq(.., token) => TokenTree::Token(token.clone()).into(),
|
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
|
||||||
|
// Currently only literals are allowed here. If more complex expression kinds are
|
||||||
|
// allowed in the future, then `nt_to_tokenstream` should be used to extract the
|
||||||
|
// token stream. This will require some cleverness, perhaps with a function
|
||||||
|
// pointer, because `nt_to_tokenstream` is not directly usable from this crate.
|
||||||
|
// It will also require changing the `parse_expr` call in `parse_mac_args_common`
|
||||||
|
// to `parse_expr_force_collect`.
|
||||||
|
if let ExprKind::Lit(lit) = &expr.kind {
|
||||||
|
let token = Token::new(TokenKind::Literal(lit.token), lit.span);
|
||||||
|
TokenTree::Token(token).into()
|
||||||
|
} else {
|
||||||
|
unreachable!("couldn't extract literal when getting inner tokens: {:?}", expr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||||
|
unreachable!("in literal form when getting inner tokens: {:?}", lit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1580,6 +1608,30 @@ pub fn need_semicolon(&self) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<CTX> HashStable<CTX> for MacArgs
|
||||||
|
where
|
||||||
|
CTX: crate::HashStableContext,
|
||||||
|
{
|
||||||
|
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
|
||||||
|
mem::discriminant(self).hash_stable(ctx, hasher);
|
||||||
|
match self {
|
||||||
|
MacArgs::Empty => {}
|
||||||
|
MacArgs::Delimited(dspan, delim, tokens) => {
|
||||||
|
dspan.hash_stable(ctx, hasher);
|
||||||
|
delim.hash_stable(ctx, hasher);
|
||||||
|
tokens.hash_stable(ctx, hasher);
|
||||||
|
}
|
||||||
|
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => {
|
||||||
|
unreachable!("hash_stable {:?}", expr);
|
||||||
|
}
|
||||||
|
MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => {
|
||||||
|
eq_span.hash_stable(ctx, hasher);
|
||||||
|
lit.hash_stable(ctx, hasher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
pub enum MacDelimiter {
|
pub enum MacDelimiter {
|
||||||
Parenthesis,
|
Parenthesis,
|
||||||
|
@ -3,14 +3,16 @@
|
|||||||
use crate::ast;
|
use crate::ast;
|
||||||
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
|
use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute};
|
||||||
use crate::ast::{Lit, LitKind};
|
use crate::ast::{Lit, LitKind};
|
||||||
use crate::ast::{MacArgs, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
|
use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem};
|
||||||
use crate::ast::{Path, PathSegment};
|
use crate::ast::{Path, PathSegment};
|
||||||
|
use crate::ptr::P;
|
||||||
use crate::token::{self, CommentKind, Delimiter, Token};
|
use crate::token::{self, CommentKind, Delimiter, Token};
|
||||||
use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
|
use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
|
||||||
use crate::tokenstream::{DelimSpan, Spacing, TokenTree, TreeAndSpacing};
|
use crate::tokenstream::{DelimSpan, Spacing, TokenTree, TreeAndSpacing};
|
||||||
use crate::tokenstream::{LazyTokenStream, TokenStream};
|
use crate::tokenstream::{LazyTokenStream, TokenStream};
|
||||||
use crate::util::comments;
|
use crate::util::comments;
|
||||||
|
|
||||||
|
use rustc_data_structures::thin_vec::ThinVec;
|
||||||
use rustc_index::bit_set::GrowableBitSet;
|
use rustc_index::bit_set::GrowableBitSet;
|
||||||
use rustc_span::source_map::BytePos;
|
use rustc_span::source_map::BytePos;
|
||||||
use rustc_span::symbol::{sym, Ident, Symbol};
|
use rustc_span::symbol::{sym, Ident, Symbol};
|
||||||
@ -475,7 +477,16 @@ pub fn value_str(&self) -> Option<Symbol> {
|
|||||||
pub fn mac_args(&self, span: Span) -> MacArgs {
|
pub fn mac_args(&self, span: Span) -> MacArgs {
|
||||||
match self {
|
match self {
|
||||||
MetaItemKind::Word => MacArgs::Empty,
|
MetaItemKind::Word => MacArgs::Empty,
|
||||||
MetaItemKind::NameValue(lit) => MacArgs::Eq(span, lit.to_token()),
|
MetaItemKind::NameValue(lit) => {
|
||||||
|
let expr = P(ast::Expr {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
kind: ast::ExprKind::Lit(lit.clone()),
|
||||||
|
span: lit.span,
|
||||||
|
attrs: ThinVec::new(),
|
||||||
|
tokens: None,
|
||||||
|
});
|
||||||
|
MacArgs::Eq(span, MacArgsEq::Ast(expr))
|
||||||
|
}
|
||||||
MetaItemKind::List(list) => {
|
MetaItemKind::List(list) => {
|
||||||
let mut tts = Vec::new();
|
let mut tts = Vec::new();
|
||||||
for (i, item) in list.iter().enumerate() {
|
for (i, item) in list.iter().enumerate() {
|
||||||
@ -552,12 +563,16 @@ fn name_value_from_tokens(
|
|||||||
|
|
||||||
fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> {
|
fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> {
|
||||||
match args {
|
match args {
|
||||||
|
MacArgs::Empty => Some(MetaItemKind::Word),
|
||||||
MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => {
|
MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => {
|
||||||
MetaItemKind::list_from_tokens(tokens.clone())
|
MetaItemKind::list_from_tokens(tokens.clone())
|
||||||
}
|
}
|
||||||
MacArgs::Delimited(..) => None,
|
MacArgs::Delimited(..) => None,
|
||||||
MacArgs::Eq(_, token) => Lit::from_token(token).ok().map(MetaItemKind::NameValue),
|
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match &expr.kind {
|
||||||
MacArgs::Empty => Some(MetaItemKind::Word),
|
ast::ExprKind::Lit(lit) => Some(MetaItemKind::NameValue(lit.clone())),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,21 +370,12 @@ pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) {
|
|||||||
visit_delim_span(dspan, vis);
|
visit_delim_span(dspan, vis);
|
||||||
visit_tts(tokens, vis);
|
visit_tts(tokens, vis);
|
||||||
}
|
}
|
||||||
MacArgs::Eq(eq_span, token) => {
|
MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => {
|
||||||
vis.visit_span(eq_span);
|
vis.visit_span(eq_span);
|
||||||
if T::VISIT_TOKENS {
|
vis.visit_expr(expr);
|
||||||
visit_token(token, vis);
|
|
||||||
} else {
|
|
||||||
// The value in `#[key = VALUE]` must be visited as an expression for backward
|
|
||||||
// compatibility, so that macros can be expanded in that position.
|
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||||
|
unreachable!("in literal form when visiting mac args eq: {:?}", lit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -738,7 +729,7 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
|
|||||||
}
|
}
|
||||||
token::Interpolated(nt) => {
|
token::Interpolated(nt) => {
|
||||||
let mut nt = Lrc::make_mut(nt);
|
let mut nt = Lrc::make_mut(nt);
|
||||||
visit_interpolated(&mut nt, vis);
|
visit_nonterminal(&mut nt, vis);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -769,7 +760,7 @@ pub fn visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
|
|||||||
// contain multiple items, but decided against it when I looked at
|
// contain multiple items, but decided against it when I looked at
|
||||||
// `parse_item_or_view_item` and tried to figure out what I would do with
|
// `parse_item_or_view_item` and tried to figure out what I would do with
|
||||||
// multiple items there....
|
// multiple items there....
|
||||||
pub fn visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) {
|
pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) {
|
||||||
match nt {
|
match nt {
|
||||||
token::NtItem(item) => visit_clobber(item, |item| {
|
token::NtItem(item) => visit_clobber(item, |item| {
|
||||||
// This is probably okay, because the only visitors likely to
|
// This is probably okay, because the only visitors likely to
|
||||||
|
@ -237,6 +237,15 @@ pub enum TokenKind {
|
|||||||
/// treat regular and interpolated lifetime identifiers in the same way.
|
/// treat regular and interpolated lifetime identifiers in the same way.
|
||||||
Lifetime(Symbol),
|
Lifetime(Symbol),
|
||||||
|
|
||||||
|
/// An embedded AST node, as produced by a macro. This only exists for
|
||||||
|
/// historical reasons. We'd like to get rid of it, for multiple reasons.
|
||||||
|
/// - It's conceptually very strange. Saying a token can contain an AST
|
||||||
|
/// node is like saying, in natural language, that a word can contain a
|
||||||
|
/// sentence.
|
||||||
|
/// - It requires special handling in a bunch of places in the parser.
|
||||||
|
/// - It prevents `Token` from implementing `Copy`.
|
||||||
|
/// It adds complexity and likely slows things down. Please don't add new
|
||||||
|
/// occurrences of this token kind!
|
||||||
Interpolated(Lrc<Nonterminal>),
|
Interpolated(Lrc<Nonterminal>),
|
||||||
|
|
||||||
/// A doc comment token.
|
/// A doc comment token.
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
//! those that are created by the expansion of a macro.
|
//! those that are created by the expansion of a macro.
|
||||||
|
|
||||||
use crate::ast::*;
|
use crate::ast::*;
|
||||||
use crate::token;
|
|
||||||
|
|
||||||
use rustc_span::symbol::{Ident, Symbol};
|
use rustc_span::symbol::{Ident, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
@ -940,14 +939,9 @@ pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) {
|
|||||||
match args {
|
match args {
|
||||||
MacArgs::Empty => {}
|
MacArgs::Empty => {}
|
||||||
MacArgs::Delimited(_dspan, _delim, _tokens) => {}
|
MacArgs::Delimited(_dspan, _delim, _tokens) => {}
|
||||||
// The value in `#[key = VALUE]` must be visited as an expression for backward
|
MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr),
|
||||||
// compatibility, so that macros can be expanded in that position.
|
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||||
MacArgs::Eq(_eq_span, token) => match &token.kind {
|
unreachable!("in literal form when walking mac args eq: {:?}", lit)
|
||||||
token::Interpolated(nt) => match &**nt {
|
}
|
||||||
token::NtExpr(expr) => visitor.visit_expr(expr),
|
|
||||||
t => panic!("unexpected token in key-value attribute: {:?}", t),
|
|
||||||
},
|
|
||||||
t => panic!("unexpected token in key-value attribute: {:?}", t),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,7 @@
|
|||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
|
|
||||||
use rustc_ast::token::{Delimiter, Token};
|
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream};
|
||||||
use rustc_ast::tokenstream::{CanSynthesizeMissingTokens, TokenStream, TokenTree};
|
|
||||||
use rustc_ast::visit;
|
use rustc_ast::visit;
|
||||||
use rustc_ast::{self as ast, *};
|
use rustc_ast::{self as ast, *};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
@ -884,37 +883,24 @@ fn lower_mac_args(&self, args: &MacArgs) -> MacArgs {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
// This is an inert key-value attribute - it will never be visible to macros
|
// This is an inert key-value attribute - it will never be visible to macros
|
||||||
// after it gets lowered to HIR. Therefore, we can synthesize tokens with fake
|
// after it gets lowered to HIR. Therefore, we can extract literals to handle
|
||||||
// spans to handle nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
|
// nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
|
||||||
MacArgs::Eq(eq_span, ref token) => {
|
MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => {
|
||||||
// In valid code the value is always representable as a single literal token.
|
// In valid code the value always ends up as a single literal. Otherwise, a dummy
|
||||||
fn unwrap_single_token(sess: &Session, tokens: TokenStream, span: Span) -> Token {
|
// literal suffices because the error is handled elsewhere.
|
||||||
if tokens.len() != 1 {
|
let lit = if let ExprKind::Lit(lit) = &expr.kind {
|
||||||
sess.diagnostic()
|
lit.clone()
|
||||||
.delay_span_bug(span, "multiple tokens in key-value attribute's value");
|
} else {
|
||||||
|
Lit {
|
||||||
|
token: token::Lit::new(token::LitKind::Err, kw::Empty, None),
|
||||||
|
kind: LitKind::Err(kw::Empty),
|
||||||
|
span: DUMMY_SP,
|
||||||
}
|
}
|
||||||
match tokens.into_trees().next() {
|
};
|
||||||
Some(TokenTree::Token(token)) => token,
|
MacArgs::Eq(eq_span, MacArgsEq::Hir(lit))
|
||||||
Some(TokenTree::Delimited(_, delim, tokens)) => {
|
|
||||||
if delim != Delimiter::Invisible {
|
|
||||||
sess.diagnostic().delay_span_bug(
|
|
||||||
span,
|
|
||||||
"unexpected delimiter in key-value attribute's value",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
unwrap_single_token(sess, tokens, span)
|
MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => {
|
||||||
}
|
unreachable!("in literal form when lowering mac args eq: {:?}", lit)
|
||||||
None => Token::dummy(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let tokens = FlattenNonterminals {
|
|
||||||
parse_sess: &self.sess.parse_sess,
|
|
||||||
synthesize_tokens: CanSynthesizeMissingTokens::Yes,
|
|
||||||
nt_to_tokenstream: self.nt_to_tokenstream,
|
|
||||||
}
|
|
||||||
.process_token(token.clone());
|
|
||||||
MacArgs::Eq(eq_span, unwrap_single_token(self.sess, tokens, token.span))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
use rustc_ast::util::parser;
|
use rustc_ast::util::parser;
|
||||||
use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
|
use rustc_ast::{self as ast, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
|
||||||
use rustc_ast::{attr, Term};
|
use rustc_ast::{attr, Term};
|
||||||
use rustc_ast::{GenericArg, MacArgs};
|
use rustc_ast::{GenericArg, MacArgs, MacArgsEq};
|
||||||
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
|
use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier};
|
||||||
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
|
use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass};
|
||||||
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
|
||||||
@ -469,14 +469,22 @@ fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) {
|
|||||||
true,
|
true,
|
||||||
span,
|
span,
|
||||||
),
|
),
|
||||||
MacArgs::Empty | MacArgs::Eq(..) => {
|
MacArgs::Empty => {
|
||||||
|
self.print_path(&item.path, false, 0);
|
||||||
|
}
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
|
||||||
self.print_path(&item.path, false, 0);
|
self.print_path(&item.path, false, 0);
|
||||||
if let MacArgs::Eq(_, token) = &item.args {
|
|
||||||
self.space();
|
self.space();
|
||||||
self.word_space("=");
|
self.word_space("=");
|
||||||
let token_str = self.token_to_string_ext(token, true);
|
let token_str = self.expr_to_string(expr);
|
||||||
self.word(token_str);
|
self.word(token_str);
|
||||||
}
|
}
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => {
|
||||||
|
self.print_path(&item.path, false, 0);
|
||||||
|
self.space();
|
||||||
|
self.word_space("=");
|
||||||
|
let token_str = self.literal_to_string(lit);
|
||||||
|
self.word(token_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.end();
|
self.end();
|
||||||
@ -817,6 +825,10 @@ fn expr_to_string(&self, e: &ast::Expr) -> String {
|
|||||||
Self::to_string(|s| s.print_expr(e))
|
Self::to_string(|s| s.print_expr(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn literal_to_string(&self, lit: &ast::Lit) -> String {
|
||||||
|
Self::to_string(|s| s.print_literal(lit))
|
||||||
|
}
|
||||||
|
|
||||||
fn tt_to_string(&self, tt: &TokenTree) -> String {
|
fn tt_to_string(&self, tt: &TokenTree) -> String {
|
||||||
Self::to_string(|s| s.print_tt(tt, false))
|
Self::to_string(|s| s.print_tt(tt, false))
|
||||||
}
|
}
|
||||||
|
@ -26,11 +26,10 @@
|
|||||||
use rustc_ast::AttrId;
|
use rustc_ast::AttrId;
|
||||||
use rustc_ast::DUMMY_NODE_ID;
|
use rustc_ast::DUMMY_NODE_ID;
|
||||||
use rustc_ast::{self as ast, AnonConst, AstLike, AttrStyle, AttrVec, Const, CrateSugar, Extern};
|
use rustc_ast::{self as ast, AnonConst, AstLike, AttrStyle, AttrVec, Const, CrateSugar, Extern};
|
||||||
use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacDelimiter, Mutability, StrLit, Unsafe};
|
use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacArgsEq, MacDelimiter, Mutability, StrLit};
|
||||||
use rustc_ast::{Visibility, VisibilityKind};
|
use rustc_ast::{Unsafe, Visibility, VisibilityKind};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::sync::Lrc;
|
|
||||||
use rustc_errors::PResult;
|
use rustc_errors::PResult;
|
||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan,
|
struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError, MultiSpan,
|
||||||
@ -1157,13 +1156,7 @@ fn parse_mac_args_common(&mut self, delimited_only: bool) -> PResult<'a, MacArgs
|
|||||||
} else if !delimited_only {
|
} else if !delimited_only {
|
||||||
if self.eat(&token::Eq) {
|
if self.eat(&token::Eq) {
|
||||||
let eq_span = self.prev_token.span;
|
let eq_span = self.prev_token.span;
|
||||||
|
MacArgs::Eq(eq_span, MacArgsEq::Ast(self.parse_expr_force_collect()?))
|
||||||
// Collect tokens because they are used during lowering to HIR.
|
|
||||||
let expr = self.parse_expr_force_collect()?;
|
|
||||||
let span = expr.span;
|
|
||||||
|
|
||||||
let token_kind = token::Interpolated(Lrc::new(token::NtExpr(expr)));
|
|
||||||
MacArgs::Eq(eq_span, Token::new(token_kind, span))
|
|
||||||
} else {
|
} else {
|
||||||
MacArgs::Empty
|
MacArgs::Empty
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
use crate::parse_in;
|
use crate::parse_in;
|
||||||
|
|
||||||
use rustc_ast::tokenstream::{DelimSpan, TokenTree};
|
use rustc_ast::tokenstream::DelimSpan;
|
||||||
use rustc_ast::{self as ast, Attribute, MacArgs, MacDelimiter, MetaItem, MetaItemKind};
|
use rustc_ast::{self as ast, Attribute, MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind};
|
||||||
|
use rustc_ast_pretty::pprust;
|
||||||
use rustc_errors::{Applicability, FatalError, PResult};
|
use rustc_errors::{Applicability, FatalError, PResult};
|
||||||
use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
|
||||||
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
|
||||||
@ -42,16 +43,40 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
|
|||||||
path: item.path.clone(),
|
path: item.path.clone(),
|
||||||
kind: match &item.args {
|
kind: match &item.args {
|
||||||
MacArgs::Empty => MetaItemKind::Word,
|
MacArgs::Empty => MetaItemKind::Word,
|
||||||
MacArgs::Eq(_, t) => {
|
|
||||||
let t = TokenTree::Token(t.clone()).into();
|
|
||||||
let v = parse_in(sess, t, "name value", |p| p.parse_unsuffixed_lit())?;
|
|
||||||
MetaItemKind::NameValue(v)
|
|
||||||
}
|
|
||||||
MacArgs::Delimited(dspan, delim, t) => {
|
MacArgs::Delimited(dspan, delim, t) => {
|
||||||
check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters");
|
check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters");
|
||||||
let nmis = parse_in(sess, t.clone(), "meta list", |p| p.parse_meta_seq_top())?;
|
let nmis = parse_in(sess, t.clone(), "meta list", |p| p.parse_meta_seq_top())?;
|
||||||
MetaItemKind::List(nmis)
|
MetaItemKind::List(nmis)
|
||||||
}
|
}
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Ast(expr)) => {
|
||||||
|
if let ast::ExprKind::Lit(lit) = &expr.kind {
|
||||||
|
if !lit.kind.is_unsuffixed() {
|
||||||
|
let mut err = sess.span_diagnostic.struct_span_err(
|
||||||
|
lit.span,
|
||||||
|
"suffixed literals are not allowed in attributes",
|
||||||
|
);
|
||||||
|
err.help(
|
||||||
|
"instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), \
|
||||||
|
use an unsuffixed version (`1`, `1.0`, etc.)",
|
||||||
|
);
|
||||||
|
return Err(err);
|
||||||
|
} else {
|
||||||
|
MetaItemKind::NameValue(lit.clone())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The non-error case can happen with e.g. `#[foo = 1+1]`. The error case can
|
||||||
|
// happen with e.g. `#[foo = include_str!("non-existent-file.rs")]`; in that
|
||||||
|
// case we delay the error because an earlier error will have already been
|
||||||
|
// reported.
|
||||||
|
let msg = format!("unexpected expression: `{}`", pprust::expr_to_string(expr));
|
||||||
|
let mut err = sess.span_diagnostic.struct_span_err(expr.span, msg);
|
||||||
|
if let ast::ExprKind::Err = expr.kind {
|
||||||
|
err.downgrade_to_delayed_bug();
|
||||||
|
}
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MacArgs::Eq(_, MacArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
{"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},{"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":{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}}]}]},"span":{"lo":0,"hi":0}}]},"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}}],"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}],"spans":{"inner_span":{"lo":0,"hi":0},"inject_use_span":{"lo":0,"hi":0}},"id":0,"is_placeholder":false}
|
{"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},{"variant":"Ast","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":{"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}}],"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}],"spans":{"inner_span":{"lo":0,"hi":0},"inject_use_span":{"lo":0,"hi":0}},"id":0,"is_placeholder":false}
|
||||||
|
@ -1 +1 @@
|
|||||||
{"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},{"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":{"0":[[{"variant":"Token","fields":[{"kind":{"variant":"Literal","fields":[{"kind":"Str","symbol":"lib","suffix":null}]},"span":{"lo":0,"hi":0}}]},"Alone"]]}}]}]},"span":{"lo":0,"hi":0}}]},"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}}],"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":"rust_2015","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}],"spans":{"inner_span":{"lo":0,"hi":0},"inject_use_span":{"lo":0,"hi":0}},"id":0,"is_placeholder":false}
|
{"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},{"variant":"Ast","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":{"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}}],"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":"rust_2015","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}],"spans":{"inner_span":{"lo":0,"hi":0},"inject_use_span":{"lo":0,"hi":0}},"id":0,"is_placeholder":false}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#![u=||{static d=||1;}]
|
#![u=||{static d=||1;}]
|
||||||
//~^ unexpected token
|
//~^ unexpected expression
|
||||||
//~| cannot find attribute `u` in this scope
|
//~| cannot find attribute `u` in this scope
|
||||||
//~| missing type for `static` item
|
//~| missing type for `static` item
|
||||||
|
|
||||||
#![a={impl std::ops::Neg for i8 {}}]
|
#![a={impl std::ops::Neg for i8 {}}]
|
||||||
//~^ ERROR unexpected token
|
//~^ ERROR unexpected expression
|
||||||
//~| ERROR cannot find attribute `a` in this scope
|
//~| ERROR cannot find attribute `a` in this scope
|
||||||
//~| ERROR `main` function not found in crate `issue_90873`
|
//~| ERROR `main` function not found in crate `issue_90873`
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: unexpected token: `||
|
error: unexpected expression: `||
|
||||||
{
|
{
|
||||||
static d: _ = || 1;
|
static d: _ = || 1;
|
||||||
}`
|
}`
|
||||||
@ -7,7 +7,7 @@ error: unexpected token: `||
|
|||||||
LL | #![u=||{static d=||1;}]
|
LL | #![u=||{static d=||1;}]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: unexpected token: `{
|
error: unexpected expression: `{
|
||||||
impl std::ops::Neg for i8 {}
|
impl std::ops::Neg for i8 {}
|
||||||
}`
|
}`
|
||||||
--> $DIR/issue-90873.rs:6:6
|
--> $DIR/issue-90873.rs:6:6
|
||||||
|
@ -7,8 +7,8 @@ macro_rules! bar {
|
|||||||
|
|
||||||
// FIXME?: `bar` here expands before `stringify` has a chance to expand.
|
// FIXME?: `bar` here expands before `stringify` has a chance to expand.
|
||||||
// `#[rustc_dummy = ...]` is validated and dropped during expansion of `bar`,
|
// `#[rustc_dummy = ...]` is validated and dropped during expansion of `bar`,
|
||||||
// the "unexpected token" errors comes from the validation.
|
// the "unexpected expression" errors comes from the validation.
|
||||||
#[rustc_dummy = stringify!(b)] //~ ERROR unexpected token: `stringify!(b)`
|
#[rustc_dummy = stringify!(b)] //~ ERROR unexpected expression: `stringify!(b)`
|
||||||
bar!();
|
bar!();
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: unexpected token: `stringify!(b)`
|
error: unexpected expression: `stringify!(b)`
|
||||||
--> $DIR/key-value-expansion-on-mac.rs:11:17
|
--> $DIR/key-value-expansion-on-mac.rs:11:17
|
||||||
|
|
|
|
||||||
LL | #[rustc_dummy = stringify!(b)]
|
LL | #[rustc_dummy = stringify!(b)]
|
||||||
|
@ -18,13 +18,13 @@ macro_rules! bug {
|
|||||||
|
|
||||||
// Any expressions containing macro call `X` that's more complex than `X` itself.
|
// Any expressions containing macro call `X` that's more complex than `X` itself.
|
||||||
// Parentheses will work.
|
// Parentheses will work.
|
||||||
bug!((column!())); //~ ERROR unexpected token: `(7u32)`
|
bug!((column!())); //~ ERROR unexpected expression: `(7u32)`
|
||||||
|
|
||||||
// Original test case.
|
// Original test case.
|
||||||
|
|
||||||
macro_rules! bug {
|
macro_rules! bug {
|
||||||
() => {
|
() => {
|
||||||
bug!("bug" + stringify!(found)); //~ ERROR unexpected token: `"bug" + "found"`
|
bug!("bug" + stringify!(found)); //~ ERROR unexpected expression: `"bug" + "found"`
|
||||||
};
|
};
|
||||||
($test:expr) => {
|
($test:expr) => {
|
||||||
#[doc = $test]
|
#[doc = $test]
|
||||||
@ -46,7 +46,7 @@ macro_rules! doc_comment {
|
|||||||
macro_rules! some_macro {
|
macro_rules! some_macro {
|
||||||
($t1: ty) => {
|
($t1: ty) => {
|
||||||
doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}
|
doc_comment! {format!("{coor}", coor = stringify!($t1)).as_str()}
|
||||||
//~^ ERROR unexpected token: `{
|
//~^ ERROR unexpected expression: `{
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
error: unexpected token: `(7u32)`
|
error: unexpected expression: `(7u32)`
|
||||||
--> $DIR/key-value-expansion.rs:21:6
|
--> $DIR/key-value-expansion.rs:21:6
|
||||||
|
|
|
|
||||||
LL | bug!((column!()));
|
LL | bug!((column!()));
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
|
||||||
error: unexpected token: `"bug" + "found"`
|
error: unexpected expression: `"bug" + "found"`
|
||||||
--> $DIR/key-value-expansion.rs:27:14
|
--> $DIR/key-value-expansion.rs:27:14
|
||||||
|
|
|
|
||||||
LL | bug!("bug" + stringify!(found));
|
LL | bug!("bug" + stringify!(found));
|
||||||
@ -15,7 +15,7 @@ LL | bug!();
|
|||||||
|
|
|
|
||||||
= note: this error originates in the macro `bug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `bug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: unexpected token: `{
|
error: unexpected expression: `{
|
||||||
let res =
|
let res =
|
||||||
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""],
|
::alloc::fmt::format(::core::fmt::Arguments::new_v1(&[""],
|
||||||
&[::core::fmt::ArgumentV1::new_display(&"u8")]));
|
&[::core::fmt::ArgumentV1::new_display(&"u8")]));
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#![l=|x|[b;x ]] //~ ERROR unexpected token: `|x| [b; x]`
|
#![l=|x|[b;x ]] //~ ERROR unexpected expression: `|x| [b; x]`
|
||||||
//~^ ERROR cannot find attribute `l` in this scope
|
//~^ ERROR cannot find attribute `l` in this scope
|
||||||
|
|
||||||
// notice the space at the start,
|
// notice the space at the start,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error: unexpected token: `|x| [b; x]`
|
error: unexpected expression: `|x| [b; x]`
|
||||||
--> $DIR/issue-90878-2.rs:1:7
|
--> $DIR/issue-90878-2.rs:1:7
|
||||||
|
|
|
|
||||||
LL | #![l=|x|[b;x ]]
|
LL | #![l=|x|[b;x ]]
|
||||||
|
@ -10,7 +10,7 @@ macro_rules! check {
|
|||||||
check!("0"); // OK
|
check!("0"); // OK
|
||||||
check!(0); // OK
|
check!(0); // OK
|
||||||
check!(0u8); //~ ERROR suffixed literals are not allowed in attributes
|
check!(0u8); //~ ERROR suffixed literals are not allowed in attributes
|
||||||
check!(-0); //~ ERROR unexpected token: `-0`
|
check!(-0); //~ ERROR unexpected expression: `-0`
|
||||||
check!(0 + 0); //~ ERROR unexpected token: `0 + 0`
|
check!(0 + 0); //~ ERROR unexpected expression: `0 + 0`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -6,13 +6,13 @@ LL | check!(0u8);
|
|||||||
|
|
|
|
||||||
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
|
= help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
|
||||||
|
|
||||||
error: unexpected token: `-0`
|
error: unexpected expression: `-0`
|
||||||
--> $DIR/malformed-interpolated.rs:13:8
|
--> $DIR/malformed-interpolated.rs:13:8
|
||||||
|
|
|
|
||||||
LL | check!(-0);
|
LL | check!(-0);
|
||||||
| ^^
|
| ^^
|
||||||
|
|
||||||
error: unexpected token: `0 + 0`
|
error: unexpected expression: `0 + 0`
|
||||||
--> $DIR/malformed-interpolated.rs:14:8
|
--> $DIR/malformed-interpolated.rs:14:8
|
||||||
|
|
|
|
||||||
LL | check!(0 + 0);
|
LL | check!(0 + 0);
|
||||||
|
@ -688,7 +688,8 @@ pub fn eq_mac_args(l: &MacArgs, r: &MacArgs) -> bool {
|
|||||||
match (l, r) {
|
match (l, r) {
|
||||||
(Empty, Empty) => true,
|
(Empty, Empty) => true,
|
||||||
(Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts),
|
(Delimited(_, ld, lts), Delimited(_, rd, rts)) => ld == rd && lts.eq_unspanned(rts),
|
||||||
(Eq(_, lt), Eq(_, rt)) => lt.kind == rt.kind,
|
(Eq(_, MacArgsEq::Ast(le)), Eq(_, MacArgsEq::Ast(re))) => eq_expr(le, re),
|
||||||
|
(Eq(_, MacArgsEq::Hir(ll)), Eq(_, MacArgsEq::Hir(rl))) => ll.kind == rl.kind,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user