From a81804b4d5f222f94758139b504aa2570528f9f1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 1 Dec 2019 02:25:32 +0300 Subject: [PATCH] syntax: Introduce a struct `MacArgs` for macro arguments --- src/librustc_lint/builtin.rs | 2 +- src/librustc_parse/parser/attr.rs | 2 +- src/librustc_parse/parser/expr.rs | 5 +- src/librustc_parse/parser/item.rs | 22 +++-- src/librustc_parse/parser/mod.rs | 64 +++++++++----- src/librustc_parse/parser/pat.rs | 5 +- src/librustc_parse/parser/stmt.rs | 12 +-- src/librustc_parse/parser/ty.rs | 5 +- src/libsyntax/ast.rs | 84 +++++++++++++++---- src/libsyntax/lib.rs | 1 + src/libsyntax/mut_visit.rs | 24 +++++- src/libsyntax/print/pprust.rs | 24 +++--- src/libsyntax_expand/mbe/transcribe.rs | 9 +- src/libsyntax_expand/placeholders.rs | 4 +- src/libsyntax_ext/assert.rs | 23 ++--- src/test/ui/issues/issue-10536.rs | 4 +- src/test/ui/issues/issue-10536.stderr | 8 +- .../ui/parser/macro-bad-delimiter-ident.rs | 2 +- .../parser/macro-bad-delimiter-ident.stderr | 4 +- 19 files changed, 192 insertions(+), 112 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index b08a095beac4e..6cfc6cf226fa5 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1453,7 +1453,7 @@ impl EarlyLintPass for KeywordIdents { self.check_tokens(cx, mac_def.stream()); } fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::Mac) { - self.check_tokens(cx, mac.tts.clone().into()); + self.check_tokens(cx, mac.args.inner_tokens()); } fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: ast::Ident) { self.check_ident_token(cx, UnderMacro(false), ident); diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 524b551e54cb3..a0f535a4b954d 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -244,7 +244,7 @@ impl<'a> Parser<'a> { Ok(attrs) } - fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> { + pub(super) fn parse_unsuffixed_lit(&mut self) -> PResult<'a, ast::Lit> { let lit = self.parse_lit()?; debug!("checking if {:?} is unusuffixed", lit); diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 43c740f7f93f1..a6629aef1eeff 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -922,12 +922,11 @@ impl<'a> Parser<'a> { // `!`, as an operator, is prefix, so we know this isn't that. if self.eat(&token::Not) { // MACRO INVOCATION expression - let (delim, tts) = self.expect_delimited_token_tree()?; + let args = self.parse_mac_args()?; hi = self.prev_span; ex = ExprKind::Mac(Mac { path, - tts, - delim, + args, span: lo.to(hi), prior_type_ascription: self.last_type_ascription, }); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index a0669a2a1748e..9bf5ae3cc5af0 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -8,7 +8,7 @@ use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, Us use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit}; use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, Variant, VariantData, StructField}; -use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param}; +use syntax::ast::{Mac, Block, BindingMode, FnDecl, FnSig, SelfKind, Param}; use syntax::print::pprust; use syntax::ptr::P; use syntax::ThinVec; @@ -437,16 +437,15 @@ impl<'a> Parser<'a> { // Item macro let path = self.parse_path(PathStyle::Mod)?; self.expect(&token::Not)?; - let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + let args = self.parse_mac_args()?; + if args.need_semicolon() && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; let mac = Mac { path, - tts, - delim, + args, span: mac_lo.to(hi), prior_type_ascription: self.last_type_ascription, }; @@ -518,15 +517,14 @@ impl<'a> Parser<'a> { *at_end = true; // eat a matched-delimiter token tree: - let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { + let args = self.parse_mac_args()?; + if args.need_semicolon() { self.expect_semi()?; } Ok(Some(Mac { path, - tts, - delim, + args, span: lo.to(self.prev_span), prior_type_ascription: self.last_type_ascription, })) @@ -1660,12 +1658,12 @@ impl<'a> Parser<'a> { self.bump(); let ident = self.parse_ident()?; - let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + let args = self.parse_mac_args()?; + if args.need_semicolon() && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(); } - (ident, ast::MacroDef { tokens, legacy: true }) + (ident, ast::MacroDef { tokens: args.inner_tokens(), legacy: true }) } else { return Ok(None); }; diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index ea7673767d07e..77bbf8bb941f8 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -16,7 +16,7 @@ use crate::lexer::UnmatchedBrace; use syntax::ast::{ self, DUMMY_NODE_ID, AttrStyle, Attribute, CrateSugar, Extern, Ident, StrLit, - IsAsync, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety, + IsAsync, MacArgs, MacDelimiter, Mutability, Visibility, VisibilityKind, Unsafety, }; use syntax::print::pprust; @@ -1010,27 +1010,49 @@ impl<'a> Parser<'a> { } } - fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, TokenStream)> { - let delim = match self.token.kind { - token::OpenDelim(delim) => delim, - _ => { - let msg = "expected open delimiter"; - let mut err = self.fatal(msg); - err.span_label(self.token.span, msg); - return Err(err) + fn parse_mac_args(&mut self) -> PResult<'a, P> { + self.parse_mac_args_common(true) + } + + #[allow(dead_code)] + fn parse_attr_args(&mut self) -> PResult<'a, P> { + self.parse_mac_args_common(false) + } + + fn parse_mac_args_common(&mut self, delimited_only: bool) -> PResult<'a, P> { + Ok(P(if self.check(&token::OpenDelim(DelimToken::Paren)) || + self.check(&token::OpenDelim(DelimToken::Bracket)) || + self.check(&token::OpenDelim(DelimToken::Brace)) { + match self.parse_token_tree() { + TokenTree::Delimited(dspan, delim, tokens) => + MacArgs::Delimited(dspan, MacDelimiter::from_token(delim), tokens), + _ => unreachable!(), } - }; - let tts = match self.parse_token_tree() { - TokenTree::Delimited(_, _, tts) => tts, - _ => unreachable!(), - }; - let delim = match delim { - token::Paren => MacDelimiter::Parenthesis, - token::Bracket => MacDelimiter::Bracket, - token::Brace => MacDelimiter::Brace, - token::NoDelim => self.bug("unexpected no delimiter"), - }; - Ok((delim, tts.into())) + } else if !delimited_only { + if self.eat(&token::Eq) { + let eq_span = self.prev_span; + let mut is_interpolated_expr = false; + if let token::Interpolated(nt) = &self.token.kind { + if let token::NtExpr(..) = **nt { + 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()) + } else { + MacArgs::Empty + } + } else { + return self.unexpected(); + })) } fn parse_or_use_outer_attributes( diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index b068a4f16a533..c16b5f5574afc 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -595,11 +595,10 @@ impl<'a> Parser<'a> { /// Parse macro invocation fn parse_pat_mac_invoc(&mut self, lo: Span, path: Path) -> PResult<'a, PatKind> { self.bump(); - let (delim, tts) = self.expect_delimited_token_tree()?; + let args = self.parse_mac_args()?; let mac = Mac { path, - tts, - delim, + args, span: lo.to(self.prev_span), prior_type_ascription: self.last_type_ascription, }; diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index a5f20691d077c..68c85ad8abfb3 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -10,7 +10,7 @@ use syntax::ThinVec; use syntax::ptr::P; use syntax::ast; use syntax::ast::{DUMMY_NODE_ID, Stmt, StmtKind, Local, Block, BlockCheckMode, Expr, ExprKind}; -use syntax::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac, MacDelimiter}; +use syntax::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac}; use syntax::util::classify; use syntax::token; use syntax::source_map::{respan, Span}; @@ -93,10 +93,11 @@ impl<'a> Parser<'a> { })); } - let (delim, tts) = self.expect_delimited_token_tree()?; + let args = self.parse_mac_args()?; + let delim = args.delim(); let hi = self.prev_span; - let style = if delim == MacDelimiter::Brace { + let style = if delim == token::Brace { MacStmtStyle::Braces } else { MacStmtStyle::NoBraces @@ -104,12 +105,11 @@ impl<'a> Parser<'a> { let mac = Mac { path, - tts, - delim, + args, span: lo.to(hi), prior_type_ascription: self.last_type_ascription, }; - let kind = if delim == MacDelimiter::Brace || + let kind = if delim == token::Brace || self.token == token::Semi || self.token == token::Eof { StmtKind::Mac(P((mac, style, attrs.into()))) } diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index 8e6bc29be5218..802bef525dbaa 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -177,11 +177,10 @@ impl<'a> Parser<'a> { let path = self.parse_path(PathStyle::Type)?; if self.eat(&token::Not) { // Macro invocation in type position - let (delim, tts) = self.expect_delimited_token_tree()?; + let args = self.parse_mac_args()?; let mac = Mac { path, - tts, - delim, + args, span: lo.to(self.prev_span), prior_type_ascription: self.last_type_ascription, }; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 512f43c86ca01..21126f8301a2a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -27,7 +27,7 @@ pub use syntax_pos::symbol::{Ident, Symbol as Name}; use crate::ptr::P; use crate::source_map::{dummy_spanned, respan, Spanned}; use crate::token::{self, DelimToken}; -use crate::tokenstream::TokenStream; +use crate::tokenstream::{TokenStream, TokenTree, DelimSpan}; use syntax_pos::symbol::{kw, sym, Symbol}; use syntax_pos::{Span, DUMMY_SP, ExpnId}; @@ -40,6 +40,7 @@ use rustc_index::vec::Idx; use rustc_serialize::{self, Decoder, Encoder}; use rustc_macros::HashStable_Generic; +use std::iter; use std::fmt; #[cfg(test)] @@ -1372,34 +1373,78 @@ pub enum Movability { Movable, } -/// Represents a macro invocation. The `Path` indicates which macro -/// is being invoked, and the vector of token-trees contains the source -/// of the macro invocation. -/// -/// N.B., the additional ident for a `macro_rules`-style macro is actually -/// stored in the enclosing item. +/// Represents a macro invocation. The `path` indicates which macro +/// is being invoked, and the `args` are arguments passed to it. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Mac { pub path: Path, - pub delim: MacDelimiter, - pub tts: TokenStream, + pub args: P, pub span: Span, pub prior_type_ascription: Option<(Span, bool)>, } -#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] -pub enum MacDelimiter { - Parenthesis, - Bracket, - Brace, +/// Arguments passed to an attribute or a function-like macro. +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum MacArgs { + /// No arguments - `#[attr]`. + Empty, + /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`. + Delimited(DelimSpan, MacDelimiter, TokenStream), + /// Arguments of a key-value attribute - `#[attr = "value"]`. + /// Span belongs to the `=` token, token stream is the "value". + Eq(Span, TokenStream), +} + +impl MacArgs { + pub fn delim(&self) -> DelimToken { + match self { + MacArgs::Delimited(_, delim, _) => delim.to_token(), + MacArgs::Empty | MacArgs::Eq(..) => token::NoDelim, + } + } + + /// Tokens inside the delimiters or after `=`. + /// Proc macros see these tokens, for example. + pub fn inner_tokens(&self) -> TokenStream { + match self { + MacArgs::Empty => TokenStream::default(), + MacArgs::Delimited(.., tokens) => tokens.clone(), + MacArgs::Eq(.., tokens) => tokens.clone(), + } + } + + /// Tokens together with the delimiters or `=`. + /// Use of this functions generally means that something suspicious 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 { + !matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace ,_)) + } } impl Mac { pub fn stream(&self) -> TokenStream { - self.tts.clone() + self.args.inner_tokens() } } +#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Debug)] +pub enum MacDelimiter { + Parenthesis, + Bracket, + Brace, +} + impl MacDelimiter { crate fn to_token(self) -> DelimToken { match self { @@ -1408,6 +1453,15 @@ impl MacDelimiter { MacDelimiter::Brace => DelimToken::Brace, } } + + pub fn from_token(delim: DelimToken) -> MacDelimiter { + match delim { + token::Paren => MacDelimiter::Parenthesis, + token::Bracket => MacDelimiter::Bracket, + token::Brace => MacDelimiter::Brace, + token::NoDelim => panic!("expected a delimiter"), + } + } } /// Represents a macro definition. diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 3d4a5d624c119..3dcdd4db6377a 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -12,6 +12,7 @@ #![feature(const_transmute)] #![feature(crate_visibility_modifier)] #![feature(label_break_value)] +#![feature(matches_macro)] #![feature(nll)] #![feature(try_trait)] #![feature(slice_patterns)] diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index fbe28215a56c8..7c86fc5cba599 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -359,6 +359,26 @@ pub fn visit_fn_sig(FnSig { header, decl }: &mut FnSig, vis: &mut vis.visit_fn_decl(decl); } +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_mac_args(args: &mut MacArgs, vis: &mut T) { + match args { + MacArgs::Empty => {} + MacArgs::Delimited(dspan, _delim, tokens) => { + visit_delim_span(dspan, vis); + vis.visit_tts(tokens); + } + MacArgs::Eq(eq_span, tokens) => { + vis.visit_span(eq_span); + vis.visit_tts(tokens); + } + } +} + +pub fn visit_delim_span(dspan: &mut DelimSpan, vis: &mut T) { + vis.visit_span(&mut dspan.open); + vis.visit_span(&mut dspan.close); +} + pub fn noop_flat_map_field_pattern( mut fp: FieldPat, vis: &mut T, @@ -560,9 +580,9 @@ pub fn noop_visit_attribute(attr: &mut Attribute, vis: &mut T) { } pub fn noop_visit_mac(mac: &mut Mac, vis: &mut T) { - let Mac { path, delim: _, tts, span, prior_type_ascription: _ } = mac; + let Mac { path, args, span, prior_type_ascription: _ } = mac; vis.visit_path(path); - vis.visit_tts(tts); + visit_mac_args(args, vis); vis.visit_span(span); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 0d2e8dddce671..416704e255eac 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1,6 +1,6 @@ use crate::ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax}; use crate::ast::{SelfKind, GenericBound, TraitBoundModifier}; -use crate::ast::{Attribute, MacDelimiter, GenericArg}; +use crate::ast::{Attribute, GenericArg}; use crate::util::parser::{self, AssocOp, Fixity}; use crate::util::comments; use crate::attr; @@ -1097,9 +1097,8 @@ impl<'a> State<'a> { } ast::ForeignItemKind::Macro(ref m) => { self.print_mac(m); - match m.delim { - MacDelimiter::Brace => {}, - _ => self.s.word(";") + if m.args.need_semicolon() { + self.s.word(";"); } } } @@ -1361,9 +1360,8 @@ impl<'a> State<'a> { } ast::ItemKind::Mac(ref mac) => { self.print_mac(mac); - match mac.delim { - MacDelimiter::Brace => {} - _ => self.s.word(";"), + if mac.args.need_semicolon() { + self.s.word(";"); } } ast::ItemKind::MacroDef(ref macro_def) => { @@ -1578,9 +1576,8 @@ impl<'a> State<'a> { } ast::TraitItemKind::Macro(ref mac) => { self.print_mac(mac); - match mac.delim { - MacDelimiter::Brace => {} - _ => self.s.word(";"), + if mac.args.need_semicolon() { + self.s.word(";"); } } } @@ -1608,9 +1605,8 @@ impl<'a> State<'a> { } ast::ImplItemKind::Macro(ref mac) => { self.print_mac(mac); - match mac.delim { - MacDelimiter::Brace => {} - _ => self.s.word(";"), + if mac.args.need_semicolon() { + self.s.word(";"); } } } @@ -1775,7 +1771,7 @@ impl<'a> State<'a> { Some(MacHeader::Path(&m.path)), true, None, - m.delim.to_token(), + m.args.delim(), m.stream(), true, m.span, diff --git a/src/libsyntax_expand/mbe/transcribe.rs b/src/libsyntax_expand/mbe/transcribe.rs index 4092d4b97de04..a1157667df1b4 100644 --- a/src/libsyntax_expand/mbe/transcribe.rs +++ b/src/libsyntax_expand/mbe/transcribe.rs @@ -30,13 +30,6 @@ impl MutVisitor for Marker { } } -impl Marker { - fn visit_delim_span(&mut self, dspan: &mut DelimSpan) { - self.visit_span(&mut dspan.open); - self.visit_span(&mut dspan.close); - } -} - /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). enum Frame { Delimited { forest: Lrc, idx: usize, span: DelimSpan }, @@ -271,7 +264,7 @@ pub(super) fn transcribe( // jump back out of the Delimited, pop the result_stack and add the new results back to // the previous results (from outside the Delimited). mbe::TokenTree::Delimited(mut span, delimited) => { - marker.visit_delim_span(&mut span); + mut_visit::visit_delim_span(&mut span, &mut marker); stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); result_stack.push(mem::take(&mut result)); } diff --git a/src/libsyntax_expand/placeholders.rs b/src/libsyntax_expand/placeholders.rs index 6cbe8c132457c..11fe860fc8102 100644 --- a/src/libsyntax_expand/placeholders.rs +++ b/src/libsyntax_expand/placeholders.rs @@ -3,7 +3,6 @@ use crate::expand::{AstFragment, AstFragmentKind}; use syntax::ast; use syntax::source_map::{DUMMY_SP, dummy_spanned}; -use syntax::tokenstream::TokenStream; use syntax::mut_visit::*; use syntax::ptr::P; use syntax::ThinVec; @@ -17,8 +16,7 @@ pub fn placeholder(kind: AstFragmentKind, id: ast::NodeId, vis: Option ast::Mac { ast::Mac { path: ast::Path { span: DUMMY_SP, segments: Vec::new() }, - tts: TokenStream::default().into(), - delim: ast::MacDelimiter::Brace, + args: P(ast::MacArgs::Empty), span: DUMMY_SP, prior_type_ascription: None, } diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index c4f3c03813fcd..9b9b7fd386f36 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -6,7 +6,7 @@ use syntax::token::{self, TokenKind}; use syntax::print::pprust; use syntax::ptr::P; use syntax::symbol::{sym, Symbol}; -use syntax::tokenstream::{TokenStream, TokenTree}; +use syntax::tokenstream::{DelimSpan, TokenStream, TokenTree}; use syntax_expand::base::*; use syntax_pos::{Span, DUMMY_SP}; @@ -26,18 +26,19 @@ pub fn expand_assert<'cx>( // `core::panic` and `std::panic` are different macros, so we use call-site // context to pick up whichever is currently in scope. let sp = cx.with_call_site_ctxt(sp); + let tokens = custom_message.unwrap_or_else(|| { + TokenStream::from(TokenTree::token( + TokenKind::lit(token::Str, Symbol::intern(&format!( + "assertion failed: {}", + pprust::expr_to_string(&cond_expr).escape_debug() + )), None), + DUMMY_SP, + )) + }); + let args = P(MacArgs::Delimited(DelimSpan::from_single(sp), MacDelimiter::Parenthesis, tokens)); let panic_call = Mac { path: Path::from_ident(Ident::new(sym::panic, sp)), - tts: custom_message.unwrap_or_else(|| { - TokenStream::from(TokenTree::token( - TokenKind::lit(token::Str, Symbol::intern(&format!( - "assertion failed: {}", - pprust::expr_to_string(&cond_expr).escape_debug() - )), None), - DUMMY_SP, - )) - }).into(), - delim: MacDelimiter::Parenthesis, + args, span: sp, prior_type_ascription: None, }; diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index 111078abb3700..f536d8f940a93 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -11,9 +11,9 @@ macro_rules! foo{ pub fn main() { foo!(); - assert!({one! two()}); //~ ERROR expected open delimiter + assert!({one! two()}); //~ ERROR expected one of `(`, `[`, or `{`, found `two` // regardless of whether nested macro_rules works, the following should at // least throw a conventional error. - assert!({one! two}); //~ ERROR expected open delimiter + assert!({one! two}); //~ ERROR expected one of `(`, `[`, or `{`, found `two` } diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index 73f948107f185..cc048445871a4 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,14 +1,14 @@ -error: expected open delimiter +error: expected one of `(`, `[`, or `{`, found `two` --> $DIR/issue-10536.rs:14:19 | LL | assert!({one! two()}); - | ^^^ expected open delimiter + | ^^^ expected one of `(`, `[`, or `{` -error: expected open delimiter +error: expected one of `(`, `[`, or `{`, found `two` --> $DIR/issue-10536.rs:18:19 | LL | assert!({one! two}); - | ^^^ expected open delimiter + | ^^^ expected one of `(`, `[`, or `{` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.rs b/src/test/ui/parser/macro-bad-delimiter-ident.rs index 13dec95435be0..f461f06b4dca6 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.rs +++ b/src/test/ui/parser/macro-bad-delimiter-ident.rs @@ -1,3 +1,3 @@ fn main() { - foo! bar < //~ ERROR expected open delimiter + foo! bar < //~ ERROR expected one of `(`, `[`, or `{`, found `bar` } diff --git a/src/test/ui/parser/macro-bad-delimiter-ident.stderr b/src/test/ui/parser/macro-bad-delimiter-ident.stderr index e97839a4f4a52..f2365fed273b1 100644 --- a/src/test/ui/parser/macro-bad-delimiter-ident.stderr +++ b/src/test/ui/parser/macro-bad-delimiter-ident.stderr @@ -1,8 +1,8 @@ -error: expected open delimiter +error: expected one of `(`, `[`, or `{`, found `bar` --> $DIR/macro-bad-delimiter-ident.rs:2:10 | LL | foo! bar < - | ^^^ expected open delimiter + | ^^^ expected one of `(`, `[`, or `{` error: aborting due to previous error