Skip to content

Commit 7426f5c

Browse files
committed
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
2 parents b4463d7 + a137d00 commit 7426f5c

File tree

9 files changed

+156
-82
lines changed

9 files changed

+156
-82
lines changed

src/libsyntax/ast.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1244,9 +1244,17 @@ pub type Mac = Spanned<Mac_>;
12441244
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
12451245
pub struct Mac_ {
12461246
pub path: Path,
1247+
pub delim: MacDelimiter,
12471248
pub tts: ThinTokenStream,
12481249
}
12491250

1251+
#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
1252+
pub enum MacDelimiter {
1253+
Parenthesis,
1254+
Bracket,
1255+
Brace,
1256+
}
1257+
12501258
impl Mac_ {
12511259
pub fn stream(&self) -> TokenStream {
12521260
self.tts.clone().into()

src/libsyntax/ext/placeholders.rs

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub fn placeholder(kind: ExpansionKind, id: ast::NodeId) -> Expansion {
2727
dummy_spanned(ast::Mac_ {
2828
path: ast::Path { span: DUMMY_SP, segments: Vec::new() },
2929
tts: TokenStream::empty().into(),
30+
delim: ast::MacDelimiter::Brace,
3031
})
3132
}
3233

src/libsyntax/fold.rs

+1
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ pub fn noop_fold_mac<T: Folder>(Spanned {node, span}: Mac, fld: &mut T) -> Mac {
521521
node: Mac_ {
522522
tts: fld.fold_tts(node.stream()).into(),
523523
path: fld.fold_path(node.path),
524+
delim: node.delim,
524525
},
525526
span: fld.new_span(span)
526527
}

src/libsyntax/parse/parser.rs

+38-28
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
2626
use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind, UintTy};
2727
use ast::Local;
2828
use ast::MacStmtStyle;
29-
use ast::{Mac, Mac_};
29+
use ast::{Mac, Mac_, MacDelimiter};
3030
use ast::{MutTy, Mutability};
3131
use ast::{Pat, PatKind, PathSegment};
3232
use ast::{PolyTraitRef, QSelf};
@@ -1611,8 +1611,9 @@ impl<'a> Parser<'a> {
16111611
let path = self.parse_path(PathStyle::Type)?;
16121612
if self.eat(&token::Not) {
16131613
// Macro invocation in type position
1614-
let (_, tts) = self.expect_delimited_token_tree()?;
1615-
TyKind::Mac(respan(lo.to(self.prev_span), Mac_ { path: path, tts: tts }))
1614+
let (delim, tts) = self.expect_delimited_token_tree()?;
1615+
let node = Mac_ { path, tts, delim };
1616+
TyKind::Mac(respan(lo.to(self.prev_span), node))
16161617
} else {
16171618
// Just a type path or bound list (trait object type) starting with a trait.
16181619
// `Type`
@@ -2195,19 +2196,27 @@ impl<'a> Parser<'a> {
21952196
})
21962197
}
21972198

2198-
fn expect_delimited_token_tree(&mut self) -> PResult<'a, (token::DelimToken, ThinTokenStream)> {
2199-
match self.token {
2200-
token::OpenDelim(delim) => match self.parse_token_tree() {
2201-
TokenTree::Delimited(_, delimited) => Ok((delim, delimited.stream().into())),
2202-
_ => unreachable!(),
2203-
},
2199+
fn expect_delimited_token_tree(&mut self) -> PResult<'a, (MacDelimiter, ThinTokenStream)> {
2200+
let delim = match self.token {
2201+
token::OpenDelim(delim) => delim,
22042202
_ => {
22052203
let msg = "expected open delimiter";
22062204
let mut err = self.fatal(msg);
22072205
err.span_label(self.span, msg);
2208-
Err(err)
2206+
return Err(err)
22092207
}
2210-
}
2208+
};
2209+
let delimited = match self.parse_token_tree() {
2210+
TokenTree::Delimited(_, delimited) => delimited,
2211+
_ => unreachable!(),
2212+
};
2213+
let delim = match delim {
2214+
token::Paren => MacDelimiter::Parenthesis,
2215+
token::Bracket => MacDelimiter::Bracket,
2216+
token::Brace => MacDelimiter::Brace,
2217+
token::NoDelim => self.bug("unexpected no delimiter"),
2218+
};
2219+
Ok((delim, delimited.stream().into()))
22112220
}
22122221

22132222
/// At the bottom (top?) of the precedence hierarchy,
@@ -2420,9 +2429,10 @@ impl<'a> Parser<'a> {
24202429
// `!`, as an operator, is prefix, so we know this isn't that
24212430
if self.eat(&token::Not) {
24222431
// MACRO INVOCATION expression
2423-
let (_, tts) = self.expect_delimited_token_tree()?;
2432+
let (delim, tts) = self.expect_delimited_token_tree()?;
24242433
let hi = self.prev_span;
2425-
return Ok(self.mk_mac_expr(lo.to(hi), Mac_ { path: pth, tts: tts }, attrs));
2434+
let node = Mac_ { path: pth, tts, delim };
2435+
return Ok(self.mk_mac_expr(lo.to(hi), node, attrs))
24262436
}
24272437
if self.check(&token::OpenDelim(token::Brace)) {
24282438
// This is a struct literal, unless we're prohibited
@@ -3895,8 +3905,8 @@ impl<'a> Parser<'a> {
38953905
token::Not if qself.is_none() => {
38963906
// Parse macro invocation
38973907
self.bump();
3898-
let (_, tts) = self.expect_delimited_token_tree()?;
3899-
let mac = respan(lo.to(self.prev_span), Mac_ { path: path, tts: tts });
3908+
let (delim, tts) = self.expect_delimited_token_tree()?;
3909+
let mac = respan(lo.to(self.prev_span), Mac_ { path, tts, delim });
39003910
pat = PatKind::Mac(mac);
39013911
}
39023912
token::DotDotDot | token::DotDotEq | token::DotDot => {
@@ -4289,7 +4299,7 @@ impl<'a> Parser<'a> {
42894299

42904300
let ident = self.parse_ident()?;
42914301
let (delim, tokens) = self.expect_delimited_token_tree()?;
4292-
if delim != token::Brace {
4302+
if delim != MacDelimiter::Brace {
42934303
if !self.eat(&token::Semi) {
42944304
let msg = "macros that expand to items must either \
42954305
be surrounded with braces or followed by a semicolon";
@@ -4374,8 +4384,8 @@ impl<'a> Parser<'a> {
43744384
// check that we're pointing at delimiters (need to check
43754385
// again after the `if`, because of `parse_ident`
43764386
// consuming more tokens).
4377-
let delim = match self.token {
4378-
token::OpenDelim(delim) => delim,
4387+
match self.token {
4388+
token::OpenDelim(_) => {}
43794389
_ => {
43804390
// we only expect an ident if we didn't parse one
43814391
// above.
@@ -4391,20 +4401,20 @@ impl<'a> Parser<'a> {
43914401
err.span_label(self.span, format!("expected {}`(` or `{{`", ident_str));
43924402
return Err(err)
43934403
},
4394-
};
4404+
}
43954405

4396-
let (_, tts) = self.expect_delimited_token_tree()?;
4406+
let (delim, tts) = self.expect_delimited_token_tree()?;
43974407
let hi = self.prev_span;
43984408

4399-
let style = if delim == token::Brace {
4409+
let style = if delim == MacDelimiter::Brace {
44004410
MacStmtStyle::Braces
44014411
} else {
44024412
MacStmtStyle::NoBraces
44034413
};
44044414

44054415
if id.name == keywords::Invalid.name() {
4406-
let mac = respan(lo.to(hi), Mac_ { path: pth, tts: tts });
4407-
let node = if delim == token::Brace ||
4416+
let mac = respan(lo.to(hi), Mac_ { path: pth, tts, delim });
4417+
let node = if delim == MacDelimiter::Brace ||
44084418
self.token == token::Semi || self.token == token::Eof {
44094419
StmtKind::Mac(P((mac, style, attrs.into())))
44104420
}
@@ -4452,7 +4462,7 @@ impl<'a> Parser<'a> {
44524462
node: StmtKind::Item({
44534463
self.mk_item(
44544464
span, id /*id is good here*/,
4455-
ItemKind::Mac(respan(span, Mac_ { path: pth, tts: tts })),
4465+
ItemKind::Mac(respan(span, Mac_ { path: pth, tts, delim })),
44564466
respan(lo, VisibilityKind::Inherited),
44574467
attrs)
44584468
}),
@@ -6894,7 +6904,7 @@ impl<'a> Parser<'a> {
68946904
};
68956905
// eat a matched-delimiter token tree:
68966906
let (delim, tts) = self.expect_delimited_token_tree()?;
6897-
if delim != token::Brace {
6907+
if delim != MacDelimiter::Brace {
68986908
if !self.eat(&token::Semi) {
68996909
self.span_err(self.prev_span,
69006910
"macros that expand to items must either \
@@ -6904,7 +6914,7 @@ impl<'a> Parser<'a> {
69046914
}
69056915

69066916
let hi = self.prev_span;
6907-
let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts: tts });
6917+
let mac = respan(mac_lo.to(hi), Mac_ { path: pth, tts, delim });
69086918
let item = self.mk_item(lo.to(hi), id, ItemKind::Mac(mac), visibility, attrs);
69096919
return Ok(Some(item));
69106920
}
@@ -6948,11 +6958,11 @@ impl<'a> Parser<'a> {
69486958

69496959
// eat a matched-delimiter token tree:
69506960
let (delim, tts) = self.expect_delimited_token_tree()?;
6951-
if delim != token::Brace {
6961+
if delim != MacDelimiter::Brace {
69526962
self.expect(&token::Semi)?
69536963
}
69546964

6955-
Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts: tts })))
6965+
Ok(Some(respan(lo.to(self.prev_span), Mac_ { path: pth, tts, delim })))
69566966
} else {
69576967
Ok(None)
69586968
}

src/libsyntax/print/pprust.rs

+50-54
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use self::AnnNode::*;
1313
use rustc_target::spec::abi::{self, Abi};
1414
use ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
1515
use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
16-
use ast::Attribute;
16+
use ast::{Attribute, MacDelimiter};
1717
use util::parser::{self, AssocOp, Fixity};
1818
use attr;
1919
use codemap::{self, CodeMap};
@@ -422,7 +422,7 @@ pub fn arg_to_string(arg: &ast::Arg) -> String {
422422
}
423423

424424
pub fn mac_to_string(arg: &ast::Mac) -> String {
425-
to_string(|s| s.print_mac(arg, ::parse::token::Paren))
425+
to_string(|s| s.print_mac(arg))
426426
}
427427

428428
pub fn foreign_item_to_string(arg: &ast::ForeignItem) -> String {
@@ -1098,7 +1098,7 @@ impl<'a> State<'a> {
10981098
self.s.word("Self")?;
10991099
}
11001100
ast::TyKind::Mac(ref m) => {
1101-
self.print_mac(m, token::Paren)?;
1101+
self.print_mac(m)?;
11021102
}
11031103
}
11041104
self.end()
@@ -1140,8 +1140,11 @@ impl<'a> State<'a> {
11401140
self.end() // end the outer cbox
11411141
}
11421142
ast::ForeignItemKind::Macro(ref m) => {
1143-
self.print_mac(m, token::Paren)?;
1144-
self.s.word(";")
1143+
self.print_mac(m)?;
1144+
match m.node.delim {
1145+
MacDelimiter::Brace => Ok(()),
1146+
_ => self.s.word(";")
1147+
}
11451148
}
11461149
}
11471150
}
@@ -1394,16 +1397,24 @@ impl<'a> State<'a> {
13941397
self.print_where_clause(&generics.where_clause)?;
13951398
self.s.word(";")?;
13961399
}
1397-
ast::ItemKind::Mac(codemap::Spanned { ref node, .. }) => {
1398-
self.print_path(&node.path, false, 0)?;
1399-
self.s.word("! ")?;
1400-
self.print_ident(item.ident)?;
1401-
self.cbox(INDENT_UNIT)?;
1402-
self.popen()?;
1403-
self.print_tts(node.stream())?;
1404-
self.pclose()?;
1405-
self.s.word(";")?;
1406-
self.end()?;
1400+
ast::ItemKind::Mac(ref mac) => {
1401+
if item.ident.name == keywords::Invalid.name() {
1402+
self.print_mac(mac)?;
1403+
match mac.node.delim {
1404+
MacDelimiter::Brace => {}
1405+
_ => self.s.word(";")?,
1406+
}
1407+
} else {
1408+
self.print_path(&mac.node.path, false, 0)?;
1409+
self.s.word("! ")?;
1410+
self.print_ident(item.ident)?;
1411+
self.cbox(INDENT_UNIT)?;
1412+
self.popen()?;
1413+
self.print_tts(mac.node.stream())?;
1414+
self.pclose()?;
1415+
self.s.word(";")?;
1416+
self.end()?;
1417+
}
14071418
}
14081419
ast::ItemKind::MacroDef(ref tts) => {
14091420
self.s.word("macro_rules! ")?;
@@ -1609,16 +1620,12 @@ impl<'a> State<'a> {
16091620
self.print_associated_type(ti.ident, Some(bounds),
16101621
default.as_ref().map(|ty| &**ty))?;
16111622
}
1612-
ast::TraitItemKind::Macro(codemap::Spanned { ref node, .. }) => {
1613-
// code copied from ItemKind::Mac:
1614-
self.print_path(&node.path, false, 0)?;
1615-
self.s.word("! ")?;
1616-
self.cbox(INDENT_UNIT)?;
1617-
self.popen()?;
1618-
self.print_tts(node.stream())?;
1619-
self.pclose()?;
1620-
self.s.word(";")?;
1621-
self.end()?
1623+
ast::TraitItemKind::Macro(ref mac) => {
1624+
self.print_mac(mac)?;
1625+
match mac.node.delim {
1626+
MacDelimiter::Brace => {}
1627+
_ => self.s.word(";")?,
1628+
}
16221629
}
16231630
}
16241631
self.ann.post(self, NodeSubItem(ti.id))
@@ -1643,16 +1650,12 @@ impl<'a> State<'a> {
16431650
ast::ImplItemKind::Type(ref ty) => {
16441651
self.print_associated_type(ii.ident, None, Some(ty))?;
16451652
}
1646-
ast::ImplItemKind::Macro(codemap::Spanned { ref node, .. }) => {
1647-
// code copied from ItemKind::Mac:
1648-
self.print_path(&node.path, false, 0)?;
1649-
self.s.word("! ")?;
1650-
self.cbox(INDENT_UNIT)?;
1651-
self.popen()?;
1652-
self.print_tts(node.stream())?;
1653-
self.pclose()?;
1654-
self.s.word(";")?;
1655-
self.end()?
1653+
ast::ImplItemKind::Macro(ref mac) => {
1654+
self.print_mac(mac)?;
1655+
match mac.node.delim {
1656+
MacDelimiter::Brace => {}
1657+
_ => self.s.word(";")?,
1658+
}
16561659
}
16571660
}
16581661
self.ann.post(self, NodeSubItem(ii.id))
@@ -1695,11 +1698,7 @@ impl<'a> State<'a> {
16951698
let (ref mac, style, ref attrs) = **mac;
16961699
self.space_if_not_bol()?;
16971700
self.print_outer_attributes(attrs)?;
1698-
let delim = match style {
1699-
ast::MacStmtStyle::Braces => token::Brace,
1700-
_ => token::Paren
1701-
};
1702-
self.print_mac(mac, delim)?;
1701+
self.print_mac(mac)?;
17031702
if style == ast::MacStmtStyle::Semicolon {
17041703
self.s.word(";")?;
17051704
}
@@ -1829,25 +1828,22 @@ impl<'a> State<'a> {
18291828
self.print_else(elseopt)
18301829
}
18311830

1832-
pub fn print_mac(&mut self, m: &ast::Mac, delim: token::DelimToken)
1833-
-> io::Result<()> {
1831+
pub fn print_mac(&mut self, m: &ast::Mac) -> io::Result<()> {
18341832
self.print_path(&m.node.path, false, 0)?;
18351833
self.s.word("!")?;
1836-
match delim {
1837-
token::Paren => self.popen()?,
1838-
token::Bracket => self.s.word("[")?,
1839-
token::Brace => {
1834+
match m.node.delim {
1835+
MacDelimiter::Parenthesis => self.popen()?,
1836+
MacDelimiter::Bracket => self.s.word("[")?,
1837+
MacDelimiter::Brace => {
18401838
self.head("")?;
18411839
self.bopen()?;
18421840
}
1843-
token::NoDelim => {}
18441841
}
18451842
self.print_tts(m.node.stream())?;
1846-
match delim {
1847-
token::Paren => self.pclose(),
1848-
token::Bracket => self.s.word("]"),
1849-
token::Brace => self.bclose(m.span),
1850-
token::NoDelim => Ok(()),
1843+
match m.node.delim {
1844+
MacDelimiter::Parenthesis => self.pclose(),
1845+
MacDelimiter::Bracket => self.s.word("]"),
1846+
MacDelimiter::Brace => self.bclose(m.span),
18511847
}
18521848
}
18531849

@@ -2333,7 +2329,7 @@ impl<'a> State<'a> {
23332329

23342330
self.pclose()?;
23352331
}
2336-
ast::ExprKind::Mac(ref m) => self.print_mac(m, token::Paren)?,
2332+
ast::ExprKind::Mac(ref m) => self.print_mac(m)?,
23372333
ast::ExprKind::Paren(ref e) => {
23382334
self.popen()?;
23392335
self.print_inner_attributes_inline(attrs)?;
@@ -2660,7 +2656,7 @@ impl<'a> State<'a> {
26602656
self.print_pat(inner)?;
26612657
self.pclose()?;
26622658
}
2663-
PatKind::Mac(ref m) => self.print_mac(m, token::Paren)?,
2659+
PatKind::Mac(ref m) => self.print_mac(m)?,
26642660
}
26652661
self.ann.post(self, NodePat(pat))
26662662
}

src/libsyntax_ext/assert.rs

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub fn expand_assert<'cx>(
5353
),
5454
)).into()
5555
},
56+
delim: MacDelimiter::Parenthesis,
5657
};
5758
let if_expr = cx.expr_if(
5859
sp,

0 commit comments

Comments
 (0)