diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 985359e1234e8..0d9178b5e2c93 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -634,6 +634,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere false, None, *delim, + None, tokens, true, span, @@ -679,6 +680,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere false, None, *delim, + Some(spacing.open), tts, convert_dollar_crate, dspan.entire(), @@ -735,6 +737,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere has_bang: bool, ident: Option, delim: Delimiter, + open_spacing: Option, tts: &TokenStream, convert_dollar_crate: bool, span: Span, @@ -758,16 +761,26 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.nbsp(); } self.word("{"); - if !tts.is_empty() { + + // Respect `Alone`, if provided, and print a space. Unless the list is empty. + let open_space = (open_spacing == None || open_spacing == Some(Spacing::Alone)) + && !tts.is_empty(); + if open_space { self.space(); } let ib = self.ibox(0); self.print_tts(tts, convert_dollar_crate); self.end(ib); - let empty = tts.is_empty(); - self.bclose(span, empty, cb.unwrap()); + + // Use `open_space` for the spacing *before* the closing delim. + // Because spacing on delimiters is lost when going through + // proc macros, and otherwise we can end up with ugly cases + // like `{ x}`. Symmetry is better. + self.bclose(span, !open_space, cb.unwrap()); } delim => { + // `open_spacing` is ignored. We never print spaces after + // non-brace opening delims or before non-brace closing delims. let token_str = self.token_kind_to_string(&delim.as_open_token_kind()); self.word(token_str); let ib = self.ibox(0); @@ -797,6 +810,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere has_bang, Some(*ident), macro_def.body.delim, + None, ¯o_def.body.tokens, true, sp, @@ -844,9 +858,9 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.end(ib); } - fn bclose_maybe_open(&mut self, span: rustc_span::Span, empty: bool, cb: Option) { + fn bclose_maybe_open(&mut self, span: rustc_span::Span, no_space: bool, cb: Option) { let has_comment = self.maybe_print_comment(span.hi()); - if !empty || has_comment { + if !no_space || has_comment { self.break_offset_if_not_bol(1, -INDENT_UNIT); } self.word("}"); @@ -855,9 +869,9 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } } - fn bclose(&mut self, span: rustc_span::Span, empty: bool, cb: BoxMarker) { + fn bclose(&mut self, span: rustc_span::Span, no_space: bool, cb: BoxMarker) { let cb = Some(cb); - self.bclose_maybe_open(span, empty, cb) + self.bclose_maybe_open(span, no_space, cb) } fn break_offset_if_not_bol(&mut self, n: usize, off: isize) { @@ -1423,8 +1437,8 @@ impl<'a> State<'a> { } } - let empty = !has_attrs && blk.stmts.is_empty(); - self.bclose_maybe_open(blk.span, empty, cb); + let no_space = !has_attrs && blk.stmts.is_empty(); + self.bclose_maybe_open(blk.span, no_space, cb); self.ann.post(self, AnnNode::Block(blk)) } @@ -1471,6 +1485,7 @@ impl<'a> State<'a> { true, None, m.args.delim, + None, &m.args.tokens, true, m.span(), diff --git a/compiler/rustc_builtin_macros/src/autodiff.rs b/compiler/rustc_builtin_macros/src/autodiff.rs index 6d97dfa3a4d41..8c5c20c7af48c 100644 --- a/compiler/rustc_builtin_macros/src/autodiff.rs +++ b/compiler/rustc_builtin_macros/src/autodiff.rs @@ -323,9 +323,9 @@ mod llvm_enzyme { Spacing::Joint, )]; let never_arg = ast::DelimArgs { - dspan: ast::tokenstream::DelimSpan::from_single(span), + dspan: DelimSpan::from_single(span), delim: ast::token::Delimiter::Parenthesis, - tokens: ast::tokenstream::TokenStream::from_iter(ts2), + tokens: TokenStream::from_iter(ts2), }; let inline_item = ast::AttrItem { unsafety: ast::Safety::Default, diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 6d616cf84bbd4..14b8cc90d97d6 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -1,8 +1,10 @@ use rustc_ast::ptr::P; +use rustc_ast::token::Delimiter; +use rustc_ast::tokenstream::TokenStream; use rustc_ast::util::literal; use rustc_ast::{ self as ast, AnonConst, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp, - attr, token, + attr, token, tokenstream, }; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -55,13 +57,13 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, path: ast::Path, - delim: ast::token::Delimiter, - tokens: ast::tokenstream::TokenStream, + delim: Delimiter, + tokens: TokenStream, ) -> P { P(ast::MacCall { path, args: P(ast::DelimArgs { - dspan: ast::tokenstream::DelimSpan { open: span, close: span }, + dspan: tokenstream::DelimSpan { open: span, close: span }, delim, tokens, }), @@ -480,8 +482,8 @@ impl<'a> ExtCtxt<'a> { span, [sym::std, sym::unreachable].map(|s| Ident::new(s, span)).to_vec(), ), - ast::token::Delimiter::Parenthesis, - ast::tokenstream::TokenStream::default(), + Delimiter::Parenthesis, + TokenStream::default(), ), ) } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b878147522dc8..d5ae8f7a95479 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -146,6 +146,7 @@ impl<'a> State<'a> { false, None, *delim, + None, &tokens, true, span, diff --git a/tests/ui/macros/stringify.rs b/tests/ui/macros/stringify.rs index 3490d3efc5992..3f3d9252adbe8 100644 --- a/tests/ui/macros/stringify.rs +++ b/tests/ui/macros/stringify.rs @@ -288,6 +288,9 @@ fn test_expr() { // ExprKind::OffsetOf: untestable because this test works pre-expansion. // ExprKind::MacCall + c1!(expr, [ mac!() ], "mac!()"); + c1!(expr, [ mac![] ], "mac![]"); + c1!(expr, [ mac! {} ], "mac! {}"); c1!(expr, [ mac!(...) ], "mac!(...)"); c1!(expr, [ mac![...] ], "mac![...]"); c1!(expr, [ mac! { ... } ], "mac! { ... }"); @@ -353,7 +356,8 @@ fn test_item() { c1!(item, [ pub extern crate self as std; ], "pub extern crate self as std;"); // ItemKind::Use - c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{ a, b::c };"); // FIXME + c1!(item, [ pub use crate::{a, b::c}; ], "pub use crate::{a, b::c};"); + c1!(item, [ pub use crate::{ e, ff }; ], "pub use crate::{ e, ff };"); c1!(item, [ pub use A::*; ], "pub use A::*;"); // ItemKind::Static @@ -482,9 +486,12 @@ fn test_item() { c1!(item, [ impl ~const Struct {} ], "impl ~const Struct {}"); // ItemKind::MacCall + c1!(item, [ mac!(); ], "mac!();"); + c1!(item, [ mac![]; ], "mac![];"); + c1!(item, [ mac! {} ], "mac! {}"); c1!(item, [ mac!(...); ], "mac!(...);"); c1!(item, [ mac![...]; ], "mac![...];"); - c1!(item, [ mac! { ... } ], "mac! { ... }"); + c1!(item, [ mac! {...} ], "mac! {...}"); // ItemKind::MacroDef c1!(item, @@ -598,8 +605,11 @@ fn test_pat() { c1!(pat, [ (pat) ], "(pat)"); // PatKind::MacCall + c1!(pat, [ mac!() ], "mac!()"); + c1!(pat, [ mac![] ], "mac![]"); + c1!(pat, [ mac! {} ], "mac! {}"); c1!(pat, [ mac!(...) ], "mac!(...)"); - c1!(pat, [ mac![...] ], "mac![...]"); + c1!(pat, [ mac! [ ... ] ], "mac! [...]"); c1!(pat, [ mac! { ... } ], "mac! { ... }"); // Attributes are not allowed on patterns. @@ -644,6 +654,9 @@ fn test_stmt() { c1!(stmt, [ ; ], ";"); // StmtKind::MacCall + c1!(stmt, [ mac! ( ) ], "mac! ()"); + c1!(stmt, [ mac![] ], "mac![]"); + c1!(stmt, [ mac!{} ], "mac!{}"); c1!(stmt, [ mac!(...) ], "mac!(...)"); c1!(stmt, [ mac![...] ], "mac![...]"); c1!(stmt, [ mac! { ... } ], "mac! { ... }"); @@ -739,6 +752,9 @@ fn test_ty() { // TyKind::ImplicitSelf: there is no syntax for this. // TyKind::MacCall + c1!(ty, [ mac!() ], "mac!()"); + c1!(ty, [ mac![] ], "mac![]"); + c1!(ty, [ mac! { } ], "mac! {}"); c1!(ty, [ mac!(...) ], "mac!(...)"); c1!(ty, [ mac![...] ], "mac![...]"); c1!(ty, [ mac! { ... } ], "mac! { ... }"); diff --git a/tests/ui/macros/trace_faulty_macros.stderr b/tests/ui/macros/trace_faulty_macros.stderr index 73fed66e61906..e90d7a98db4c7 100644 --- a/tests/ui/macros/trace_faulty_macros.stderr +++ b/tests/ui/macros/trace_faulty_macros.stderr @@ -87,9 +87,9 @@ LL | let a = pat_macro!(); | ^^^^^^^^^^^^ | = note: expanding `pat_macro! { }` - = note: to `pat_macro! (A { a : a, b : 0, c : _, .. });` - = note: expanding `pat_macro! { A { a : a, b : 0, c : _, .. } }` - = note: to `A { a : a, b : 0, c : _, .. }` + = note: to `pat_macro! (A {a : a, b : 0, c : _, ..});` + = note: expanding `pat_macro! { A {a : a, b : 0, c : _, ..} }` + = note: to `A {a : a, b : 0, c : _, ..}` note: trace_macro --> $DIR/trace_faulty_macros.rs:53:5 diff --git a/tests/ui/proc-macro/attr-complex-fn.stdout b/tests/ui/proc-macro/attr-complex-fn.stdout index 7c23d1ecae45d..9bbb746bb4d62 100644 --- a/tests/ui/proc-macro/attr-complex-fn.stdout +++ b/tests/ui/proc-macro/attr-complex-fn.stdout @@ -77,7 +77,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ span: $DIR/attr-complex-fn.rs:19:42: 19:44 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): impl MyTrait for MyStruct<{ true }> { #![rustc_dummy] } +PRINT-ATTR INPUT (DISPLAY): impl MyTrait for MyStruct<{true}> { #![rustc_dummy] } PRINT-ATTR RE-COLLECTED (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { #![rustc_dummy] } PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { #! [rustc_dummy] } PRINT-ATTR INPUT (DEBUG): TokenStream [ diff --git a/tests/ui/proc-macro/weird-braces.stdout b/tests/ui/proc-macro/weird-braces.stdout index 7da769ef0d247..0215deb05c302 100644 --- a/tests/ui/proc-macro/weird-braces.stdout +++ b/tests/ui/proc-macro/weird-braces.stdout @@ -5,7 +5,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ span: $DIR/weird-braces.rs:16:25: 16:36 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second_outer)] impl Bar<{ 1 > 0 }> for Foo<{ true }> +PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second_outer)] impl Bar<{1 > 0}> for Foo<{true}> { #![print_target_and_args(first_inner)] #![print_target_and_args(second_inner)] @@ -191,7 +191,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ span: $DIR/weird-braces.rs:17:25: 17:37 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 }> for Foo<{ true }> +PRINT-ATTR INPUT (DISPLAY): impl Bar<{1 > 0}> for Foo<{true}> { #![print_target_and_args(first_inner)] #![print_target_and_args(second_inner)] @@ -350,8 +350,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ span: $DIR/weird-braces.rs:19:30: 19:41 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 }> for Foo<{ true }> -{ #![print_target_and_args(second_inner)] } +PRINT-ATTR INPUT (DISPLAY): impl Bar<{1 > 0}> for Foo<{true}> { #![print_target_and_args(second_inner)] } PRINT-ATTR RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } > { #![print_target_and_args(second_inner)] } PRINT-ATTR DEEP-RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } > @@ -470,7 +469,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [ span: $DIR/weird-braces.rs:20:30: 20:42 (#0), }, ] -PRINT-ATTR INPUT (DISPLAY): impl Bar<{ 1 > 0 }> for Foo<{ true }> {} +PRINT-ATTR INPUT (DISPLAY): impl Bar<{1 > 0}> for Foo<{true}> {} PRINT-ATTR RE-COLLECTED (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } > {} PRINT-ATTR INPUT (DEBUG): TokenStream [ Ident { diff --git a/tests/ui/unpretty/expanded-exhaustive.stdout b/tests/ui/unpretty/expanded-exhaustive.stdout index 841edf63c9191..c6ffbb0d316bb 100644 --- a/tests/ui/unpretty/expanded-exhaustive.stdout +++ b/tests/ui/unpretty/expanded-exhaustive.stdout @@ -505,7 +505,7 @@ mod items { mod item_mac_call { } /// ItemKind::MacroDef mod item_macro_def { - macro_rules! mac { () => { ... }; } + macro_rules! mac { () => {...}; } pub macro stringify { () => {} } } /// ItemKind::Delegation