From 31731511c0563d71289d29d1f53a21fe2fce5534 Mon Sep 17 00:00:00 2001
From: Smitty <me@smitop.com>
Date: Sat, 18 Dec 2021 08:50:01 -0500
Subject: [PATCH 01/10] Support [x; n] expressions in concat_bytes!

Contributes to #87555.
---
 .../rustc_builtin_macros/src/concat_bytes.rs  | 105 +++++++++++-------
 src/test/ui/macros/concat-bytes-error.rs      |   8 ++
 src/test/ui/macros/concat-bytes-error.stderr  |  52 ++++++++-
 src/test/ui/macros/concat-bytes.rs            |  12 +-
 4 files changed, 135 insertions(+), 42 deletions(-)

diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index a107f5993b546..87920e5175268 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -72,6 +72,52 @@ fn invalid_type_err(cx: &mut base::ExtCtxt<'_>, expr: &P<rustc_ast::Expr>, is_ne
     }
 }
 
+fn handle_array_element(
+    cx: &mut base::ExtCtxt<'_>,
+    has_errors: &mut bool,
+    missing_literals: &mut Vec<rustc_span::Span>,
+    expr: &P<rustc_ast::Expr>,
+) -> Option<u8> {
+    match expr.kind {
+        ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
+            if !*has_errors {
+                cx.span_err(expr.span, "cannot concatenate doubly nested array");
+            }
+            *has_errors = true;
+            None
+        }
+        ast::ExprKind::Lit(ref lit) => match lit.kind {
+            ast::LitKind::Int(
+                val,
+                ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
+            ) if val <= u8::MAX.into() => Some(val as u8),
+
+            ast::LitKind::Byte(val) => Some(val),
+            ast::LitKind::ByteStr(_) => {
+                if !*has_errors {
+                    cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
+                        .note("byte strings are treated as arrays of bytes")
+                        .help("try flattening the array")
+                        .emit();
+                }
+                *has_errors = true;
+                None
+            }
+            _ => {
+                if !*has_errors {
+                    invalid_type_err(cx, expr, true);
+                }
+                *has_errors = true;
+                None
+            }
+        },
+        _ => {
+            missing_literals.push(expr.span);
+            None
+        }
+    }
+}
+
 pub fn expand_concat_bytes(
     cx: &mut base::ExtCtxt<'_>,
     sp: rustc_span::Span,
@@ -88,48 +134,27 @@ pub fn expand_concat_bytes(
         match e.kind {
             ast::ExprKind::Array(ref exprs) => {
                 for expr in exprs {
-                    match expr.kind {
-                        ast::ExprKind::Array(_) => {
-                            if !has_errors {
-                                cx.span_err(expr.span, "cannot concatenate doubly nested array");
-                            }
-                            has_errors = true;
-                        }
-                        ast::ExprKind::Lit(ref lit) => match lit.kind {
-                            ast::LitKind::Int(
-                                val,
-                                ast::LitIntType::Unsuffixed
-                                | ast::LitIntType::Unsigned(ast::UintTy::U8),
-                            ) if val <= u8::MAX.into() => {
-                                accumulator.push(val as u8);
-                            }
-
-                            ast::LitKind::Byte(val) => {
-                                accumulator.push(val);
-                            }
-                            ast::LitKind::ByteStr(_) => {
-                                if !has_errors {
-                                    cx.struct_span_err(
-                                        expr.span,
-                                        "cannot concatenate doubly nested array",
-                                    )
-                                    .note("byte strings are treated as arrays of bytes")
-                                    .help("try flattening the array")
-                                    .emit();
-                                }
-                                has_errors = true;
-                            }
-                            _ => {
-                                if !has_errors {
-                                    invalid_type_err(cx, expr, true);
-                                }
-                                has_errors = true;
-                            }
-                        },
-                        _ => {
-                            missing_literals.push(expr.span);
+                    if let Some(elem) =
+                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                    {
+                        accumulator.push(elem);
+                    }
+                }
+            }
+            ast::ExprKind::Repeat(ref expr, ref count) => {
+                if let ast::ExprKind::Lit(ast::Lit {
+                    kind: ast::LitKind::Int(count_val, _), ..
+                }) = count.value.kind
+                {
+                    if let Some(elem) =
+                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                    {
+                        for _ in 0..count_val {
+                            accumulator.push(elem);
                         }
                     }
+                } else {
+                    cx.span_err(count.value.span, "repeat count is not a number");
                 }
             }
             ast::ExprKind::Lit(ref lit) => match lit.kind {
diff --git a/src/test/ui/macros/concat-bytes-error.rs b/src/test/ui/macros/concat-bytes-error.rs
index 9b4a9c2cf811d..2c7997d5e5905 100644
--- a/src/test/ui/macros/concat-bytes-error.rs
+++ b/src/test/ui/macros/concat-bytes-error.rs
@@ -39,4 +39,12 @@ fn main() {
     ]);
     concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals
     concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8`
+    concat_bytes!([3; ()]); //~ ERROR repeat count is not a number
+    concat_bytes!([3; -2]); //~ ERROR repeat count is not a number
+    concat_bytes!([pie; -2]); //~ ERROR repeat count is not a number
+    concat_bytes!([pie; 2]); //~ ERROR expected a byte literal
+    concat_bytes!([2.2; 0]); //~ ERROR cannot concatenate float literals
+    concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a number
+    concat_bytes!([[1, 2, 3]; 3]); //~ ERROR cannot concatenate doubly nested array
+    concat_bytes!([[42; 2]; 3]); //~ ERROR cannot concatenate doubly nested array
 }
diff --git a/src/test/ui/macros/concat-bytes-error.stderr b/src/test/ui/macros/concat-bytes-error.stderr
index 1fc2d5c4843a0..f0c53839b3ad5 100644
--- a/src/test/ui/macros/concat-bytes-error.stderr
+++ b/src/test/ui/macros/concat-bytes-error.stderr
@@ -127,5 +127,55 @@ error: numeric literal is not a `u8`
 LL |     concat_bytes!([5u16]);
    |                    ^^^^
 
-error: aborting due to 20 previous errors
+error: repeat count is not a number
+  --> $DIR/concat-bytes-error.rs:42:23
+   |
+LL |     concat_bytes!([3; ()]);
+   |                       ^^
+
+error: repeat count is not a number
+  --> $DIR/concat-bytes-error.rs:43:23
+   |
+LL |     concat_bytes!([3; -2]);
+   |                       ^^
+
+error: repeat count is not a number
+  --> $DIR/concat-bytes-error.rs:44:25
+   |
+LL |     concat_bytes!([pie; -2]);
+   |                         ^^
+
+error: expected a byte literal
+  --> $DIR/concat-bytes-error.rs:45:20
+   |
+LL |     concat_bytes!([pie; 2]);
+   |                    ^^^
+   |
+   = note: only byte literals (like `b"foo"`, `b's'`, and `[3, 4, 5]`) can be passed to `concat_bytes!()`
+
+error: cannot concatenate float literals
+  --> $DIR/concat-bytes-error.rs:46:20
+   |
+LL |     concat_bytes!([2.2; 0]);
+   |                    ^^^
+
+error: repeat count is not a number
+  --> $DIR/concat-bytes-error.rs:47:25
+   |
+LL |     concat_bytes!([5.5; ()]);
+   |                         ^^
+
+error: cannot concatenate doubly nested array
+  --> $DIR/concat-bytes-error.rs:48:20
+   |
+LL |     concat_bytes!([[1, 2, 3]; 3]);
+   |                    ^^^^^^^^^
+
+error: cannot concatenate doubly nested array
+  --> $DIR/concat-bytes-error.rs:49:20
+   |
+LL |     concat_bytes!([[42; 2]; 3]);
+   |                    ^^^^^^^
+
+error: aborting due to 28 previous errors
 
diff --git a/src/test/ui/macros/concat-bytes.rs b/src/test/ui/macros/concat-bytes.rs
index 5415cf3fe2235..fd8f99417ec98 100644
--- a/src/test/ui/macros/concat-bytes.rs
+++ b/src/test/ui/macros/concat-bytes.rs
@@ -3,5 +3,15 @@
 
 fn main() {
     assert_eq!(concat_bytes!(), &[]);
-    assert_eq!(concat_bytes!(b'A', b"BC", [68, b'E', 70]), b"ABCDEF");
+    assert_eq!(
+        concat_bytes!(b'A', b"BC", [68, b'E', 70], [b'G'; 1], [72; 2], [73u8; 3], [65; 0]),
+        b"ABCDEFGHHIII",
+    );
+    assert_eq!(
+        concat_bytes!(
+            concat_bytes!(b"AB", b"CD"),
+            concat_bytes!(b"EF", b"GH"),
+        ),
+        b"ABCDEFGH",
+    );
 }

From d31f7f1097539c41fea01a7f05400d05d31786c7 Mon Sep 17 00:00:00 2001
From: Aaron Hill <aa1ronham@gmail.com>
Date: Sat, 18 Dec 2021 11:25:05 -0500
Subject: [PATCH 02/10] Ignore other `PredicateKind`s in rustdoc auto trait
 finder

Fixes #92073

There's not really anything we can do with them, and they're
causing ICEs. I'm not using a wildcard match, as we should check
that any new `PredicateKind`s are handled properly by rustdoc.
---
 .../rustc_trait_selection/src/traits/auto_trait.rs   | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 53ff911ea0cda..05d2a373dc639 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -839,7 +839,17 @@ impl<'tcx> AutoTraitFinder<'tcx> {
                         _ => return false,
                     }
                 }
-                _ => panic!("Unexpected predicate {:?} {:?}", ty, predicate),
+                // There's not really much we can do with these predicates -
+                // we start out with a `ParamEnv` with no inference variables,
+                // and these don't correspond to adding any new bounds to
+                // the `ParamEnv`.
+                ty::PredicateKind::WellFormed(..)
+                | ty::PredicateKind::ObjectSafe(..)
+                | ty::PredicateKind::ClosureKind(..)
+                | ty::PredicateKind::Subtype(..)
+                | ty::PredicateKind::ConstEvaluatable(..)
+                | ty::PredicateKind::Coerce(..)
+                | ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
             };
         }
         true

From 4bbbdb7f459c72f02bf4b204c2ebad8fc7cd9b0c Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Wed, 22 Dec 2021 19:18:06 -0800
Subject: [PATCH 03/10] Remove VCVARS_BAT

---
 .github/workflows/ci.yml     | 1 -
 src/ci/github-actions/ci.yml | 1 -
 2 files changed, 2 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fd015e1cd4302..67deb3d977942 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -355,7 +355,6 @@ jobs:
             env:
               SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo
               RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-lld"
-              VCVARS_BAT: vcvars64.bat
             os: windows-latest-xl
           - name: x86_64-msvc-tools
             env:
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 96af401369e94..ac5d5822bfbd5 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -548,7 +548,6 @@ jobs:
             env:
               SCRIPT: python x.py --stage 2 test src/tools/cargotest src/tools/cargo
               RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-lld
-              VCVARS_BAT: vcvars64.bat
             <<: *job-windows-xl
 
           - name: x86_64-msvc-tools

From a51326f1bafe669523a2aa413d2c068b2fe86ed6 Mon Sep 17 00:00:00 2001
From: David Tolnay <dtolnay@gmail.com>
Date: Thu, 23 Dec 2021 13:02:31 -0800
Subject: [PATCH 04/10] Add a test suite for stringify macro

---
 src/test/ui/macros/stringify.rs | 894 ++++++++++++++++++++++++++++++++
 1 file changed, 894 insertions(+)
 create mode 100644 src/test/ui/macros/stringify.rs

diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs
new file mode 100644
index 0000000000000..924329d7a8441
--- /dev/null
+++ b/src/test/ui/macros/stringify.rs
@@ -0,0 +1,894 @@
+// run-pass
+// edition:2021
+// compile-flags: --test
+
+#![feature(async_closure)]
+#![feature(const_trait_impl)]
+#![feature(generators)]
+#![feature(half_open_range_patterns)]
+#![feature(more_qualified_paths)]
+#![feature(raw_ref_op)]
+#![deny(unused_macros)]
+
+macro_rules! stringify_block {
+    ($block:block) => {
+        stringify!($block)
+    };
+}
+
+macro_rules! stringify_expr {
+    ($expr:expr) => {
+        stringify!($expr)
+    };
+}
+
+macro_rules! stringify_item {
+    ($item:item) => {
+        stringify!($item)
+    };
+}
+
+macro_rules! stringify_meta {
+    ($meta:meta) => {
+        stringify!($meta)
+    };
+}
+
+macro_rules! stringify_pat {
+    ($pat:pat) => {
+        stringify!($pat)
+    };
+}
+
+macro_rules! stringify_path {
+    ($path:path) => {
+        stringify!($path)
+    };
+}
+
+macro_rules! stringify_stmt {
+    ($stmt:stmt) => {
+        stringify!($stmt)
+    };
+}
+
+macro_rules! stringify_ty {
+    ($ty:ty) => {
+        stringify!($ty)
+    };
+}
+
+macro_rules! stringify_vis {
+    ($vis:vis) => {
+        stringify!($vis)
+    };
+}
+
+#[test]
+fn test_block() {
+    assert_eq!(stringify_block!({}), "{}");
+    assert_eq!(stringify_block!({ true }), "{ true }");
+    assert_eq!(stringify_block!({ return }), "{ return }");
+    assert_eq!(
+        stringify_block!({
+            return;
+        }),
+        "{ return; }",
+    );
+    assert_eq!(
+        stringify_block!({
+            let _;
+            true
+        }),
+        "{ let _; true }",
+    );
+}
+
+#[test]
+fn test_expr() {
+    // ExprKind::Box
+    assert_eq!(stringify_expr!(box expr), "box expr");
+
+    // ExprKind::Array
+    assert_eq!(stringify_expr!([]), "[]");
+    assert_eq!(stringify_expr!([true]), "[true]");
+    assert_eq!(stringify_expr!([true,]), "[true]");
+    assert_eq!(stringify_expr!([true, true]), "[true, true]");
+
+    // ExprKind::Call
+    assert_eq!(stringify_expr!(f()), "f()");
+    assert_eq!(stringify_expr!(f::<u8>()), "f::<u8>()");
+    assert_eq!(stringify_expr!(f::<1>()), "f::<1>()");
+    assert_eq!(stringify_expr!(f::<'a, u8, 1>()), "f::<'a, u8, 1>()");
+    assert_eq!(stringify_expr!(f(true)), "f(true)");
+    assert_eq!(stringify_expr!(f(true,)), "f(true)");
+    assert_eq!(stringify_expr!(()()), "()()");
+
+    // ExprKind::MethodCall
+    assert_eq!(stringify_expr!(x.f()), "x.f()");
+    assert_eq!(stringify_expr!(x.f::<u8>()), "x.f::<u8>()");
+
+    // ExprKind::Tup
+    assert_eq!(stringify_expr!(()), "()");
+    assert_eq!(stringify_expr!((true,)), "(true,)");
+    assert_eq!(stringify_expr!((true, false)), "(true, false)");
+    assert_eq!(stringify_expr!((true, false,)), "(true, false)");
+
+    // ExprKind::Binary
+    assert_eq!(stringify_expr!(true || false), "true || false");
+    assert_eq!(
+        stringify_expr!(true || false && false),
+        "true || false && false",
+    );
+
+    // ExprKind::Unary
+    assert_eq!(stringify_expr!(*expr), "*expr");
+    assert_eq!(stringify_expr!(!expr), "!expr");
+    assert_eq!(stringify_expr!(-expr), "-expr");
+
+    // ExprKind::Lit
+    assert_eq!(stringify_expr!('x'), "'x'");
+    assert_eq!(stringify_expr!(1_000_i8), "1_000_i8");
+    assert_eq!(stringify_expr!(1.00000000000000001), "1.00000000000000001");
+
+    // ExprKind::Cast
+    assert_eq!(stringify_expr!(expr as T), "expr as T");
+    assert_eq!(stringify_expr!(expr as T<u8>), "expr as T<u8>");
+
+    // ExprKind::Type
+    assert_eq!(stringify_expr!(expr: T), "expr: T");
+    assert_eq!(stringify_expr!(expr: T<u8>), "expr: T<u8>");
+
+    // ExprKind::If
+    assert_eq!(stringify_expr!(if true {}), "if true {}");
+    assert_eq!(
+        stringify_expr!(if true {
+        } else {
+        }),
+        "if true {} else {}",
+    );
+    assert_eq!(
+        stringify_expr!(if let true = true {
+        } else {
+        }),
+        "if let true = true {} else {}",
+    );
+    assert_eq!(
+        stringify_expr!(if true {
+        } else if false {
+        }),
+        "if true {} else if false {}",
+    );
+    assert_eq!(
+        stringify_expr!(if true {
+        } else if false {
+        } else {
+        }),
+        "if true {} else if false {} else {}",
+    );
+    assert_eq!(
+        stringify_expr!(if true {
+            return;
+        } else if false {
+            0
+        } else {
+            0
+        }),
+        "if true { return; } else if false { 0 } else { 0 }",
+    );
+
+    // ExprKind::While
+    assert_eq!(stringify_expr!(while true {}), "while true {}");
+    assert_eq!(stringify_expr!('a: while true {}), "'a: while true {}");
+    assert_eq!(
+        stringify_expr!(while let true = true {}),
+        "while let true = true {}",
+    );
+
+    // ExprKind::ForLoop
+    assert_eq!(stringify_expr!(for _ in x {}), "for _ in x {}");
+    assert_eq!(stringify_expr!('a: for _ in x {}), "'a: for _ in x {}");
+
+    // ExprKind::Loop
+    assert_eq!(stringify_expr!(loop {}), "loop {}");
+    assert_eq!(stringify_expr!('a: loop {}), "'a: loop {}");
+
+    // ExprKind::Match
+    assert_eq!(stringify_expr!(match self {}), "match self {}");
+    assert_eq!(
+        stringify_expr!(match self {
+            Ok => 1,
+        }),
+        "match self { Ok => 1, }",
+    );
+    assert_eq!(
+        stringify_expr!(match self {
+            Ok => 1,
+            Err => 0,
+        }),
+        "match self { Ok => 1, Err => 0, }",
+    );
+
+    // ExprKind::Closure
+    assert_eq!(stringify_expr!(|| {}), "|| {}");
+    assert_eq!(stringify_expr!(|x| {}), "|x| {}");
+    assert_eq!(stringify_expr!(|x: u8| {}), "|x: u8| {}");
+    assert_eq!(stringify_expr!(|| ()), "|| ()");
+    assert_eq!(stringify_expr!(move || self), "move || self");
+    assert_eq!(stringify_expr!(async || self), "async || self");
+    assert_eq!(stringify_expr!(async move || self), "async move || self");
+    assert_eq!(stringify_expr!(static || self), "static || self");
+    assert_eq!(stringify_expr!(static move || self), "static move || self");
+    #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5149
+    assert_eq!(
+        stringify_expr!(static async || self),
+        "static async || self",
+    );
+    #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5149
+    assert_eq!(
+        stringify_expr!(static async move || self),
+        "static async move || self",
+    );
+    assert_eq!(stringify_expr!(|| -> u8 { self }), "|| -> u8 { self }");
+    assert_eq!(stringify_expr!(1 + || {}), "1 + (|| {})"); // ??
+
+    // ExprKind::Block
+    assert_eq!(stringify_expr!({}), "{}");
+    assert_eq!(stringify_expr!(unsafe {}), "unsafe {}");
+    assert_eq!(stringify_expr!('a: {}), "'a: {}");
+    assert_eq!(
+        stringify_expr!(
+            #[attr]
+            {}
+        ),
+        "#[attr] { }", // FIXME
+    );
+    assert_eq!(
+        stringify_expr!(
+            {
+                #![attr]
+            }
+        ),
+        "{\n    #![attr]\n}",
+    );
+
+    // ExprKind::Async
+    assert_eq!(stringify_expr!(async {}), "async {}");
+    assert_eq!(stringify_expr!(async move {}), "async move {}");
+
+    // ExprKind::Await
+    assert_eq!(stringify_expr!(expr.await), "expr.await");
+
+    // ExprKind::TryBlock
+    assert_eq!(stringify_expr!(try {}), "try  {}"); // FIXME
+
+    // ExprKind::Assign
+    assert_eq!(stringify_expr!(expr = true), "expr = true");
+
+    // ExprKind::AssignOp
+    assert_eq!(stringify_expr!(expr += true), "expr += true");
+
+    // ExprKind::Field
+    assert_eq!(stringify_expr!(expr.field), "expr.field");
+    assert_eq!(stringify_expr!(expr.0), "expr.0");
+
+    // ExprKind::Index
+    assert_eq!(stringify_expr!(expr[true]), "expr[true]");
+
+    // ExprKind::Range
+    assert_eq!(stringify_expr!(..), "..");
+    assert_eq!(stringify_expr!(..hi), "..hi");
+    assert_eq!(stringify_expr!(lo..), "lo..");
+    assert_eq!(stringify_expr!(lo..hi), "lo..hi");
+    assert_eq!(stringify_expr!(..=hi), "..=hi");
+    assert_eq!(stringify_expr!(lo..=hi), "lo..=hi");
+    assert_eq!(stringify_expr!(-2..=-1), "-2..=-1");
+
+    // ExprKind::Path
+    assert_eq!(stringify_expr!(thing), "thing");
+    assert_eq!(stringify_expr!(m::thing), "m::thing");
+    assert_eq!(stringify_expr!(self::thing), "self::thing");
+    assert_eq!(stringify_expr!(crate::thing), "crate::thing");
+    assert_eq!(stringify_expr!(Self::thing), "Self::thing");
+    assert_eq!(stringify_expr!(<Self as T>::thing), "<Self as T>::thing");
+    assert_eq!(stringify_expr!(Self::<'static>), "Self::<'static>");
+
+    // ExprKind::AddrOf
+    assert_eq!(stringify_expr!(&expr), "&expr");
+    assert_eq!(stringify_expr!(&mut expr), "&mut expr");
+    assert_eq!(stringify_expr!(&raw const expr), "&raw const expr");
+    assert_eq!(stringify_expr!(&raw mut expr), "&raw mut expr");
+
+    // ExprKind::Break
+    assert_eq!(stringify_expr!(break), "break");
+    assert_eq!(stringify_expr!(break 'a), "break 'a");
+    assert_eq!(stringify_expr!(break true), "break true");
+    assert_eq!(stringify_expr!(break 'a true), "break 'a true");
+
+    // ExprKind::Continue
+    assert_eq!(stringify_expr!(continue), "continue");
+    assert_eq!(stringify_expr!(continue 'a), "continue 'a");
+
+    // ExprKind::Ret
+    assert_eq!(stringify_expr!(return), "return");
+    assert_eq!(stringify_expr!(return true), "return true");
+
+    // ExprKind::MacCall
+    assert_eq!(stringify_expr!(mac!(...)), "mac!(...)");
+    assert_eq!(stringify_expr!(mac![...]), "mac![...]");
+    assert_eq!(stringify_expr!(mac! { ... }), "mac! { ... }");
+
+    // ExprKind::Struct
+    assert_eq!(stringify_expr!(Struct {}), "Struct{}"); // FIXME
+    #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5151
+    assert_eq!(stringify_expr!(<Struct as Trait>::Type {}), "<Struct as Trait>::Type{}");
+    assert_eq!(stringify_expr!(Struct { .. }), "Struct{..}"); // FIXME
+    assert_eq!(stringify_expr!(Struct { ..base }), "Struct{..base}"); // FIXME
+    assert_eq!(stringify_expr!(Struct { x }), "Struct{x,}");
+    assert_eq!(stringify_expr!(Struct { x, .. }), "Struct{x, ..}");
+    assert_eq!(stringify_expr!(Struct { x, ..base }), "Struct{x, ..base}");
+    assert_eq!(stringify_expr!(Struct { x: true }), "Struct{x: true,}");
+    assert_eq!(
+        stringify_expr!(Struct { x: true, .. }),
+        "Struct{x: true, ..}",
+    );
+    assert_eq!(
+        stringify_expr!(Struct { x: true, ..base }),
+        "Struct{x: true, ..base}",
+    );
+
+    // ExprKind::Repeat
+    assert_eq!(stringify_expr!([(); 0]), "[(); 0]");
+
+    // ExprKind::Paren
+    assert_eq!(stringify_expr!((expr)), "(expr)");
+
+    // ExprKind::Try
+    assert_eq!(stringify_expr!(expr?), "expr?");
+
+    // ExprKind::Yield
+    assert_eq!(stringify_expr!(yield), "yield");
+    assert_eq!(stringify_expr!(yield true), "yield true");
+}
+
+#[test]
+fn test_item() {
+    // ItemKind::ExternCrate
+    assert_eq!(
+        stringify_item!(
+            extern crate std;
+        ),
+        "extern crate std;",
+    );
+    assert_eq!(
+        stringify_item!(
+            pub extern crate self as std;
+        ),
+        "pub extern crate self as std;",
+    );
+
+    // ItemKind::Use
+    assert_eq!(
+        stringify_item!(
+            pub use crate::{a, b::c};
+        ),
+        "pub use crate::{a, b::c};",
+    );
+
+    // ItemKind::Static
+    assert_eq!(
+        stringify_item!(
+            pub static S: () = {};
+        ),
+        "pub static S: () = {};",
+    );
+    assert_eq!(
+        stringify_item!(
+            static mut S: () = {};
+        ),
+        "static mut S: () = {};",
+    );
+    assert_eq!(
+        stringify_item!(
+            static S: ();
+        ),
+        "static S: () ;", // FIXME
+    );
+    assert_eq!(
+        stringify_item!(
+            static mut S: ();
+        ),
+        "static mut S: () ;",
+    );
+
+    // ItemKind::Const
+    assert_eq!(
+        stringify_item!(
+            pub const S: () = {};
+        ),
+        "pub const S: () = {};",
+    );
+    assert_eq!(
+        stringify_item!(
+            const S: ();
+        ),
+        "const S: () ;", // FIXME
+    );
+
+    // ItemKind::Fn
+    assert_eq!(
+        stringify_item!(
+            pub default const async unsafe extern "C" fn f() {}
+        ),
+        "pub default const async unsafe extern \"C\" fn f() {}",
+    );
+
+    // ItemKind::Mod
+    assert_eq!(
+        stringify_item!(
+            pub mod m;
+        ),
+        "pub mod m;",
+    );
+    assert_eq!(
+        stringify_item!(
+            mod m {}
+        ),
+        "mod m {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            unsafe mod m;
+        ),
+        "unsafe mod m;",
+    );
+    assert_eq!(
+        stringify_item!(
+            unsafe mod m {}
+        ),
+        "unsafe mod m {}",
+    );
+
+    // ItemKind::ForeignMod
+    assert_eq!(
+        stringify_item!(
+            extern "C" {}
+        ),
+        "extern \"C\" {}",
+    );
+    #[rustfmt::skip]
+    assert_eq!(
+        stringify_item!(
+            pub extern "C" {}
+        ),
+        "extern \"C\" {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            unsafe extern "C++" {}
+        ),
+        "unsafe extern \"C++\" {}",
+    );
+
+    // ItemKind::TyAlias
+    #[rustfmt::skip]
+    assert_eq!(
+        stringify_item!(
+            pub default type Type<'a>: Bound
+            where
+                Self: 'a,
+            = T;
+        ),
+        "pub default type Type<'a>: Bound where Self: 'a = T;",
+    );
+
+    // ItemKind::Enum
+    assert_eq!(
+        stringify_item!(
+            pub enum Void {}
+        ),
+        "pub enum Void {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            enum Empty {
+                Unit,
+                Tuple(),
+                Struct {},
+            }
+        ),
+        "enum Empty { Unit, Tuple(), Struct {}, }",
+    );
+    assert_eq!(
+        stringify_item!(
+            enum Enum<T> where T: 'a {
+                Unit,
+                Tuple(T),
+                Struct { t: T },
+            }
+        ),
+        "enum Enum<T> where T: 'a {\n    Unit,\n    Tuple(T),\n    Struct {\n        t: T,\n    },\n}",
+    );
+
+    // ItemKind::Struct
+    assert_eq!(
+        stringify_item!(
+            pub struct Unit;
+        ),
+        "pub struct Unit;",
+    );
+    assert_eq!(
+        stringify_item!(
+            struct Tuple();
+        ),
+        "struct Tuple();",
+    );
+    assert_eq!(
+        stringify_item!(
+            struct Tuple(T);
+        ),
+        "struct Tuple(T);",
+    );
+    assert_eq!(
+        stringify_item!(
+            struct Struct {}
+        ),
+        "struct Struct {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            struct Struct<T>
+            where
+                T: 'a,
+            {
+                t: T,
+            }
+        ),
+        "struct Struct<T> where T: 'a {\n    t: T,\n}",
+    );
+
+    // ItemKind::Union
+    assert_eq!(
+        stringify_item!(
+            pub union Union {}
+        ),
+        "pub union Union {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            union Union<T> where T: 'a {
+                t: T,
+            }
+        ),
+        "union Union<T> where T: 'a {\n    t: T,\n}",
+    );
+
+    // ItemKind::Trait
+    assert_eq!(
+        stringify_item!(
+            pub unsafe auto trait Send {}
+        ),
+        "pub unsafe auto trait Send {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            trait Trait<'a>: Sized
+            where
+                Self: 'a,
+            {
+            }
+        ),
+        "trait Trait<'a>: Sized where Self: 'a {}",
+    );
+
+    // ItemKind::TraitAlias
+    assert_eq!(
+        stringify_item!(
+            pub trait Trait<T> = Sized where T: 'a;
+        ),
+        "", // FIXME
+    );
+
+    // ItemKind::Impl
+    assert_eq!(
+        stringify_item!(
+            pub impl Struct {}
+        ),
+        "pub impl Struct {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            impl<T> Struct<T> {}
+        ),
+        "impl <T> Struct<T> {}", // FIXME
+    );
+    assert_eq!(
+        stringify_item!(
+            pub impl Trait for Struct {}
+        ),
+        "pub impl Trait for Struct {}",
+    );
+    assert_eq!(
+        stringify_item!(
+            impl ~const Struct {}
+        ),
+        "impl Struct {}", // FIXME
+    );
+
+    // ItemKind::MacCall
+    assert_eq!(stringify_item!(mac!(...);), "mac!(...);");
+    assert_eq!(stringify_item!(mac![...];), "mac![...];");
+    assert_eq!(stringify_item!(mac! { ... }), "mac! { ... }");
+
+    // ItemKind::MacroDef
+    assert_eq!(
+        stringify_item!(
+            macro_rules! stringify {
+                () => {};
+            }
+        ),
+        "macro_rules! stringify { () => {} ; }", // FIXME
+    );
+    assert_eq!(
+        stringify_item!(
+            pub macro stringify() {}
+        ),
+        "pub macro stringify { () => {} }",
+    );
+}
+
+#[test]
+fn test_meta() {
+    assert_eq!(stringify_meta!(k), "k");
+    assert_eq!(stringify_meta!(k = "v"), "k = \"v\"");
+    assert_eq!(stringify_meta!(list(k1, k2 = "v")), "list(k1, k2 = \"v\")");
+    assert_eq!(stringify_meta!(serde::k), "serde::k");
+}
+
+#[test]
+fn test_pat() {
+    // PatKind::Wild
+    assert_eq!(stringify_pat!(_), "_");
+
+    // PatKind::Ident
+    assert_eq!(stringify_pat!(_x), "_x");
+    assert_eq!(stringify_pat!(ref _x), "ref _x");
+    assert_eq!(stringify_pat!(mut _x), "mut _x");
+    assert_eq!(stringify_pat!(ref mut _x), "ref mut _x");
+    assert_eq!(stringify_pat!(ref mut _x @ _), "ref mut _x @ _");
+
+    // PatKind::Struct
+    assert_eq!(stringify_pat!(Struct {}), "Struct {  }"); // FIXME
+    assert_eq!(stringify_pat!(Struct::<u8> {}), "Struct::<u8> {  }");
+    assert_eq!(
+        stringify_pat!(Struct::<'static> {}),
+        "Struct::<'static> {  }",
+    );
+    assert_eq!(stringify_pat!(Struct { x }), "Struct { x }");
+    assert_eq!(stringify_pat!(Struct { x: _x }), "Struct { x: _x }");
+    assert_eq!(stringify_pat!(Struct { .. }), "Struct { .. }");
+    assert_eq!(stringify_pat!(Struct { x, .. }), "Struct { x, .. }");
+    assert_eq!(stringify_pat!(Struct { x: _x, .. }), "Struct { x: _x, .. }");
+    #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5151
+    assert_eq!(
+        stringify_pat!(<Struct as Trait>::Type {}),
+        "<Struct as Trait>::Type {  }",
+    );
+
+    // PatKind::TupleStruct
+    assert_eq!(stringify_pat!(Tuple()), "Tuple()");
+    assert_eq!(stringify_pat!(Tuple::<u8>()), "Tuple::<u8>()");
+    assert_eq!(stringify_pat!(Tuple::<'static>()), "Tuple::<'static>()");
+    assert_eq!(stringify_pat!(Tuple(x)), "Tuple(x)");
+    assert_eq!(stringify_pat!(Tuple(..)), "Tuple(..)");
+    assert_eq!(stringify_pat!(Tuple(x, ..)), "Tuple(x, ..)");
+    assert_eq!(
+        stringify_pat!(<Struct as Trait>::Type()),
+        "<Struct as Trait>::Type()",
+    );
+
+    // PatKind::Or
+    assert_eq!(stringify_pat!(true | false), "true | false");
+    assert_eq!(stringify_pat!(| true), "true");
+    assert_eq!(stringify_pat!(|true| false), "true | false");
+
+    // PatKind::Path
+    assert_eq!(stringify_pat!(crate::Path), "crate::Path");
+    assert_eq!(stringify_pat!(Path::<u8>), "Path::<u8>");
+    assert_eq!(stringify_pat!(Path::<'static>), "Path::<'static>");
+    assert_eq!(
+        stringify_pat!(<Struct as Trait>::Type),
+        "<Struct as Trait>::Type",
+    );
+
+    // PatKind::Tuple
+    assert_eq!(stringify_pat!(()), "()");
+    assert_eq!(stringify_pat!((true,)), "(true,)");
+    assert_eq!(stringify_pat!((true, false)), "(true, false)");
+
+    // PatKind::Box
+    assert_eq!(stringify_pat!(box pat), "box pat");
+
+    // PatKind::Ref
+    assert_eq!(stringify_pat!(&pat), "&pat");
+    assert_eq!(stringify_pat!(&mut pat), "&mut pat");
+
+    // PatKind::Lit
+    assert_eq!(stringify_pat!(1_000_i8), "1_000_i8");
+
+    // PatKind::Range
+    assert_eq!(stringify_pat!(..1), "..1");
+    assert_eq!(stringify_pat!(0..), "0 .."); // FIXME
+    assert_eq!(stringify_pat!(0..1), "0 ..1");
+    assert_eq!(stringify_pat!(0..=1), "0 ..=1");
+    assert_eq!(stringify_pat!(-2..=-1), "-2 ..=-1");
+
+    // PatKind::Slice
+    assert_eq!(stringify_pat!([]), "[]");
+    assert_eq!(stringify_pat!([true]), "[true]");
+    assert_eq!(stringify_pat!([true,]), "[true]");
+    assert_eq!(stringify_pat!([true, false]), "[true, false]");
+
+    // PatKind::Rest
+    assert_eq!(stringify_pat!(..), "..");
+
+    // PatKind::Paren
+    assert_eq!(stringify_pat!((pat)), "(pat)");
+
+    // PatKind::MacCall
+    assert_eq!(stringify_pat!(mac!(...)), "mac!(...)");
+    assert_eq!(stringify_pat!(mac![...]), "mac![...]");
+    assert_eq!(stringify_pat!(mac! { ... }), "mac! { ... }");
+}
+
+#[test]
+fn test_path() {
+    assert_eq!(stringify_path!(thing), "thing");
+    assert_eq!(stringify_path!(m::thing), "m::thing");
+    assert_eq!(stringify_path!(self::thing), "self::thing");
+    assert_eq!(stringify_path!(crate::thing), "crate::thing");
+    assert_eq!(stringify_path!(Self::thing), "Self::thing");
+    assert_eq!(stringify_path!(Self<'static>), "Self<'static>");
+    assert_eq!(stringify_path!(Self::<'static>), "Self<'static>");
+    assert_eq!(stringify_path!(Self()), "Self()");
+    assert_eq!(stringify_path!(Self() -> ()), "Self() -> ()");
+}
+
+#[test]
+fn test_stmt() {
+    // StmtKind::Local
+    assert_eq!(stringify_stmt!(let _), "let _;");
+    assert_eq!(stringify_stmt!(let x = true), "let x = true;");
+    assert_eq!(stringify_stmt!(let x: bool = true), "let x: bool = true;");
+
+    // StmtKind::Item
+    assert_eq!(
+        stringify_stmt!(
+            struct S;
+        ),
+        "struct S;",
+    );
+
+    // StmtKind::Expr
+    assert_eq!(stringify_stmt!(loop {}), "loop {}");
+
+    // StmtKind::Semi
+    assert_eq!(stringify_stmt!(1 + 1), "1 + 1;");
+
+    // StmtKind::Empty
+    assert_eq!(stringify_stmt!(;), ";");
+
+    // StmtKind::MacCall
+    assert_eq!(stringify_stmt!(mac!(...)), "mac!(...)");
+    assert_eq!(stringify_stmt!(mac![...]), "mac![...]");
+    assert_eq!(stringify_stmt!(mac! { ... }), "mac! { ... }");
+}
+
+#[test]
+fn test_ty() {
+    // TyKind::Slice
+    assert_eq!(stringify_ty!([T]), "[T]");
+
+    // TyKind::Array
+    assert_eq!(stringify_ty!([T; 0]), "[T; 0]");
+
+    // TyKind::Ptr
+    assert_eq!(stringify_ty!(*const T), "*const T");
+    assert_eq!(stringify_ty!(*mut T), "*mut T");
+
+    // TyKind::Rptr
+    assert_eq!(stringify_ty!(&T), "&T");
+    assert_eq!(stringify_ty!(&mut T), "&mut T");
+    assert_eq!(stringify_ty!(&'a T), "&'a T");
+    assert_eq!(stringify_ty!(&'a mut T), "&'a mut T");
+
+    // TyKind::BareFn
+    assert_eq!(stringify_ty!(fn()), "fn()");
+    assert_eq!(stringify_ty!(fn() -> ()), "fn() -> ()");
+    assert_eq!(stringify_ty!(fn(u8)), "fn(u8)");
+    assert_eq!(stringify_ty!(fn(x: u8)), "fn(x: u8)");
+    #[rustfmt::skip]
+    assert_eq!(stringify_ty!(for<> fn()), "fn()");
+    assert_eq!(stringify_ty!(for<'a> fn()), "for<'a>fn()"); // FIXME
+
+    // TyKind::Never
+    assert_eq!(stringify_ty!(!), "!");
+
+    // TyKind::Tup
+    assert_eq!(stringify_ty!(()), "()");
+    assert_eq!(stringify_ty!((T,)), "(T,)");
+    assert_eq!(stringify_ty!((T, U)), "(T, U)");
+
+    // TyKind::Path
+    assert_eq!(stringify_ty!(T), "T");
+    assert_eq!(stringify_ty!(Ref<'a>), "Ref<'a>");
+    assert_eq!(stringify_ty!(PhantomData<T>), "PhantomData<T>");
+    assert_eq!(stringify_ty!(PhantomData::<T>), "PhantomData<T>");
+    assert_eq!(stringify_ty!(Fn() -> !), "Fn() -> !");
+    assert_eq!(stringify_ty!(Fn(u8) -> !), "Fn(u8) -> !");
+    assert_eq!(
+        stringify_ty!(<Struct as Trait>::Type),
+        "<Struct as Trait>::Type",
+    );
+
+    // TyKind::TraitObject
+    assert_eq!(stringify_ty!(dyn Send), "dyn Send");
+    assert_eq!(stringify_ty!(dyn Send + 'a), "dyn Send + 'a");
+    assert_eq!(stringify_ty!(dyn 'a + Send), "dyn 'a + Send");
+    assert_eq!(stringify_ty!(dyn ?Sized), "dyn ?Sized");
+    assert_eq!(stringify_ty!(dyn ~const Clone), "dyn Clone"); // FIXME
+    assert_eq!(stringify_ty!(dyn for<'a> Send), "dyn for<'a> Send");
+
+    // TyKind::ImplTrait
+    assert_eq!(stringify_ty!(impl Send), "impl Send");
+    assert_eq!(stringify_ty!(impl Send + 'a), "impl Send + 'a");
+    assert_eq!(stringify_ty!(impl 'a + Send), "impl 'a + Send");
+    assert_eq!(stringify_ty!(impl ?Sized), "impl ?Sized");
+    assert_eq!(stringify_ty!(impl ~const Clone), "impl Clone"); // FIXME
+    assert_eq!(stringify_ty!(impl for<'a> Send), "impl for<'a> Send");
+
+    // TyKind::Paren
+    assert_eq!(stringify_ty!((T)), "(T)");
+
+    // TyKind::Infer
+    assert_eq!(stringify_ty!(_), "_");
+
+    // TyKind::MacCall
+    assert_eq!(stringify_ty!(mac!(...)), "mac!(...)");
+    assert_eq!(stringify_ty!(mac![...]), "mac![...]");
+    assert_eq!(stringify_ty!(mac! { ... }), "mac! { ... }");
+}
+
+#[test]
+fn test_vis() {
+    // VisibilityKind::Public
+    assert_eq!(stringify_vis!(pub), "pub ");
+
+    // VisibilityKind::Crate
+    assert_eq!(stringify_vis!(crate), "crate ");
+
+    // VisibilityKind::Restricted
+    assert_eq!(stringify_vis!(pub(self)), "pub(self) ");
+    assert_eq!(stringify_vis!(pub(super)), "pub(super) ");
+    assert_eq!(stringify_vis!(pub(in self)), "pub(self) ");
+    assert_eq!(stringify_vis!(pub(in super)), "pub(super) ");
+    assert_eq!(stringify_vis!(pub(in path::to)), "pub(in path::to) ");
+    assert_eq!(stringify_vis!(pub(in ::path::to)), "pub(in ::path::to) ");
+    assert_eq!(
+        stringify_vis!(pub(in self::path::to)),
+        "pub(in self::path::to) ",
+    );
+    assert_eq!(
+        stringify_vis!(pub(in super::path::to)),
+        "pub(in super::path::to) ",
+    );
+
+    // VisibilityKind::Inherited
+    // Directly calling `stringify_vis!()` does not work.
+    macro_rules! stringify_inherited_vis {
+        ($vis:vis struct) => {
+            stringify_vis!($vis)
+        };
+    }
+    assert_eq!(stringify_inherited_vis!(struct), "");
+}

From ac43ba8bb8edd53090f8749c6be93eb7b7950488 Mon Sep 17 00:00:00 2001
From: David Tolnay <dtolnay@gmail.com>
Date: Thu, 23 Dec 2021 16:53:30 -0800
Subject: [PATCH 05/10] Format with rust-lang/rust's rustfmt settings

---
 src/test/ui/macros/stringify.rs | 55 +++++++++------------------------
 1 file changed, 14 insertions(+), 41 deletions(-)

diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs
index 924329d7a8441..39aac34d45a4a 100644
--- a/src/test/ui/macros/stringify.rs
+++ b/src/test/ui/macros/stringify.rs
@@ -116,10 +116,7 @@ fn test_expr() {
 
     // ExprKind::Binary
     assert_eq!(stringify_expr!(true || false), "true || false");
-    assert_eq!(
-        stringify_expr!(true || false && false),
-        "true || false && false",
-    );
+    assert_eq!(stringify_expr!(true || false && false), "true || false && false");
 
     // ExprKind::Unary
     assert_eq!(stringify_expr!(*expr), "*expr");
@@ -180,10 +177,7 @@ fn test_expr() {
     // ExprKind::While
     assert_eq!(stringify_expr!(while true {}), "while true {}");
     assert_eq!(stringify_expr!('a: while true {}), "'a: while true {}");
-    assert_eq!(
-        stringify_expr!(while let true = true {}),
-        "while let true = true {}",
-    );
+    assert_eq!(stringify_expr!(while let true = true {}), "while let true = true {}");
 
     // ExprKind::ForLoop
     assert_eq!(stringify_expr!(for _ in x {}), "for _ in x {}");
@@ -328,14 +322,8 @@ fn test_expr() {
     assert_eq!(stringify_expr!(Struct { x, .. }), "Struct{x, ..}");
     assert_eq!(stringify_expr!(Struct { x, ..base }), "Struct{x, ..base}");
     assert_eq!(stringify_expr!(Struct { x: true }), "Struct{x: true,}");
-    assert_eq!(
-        stringify_expr!(Struct { x: true, .. }),
-        "Struct{x: true, ..}",
-    );
-    assert_eq!(
-        stringify_expr!(Struct { x: true, ..base }),
-        "Struct{x: true, ..base}",
-    );
+    assert_eq!(stringify_expr!(Struct { x: true, .. }), "Struct{x: true, ..}");
+    assert_eq!(stringify_expr!(Struct { x: true, ..base }), "Struct{x: true, ..base}");
 
     // ExprKind::Repeat
     assert_eq!(stringify_expr!([(); 0]), "[(); 0]");
@@ -501,7 +489,10 @@ fn test_item() {
     );
     assert_eq!(
         stringify_item!(
-            enum Enum<T> where T: 'a {
+            enum Enum<T>
+            where
+                T: 'a,
+            {
                 Unit,
                 Tuple(T),
                 Struct { t: T },
@@ -660,10 +651,7 @@ fn test_pat() {
     // PatKind::Struct
     assert_eq!(stringify_pat!(Struct {}), "Struct {  }"); // FIXME
     assert_eq!(stringify_pat!(Struct::<u8> {}), "Struct::<u8> {  }");
-    assert_eq!(
-        stringify_pat!(Struct::<'static> {}),
-        "Struct::<'static> {  }",
-    );
+    assert_eq!(stringify_pat!(Struct::<'static> {}), "Struct::<'static> {  }");
     assert_eq!(stringify_pat!(Struct { x }), "Struct { x }");
     assert_eq!(stringify_pat!(Struct { x: _x }), "Struct { x: _x }");
     assert_eq!(stringify_pat!(Struct { .. }), "Struct { .. }");
@@ -682,10 +670,7 @@ fn test_pat() {
     assert_eq!(stringify_pat!(Tuple(x)), "Tuple(x)");
     assert_eq!(stringify_pat!(Tuple(..)), "Tuple(..)");
     assert_eq!(stringify_pat!(Tuple(x, ..)), "Tuple(x, ..)");
-    assert_eq!(
-        stringify_pat!(<Struct as Trait>::Type()),
-        "<Struct as Trait>::Type()",
-    );
+    assert_eq!(stringify_pat!(<Struct as Trait>::Type()), "<Struct as Trait>::Type()");
 
     // PatKind::Or
     assert_eq!(stringify_pat!(true | false), "true | false");
@@ -696,10 +681,7 @@ fn test_pat() {
     assert_eq!(stringify_pat!(crate::Path), "crate::Path");
     assert_eq!(stringify_pat!(Path::<u8>), "Path::<u8>");
     assert_eq!(stringify_pat!(Path::<'static>), "Path::<'static>");
-    assert_eq!(
-        stringify_pat!(<Struct as Trait>::Type),
-        "<Struct as Trait>::Type",
-    );
+    assert_eq!(stringify_pat!(<Struct as Trait>::Type), "<Struct as Trait>::Type");
 
     // PatKind::Tuple
     assert_eq!(stringify_pat!(()), "()");
@@ -826,10 +808,7 @@ fn test_ty() {
     assert_eq!(stringify_ty!(PhantomData::<T>), "PhantomData<T>");
     assert_eq!(stringify_ty!(Fn() -> !), "Fn() -> !");
     assert_eq!(stringify_ty!(Fn(u8) -> !), "Fn(u8) -> !");
-    assert_eq!(
-        stringify_ty!(<Struct as Trait>::Type),
-        "<Struct as Trait>::Type",
-    );
+    assert_eq!(stringify_ty!(<Struct as Trait>::Type), "<Struct as Trait>::Type");
 
     // TyKind::TraitObject
     assert_eq!(stringify_ty!(dyn Send), "dyn Send");
@@ -874,14 +853,8 @@ fn test_vis() {
     assert_eq!(stringify_vis!(pub(in super)), "pub(super) ");
     assert_eq!(stringify_vis!(pub(in path::to)), "pub(in path::to) ");
     assert_eq!(stringify_vis!(pub(in ::path::to)), "pub(in ::path::to) ");
-    assert_eq!(
-        stringify_vis!(pub(in self::path::to)),
-        "pub(in self::path::to) ",
-    );
-    assert_eq!(
-        stringify_vis!(pub(in super::path::to)),
-        "pub(in super::path::to) ",
-    );
+    assert_eq!(stringify_vis!(pub(in self::path::to)), "pub(in self::path::to) ");
+    assert_eq!(stringify_vis!(pub(in super::path::to)), "pub(in super::path::to) ");
 
     // VisibilityKind::Inherited
     // Directly calling `stringify_vis!()` does not work.

From 55fc986be72c0db77b65b0198ed5b26ac918ddad Mon Sep 17 00:00:00 2001
From: David Tolnay <dtolnay@gmail.com>
Date: Thu, 23 Dec 2021 16:51:24 -0800
Subject: [PATCH 06/10] Fix tidy line length lint in stringify tests

---
 src/test/ui/macros/stringify.rs | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/test/ui/macros/stringify.rs b/src/test/ui/macros/stringify.rs
index 39aac34d45a4a..fcf6a9278d8fe 100644
--- a/src/test/ui/macros/stringify.rs
+++ b/src/test/ui/macros/stringify.rs
@@ -243,7 +243,9 @@ fn test_expr() {
                 #![attr]
             }
         ),
-        "{\n    #![attr]\n}",
+        "{\n\
+        \x20   #![attr]\n\
+        }",
     );
 
     // ExprKind::Async
@@ -498,7 +500,13 @@ fn test_item() {
                 Struct { t: T },
             }
         ),
-        "enum Enum<T> where T: 'a {\n    Unit,\n    Tuple(T),\n    Struct {\n        t: T,\n    },\n}",
+        "enum Enum<T> where T: 'a {\n\
+        \x20   Unit,\n\
+        \x20   Tuple(T),\n\
+        \x20   Struct {\n\
+        \x20       t: T,\n\
+        \x20   },\n\
+        }",
     );
 
     // ItemKind::Struct
@@ -535,7 +543,9 @@ fn test_item() {
                 t: T,
             }
         ),
-        "struct Struct<T> where T: 'a {\n    t: T,\n}",
+        "struct Struct<T> where T: 'a {\n\
+        \x20   t: T,\n\
+        }",
     );
 
     // ItemKind::Union
@@ -551,7 +561,9 @@ fn test_item() {
                 t: T,
             }
         ),
-        "union Union<T> where T: 'a {\n    t: T,\n}",
+        "union Union<T> where T: 'a {\n\
+        \x20   t: T,\n\
+        }",
     );
 
     // ItemKind::Trait

From 9702348957083e1104776edcf897ca1808364869 Mon Sep 17 00:00:00 2001
From: Smitty <me@smitop.com>
Date: Mon, 27 Dec 2021 12:31:40 -0500
Subject: [PATCH 07/10] Clarify that repeat count must be positive

---
 compiler/rustc_builtin_macros/src/concat_bytes.rs | 2 +-
 src/test/ui/macros/concat-bytes-error.rs          | 8 ++++----
 src/test/ui/macros/concat-bytes-error.stderr      | 8 ++++----
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 87920e5175268..eb08170959bfb 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -154,7 +154,7 @@ pub fn expand_concat_bytes(
                         }
                     }
                 } else {
-                    cx.span_err(count.value.span, "repeat count is not a number");
+                    cx.span_err(count.value.span, "repeat count is not a positive number");
                 }
             }
             ast::ExprKind::Lit(ref lit) => match lit.kind {
diff --git a/src/test/ui/macros/concat-bytes-error.rs b/src/test/ui/macros/concat-bytes-error.rs
index 2c7997d5e5905..db5d3cab0bd8a 100644
--- a/src/test/ui/macros/concat-bytes-error.rs
+++ b/src/test/ui/macros/concat-bytes-error.rs
@@ -39,12 +39,12 @@ fn main() {
     ]);
     concat_bytes!(5u16); //~ ERROR cannot concatenate numeric literals
     concat_bytes!([5u16]); //~ ERROR numeric literal is not a `u8`
-    concat_bytes!([3; ()]); //~ ERROR repeat count is not a number
-    concat_bytes!([3; -2]); //~ ERROR repeat count is not a number
-    concat_bytes!([pie; -2]); //~ ERROR repeat count is not a number
+    concat_bytes!([3; ()]); //~ ERROR repeat count is not a positive number
+    concat_bytes!([3; -2]); //~ ERROR repeat count is not a positive number
+    concat_bytes!([pie; -2]); //~ ERROR repeat count is not a positive number
     concat_bytes!([pie; 2]); //~ ERROR expected a byte literal
     concat_bytes!([2.2; 0]); //~ ERROR cannot concatenate float literals
-    concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a number
+    concat_bytes!([5.5; ()]); //~ ERROR repeat count is not a positive number
     concat_bytes!([[1, 2, 3]; 3]); //~ ERROR cannot concatenate doubly nested array
     concat_bytes!([[42; 2]; 3]); //~ ERROR cannot concatenate doubly nested array
 }
diff --git a/src/test/ui/macros/concat-bytes-error.stderr b/src/test/ui/macros/concat-bytes-error.stderr
index f0c53839b3ad5..d6cd1a3d178b0 100644
--- a/src/test/ui/macros/concat-bytes-error.stderr
+++ b/src/test/ui/macros/concat-bytes-error.stderr
@@ -127,19 +127,19 @@ error: numeric literal is not a `u8`
 LL |     concat_bytes!([5u16]);
    |                    ^^^^
 
-error: repeat count is not a number
+error: repeat count is not a positive number
   --> $DIR/concat-bytes-error.rs:42:23
    |
 LL |     concat_bytes!([3; ()]);
    |                       ^^
 
-error: repeat count is not a number
+error: repeat count is not a positive number
   --> $DIR/concat-bytes-error.rs:43:23
    |
 LL |     concat_bytes!([3; -2]);
    |                       ^^
 
-error: repeat count is not a number
+error: repeat count is not a positive number
   --> $DIR/concat-bytes-error.rs:44:25
    |
 LL |     concat_bytes!([pie; -2]);
@@ -159,7 +159,7 @@ error: cannot concatenate float literals
 LL |     concat_bytes!([2.2; 0]);
    |                    ^^^
 
-error: repeat count is not a number
+error: repeat count is not a positive number
   --> $DIR/concat-bytes-error.rs:47:25
    |
 LL |     concat_bytes!([5.5; ()]);

From 4361d9778b709512c6a9187e5998853787f3900d Mon Sep 17 00:00:00 2001
From: Wesley Wiser <wesleywiser@microsoft.com>
Date: Mon, 27 Dec 2021 15:37:12 -0500
Subject: [PATCH 08/10] Add myself to .mailmap

---
 .mailmap | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.mailmap b/.mailmap
index 9d82f8895dc1c..9366ef383fc6d 100644
--- a/.mailmap
+++ b/.mailmap
@@ -296,6 +296,7 @@ Ulrik Sverdrup <bluss@users.noreply.github.com> Ulrik Sverdrup <root@localhost>
 Vadim Petrochenkov <vadim.petrochenkov@gmail.com>
 Vadim Petrochenkov <vadim.petrochenkov@gmail.com> petrochenkov <vadim.petrochenkov@gmail.com>
 Vitali Haravy <HumaneProgrammer@gmail.com> Vitali Haravy <humaneprogrammer@gmail.com>
+Wesley Wiser <wwiser@gmail.com> <wesleywiser@microsoft.com>
 whitequark <whitequark@whitequark.org>
 William Ting <io@williamting.com> <william.h.ting@gmail.com>
 Xuefeng Wu <benewu@gmail.com> Xuefeng Wu <xfwu@thoughtworks.com>

From 3115d8413af8599972c43a301514a0ad0d601c43 Mon Sep 17 00:00:00 2001
From: Dylan MacKenzie <ecstaticmorse@gmail.com>
Date: Mon, 27 Dec 2021 15:35:01 -0800
Subject: [PATCH 09/10] Document units for `std::column`

---
 library/core/src/macros/mod.rs | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index b18508186a618..c648cdab13206 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1062,6 +1062,18 @@ pub(crate) mod builtin {
     /// let current_col = column!();
     /// println!("defined on column: {}", current_col);
     /// ```
+    ///
+    /// `column!` counts Unicode code points, not bytes or graphemes. As a result, the first two
+    /// invocations return the same value, but the third does not.
+    ///
+    /// ```
+    /// let a = ("foobar", column!()).1;
+    /// let b = ("人之初性本善", column!()).1;
+    /// let c = ("f̅o̅o̅b̅a̅r̅", column!()).1; // Uses combining overline (U+0305)
+    ///
+    /// assert_eq!(a, b);
+    /// assert_ne!(b, c);
+    /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_builtin_macro]
     #[macro_export]

From 60c94031de44f9d56ca7a31e4083c7cfb78ba0a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= <lnicola@dend.ro>
Date: Tue, 28 Dec 2021 09:44:21 +0200
Subject: [PATCH 10/10] :arrow_up: rust-analyzer

---
 src/tools/rust-analyzer | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer
index 0add6e95e5863..68319187d6370 160000
--- a/src/tools/rust-analyzer
+++ b/src/tools/rust-analyzer
@@ -1 +1 @@
-Subproject commit 0add6e95e58633fde2fff0bccaf6c7d71ebc130f
+Subproject commit 68319187d63707fa36d7c215ed0e444e87d9652a