diff options
| author | bors <bors@rust-lang.org> | 2018-05-24 07:14:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-05-24 07:14:21 +0000 |
| commit | 7426f5ccf7b362785a5abeb365674d3da3d4df2e (patch) | |
| tree | 34352c2086a16c38dff8879a915d7d158f909b20 /src/libsyntax/parse | |
| parent | b4463d788bfd30b622a87a0e6f8e9271b9102e50 (diff) | |
| parent | a137d00ce52e9db78bb803d1384fdf3a4c4e63ea (diff) | |
| download | rust-7426f5ccf7b362785a5abeb365674d3da3d4df2e.tar.gz rust-7426f5ccf7b362785a5abeb365674d3da3d4df2e.zip | |
Auto merge of #50971 - alexcrichton:no-stringify, r=petrochenkov
rustc: Correctly pretty-print macro delimiters This commit updates the `Mac_` AST structure to keep track of the delimiters that it originally had for its invocation. This allows us to faithfully pretty-print macro invocations not using parentheses (e.g. `vec![...]`). This in turn helps procedural macros due to #43081. Closes #50840
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 1429d881fe9..9b9fcfa74b1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -26,7 +26,7 @@ use ast::{Ident, ImplItem, IsAuto, Item, ItemKind}; use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind, UintTy}; use ast::Local; use ast::MacStmtStyle; -use ast::{Mac, Mac_}; +use ast::{Mac, Mac_, MacDelimiter}; use ast::{MutTy, Mutability}; use ast::{Pat, PatKind, PathSegment}; use ast::{PolyTraitRef, QSelf}; @@ -1611,8 +1611,9 @@ impl<'a> Parser<'a> { let path = self.parse_path(PathStyle::Type)?; if self.eat(&token::Not) { // Macro invocation in type position - let (_, tts) = self.expect_delimited_token_tree()?; - TyKind::Mac(respan(lo.to(self.prev_span), Mac_ { path: path, tts: tts })) + let (delim, tts) = self.expect_delimited_token_tree()?; + let node = Mac_ { path, tts, delim }; + TyKind::Mac(respan(lo.to(self.prev_span), node)) } else { // Just a type path or bound list (trait object type) starting with a trait. // `Type` @@ -2195,19 +2196,27 @@ impl<'a> Parser<'a> { }) } - fn expect_delimited_token_tree(&mut self) -> PResult<'a, (token::DelimToken, ThinTokenStream)> { - match self.token { - token::OpenDelim(delim) => match self.parse_token_tree() { - TokenTree::Delimited(_, delimited) => Ok((delim, delimited.stream().into())), - _ => unreachable!(), - }, + fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, ThinTokenStream)> { + let delim = match self.token { + token::OpenDelim(delim) => delim, _ => { let msg = "expected open delimiter"; let mut err = self.fatal(msg); err.span_label(self.span, msg); - Err(err) + return Err(err) } - } + }; + let delimited = match self.parse_token_tree() { + TokenTree::Delimited(_, delimited) => delimited, + _ => 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, delimited.stream().into())) } /// At the bottom (top?) of the precedence hierarchy, @@ -2420,9 +2429,10 @@ 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 (_, tts) = self.expect_delimited_token_tree()?; + let (delim, tts) = self.expect_delimited_token_tree()?; let hi = self.prev_span; - return Ok(self.mk_mac_expr(lo.to(hi), Mac_ { path: pth, tts: tts }, attrs)); + let node = Mac_ { path: pth, tts, delim }; + return Ok(self.mk_mac_expr(lo.to(hi), node, attrs)) } if self.check(&token::OpenDelim(token::Brace)) { // This is a struct literal, unless we're prohibited @@ -3895,8 +3905,8 @@ impl<'a> Parser<'a> { token::Not if qself.is_none() => { // Parse macro invocation self.bump(); - let (_, tts) = self.expect_delimited_token_tree()?; - let mac = respan(lo.to(self.prev_span), Mac_ { path: path, tts: tts }); + let (delim, tts) = self.expect_delimited_token_tree()?; + let mac = respan(lo.to(self.prev_span), Mac_ { path, tts, delim }); pat = PatKind::Mac(mac); } token::DotDotDot | token::DotDotEq | token::DotDot => { @@ -4289,7 +4299,7 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != token::Brace { + if delim != MacDelimiter::Brace { if !self.eat(&token::Semi) { let msg = "macros that expand to items must either \ be surrounded with braces or followed by a semicolon"; @@ -4374,8 +4384,8 @@ impl<'a> Parser<'a> { // check that we're pointing at delimiters (need to check // again after the `if`, because of `parse_ident` // consuming more tokens). - let delim = match self.token { - token::OpenDelim(delim) => delim, + match self.token { + token::OpenDelim(_) => {} _ => { // we only expect an ident if we didn't parse one // above. @@ -4391,20 +4401,20 @@ impl<'a> Parser<'a> { err.span_label(self.span, format!("expected {}`(` or `{{`", ident_str)); return Err(err) }, - }; + } - let (_, tts) = self.expect_delimited_token_tree()?; + let (delim, tts) = self.expect_delimited_token_tree()?; let hi = self.prev_span; - let style = if delim == token::Brace { + let style = if delim == MacDelimiter::Brace { MacStmtStyle::Braces } else { MacStmtStyle::NoBraces }; if id.name == keywords::Invalid.name() { - let mac = respan(lo.to(hi), Mac_ { path: pth, tts: tts }); - let node = if delim == token::Brace || + let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim }); + let node = if delim == MacDelimiter::Brace || self.token == token::Semi || self.token == token::Eof { StmtKind::Mac(P((mac, style, attrs.into()))) } @@ -4452,7 +4462,7 @@ impl<'a> Parser<'a> { node: StmtKind::Item({ self.mk_item( span, id /*id is good here*/, - ItemKind::Mac(respan(span, Mac_ { path: pth, tts: tts })), + ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })), respan(lo, VisibilityKind::Inherited), attrs) }), @@ -6894,7 +6904,7 @@ impl<'a> Parser<'a> { }; // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != token::Brace { + if delim != MacDelimiter::Brace { if !self.eat(&token::Semi) { self.span_err(self.prev_span, "macros that expand to items must either \ @@ -6904,7 +6914,7 @@ impl<'a> Parser<'a> { } let hi = self.prev_span; - let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts: tts }); + let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim }); let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs); return Ok(Some(item)); } @@ -6948,11 +6958,11 @@ impl<'a> Parser<'a> { // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != token::Brace { + if delim != MacDelimiter::Brace { self.expect(&token::Semi)? } - Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts: tts }))) + Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim }))) } else { Ok(None) } |
