Skip to content

Commit 86b55f1

Browse files
committed
Add spacing to DelimArgs.
This improves pretty printing. Most notably, the `FIXME` for suboptimal printing of `use` groups in `tests/ui/macros/stringify.rs` is fixed. And all other test output changes result in pretty printed output being closer to the original formatting in the source code.
1 parent 1741890 commit 86b55f1

File tree

20 files changed

+87
-53
lines changed

20 files changed

+87
-53
lines changed

compiler/rustc_ast/src/ast.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use thin_vec::{ThinVec, thin_vec};
3838
pub use crate::format::*;
3939
use crate::ptr::P;
4040
use crate::token::{self, CommentKind, Delimiter};
41-
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, TokenStream};
41+
use crate::tokenstream::{DelimSpan, LazyAttrTokenStream, Spacing, TokenStream};
4242
use crate::util::parser::{ExprPrecedence, Fixity};
4343

4444
/// A "Label" is an identifier of some point in sources,
@@ -1930,6 +1930,10 @@ impl AttrArgs {
19301930
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
19311931
pub struct DelimArgs {
19321932
pub dspan: DelimSpan,
1933+
// The spacing after the open delimiter. Used when pretty-printing to
1934+
// decide whether to put a space after the opening delim and a space before
1935+
// the closing delim.
1936+
pub open_spacing: Spacing,
19331937
pub delim: Delimiter, // Note: `Delimiter::Invisible` never occurs
19341938
pub tokens: TokenStream,
19351939
}

compiler/rustc_ast/src/attr/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -483,9 +483,12 @@ impl MetaItemKind {
483483
fn from_attr_args(args: &AttrArgs) -> Option<MetaItemKind> {
484484
match args {
485485
AttrArgs::Empty => Some(MetaItemKind::Word),
486-
AttrArgs::Delimited(DelimArgs { dspan: _, delim: Delimiter::Parenthesis, tokens }) => {
487-
MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List)
488-
}
486+
AttrArgs::Delimited(DelimArgs {
487+
dspan: _,
488+
open_spacing: _,
489+
delim: Delimiter::Parenthesis,
490+
tokens,
491+
}) => MetaItemKind::list_from_tokens(tokens.clone()).map(MetaItemKind::List),
489492
AttrArgs::Delimited(..) => None,
490493
AttrArgs::Eq { expr, .. } => match expr.kind {
491494
ExprKind::Lit(token_lit) => {
@@ -679,6 +682,7 @@ pub fn mk_attr_nested_word(
679682
let path = Path::from_ident(outer_ident);
680683
let attr_args = AttrArgs::Delimited(DelimArgs {
681684
dspan: DelimSpan::from_single(span),
685+
open_spacing: Spacing::Joint,
682686
delim: Delimiter::Parenthesis,
683687
tokens: inner_tokens,
684688
});

compiler/rustc_ast/src/mut_visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
473473

474474
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
475475
fn visit_delim_args<T: MutVisitor>(vis: &mut T, args: &mut DelimArgs) {
476-
let DelimArgs { dspan, delim: _, tokens } = args;
476+
let DelimArgs { dspan, open_spacing: _, delim: _, tokens } = args;
477477
visit_tts(vis, tokens);
478478
visit_delim_span(vis, dspan);
479479
}

compiler/rustc_ast_pretty/src/pprust/state.rs

+33-18
Original file line numberDiff line numberDiff line change
@@ -629,15 +629,17 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
629629
ast::Safety::Default | ast::Safety::Safe(_) => {}
630630
}
631631
match &item.args {
632-
AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common(
633-
Some(MacHeader::Path(&item.path)),
634-
false,
635-
None,
636-
*delim,
637-
tokens,
638-
true,
639-
span,
640-
),
632+
AttrArgs::Delimited(DelimArgs { dspan: _, open_spacing, delim, tokens }) => self
633+
.print_mac_common(
634+
Some(MacHeader::Path(&item.path)),
635+
false,
636+
None,
637+
*delim,
638+
*open_spacing,
639+
tokens,
640+
true,
641+
span,
642+
),
641643
AttrArgs::Empty => {
642644
self.print_path(&item.path, false, 0);
643645
}
@@ -679,6 +681,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
679681
false,
680682
None,
681683
*delim,
684+
spacing.open,
682685
tts,
683686
convert_dollar_crate,
684687
dspan.entire(),
@@ -735,6 +738,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
735738
has_bang: bool,
736739
ident: Option<Ident>,
737740
delim: Delimiter,
741+
open_spacing: Spacing,
738742
tts: &TokenStream,
739743
convert_dollar_crate: bool,
740744
span: Span,
@@ -760,16 +764,25 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
760764
self.nbsp();
761765
}
762766
self.word("{");
763-
if !tts.is_empty() {
767+
768+
// Respect `Alone` and print a space, unless the list is empty.
769+
let open_space = open_spacing == Spacing::Alone && !tts.is_empty();
770+
if open_space {
764771
self.space();
765772
}
766773
self.ibox(0);
767774
self.print_tts(tts, convert_dollar_crate);
768775
self.end();
769-
let empty = tts.is_empty();
770-
self.bclose(span, empty);
776+
777+
// Use `spacing.open` for the spacing *before* the closing
778+
// delim. Because spacing on delimiters is lost when going
779+
// through proc macros, and otherwise we can end up with ugly
780+
// cases like `{ x}`. Symmetry is better.
781+
self.bclose(span, !open_space);
771782
}
772783
delim => {
784+
// `open_spacing` is ignored. We never print spaces after
785+
// non-brace opening delims or before non-brace closing delims.
773786
let token_str = self.token_kind_to_string(&delim.as_open_token_kind());
774787
self.word(token_str);
775788
self.ibox(0);
@@ -799,6 +812,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
799812
has_bang,
800813
Some(*ident),
801814
macro_def.body.delim,
815+
macro_def.body.open_spacing,
802816
&macro_def.body.tokens,
803817
true,
804818
sp,
@@ -845,9 +859,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
845859
self.end(); // Close the head-box.
846860
}
847861

848-
fn bclose_maybe_open(&mut self, span: rustc_span::Span, empty: bool, close_box: bool) {
862+
fn bclose_maybe_open(&mut self, span: rustc_span::Span, no_space: bool, close_box: bool) {
849863
let has_comment = self.maybe_print_comment(span.hi());
850-
if !empty || has_comment {
864+
if !no_space || has_comment {
851865
self.break_offset_if_not_bol(1, -INDENT_UNIT);
852866
}
853867
self.word("}");
@@ -856,9 +870,9 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
856870
}
857871
}
858872

859-
fn bclose(&mut self, span: rustc_span::Span, empty: bool) {
873+
fn bclose(&mut self, span: rustc_span::Span, no_space: bool) {
860874
let close_box = true;
861-
self.bclose_maybe_open(span, empty, close_box)
875+
self.bclose_maybe_open(span, no_space, close_box)
862876
}
863877

864878
fn break_offset_if_not_bol(&mut self, n: usize, off: isize) {
@@ -1420,8 +1434,8 @@ impl<'a> State<'a> {
14201434
}
14211435
}
14221436

1423-
let empty = !has_attrs && blk.stmts.is_empty();
1424-
self.bclose_maybe_open(blk.span, empty, close_box);
1437+
let no_space = !has_attrs && blk.stmts.is_empty();
1438+
self.bclose_maybe_open(blk.span, no_space, close_box);
14251439
self.ann.post(self, AnnNode::Block(blk))
14261440
}
14271441

@@ -1468,6 +1482,7 @@ impl<'a> State<'a> {
14681482
true,
14691483
None,
14701484
m.args.delim,
1485+
m.args.open_spacing,
14711486
&m.args.tokens,
14721487
true,
14731488
m.span(),

compiler/rustc_builtin_macros/src/assert.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod context;
22

33
use rustc_ast::ptr::P;
44
use rustc_ast::token::Delimiter;
5-
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
5+
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream};
66
use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, Path, PathSegment, UnOp, token};
77
use rustc_ast_pretty::pprust;
88
use rustc_errors::PResult;
@@ -59,6 +59,7 @@ pub(crate) fn expand_assert<'cx>(
5959
path: panic_path(),
6060
args: P(DelimArgs {
6161
dspan: DelimSpan::from_single(call_site_span),
62+
open_spacing: Spacing::Joint,
6263
delim: Delimiter::Parenthesis,
6364
tokens,
6465
}),

compiler/rustc_builtin_macros/src/assert/context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::ptr::P;
22
use rustc_ast::token::{self, Delimiter, IdentIsRaw};
3-
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
3+
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree};
44
use rustc_ast::{
55
BinOpKind, BorrowKind, DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, ItemKind, MacCall, MethodCall,
66
Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind,
@@ -180,6 +180,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
180180
path: panic_path,
181181
args: P(DelimArgs {
182182
dspan: DelimSpan::from_single(self.span),
183+
open_spacing: Spacing::Joint,
183184
delim: Delimiter::Parenthesis,
184185
tokens: initial.into_iter().chain(captures).collect::<TokenStream>(),
185186
}),

compiler/rustc_builtin_macros/src/autodiff.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,10 @@ mod llvm_enzyme {
323323
Spacing::Joint,
324324
)];
325325
let never_arg = ast::DelimArgs {
326-
dspan: ast::tokenstream::DelimSpan::from_single(span),
326+
dspan: DelimSpan::from_single(span),
327+
open_spacing: Spacing::Joint,
327328
delim: ast::token::Delimiter::Parenthesis,
328-
tokens: ast::tokenstream::TokenStream::from_iter(ts2),
329+
tokens: TokenStream::from_iter(ts2),
329330
};
330331
let inline_item = ast::AttrItem {
331332
unsafety: ast::Safety::Default,
@@ -395,6 +396,7 @@ mod llvm_enzyme {
395396
// Now update for d_fn
396397
rustc_ad_attr.item.args = rustc_ast::AttrArgs::Delimited(rustc_ast::DelimArgs {
397398
dspan: DelimSpan::dummy(),
399+
open_spacing: Spacing::Joint,
398400
delim: rustc_ast::token::Delimiter::Parenthesis,
399401
tokens: ts,
400402
});

compiler/rustc_builtin_macros/src/edition_panic.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_ast::ptr::P;
22
use rustc_ast::token::Delimiter;
3-
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
3+
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream};
44
use rustc_ast::*;
55
use rustc_expand::base::*;
66
use rustc_span::edition::Edition;
@@ -60,6 +60,7 @@ fn expand<'cx>(
6060
},
6161
args: P(DelimArgs {
6262
dspan: DelimSpan::from_single(sp),
63+
open_spacing: Spacing::Joint,
6364
delim: Delimiter::Parenthesis,
6465
tokens: tts,
6566
}),

compiler/rustc_expand/src/build.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_ast::ptr::P;
22
use rustc_ast::util::literal;
33
use rustc_ast::{
44
self as ast, AnonConst, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp,
5-
attr, token,
5+
attr, token, tokenstream,
66
};
77
use rustc_span::source_map::Spanned;
88
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
@@ -54,14 +54,16 @@ impl<'a> ExtCtxt<'a> {
5454
pub fn macro_call(
5555
&self,
5656
span: Span,
57+
open_spacing: tokenstream::Spacing,
5758
path: ast::Path,
58-
delim: ast::token::Delimiter,
59-
tokens: ast::tokenstream::TokenStream,
59+
delim: token::Delimiter,
60+
tokens: tokenstream::TokenStream,
6061
) -> P<ast::MacCall> {
6162
P(ast::MacCall {
6263
path,
6364
args: P(ast::DelimArgs {
64-
dspan: ast::tokenstream::DelimSpan { open: span, close: span },
65+
dspan: tokenstream::DelimSpan { open: span, close: span },
66+
open_spacing,
6567
delim,
6668
tokens,
6769
}),
@@ -476,12 +478,13 @@ impl<'a> ExtCtxt<'a> {
476478
span,
477479
self.macro_call(
478480
span,
481+
tokenstream::Spacing::Joint,
479482
self.path_global(
480483
span,
481484
[sym::std, sym::unreachable].map(|s| Ident::new(s, span)).to_vec(),
482485
),
483-
ast::token::Delimiter::Parenthesis,
484-
ast::tokenstream::TokenStream::default(),
486+
token::Delimiter::Parenthesis,
487+
tokenstream::TokenStream::default(),
485488
),
486489
)
487490
}

compiler/rustc_expand/src/placeholders.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_ast::mut_visit::*;
22
use rustc_ast::ptr::P;
33
use rustc_ast::token::Delimiter;
4+
use rustc_ast::tokenstream::Spacing;
45
use rustc_ast::visit::AssocCtxt;
56
use rustc_ast::{self as ast, Safety};
67
use rustc_data_structures::fx::FxHashMap;
@@ -20,6 +21,7 @@ pub(crate) fn placeholder(
2021
path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None },
2122
args: P(ast::DelimArgs {
2223
dspan: ast::tokenstream::DelimSpan::dummy(),
24+
open_spacing: Spacing::Joint,
2325
delim: Delimiter::Parenthesis,
2426
tokens: ast::tokenstream::TokenStream::new(Vec::new()),
2527
}),

compiler/rustc_hir_pretty/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,13 @@ impl<'a> State<'a> {
140140
};
141141

142142
match &item.args {
143-
hir::AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self
143+
hir::AttrArgs::Delimited(DelimArgs { dspan: _, open_spacing, delim, tokens }) => self
144144
.print_mac_common(
145145
Some(MacHeader::Path(&path)),
146146
false,
147147
None,
148148
*delim,
149+
*open_spacing,
149150
&tokens,
150151
true,
151152
span,

compiler/rustc_parse/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ pub fn parse_cfg_attr(
225225
<https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";
226226

227227
match cfg_attr.get_normal_item().args {
228-
ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
228+
ast::AttrArgs::Delimited(ast::DelimArgs { dspan, open_spacing: _, delim, ref tokens })
229229
if !tokens.is_empty() =>
230230
{
231231
crate::validate_attr::check_cfg_attr_bad_delim(psess, dspan, delim);

compiler/rustc_parse/src/parser/item.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ast::token::IdentIsRaw;
55
use rustc_ast::ast::*;
66
use rustc_ast::ptr::P;
77
use rustc_ast::token::{self, Delimiter, InvisibleOrigin, MetaVarKind, TokenKind};
8-
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
8+
use rustc_ast::tokenstream::{DelimSpan, Spacing, TokenStream, TokenTree};
99
use rustc_ast::util::case::Case;
1010
use rustc_ast::{self as ast};
1111
use rustc_ast_pretty::pprust;
@@ -2198,7 +2198,7 @@ impl<'a> Parser<'a> {
21982198
let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>`
21992199
let tokens = TokenStream::new(vec![params, arrow, body]);
22002200
let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi());
2201-
P(DelimArgs { dspan, delim: Delimiter::Brace, tokens })
2201+
P(DelimArgs { dspan, open_spacing: Spacing::Alone, delim: Delimiter::Brace, tokens })
22022202
} else {
22032203
self.unexpected_any()?
22042204
};

compiler/rustc_parse/src/parser/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1464,10 +1464,11 @@ impl<'a> Parser<'a> {
14641464
|| self.check(exp!(OpenBrace));
14651465

14661466
delimited.then(|| {
1467-
let TokenTree::Delimited(dspan, _, delim, tokens) = self.parse_token_tree() else {
1467+
let TokenTree::Delimited(dspan, spacing, delim, tokens) = self.parse_token_tree()
1468+
else {
14681469
unreachable!()
14691470
};
1470-
DelimArgs { dspan, delim, tokens }
1471+
DelimArgs { dspan, open_spacing: spacing.open, delim, tokens }
14711472
})
14721473
}
14731474

compiler/rustc_parse/src/validate_attr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub fn parse_meta<'a>(psess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Met
6464
path: item.path.clone(),
6565
kind: match &item.args {
6666
AttrArgs::Empty => MetaItemKind::Word,
67-
AttrArgs::Delimited(DelimArgs { dspan, delim, tokens }) => {
67+
AttrArgs::Delimited(DelimArgs { dspan, open_spacing: _, delim, tokens }) => {
6868
check_meta_bad_delim(psess, *dspan, *delim);
6969
let nmis =
7070
parse_in(psess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?;

tests/ui/macros/stringify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ fn test_item() {
356356
c1!(item, [ pub extern crate self as std; ], "pub extern crate self as std;");
357357

358358
// ItemKind::Use
359-
c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{ a, b::c };"); // FIXME
359+
c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{a, b::c};");
360360
c1!(item, [ pub use crate::{ e, ff }; ], "pub use crate::{ e, ff };");
361361
c1!(item, [ pub use A::*; ], "pub use A::*;");
362362

@@ -491,7 +491,7 @@ fn test_item() {
491491
c1!(item, [ mac! {} ], "mac! {}");
492492
c1!(item, [ mac!(...); ], "mac!(...);");
493493
c1!(item, [ mac![...]; ], "mac![...];");
494-
c1!(item, [ mac! {...} ], "mac! { ... }");
494+
c1!(item, [ mac! {...} ], "mac! {...}");
495495

496496
// ItemKind::MacroDef
497497
c1!(item,

0 commit comments

Comments
 (0)