diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 0e42e0e3793f5..a7908f7006062 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -140,12 +140,15 @@ pub fn print_crate<'a>(
 // and also addresses some specific regressions described in #63896 and #73345.
 fn tt_prepend_space(tt: &TokenTree, prev: &TokenTree) -> bool {
     if let TokenTree::Token(token) = prev {
+        if matches!(token.kind, token::Dot) {
+            return false;
+        }
         if let token::DocComment(comment_kind, ..) = token.kind {
             return comment_kind != CommentKind::Line;
         }
     }
     match tt {
-        TokenTree::Token(token) => token.kind != token::Comma,
+        TokenTree::Token(token) => !matches!(token.kind, token::Comma | token::Not | token::Dot),
         TokenTree::Delimited(_, DelimToken::Paren, _) => {
             !matches!(prev, TokenTree::Token(Token { kind: token::Ident(..), .. }))
         }
diff --git a/src/test/pretty/ast-stmt-expr-attr.rs b/src/test/pretty/ast-stmt-expr-attr.rs
index de42a8c4ed5ed..fb406514f4b5e 100644
--- a/src/test/pretty/ast-stmt-expr-attr.rs
+++ b/src/test/pretty/ast-stmt-expr-attr.rs
@@ -114,11 +114,11 @@ fn syntax() {
     let _ = #[attr] continue ;
     let _ = #[attr] return;
     let _ = #[attr] foo!();
-    let _ = #[attr] foo!(# ! [attr]);
+    let _ = #[attr] foo!(#! [attr]);
     let _ = #[attr] foo![];
-    let _ = #[attr] foo![# ! [attr]];
+    let _ = #[attr] foo![#! [attr]];
     let _ = #[attr] foo! { };
-    let _ = #[attr] foo! { # ! [attr] };
+    let _ = #[attr] foo! { #! [attr] };
     let _ = #[attr] Foo{bar: baz,};
     let _ = #[attr] Foo{..foo};
     let _ = #[attr] Foo{bar: baz, ..foo};
diff --git a/src/test/pretty/delimited-token-groups.rs b/src/test/pretty/delimited-token-groups.rs
index 66de0fc6cf7fa..125f2b0fa1687 100644
--- a/src/test/pretty/delimited-token-groups.rs
+++ b/src/test/pretty/delimited-token-groups.rs
@@ -9,7 +9,7 @@ mac! {
     {
         fn clone() -> S
         {
-            panic ! () ;
+            panic! () ;
 
         }
     }
diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr
index 6217decd8ef88..bf48e80eff147 100644
--- a/src/test/ui/macros/trace-macro.stderr
+++ b/src/test/ui/macros/trace-macro.stderr
@@ -5,5 +5,5 @@ LL |     println!("Hello, World!");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expanding `println! { "Hello, World!" }`
-   = note: to `{ $crate :: io :: _print($crate :: format_args_nl ! ("Hello, World!")) ; }`
+   = note: to `{ $crate :: io :: _print($crate :: format_args_nl! ("Hello, World!")) ; }`
 
diff --git a/src/test/ui/macros/trace_faulty_macros.stderr b/src/test/ui/macros/trace_faulty_macros.stderr
index 6a54bb10b79a2..96e7d61398b7e 100644
--- a/src/test/ui/macros/trace_faulty_macros.stderr
+++ b/src/test/ui/macros/trace_faulty_macros.stderr
@@ -19,7 +19,7 @@ LL |     my_faulty_macro!();
    |     ^^^^^^^^^^^^^^^^^^^
    |
    = note: expanding `my_faulty_macro! {  }`
-   = note: to `my_faulty_macro ! (bcd) ;`
+   = note: to `my_faulty_macro! (bcd) ;`
    = note: expanding `my_faulty_macro! { bcd }`
 
 error: recursion limit reached while expanding `my_recursive_macro!`
@@ -41,13 +41,13 @@ LL |     my_recursive_macro!();
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: expanding `my_recursive_macro! {  }`
-   = note: to `my_recursive_macro ! () ;`
+   = note: to `my_recursive_macro! () ;`
    = note: expanding `my_recursive_macro! {  }`
-   = note: to `my_recursive_macro ! () ;`
+   = note: to `my_recursive_macro! () ;`
    = note: expanding `my_recursive_macro! {  }`
-   = note: to `my_recursive_macro ! () ;`
+   = note: to `my_recursive_macro! () ;`
    = note: expanding `my_recursive_macro! {  }`
-   = note: to `my_recursive_macro ! () ;`
+   = note: to `my_recursive_macro! () ;`
 
 error: expected expression, found `A { a: a, b: 0, c: _, .. }`
   --> $DIR/trace_faulty_macros.rs:16:9
@@ -73,7 +73,7 @@ LL |     let a = pat_macro!();
    |             ^^^^^^^^^^^^
    |
    = note: expanding `pat_macro! {  }`
-   = note: to `pat_macro ! (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: _, .. }`
 
diff --git a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout
index 6cf864f359085..eae169b162f4d 100644
--- a/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout
+++ b/src/test/ui/proc-macro/allowed-attr-stmt-expr.stdout
@@ -87,7 +87,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
         span: $DIR/allowed-attr-stmt-expr.rs:57:33: 57:34 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro ! ("{}", string) ;
+PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
@@ -140,7 +140,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
         span: $DIR/allowed-attr-stmt-expr.rs:61:28: 61:29 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): second_make_stmt ! (#[allow(dead_code)] struct Bar { }) ;
+PRINT-ATTR INPUT (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar { }) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "second_make_stmt",
diff --git a/src/test/ui/proc-macro/attr-complex-fn.stdout b/src/test/ui/proc-macro/attr-complex-fn.stdout
index 72783efe08dba..fbefa3923ee22 100644
--- a/src/test/ui/proc-macro/attr-complex-fn.stdout
+++ b/src/test/ui/proc-macro/attr-complex-fn.stdout
@@ -76,7 +76,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
         span: $DIR/attr-complex-fn.rs:19:42: 19:44 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { # ! [rustc_dummy] }
+PRINT-ATTR INPUT (DISPLAY): impl < T > MyTrait < T > for MyStruct < { true } > { #! [rustc_dummy] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "impl",
diff --git a/src/test/ui/proc-macro/attr-stmt-expr.stdout b/src/test/ui/proc-macro/attr-stmt-expr.stdout
index f75309e6872f9..edb9fbab342e2 100644
--- a/src/test/ui/proc-macro/attr-stmt-expr.stdout
+++ b/src/test/ui/proc-macro/attr-stmt-expr.stdout
@@ -71,7 +71,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
         span: $DIR/attr-stmt-expr.rs:49:33: 49:34 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro ! ("{}", string) ;
+PRINT-ATTR INPUT (DISPLAY): #[expect_my_macro_stmt] my_macro! ("{}", string) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
@@ -124,7 +124,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
         span: $DIR/attr-stmt-expr.rs:53:28: 53:29 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): second_make_stmt ! (#[allow(dead_code)] struct Bar { }) ;
+PRINT-ATTR INPUT (DISPLAY): second_make_stmt! (#[allow(dead_code)] struct Bar { }) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "second_make_stmt",
diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs
index e056bd32d2d0e..5b386b46bb721 100644
--- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs
+++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr-rpass.rs
@@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_print_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "println ! (\"{}\", string) ;");
+    assert_eq!(item.to_string(), "println! (\"{}\", string) ;");
     item
 }
 
@@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_print_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "println ! (\"{}\", string)");
+    assert_eq!(item.to_string(), "println! (\"{}\", string)");
     item
 }
 
diff --git a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
index 19183c616516a..4d6dc06b4a4a3 100644
--- a/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
+++ b/src/test/ui/proc-macro/auxiliary/attr-stmt-expr.rs
@@ -17,7 +17,7 @@ pub fn expect_let(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_my_macro_stmt(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "my_macro ! (\"{}\", string) ;");
+    assert_eq!(item.to_string(), "my_macro! (\"{}\", string) ;");
     item
 }
 
@@ -31,7 +31,7 @@ pub fn expect_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
 #[proc_macro_attribute]
 pub fn expect_my_macro_expr(attr: TokenStream, item: TokenStream) -> TokenStream {
     assert!(attr.to_string().is_empty());
-    assert_eq!(item.to_string(), "my_macro ! (\"{}\", string)");
+    assert_eq!(item.to_string(), "my_macro! (\"{}\", string)");
     item
 }
 
diff --git a/src/test/ui/proc-macro/cfg-eval-inner.stdout b/src/test/ui/proc-macro/cfg-eval-inner.stdout
index 1f2b003958908..08ead5aaeee84 100644
--- a/src/test/ui/proc-macro/cfg-eval-inner.stdout
+++ b/src/test/ui/proc-macro/cfg-eval-inner.stdout
@@ -1,9 +1,9 @@
 PRINT-ATTR INPUT (DISPLAY): impl Foo <
 [u8 ;
  {
-     # ! [rustc_dummy(cursed_inner)] # ! [allow(unused)] struct Inner
-     { field : [u8 ; { # ! [rustc_dummy(another_cursed_inner)] 1 }] } 0
- }] > { # ! [rustc_dummy(evaluated_attr)] fn bar() { } }
+     #! [rustc_dummy(cursed_inner)] #! [allow(unused)] struct Inner
+     { field : [u8 ; { #! [rustc_dummy(another_cursed_inner)] 1 }] } 0
+ }] > { #! [rustc_dummy(evaluated_attr)] fn bar() { } }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "impl",
diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
index 7f133fd05d704..e6148a687fda0 100644
--- a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
+++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout
@@ -1,4 +1,4 @@
-PRINT-ATTR INPUT (DISPLAY): struct A(identity ! ($crate :: S)) ;
+PRINT-ATTR INPUT (DISPLAY): struct A(identity! ($crate :: S)) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
@@ -53,7 +53,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
         span: $DIR/dollar-crate-issue-62325.rs:19:35: 19:36 (#4),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): struct B(identity ! ($crate :: S)) ;
+PRINT-ATTR INPUT (DISPLAY): struct B(identity! ($crate :: S)) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "struct",
diff --git a/src/test/ui/proc-macro/inner-attr-non-inline-mod.stdout b/src/test/ui/proc-macro/inner-attr-non-inline-mod.stdout
index dbef342ef241d..6261d82e2d0b8 100644
--- a/src/test/ui/proc-macro/inner-attr-non-inline-mod.stdout
+++ b/src/test/ui/proc-macro/inner-attr-non-inline-mod.stdout
@@ -1,4 +1,4 @@
-PRINT-ATTR INPUT (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { # ! [rustfmt :: skip] }
+PRINT-ATTR INPUT (DISPLAY): #[deny(unused_attributes)] mod module_with_attrs { #! [rustfmt :: skip] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
diff --git a/src/test/ui/proc-macro/inner-attrs.stdout b/src/test/ui/proc-macro/inner-attrs.stdout
index 77f423704933c..9b7865be6220e 100644
--- a/src/test/ui/proc-macro/inner-attrs.stdout
+++ b/src/test/ui/proc-macro/inner-attrs.stdout
@@ -6,7 +6,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(second)] fn foo()
-{ # ! [print_target_and_args(third)] # ! [print_target_and_args(fourth)] }
+{ #! [print_target_and_args(third)] #! [print_target_and_args(fourth)] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Punct {
         ch: '#',
@@ -121,7 +121,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): fn foo()
-{ # ! [print_target_and_args(third)] # ! [print_target_and_args(fourth)] }
+{ #! [print_target_and_args(third)] #! [print_target_and_args(fourth)] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "fn",
@@ -210,7 +210,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/inner-attrs.rs:19:30: 19:35 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): fn foo() { # ! [print_target_and_args(fourth)] }
+PRINT-ATTR INPUT (DISPLAY): fn foo() { #! [print_target_and_args(fourth)] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "fn",
@@ -299,7 +299,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
 ]
 PRINT-ATTR INPUT (DISPLAY): #[print_target_and_args(mod_second)] mod inline_mod
 {
-    # ! [print_target_and_args(mod_third)] # !
+    #! [print_target_and_args(mod_third)] #!
     [print_target_and_args(mod_fourth)]
 }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
@@ -412,7 +412,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
 ]
 PRINT-ATTR INPUT (DISPLAY): mod inline_mod
 {
-    # ! [print_target_and_args(mod_third)] # !
+    #! [print_target_and_args(mod_third)] #!
     [print_target_and_args(mod_fourth)]
 }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
@@ -498,7 +498,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/inner-attrs.rs:26:30: 26:39 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): mod inline_mod { # ! [print_target_and_args(mod_fourth)] }
+PRINT-ATTR INPUT (DISPLAY): mod inline_mod { #! [print_target_and_args(mod_fourth)] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "mod",
@@ -571,7 +571,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
 PRINT-DERIVE INPUT (DISPLAY): struct MyDerivePrint
 {
     field :
-    [u8 ; { match true { _ => { # ! [rustc_dummy(third)] true } } ; 0 }]
+    [u8 ; { match true { _ => { #! [rustc_dummy(third)] true } } ; 0 }]
 }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
     Ident {
@@ -705,7 +705,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/inner-attrs.rs:48:29: 48:40 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): (3, 4, { # ! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
+PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Group {
         delimiter: Parenthesis,
@@ -819,7 +819,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
         span: $DIR/inner-attrs.rs:55:29: 55:40 (#0),
     },
 ]
-PRINT-ATTR INPUT (DISPLAY): (3, 4, { # ! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
+PRINT-ATTR INPUT (DISPLAY): (3, 4, { #! [cfg_attr(not(FALSE), rustc_dummy(innermost))] 5 }) ;
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Group {
         delimiter: Parenthesis,
diff --git a/src/test/ui/proc-macro/issue-75734-pp-paren.stdout b/src/test/ui/proc-macro/issue-75734-pp-paren.stdout
index b33b85f1705f5..ea03653c52f83 100644
--- a/src/test/ui/proc-macro/issue-75734-pp-paren.stdout
+++ b/src/test/ui/proc-macro/issue-75734-pp-paren.stdout
@@ -1,4 +1,4 @@
-PRINT-ATTR INPUT (DISPLAY): fn main() { & | _ : u8 | { } ; mul_2 ! (1 + 1) ; }
+PRINT-ATTR INPUT (DISPLAY): fn main() { & | _ : u8 | { } ; mul_2! (1 + 1) ; }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "fn",
diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
index d7adc5331cd77..81b2b219c4368 100644
--- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
+++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout
@@ -11,16 +11,15 @@ struct Foo < #[cfg(FALSE)] A, B >
              #[cfg(FALSE)] true => { },
              #[cfg_attr(not(FALSE), allow(warnings))] false => { }, _ => { }
          } ; #[print_helper(should_be_removed)] fn removed_fn()
-         { # ! [cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn
-         kept_fn() { # ! [cfg(not(FALSE))] let my_val = true ; } enum
-         TupleEnum
+         { #! [cfg(FALSE)] } #[print_helper(c)] #[cfg(not(FALSE))] fn
+         kept_fn() { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum
          {
              Foo(#[cfg(FALSE)] u8, #[cfg(FALSE)] bool, #[cfg(not(FALSE))] i32,
                  #[cfg(FALSE)] String, u8)
          } struct
          TupleStruct(#[cfg(FALSE)] String, #[cfg(not(FALSE))] i32,
                      #[cfg(FALSE)] bool, u8) ; fn plain_removed_fn()
-         { # ! [cfg_attr(not(FALSE), cfg(FALSE))] } 0
+         { #! [cfg_attr(not(FALSE), cfg(FALSE))] } 0
      }], #[print_helper(d)] fourth : B
 }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
@@ -1281,7 +1280,7 @@ PRINT-DERIVE INPUT (DISPLAY): #[print_helper(a)] #[allow(dead_code)] #[print_hel
          #[cfg(not(FALSE))] struct Inner ; match true
          { #[allow(warnings)] false => { }, _ => { } } ; #[print_helper(c)]
          #[cfg(not(FALSE))] fn kept_fn()
-         { # ! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum
+         { #! [cfg(not(FALSE))] let my_val = true ; } enum TupleEnum
          { Foo(#[cfg(not(FALSE))] i32, u8) } struct
          TupleStruct(#[cfg(not(FALSE))] i32, u8) ; 0
      }], #[print_helper(d)] fourth : B
diff --git a/src/test/ui/proc-macro/issue-78675-captured-inner-attrs.stdout b/src/test/ui/proc-macro/issue-78675-captured-inner-attrs.stdout
index 607c2954c7cf5..60a400a5deabf 100644
--- a/src/test/ui/proc-macro/issue-78675-captured-inner-attrs.stdout
+++ b/src/test/ui/proc-macro/issue-78675-captured-inner-attrs.stdout
@@ -1,7 +1,7 @@
-PRINT-BANG INPUT (DISPLAY): foo ! { #[fake_attr] mod bar {
+PRINT-BANG INPUT (DISPLAY): foo! { #[fake_attr] mod bar {
     #![doc = r" Foo"]
 } }
-PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): foo ! { #[fake_attr] mod bar { # ! [doc = r" Foo"] } }
+PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): foo! { #[fake_attr] mod bar { #! [doc = r" Foo"] } }
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "foo",
diff --git a/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout b/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout
index a0b0cbb19e4db..6e2b6a2e5bdf6 100644
--- a/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout
+++ b/src/test/ui/proc-macro/macro-rules-derive-cfg.stdout
@@ -4,7 +4,7 @@ PRINT-DERIVE INPUT (DISPLAY): struct Foo
     [bool ;
      {
          let a = #[rustc_dummy(first)] #[rustc_dummy(second)]
-         { # ! [allow(unused)] 30 } ; 0
+         { #! [allow(unused)] 30 } ; 0
      }]
 }
 PRINT-DERIVE INPUT (DEBUG): TokenStream [
diff --git a/src/test/ui/proc-macro/meta-macro-hygiene.stdout b/src/test/ui/proc-macro/meta-macro-hygiene.stdout
index d9337fb361bee..95ef260537a8a 100644
--- a/src/test/ui/proc-macro/meta-macro-hygiene.stdout
+++ b/src/test/ui/proc-macro/meta-macro-hygiene.stdout
@@ -30,7 +30,7 @@ macro_rules! produce_it
     */ {
     () =>
     {
-        meta_macro :: print_def_site ! ($ crate :: dummy ! ()) ;
+        meta_macro :: print_def_site! ($ crate :: dummy! ()) ;
         // `print_def_site!` will respan the `$crate` identifier
         // with `Span::def_site()`. This should cause it to resolve
         // relative to `meta_macro`, *not* `make_macro` (despite
diff --git a/src/test/ui/proc-macro/nodelim-groups.stdout b/src/test/ui/proc-macro/nodelim-groups.stdout
index 4ffe3f35e8e42..6b410f0bfb7e3 100644
--- a/src/test/ui/proc-macro/nodelim-groups.stdout
+++ b/src/test/ui/proc-macro/nodelim-groups.stdout
@@ -71,7 +71,6 @@ PRINT-BANG INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-BANG INPUT (DISPLAY): "hi" "hello".len() + "world".len() (1 + 1)
-PRINT-BANG DEEP-RE-COLLECTED (DISPLAY): "hi" "hello" . len() + "world" . len() (1 + 1)
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Literal {
         kind: Str,
diff --git a/src/test/ui/proc-macro/nonterminal-expansion.stdout b/src/test/ui/proc-macro/nonterminal-expansion.stdout
index 4522dc14b9f2d..4d884348f2ca4 100644
--- a/src/test/ui/proc-macro/nonterminal-expansion.stdout
+++ b/src/test/ui/proc-macro/nonterminal-expansion.stdout
@@ -1,5 +1,5 @@
 PRINT-ATTR_ARGS INPUT (DISPLAY): a, line!(), b
-PRINT-ATTR_ARGS RE-COLLECTED (DISPLAY): a, line ! (), b
+PRINT-ATTR_ARGS RE-COLLECTED (DISPLAY): a, line! (), b
 PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
     Ident {
         ident: "a",
diff --git a/src/test/ui/proc-macro/nonterminal-token-hygiene.stdout b/src/test/ui/proc-macro/nonterminal-token-hygiene.stdout
index 54dc856bfb03a..ac020cddf0874 100644
--- a/src/test/ui/proc-macro/nonterminal-token-hygiene.stdout
+++ b/src/test/ui/proc-macro/nonterminal-token-hygiene.stdout
@@ -52,13 +52,13 @@ macro_rules! outer
     */ {
     ($ item : item) =>
     {
-        macro inner() { print_bang ! { $ item } } inner ! () ;
+        macro inner() { print_bang! { $ item } } inner! () ;
 
     } ;
 }
 
 struct S /* 0#0 */;
-macro inner /* 0#4 */ { () => { print_bang ! { struct S; } } }
+macro inner /* 0#4 */ { () => { print_bang! { struct S; } } }
 
 struct S /* 0#5 */;
 // OK, not a duplicate definition of `S`
diff --git a/src/test/ui/proc-macro/pretty-print-tts.rs b/src/test/ui/proc-macro/pretty-print-tts.rs
new file mode 100644
index 0000000000000..ffe2a74155151
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-tts.rs
@@ -0,0 +1,20 @@
+// check-pass
+// aux-build:test-macros.rs
+// compile-flags: -Z span-debug
+
+#![feature(rustc_attrs)]
+
+#![no_std] // Don't load unnecessary hygiene information from std
+extern crate std;
+
+#[macro_use]
+extern crate test_macros;
+
+// Tests the pretty-printing behavior of various (unparsed) tokens
+print_bang_consume!({
+    #![rustc_dummy]
+    let a = "hello".len();
+    matches!(a, 5);
+});
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/pretty-print-tts.stdout b/src/test/ui/proc-macro/pretty-print-tts.stdout
new file mode 100644
index 0000000000000..f52e97a860446
--- /dev/null
+++ b/src/test/ui/proc-macro/pretty-print-tts.stdout
@@ -0,0 +1,102 @@
+PRINT-BANG INPUT (DISPLAY): { #! [rustc_dummy] let a = "hello".len() ; matches! (a, 5) ; }
+PRINT-BANG INPUT (DEBUG): TokenStream [
+    Group {
+        delimiter: Brace,
+        stream: TokenStream [
+            Punct {
+                ch: '#',
+                spacing: Joint,
+                span: $DIR/pretty-print-tts.rs:15:5: 15:6 (#0),
+            },
+            Punct {
+                ch: '!',
+                spacing: Alone,
+                span: $DIR/pretty-print-tts.rs:15:6: 15:7 (#0),
+            },
+            Group {
+                delimiter: Bracket,
+                stream: TokenStream [
+                    Ident {
+                        ident: "rustc_dummy",
+                        span: $DIR/pretty-print-tts.rs:15:8: 15:19 (#0),
+                    },
+                ],
+                span: $DIR/pretty-print-tts.rs:15:7: 15:20 (#0),
+            },
+            Ident {
+                ident: "let",
+                span: $DIR/pretty-print-tts.rs:16:5: 16:8 (#0),
+            },
+            Ident {
+                ident: "a",
+                span: $DIR/pretty-print-tts.rs:16:9: 16:10 (#0),
+            },
+            Punct {
+                ch: '=',
+                spacing: Alone,
+                span: $DIR/pretty-print-tts.rs:16:11: 16:12 (#0),
+            },
+            Literal {
+                kind: Str,
+                symbol: "hello",
+                suffix: None,
+                span: $DIR/pretty-print-tts.rs:16:13: 16:20 (#0),
+            },
+            Punct {
+                ch: '.',
+                spacing: Alone,
+                span: $DIR/pretty-print-tts.rs:16:20: 16:21 (#0),
+            },
+            Ident {
+                ident: "len",
+                span: $DIR/pretty-print-tts.rs:16:21: 16:24 (#0),
+            },
+            Group {
+                delimiter: Parenthesis,
+                stream: TokenStream [],
+                span: $DIR/pretty-print-tts.rs:16:24: 16:26 (#0),
+            },
+            Punct {
+                ch: ';',
+                spacing: Alone,
+                span: $DIR/pretty-print-tts.rs:16:26: 16:27 (#0),
+            },
+            Ident {
+                ident: "matches",
+                span: $DIR/pretty-print-tts.rs:17:5: 17:12 (#0),
+            },
+            Punct {
+                ch: '!',
+                spacing: Alone,
+                span: $DIR/pretty-print-tts.rs:17:12: 17:13 (#0),
+            },
+            Group {
+                delimiter: Parenthesis,
+                stream: TokenStream [
+                    Ident {
+                        ident: "a",
+                        span: $DIR/pretty-print-tts.rs:17:14: 17:15 (#0),
+                    },
+                    Punct {
+                        ch: ',',
+                        spacing: Alone,
+                        span: $DIR/pretty-print-tts.rs:17:15: 17:16 (#0),
+                    },
+                    Literal {
+                        kind: Integer,
+                        symbol: "5",
+                        suffix: None,
+                        span: $DIR/pretty-print-tts.rs:17:17: 17:18 (#0),
+                    },
+                ],
+                span: $DIR/pretty-print-tts.rs:17:13: 17:19 (#0),
+            },
+            Punct {
+                ch: ';',
+                spacing: Alone,
+                span: $DIR/pretty-print-tts.rs:17:19: 17:20 (#0),
+            },
+        ],
+        span: $DIR/pretty-print-tts.rs:14:21: 18:2 (#0),
+    },
+]
diff --git a/src/test/ui/proc-macro/weird-braces.stdout b/src/test/ui/proc-macro/weird-braces.stdout
index 990829456e88a..dc35df1159f88 100644
--- a/src/test/ui/proc-macro/weird-braces.stdout
+++ b/src/test/ui/proc-macro/weird-braces.stdout
@@ -8,7 +8,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
 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(first_inner)] #!
     [print_target_and_args(second_inner)]
 }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
@@ -182,7 +182,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
 ]
 PRINT-ATTR INPUT (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
 {
-    # ! [print_target_and_args(first_inner)] # !
+    #! [print_target_and_args(first_inner)] #!
     [print_target_and_args(second_inner)]
 }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
@@ -330,7 +330,7 @@ PRINT-ATTR_ARGS INPUT (DEBUG): TokenStream [
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): impl Bar < { 1 > 0 } > for Foo < { true } >
-{ # ! [print_target_and_args(second_inner)] }
+{ #! [print_target_and_args(second_inner)] }
 PRINT-ATTR INPUT (DEBUG): TokenStream [
     Ident {
         ident: "impl",