From da25af2940f44f841f91ba038535e8e84c4893f3 Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Tue, 17 Aug 2021 13:55:31 -0700
Subject: [PATCH 01/32] Make spans for tuple patterns in E0023 more precise

As suggested in #86307.
---
 compiler/rustc_typeck/src/check/pat.rs        |  6 ++-
 .../tuple_struct_destructure_fail.stderr      | 24 +++++++----
 src/test/ui/error-codes/E0023.stderr          | 30 ++++++++-----
 src/test/ui/issues/issue-72574-2.stderr       |  6 ++-
 .../match/match-pattern-field-mismatch.stderr |  6 ++-
 ...7-pat-tup-scrut-ty-diff-less-fields.stderr |  6 ++-
 src/test/ui/pattern/issue-74539.stderr        |  6 ++-
 .../ui/pattern/pat-tuple-overfield.stderr     | 12 ++++--
 .../ui/pattern/pat-tuple-underfield.stderr    | 42 ++++++++++++-------
 .../ui/pattern/pattern-error-continue.stderr  |  6 ++-
 10 files changed, 96 insertions(+), 48 deletions(-)

diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index dae574bb7bf0f..2ef79c7686c51 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -990,10 +990,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let subpats_ending = pluralize!(subpats.len());
         let fields_ending = pluralize!(fields.len());
+        let fields_span = pat_span.trim_start(qpath.span()).unwrap_or(pat_span);
         let res_span = self.tcx.def_span(res.def_id());
         let mut err = struct_span_err!(
             self.tcx.sess,
-            pat_span,
+            fields_span,
             E0023,
             "this pattern has {} field{}, but the corresponding {} has {} field{}",
             subpats.len(),
@@ -1003,9 +1004,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             fields_ending,
         );
         err.span_label(
-            pat_span,
+            fields_span,
             format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len(),),
         )
+        .span_label(qpath.span(), format!("this {}", res.descr()))
         .span_label(res_span, format!("{} defined here", res.descr()));
 
         // Identify the case `Some(x, y)` where the expected type is e.g. `Option<(T, U)>`.
diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
index 0e92cc5c9f282..ec7d76f4fe523 100644
--- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
@@ -15,22 +15,26 @@ LL |     Enum::SingleVariant(a, .., b, ..) = Enum::SingleVariant(0, 1);
    |                            previously used here
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple struct has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:30:5
+  --> $DIR/tuple_struct_destructure_fail.rs:30:16
    |
 LL | struct TupleStruct<S, T>(S, T);
    | ------------------------------- tuple struct defined here
 ...
 LL |     TupleStruct(a, a, b) = TupleStruct(1, 2);
-   |     ^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
+   |     -----------^^^^^^^^^ expected 2 fields, found 3
+   |     |
+   |     this tuple struct
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:32:5
+  --> $DIR/tuple_struct_destructure_fail.rs:32:16
    |
 LL | struct TupleStruct<S, T>(S, T);
    | ------------------------------- tuple struct defined here
 ...
 LL |     TupleStruct(_) = TupleStruct(1, 2);
-   |     ^^^^^^^^^^^^^^ expected 2 fields, found 1
+   |     -----------^^^ expected 2 fields, found 1
+   |     |
+   |     this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
@@ -42,22 +46,26 @@ LL |     TupleStruct(..) = TupleStruct(1, 2);
    |                 ~~
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:34:5
+  --> $DIR/tuple_struct_destructure_fail.rs:34:24
    |
 LL |     SingleVariant(S, T)
    |     ------------------- tuple variant defined here
 ...
 LL |     Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
+   |     -------------------^^^^^^^^^ expected 2 fields, found 3
+   |     |
+   |     this tuple variant
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:36:5
+  --> $DIR/tuple_struct_destructure_fail.rs:36:24
    |
 LL |     SingleVariant(S, T)
    |     ------------------- tuple variant defined here
 ...
 LL |     Enum::SingleVariant(_) = Enum::SingleVariant(1, 2);
-   |     ^^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 1
+   |     -------------------^^^ expected 2 fields, found 1
+   |     |
+   |     this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr
index ec3aae2971410..ecc075b6fb4b5 100644
--- a/src/test/ui/error-codes/E0023.stderr
+++ b/src/test/ui/error-codes/E0023.stderr
@@ -1,11 +1,13 @@
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:11:9
+  --> $DIR/E0023.rs:11:21
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
 ...
 LL |         Fruit::Apple(a) => {},
-   |         ^^^^^^^^^^^^^^^ expected 2 fields, found 1
+   |         ------------^^^ expected 2 fields, found 1
+   |         |
+   |         this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
@@ -13,31 +15,37 @@ LL |         Fruit::Apple(a, _) => {},
    |                       +++
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:12:9
+  --> $DIR/E0023.rs:12:21
    |
 LL |     Apple(String, String),
    |     --------------------- tuple variant defined here
 ...
 LL |         Fruit::Apple(a, b, c) => {},
-   |         ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3
+   |         ------------^^^^^^^^^ expected 2 fields, found 3
+   |         |
+   |         this tuple variant
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:13:9
+  --> $DIR/E0023.rs:13:20
    |
 LL |     Pear(u32),
    |     --------- tuple variant defined here
 ...
 LL |         Fruit::Pear(1, 2) => {},
-   |         ^^^^^^^^^^^^^^^^^ expected 1 field, found 2
+   |         -----------^^^^^^ expected 1 field, found 2
+   |         |
+   |         this tuple variant
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:14:9
+  --> $DIR/E0023.rs:14:22
    |
 LL |     Orange((String, String)),
    |     ------------------------ tuple variant defined here
 ...
 LL |         Fruit::Orange(a, b) => {},
-   |         ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2
+   |         -------------^^^^^^ expected 1 field, found 2
+   |         |
+   |         this tuple variant
    |
 help: missing parentheses
    |
@@ -45,13 +53,15 @@ LL |         Fruit::Orange((a, b)) => {},
    |                       +    +
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:15:9
+  --> $DIR/E0023.rs:15:22
    |
 LL |     Banana(()),
    |     ---------- tuple variant defined here
 ...
 LL |         Fruit::Banana() => {},
-   |         ^^^^^^^^^^^^^^^ expected 1 field, found 0
+   |         -------------^^ expected 1 field, found 0
+   |         |
+   |         this tuple variant
    |
 help: missing parentheses
    |
diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr
index 928fa58b17556..4c38d2c31ed68 100644
--- a/src/test/ui/issues/issue-72574-2.stderr
+++ b/src/test/ui/issues/issue-72574-2.stderr
@@ -19,13 +19,15 @@ LL |         Binder(_a, _x @ ..) => {}
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/issue-72574-2.rs:6:9
+  --> $DIR/issue-72574-2.rs:6:15
    |
 LL | struct Binder(i32, i32, i32);
    | ----------------------------- tuple struct defined here
 ...
 LL |         Binder(_a, _x @ ..) => {}
-   |         ^^^^^^^^^^^^^^^^^^^ expected 3 fields, found 2
+   |         ------^^^^^^^^^^^^^ expected 3 fields, found 2
+   |         |
+   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr
index e34164ec0db24..776cdfc7083bb 100644
--- a/src/test/ui/match/match-pattern-field-mismatch.stderr
+++ b/src/test/ui/match/match-pattern-field-mismatch.stderr
@@ -1,11 +1,13 @@
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields
-  --> $DIR/match-pattern-field-mismatch.rs:10:11
+  --> $DIR/match-pattern-field-mismatch.rs:10:21
    |
 LL |         Rgb(usize, usize, usize),
    |         ------------------------ tuple variant defined here
 ...
 LL |           Color::Rgb(_, _) => { }
-   |           ^^^^^^^^^^^^^^^^ expected 3 fields, found 2
+   |           ----------^^^^^^ expected 3 fields, found 2
+   |           |
+   |           this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
index 7f5da8f3c2dcc..ea5f970d1d659 100644
--- a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
+++ b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
@@ -10,13 +10,15 @@ LL |     let P() = U {};
               found struct `P<_>`
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 1 field
-  --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9
+  --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:10
    |
 LL | struct P<T>(T); // 1 type parameter wanted
    | --------------- tuple struct defined here
 ...
 LL |     let P() = U {};
-   |         ^^^ expected 1 field, found 0
+   |         -^^ expected 1 field, found 0
+   |         |
+   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr
index 7d998af7fb388..87c3842d28f4e 100644
--- a/src/test/ui/pattern/issue-74539.stderr
+++ b/src/test/ui/pattern/issue-74539.stderr
@@ -19,13 +19,15 @@ LL |         E::A(x @ ..) => {
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/issue-74539.rs:8:9
+  --> $DIR/issue-74539.rs:8:13
    |
 LL |     A(u8, u8),
    |     --------- tuple variant defined here
 ...
 LL |         E::A(x @ ..) => {
-   |         ^^^^^^^^^^^^ expected 2 fields, found 1
+   |         ----^^^^^^^^ expected 2 fields, found 1
+   |         |
+   |         this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr
index 45b6fd1b4d445..e0386d9cd4ffc 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-overfield.stderr
@@ -22,22 +22,26 @@ LL |         (1, 2, .., 3, 4) => {}
               found tuple `(_, _, _, _)`
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:10:9
+  --> $DIR/pat-tuple-overfield.rs:10:10
    |
 LL | struct S(u8, u8, u8);
    | --------------------- tuple struct defined here
 ...
 LL |         S(1, 2, 3, 4) => {}
-   |         ^^^^^^^^^^^^^ expected 3 fields, found 4
+   |         -^^^^^^^^^^^^ expected 3 fields, found 4
+   |         |
+   |         this tuple struct
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:12:9
+  --> $DIR/pat-tuple-overfield.rs:12:10
    |
 LL | struct S(u8, u8, u8);
    | --------------------- tuple struct defined here
 ...
 LL |         S(1, 2, .., 3, 4) => {}
-   |         ^^^^^^^^^^^^^^^^^ expected 3 fields, found 4
+   |         -^^^^^^^^^^^^^^^^ expected 3 fields, found 4
+   |         |
+   |         this tuple struct
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr
index 2fbcb6d67ba36..4cc20a4ac0ef7 100644
--- a/src/test/ui/pattern/pat-tuple-underfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-underfield.stderr
@@ -8,13 +8,15 @@ LL |         E::S => {}
    |         ^^^^ help: use the tuple variant pattern syntax instead: `E::S(_, _)`
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:9:9
+  --> $DIR/pat-tuple-underfield.rs:9:10
    |
 LL | struct S(i32, f32);
    | ------------------- tuple struct defined here
 ...
 LL |         S(x) => {}
-   |         ^^^^ expected 2 fields, found 1
+   |         -^^^ expected 2 fields, found 1
+   |         |
+   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
@@ -22,13 +24,15 @@ LL |         S(x, _) => {}
    |            +++
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:14:9
+  --> $DIR/pat-tuple-underfield.rs:14:10
    |
 LL | struct S(i32, f32);
    | ------------------- tuple struct defined here
 ...
 LL |         S(_) => {}
-   |         ^^^^ expected 2 fields, found 1
+   |         -^^^ expected 2 fields, found 1
+   |         |
+   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
@@ -40,13 +44,15 @@ LL |         S(..) => {}
    |           ~~
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:20:9
+  --> $DIR/pat-tuple-underfield.rs:20:10
    |
 LL | struct S(i32, f32);
    | ------------------- tuple struct defined here
 ...
 LL |         S() => {}
-   |         ^^^ expected 2 fields, found 0
+   |         -^^ expected 2 fields, found 0
+   |         |
+   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
@@ -58,13 +64,15 @@ LL |         S(..) => {}
    |           ++
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:27:9
+  --> $DIR/pat-tuple-underfield.rs:27:13
    |
 LL |     S(i32, f32),
    |     ----------- tuple variant defined here
 ...
 LL |         E::S(x) => {}
-   |         ^^^^^^^ expected 2 fields, found 1
+   |         ----^^^ expected 2 fields, found 1
+   |         |
+   |         this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
@@ -72,13 +80,15 @@ LL |         E::S(x, _) => {}
    |               +++
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:32:9
+  --> $DIR/pat-tuple-underfield.rs:32:13
    |
 LL |     S(i32, f32),
    |     ----------- tuple variant defined here
 ...
 LL |         E::S(_) => {}
-   |         ^^^^^^^ expected 2 fields, found 1
+   |         ----^^^ expected 2 fields, found 1
+   |         |
+   |         this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
@@ -90,13 +100,15 @@ LL |         E::S(..) => {}
    |              ~~
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:38:9
+  --> $DIR/pat-tuple-underfield.rs:38:13
    |
 LL |     S(i32, f32),
    |     ----------- tuple variant defined here
 ...
 LL |         E::S() => {}
-   |         ^^^^^^ expected 2 fields, found 0
+   |         ----^^ expected 2 fields, found 0
+   |         |
+   |         this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
@@ -108,13 +120,15 @@ LL |         E::S(..) => {}
    |              ++
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 4 fields
-  --> $DIR/pat-tuple-underfield.rs:50:9
+  --> $DIR/pat-tuple-underfield.rs:50:15
    |
 LL | struct Point4(i32, i32, i32, i32);
    | ---------------------------------- tuple struct defined here
 ...
 LL |         Point4(   a   ,     _    ) => {}
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected 4 fields, found 2
+   |         ------^^^^^^^^^^^^^^^^^^^^ expected 4 fields, found 2
+   |         |
+   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr
index 3f28ffed29162..216c3ca47d393 100644
--- a/src/test/ui/pattern/pattern-error-continue.stderr
+++ b/src/test/ui/pattern/pattern-error-continue.stderr
@@ -26,13 +26,15 @@ LL |         A::B(_) => (),
    |            ~
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/pattern-error-continue.rs:17:9
+  --> $DIR/pattern-error-continue.rs:17:13
    |
 LL |     B(isize, isize),
    |     --------------- tuple variant defined here
 ...
 LL |         A::B(_, _, _) => (),
-   |         ^^^^^^^^^^^^^ expected 2 fields, found 3
+   |         ----^^^^^^^^^ expected 2 fields, found 3
+   |         |
+   |         this tuple variant
 
 error[E0308]: mismatched types
   --> $DIR/pattern-error-continue.rs:22:9

From f1e860757e9494c82450c100a9ce5240858b537b Mon Sep 17 00:00:00 2001
From: Kornel <kornel@geekhood.net>
Date: Sat, 21 Aug 2021 23:40:02 +0100
Subject: [PATCH 02/32] Don't stabilize creation of TryReserveError instances

---
 library/alloc/src/collections/mod.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs
index 0d442011921ba..4e31df8b4b8c2 100644
--- a/library/alloc/src/collections/mod.rs
+++ b/library/alloc/src/collections/mod.rs
@@ -117,12 +117,12 @@ impl From<TryReserveErrorKind> for TryReserveError {
     }
 }
 
-#[unstable(feature = "try_reserve", reason = "new API", issue = "48043")]
-impl From<LayoutError> for TryReserveError {
+#[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")]
+impl From<LayoutError> for TryReserveErrorKind {
     /// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`].
     #[inline]
     fn from(_: LayoutError) -> Self {
-        TryReserveErrorKind::CapacityOverflow.into()
+        TryReserveErrorKind::CapacityOverflow
     }
 }
 

From d0b482a27c1a347eac366bde82340e527c6cecf8 Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Wed, 18 Aug 2021 16:13:25 -0700
Subject: [PATCH 03/32] Add more tuple pattern too many fields test cases

---
 src/test/ui/pattern/pat-tuple-overfield.rs    |  42 ++++
 .../ui/pattern/pat-tuple-overfield.stderr     | 222 +++++++++++++++++-
 2 files changed, 258 insertions(+), 6 deletions(-)

diff --git a/src/test/ui/pattern/pat-tuple-overfield.rs b/src/test/ui/pattern/pat-tuple-overfield.rs
index 46a5e15ffa52c..dd0548a088c72 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.rs
+++ b/src/test/ui/pattern/pat-tuple-overfield.rs
@@ -1,4 +1,18 @@
 struct S(u8, u8, u8);
+struct M(
+    u8,
+    u8,
+    u8,
+    u8,
+    u8,
+);
+
+struct Z0;
+struct Z1();
+enum E1 {
+    Z0,
+    Z1(),
+}
 
 fn main() {
     match (1, 2, 3) {
@@ -13,4 +27,32 @@ fn main() {
         //~^ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields
         _ => {}
     }
+    match M(1, 2, 3, 4, 5) {
+        M(1, 2, 3, 4, 5, 6) => {}
+        //~^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields
+    }
+    match Z0 {
+        Z0 => {}
+        Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0`
+        Z0(_) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0`
+        Z0(_, _) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0`
+    }
+    match Z1() {
+        Z1 => {} //~ ERROR match bindings cannot shadow tuple structs
+        Z1() => {}
+        Z1(_) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 0 fields
+        Z1(_, _) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 0 fields
+    }
+    match E1::Z0 {
+        E1::Z0 => {}
+        E1::Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0`
+        E1::Z0(_) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0`
+        E1::Z0(_, _) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0`
+    }
+    match E1::Z1() {
+        E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
+        E1::Z1() => {}
+        E1::Z1(_) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 0 fields
+        E1::Z1(_, _) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 0 fields
+    }
 }
diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr
index e0386d9cd4ffc..cc4ca4326eccd 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-overfield.stderr
@@ -1,5 +1,154 @@
+error[E0530]: match bindings cannot shadow tuple structs
+  --> $DIR/pat-tuple-overfield.rs:43:9
+   |
+LL | struct Z1();
+   | ------------ the tuple struct `Z1` is defined here
+...
+LL |         Z1 => {}
+   |         ^^ cannot be named the same as a tuple struct
+
+error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
+  --> $DIR/pat-tuple-overfield.rs:38:9
+   |
+LL | struct Z0;
+   | ---------- `Z0` defined here
+LL | struct Z1();
+   | ------------ similarly named tuple struct `Z1` defined here
+...
+LL |         Z0() => {}
+   |         ^^^^
+   |
+help: use this syntax instead
+   |
+LL |         Z0 => {}
+   |         ~~
+help: a tuple struct with a similar name exists
+   |
+LL |         Z1() => {}
+   |         ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
+  --> $DIR/pat-tuple-overfield.rs:39:9
+   |
+LL | struct Z0;
+   | ---------- `Z0` defined here
+LL | struct Z1();
+   | ------------ similarly named tuple struct `Z1` defined here
+...
+LL |         Z0(_) => {}
+   |         ^^^^^
+   |
+help: use this syntax instead
+   |
+LL |         Z0 => {}
+   |         ~~
+help: a tuple struct with a similar name exists
+   |
+LL |         Z1(_) => {}
+   |         ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
+  --> $DIR/pat-tuple-overfield.rs:40:9
+   |
+LL | struct Z0;
+   | ---------- `Z0` defined here
+LL | struct Z1();
+   | ------------ similarly named tuple struct `Z1` defined here
+...
+LL |         Z0(_, _) => {}
+   |         ^^^^^^^^
+   |
+help: use this syntax instead
+   |
+LL |         Z0 => {}
+   |         ~~
+help: a tuple struct with a similar name exists
+   |
+LL |         Z1(_, _) => {}
+   |         ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
+  --> $DIR/pat-tuple-overfield.rs:50:9
+   |
+LL |     Z0,
+   |     -- `E1::Z0` defined here
+LL |     Z1(),
+   |     ---- similarly named tuple variant `Z1` defined here
+...
+LL |         E1::Z0() => {}
+   |         ^^^^^^^^
+   |
+help: use this syntax instead
+   |
+LL |         E1::Z0 => {}
+   |         ~~~~~~
+help: a tuple variant with a similar name exists
+   |
+LL |         E1::Z1() => {}
+   |             ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
+  --> $DIR/pat-tuple-overfield.rs:51:9
+   |
+LL |     Z0,
+   |     -- `E1::Z0` defined here
+LL |     Z1(),
+   |     ---- similarly named tuple variant `Z1` defined here
+...
+LL |         E1::Z0(_) => {}
+   |         ^^^^^^^^^
+   |
+help: use this syntax instead
+   |
+LL |         E1::Z0 => {}
+   |         ~~~~~~
+help: a tuple variant with a similar name exists
+   |
+LL |         E1::Z1(_) => {}
+   |             ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
+  --> $DIR/pat-tuple-overfield.rs:52:9
+   |
+LL |     Z0,
+   |     -- `E1::Z0` defined here
+LL |     Z1(),
+   |     ---- similarly named tuple variant `Z1` defined here
+...
+LL |         E1::Z0(_, _) => {}
+   |         ^^^^^^^^^^^^
+   |
+help: use this syntax instead
+   |
+LL |         E1::Z0 => {}
+   |         ~~~~~~
+help: a tuple variant with a similar name exists
+   |
+LL |         E1::Z1(_, _) => {}
+   |             ~~
+
+error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
+  --> $DIR/pat-tuple-overfield.rs:55:9
+   |
+LL |     Z0,
+   |     -- similarly named unit variant `Z0` defined here
+LL |     Z1(),
+   |     ---- `E1::Z1` defined here
+...
+LL |         E1::Z1 => {}
+   |         ^^^^^^
+   |
+help: use the tuple variant pattern syntax instead
+   |
+LL |         E1::Z1() => {}
+   |         ~~~~~~~~
+help: a unit variant with a similar name exists
+   |
+LL |         E1::Z0 => {}
+   |             ~~
+
 error[E0308]: mismatched types
-  --> $DIR/pat-tuple-overfield.rs:5:9
+  --> $DIR/pat-tuple-overfield.rs:21:9
    |
 LL |     match (1, 2, 3) {
    |           --------- this expression has type `({integer}, {integer}, {integer})`
@@ -10,7 +159,7 @@ LL |         (1, 2, 3, 4) => {}
               found tuple `(_, _, _, _)`
 
 error[E0308]: mismatched types
-  --> $DIR/pat-tuple-overfield.rs:6:9
+  --> $DIR/pat-tuple-overfield.rs:22:9
    |
 LL |     match (1, 2, 3) {
    |           --------- this expression has type `({integer}, {integer}, {integer})`
@@ -22,7 +171,7 @@ LL |         (1, 2, .., 3, 4) => {}
               found tuple `(_, _, _, _)`
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:10:10
+  --> $DIR/pat-tuple-overfield.rs:26:10
    |
 LL | struct S(u8, u8, u8);
    | --------------------- tuple struct defined here
@@ -33,7 +182,7 @@ LL |         S(1, 2, 3, 4) => {}
    |         this tuple struct
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:12:10
+  --> $DIR/pat-tuple-overfield.rs:28:10
    |
 LL | struct S(u8, u8, u8);
    | --------------------- tuple struct defined here
@@ -43,7 +192,68 @@ LL |         S(1, 2, .., 3, 4) => {}
    |         |
    |         this tuple struct
 
-error: aborting due to 4 previous errors
+error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields
+  --> $DIR/pat-tuple-overfield.rs:33:10
+   |
+LL | / struct M(
+LL | |     u8,
+LL | |     u8,
+LL | |     u8,
+LL | |     u8,
+LL | |     u8,
+LL | | );
+   | |__- tuple struct defined here
+...
+LL |           M(1, 2, 3, 4, 5, 6) => {}
+   |           -^^^^^^^^^^^^^^^^^^ expected 5 fields, found 6
+   |           |
+   |           this tuple struct
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields
+  --> $DIR/pat-tuple-overfield.rs:45:11
+   |
+LL | struct Z1();
+   | ------------ tuple struct defined here
+...
+LL |         Z1(_) => {}
+   |         --^^^ expected 0 fields, found 1
+   |         |
+   |         this tuple struct
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields
+  --> $DIR/pat-tuple-overfield.rs:46:11
+   |
+LL | struct Z1();
+   | ------------ tuple struct defined here
+...
+LL |         Z1(_, _) => {}
+   |         --^^^^^^ expected 0 fields, found 2
+   |         |
+   |         this tuple struct
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields
+  --> $DIR/pat-tuple-overfield.rs:57:15
+   |
+LL |     Z1(),
+   |     ---- tuple variant defined here
+...
+LL |         E1::Z1(_) => {}
+   |         ------^^^ expected 0 fields, found 1
+   |         |
+   |         this tuple variant
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields
+  --> $DIR/pat-tuple-overfield.rs:58:15
+   |
+LL |     Z1(),
+   |     ---- tuple variant defined here
+...
+LL |         E1::Z1(_, _) => {}
+   |         ------^^^^^^ expected 0 fields, found 2
+   |         |
+   |         this tuple variant
+
+error: aborting due to 17 previous errors
 
-Some errors have detailed explanations: E0023, E0308.
+Some errors have detailed explanations: E0023, E0308, E0530, E0532.
 For more information about an error, try `rustc --explain E0023`.

From 0fa3b4f940b4705dc5a1089e917f521b093fd0bc Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Wed, 18 Aug 2021 16:13:52 -0700
Subject: [PATCH 04/32] Make E0023 spans even more precise

---
 compiler/rustc_ty_utils/src/ty.rs             | 13 +++-
 compiler/rustc_typeck/src/check/pat.rs        | 39 ++++++++--
 .../tuple_struct_destructure_fail.stderr      | 32 +++-----
 src/test/ui/error-codes/E0023.stderr          | 36 ++++-----
 src/test/ui/issues/issue-72574-2.stderr       |  8 +-
 .../match/match-pattern-field-mismatch.stderr |  8 +-
 ...7-pat-tup-scrut-ty-diff-less-fields.stderr |  4 +-
 src/test/ui/pattern/issue-74539.stderr        |  8 +-
 .../ui/pattern/pat-tuple-overfield.stderr     | 78 ++++++++-----------
 .../ui/pattern/pat-tuple-underfield.stderr    | 48 ++++--------
 .../ui/pattern/pattern-error-continue.stderr  |  8 +-
 11 files changed, 132 insertions(+), 150 deletions(-)

diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index b0d644ae028ce..7a6ace070dee5 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -223,7 +223,18 @@ fn associated_items(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItems<'_> {
 }
 
 fn def_ident_span(tcx: TyCtxt<'_>, def_id: DefId) -> Option<Span> {
-    tcx.hir().get_if_local(def_id).and_then(|node| node.ident()).map(|ident| ident.span)
+    tcx.hir()
+        .get_if_local(def_id)
+        .and_then(|node| match node {
+            // A `Ctor` doesn't have an identifier itself, but its parent
+            // struct/variant does. Compare with `hir::Map::opt_span`.
+            hir::Node::Ctor(ctor) => ctor
+                .ctor_hir_id()
+                .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id)))
+                .and_then(|parent| parent.ident()),
+            _ => node.ident(),
+        })
+        .map(|ident| ident.span)
 }
 
 /// If the given `DefId` describes an item belonging to a trait,
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 2ef79c7686c51..341385731e7d2 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -15,7 +15,7 @@ use rustc_span::hygiene::DesugaringKind;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::source_map::{Span, Spanned};
 use rustc_span::symbol::Ident;
-use rustc_span::{BytePos, DUMMY_SP};
+use rustc_span::{BytePos, MultiSpan, DUMMY_SP};
 use rustc_trait_selection::autoderef::Autoderef;
 use rustc_trait_selection::traits::{ObligationCause, Pattern};
 use ty::VariantDef;
@@ -990,11 +990,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) {
         let subpats_ending = pluralize!(subpats.len());
         let fields_ending = pluralize!(fields.len());
-        let fields_span = pat_span.trim_start(qpath.span()).unwrap_or(pat_span);
+
+        let subpat_spans = if subpats.is_empty() {
+            vec![pat_span.trim_start(qpath.span()).unwrap_or(pat_span)]
+        } else {
+            subpats.iter().map(|p| p.span).collect()
+        };
+        let last_subpat_span = *subpat_spans.last().unwrap();
         let res_span = self.tcx.def_span(res.def_id());
+        let def_ident_span = self.tcx.def_ident_span(res.def_id()).unwrap_or(res_span);
+        let field_def_spans = if fields.is_empty() {
+            vec![res_span.trim_start(def_ident_span).unwrap_or(res_span)]
+        } else {
+            fields.iter().map(|f| f.ident.span).collect()
+        };
+        let last_field_def_span = *field_def_spans.last().unwrap();
+
         let mut err = struct_span_err!(
             self.tcx.sess,
-            fields_span,
+            MultiSpan::from_spans(subpat_spans.clone()),
             E0023,
             "this pattern has {} field{}, but the corresponding {} has {} field{}",
             subpats.len(),
@@ -1004,11 +1018,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             fields_ending,
         );
         err.span_label(
-            fields_span,
-            format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len(),),
-        )
-        .span_label(qpath.span(), format!("this {}", res.descr()))
-        .span_label(res_span, format!("{} defined here", res.descr()));
+            last_subpat_span,
+            &format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len()),
+        );
+        err.span_label(qpath.span(), "");
+        if self.tcx.sess.source_map().is_multiline(def_ident_span.between(field_def_spans[0])) {
+            err.span_label(def_ident_span, format!("{} defined here", res.descr()));
+        }
+        for span in &field_def_spans[..field_def_spans.len() - 1] {
+            err.span_label(*span, "");
+        }
+        err.span_label(
+            last_field_def_span,
+            &format!("{} has {} field{}", res.descr(), fields.len(), fields_ending),
+        );
 
         // Identify the case `Some(x, y)` where the expected type is e.g. `Option<(T, U)>`.
         // More generally, the expected type wants a tuple variant with one field of an
diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
index ec7d76f4fe523..9a47ddf047991 100644
--- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
@@ -15,26 +15,22 @@ LL |     Enum::SingleVariant(a, .., b, ..) = Enum::SingleVariant(0, 1);
    |                            previously used here
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple struct has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:30:16
+  --> $DIR/tuple_struct_destructure_fail.rs:30:17
    |
 LL | struct TupleStruct<S, T>(S, T);
-   | ------------------------------- tuple struct defined here
+   |                          -  - tuple struct has 2 fields
 ...
 LL |     TupleStruct(a, a, b) = TupleStruct(1, 2);
-   |     -----------^^^^^^^^^ expected 2 fields, found 3
-   |     |
-   |     this tuple struct
+   |     ----------- ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:32:16
+  --> $DIR/tuple_struct_destructure_fail.rs:32:17
    |
 LL | struct TupleStruct<S, T>(S, T);
-   | ------------------------------- tuple struct defined here
+   |                          -  - tuple struct has 2 fields
 ...
 LL |     TupleStruct(_) = TupleStruct(1, 2);
-   |     -----------^^^ expected 2 fields, found 1
-   |     |
-   |     this tuple struct
+   |     ----------- ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -46,26 +42,22 @@ LL |     TupleStruct(..) = TupleStruct(1, 2);
    |                 ~~
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:34:24
+  --> $DIR/tuple_struct_destructure_fail.rs:34:25
    |
 LL |     SingleVariant(S, T)
-   |     ------------------- tuple variant defined here
+   |                   -  - tuple variant has 2 fields
 ...
 LL |     Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2);
-   |     -------------------^^^^^^^^^ expected 2 fields, found 3
-   |     |
-   |     this tuple variant
+   |     ------------------- ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/tuple_struct_destructure_fail.rs:36:24
+  --> $DIR/tuple_struct_destructure_fail.rs:36:25
    |
 LL |     SingleVariant(S, T)
-   |     ------------------- tuple variant defined here
+   |                   -  - tuple variant has 2 fields
 ...
 LL |     Enum::SingleVariant(_) = Enum::SingleVariant(1, 2);
-   |     -------------------^^^ expected 2 fields, found 1
-   |     |
-   |     this tuple variant
+   |     ------------------- ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr
index ecc075b6fb4b5..85e1b2cb4ceef 100644
--- a/src/test/ui/error-codes/E0023.stderr
+++ b/src/test/ui/error-codes/E0023.stderr
@@ -1,13 +1,11 @@
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:11:21
+  --> $DIR/E0023.rs:11:22
    |
 LL |     Apple(String, String),
-   |     --------------------- tuple variant defined here
+   |           ------  ------ tuple variant has 2 fields
 ...
 LL |         Fruit::Apple(a) => {},
-   |         ------------^^^ expected 2 fields, found 1
-   |         |
-   |         this tuple variant
+   |         ------------ ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -15,37 +13,31 @@ LL |         Fruit::Apple(a, _) => {},
    |                       +++
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/E0023.rs:12:21
+  --> $DIR/E0023.rs:12:22
    |
 LL |     Apple(String, String),
-   |     --------------------- tuple variant defined here
+   |           ------  ------ tuple variant has 2 fields
 ...
 LL |         Fruit::Apple(a, b, c) => {},
-   |         ------------^^^^^^^^^ expected 2 fields, found 3
-   |         |
-   |         this tuple variant
+   |         ------------ ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:13:20
+  --> $DIR/E0023.rs:13:21
    |
 LL |     Pear(u32),
-   |     --------- tuple variant defined here
+   |          --- tuple variant has 1 field
 ...
 LL |         Fruit::Pear(1, 2) => {},
-   |         -----------^^^^^^ expected 1 field, found 2
-   |         |
-   |         this tuple variant
+   |         ----------- ^  ^ expected 1 field, found 2
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:14:22
+  --> $DIR/E0023.rs:14:23
    |
 LL |     Orange((String, String)),
-   |     ------------------------ tuple variant defined here
+   |            ---------------- tuple variant has 1 field
 ...
 LL |         Fruit::Orange(a, b) => {},
-   |         -------------^^^^^^ expected 1 field, found 2
-   |         |
-   |         this tuple variant
+   |         ------------- ^  ^ expected 1 field, found 2
    |
 help: missing parentheses
    |
@@ -56,12 +48,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has
   --> $DIR/E0023.rs:15:22
    |
 LL |     Banana(()),
-   |     ---------- tuple variant defined here
+   |            -- tuple variant has 1 field
 ...
 LL |         Fruit::Banana() => {},
    |         -------------^^ expected 1 field, found 0
-   |         |
-   |         this tuple variant
    |
 help: missing parentheses
    |
diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr
index 4c38d2c31ed68..3f8ff4f0bacd5 100644
--- a/src/test/ui/issues/issue-72574-2.stderr
+++ b/src/test/ui/issues/issue-72574-2.stderr
@@ -19,15 +19,13 @@ LL |         Binder(_a, _x @ ..) => {}
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/issue-72574-2.rs:6:15
+  --> $DIR/issue-72574-2.rs:6:16
    |
 LL | struct Binder(i32, i32, i32);
-   | ----------------------------- tuple struct defined here
+   |               ---  ---  --- tuple struct has 3 fields
 ...
 LL |         Binder(_a, _x @ ..) => {}
-   |         ------^^^^^^^^^^^^^ expected 3 fields, found 2
-   |         |
-   |         this tuple struct
+   |         ------ ^^  ^^^^^^^ expected 3 fields, found 2
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr
index 776cdfc7083bb..01d7cf0d054c9 100644
--- a/src/test/ui/match/match-pattern-field-mismatch.stderr
+++ b/src/test/ui/match/match-pattern-field-mismatch.stderr
@@ -1,13 +1,11 @@
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields
-  --> $DIR/match-pattern-field-mismatch.rs:10:21
+  --> $DIR/match-pattern-field-mismatch.rs:10:22
    |
 LL |         Rgb(usize, usize, usize),
-   |         ------------------------ tuple variant defined here
+   |             -----  -----  ----- tuple variant has 3 fields
 ...
 LL |           Color::Rgb(_, _) => { }
-   |           ----------^^^^^^ expected 3 fields, found 2
-   |           |
-   |           this tuple variant
+   |           ---------- ^  ^ expected 3 fields, found 2
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
index ea5f970d1d659..c87b70625b40e 100644
--- a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
+++ b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
@@ -13,12 +13,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has
   --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:10
    |
 LL | struct P<T>(T); // 1 type parameter wanted
-   | --------------- tuple struct defined here
+   |             - tuple struct has 1 field
 ...
 LL |     let P() = U {};
    |         -^^ expected 1 field, found 0
-   |         |
-   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr
index 87c3842d28f4e..d7cbcf2cfa109 100644
--- a/src/test/ui/pattern/issue-74539.stderr
+++ b/src/test/ui/pattern/issue-74539.stderr
@@ -19,15 +19,13 @@ LL |         E::A(x @ ..) => {
    = note: only allowed in tuple, tuple struct, and slice patterns
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/issue-74539.rs:8:13
+  --> $DIR/issue-74539.rs:8:14
    |
 LL |     A(u8, u8),
-   |     --------- tuple variant defined here
+   |       --  -- tuple variant has 2 fields
 ...
 LL |         E::A(x @ ..) => {
-   |         ----^^^^^^^^ expected 2 fields, found 1
-   |         |
-   |         this tuple variant
+   |         ---- ^^^^^^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr
index cc4ca4326eccd..1df9c1c11b8a5 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-overfield.stderr
@@ -171,87 +171,77 @@ LL |         (1, 2, .., 3, 4) => {}
               found tuple `(_, _, _, _)`
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:26:10
+  --> $DIR/pat-tuple-overfield.rs:26:11
    |
 LL | struct S(u8, u8, u8);
-   | --------------------- tuple struct defined here
+   |          --  --  -- tuple struct has 3 fields
 ...
 LL |         S(1, 2, 3, 4) => {}
-   |         -^^^^^^^^^^^^ expected 3 fields, found 4
-   |         |
-   |         this tuple struct
+   |         - ^  ^  ^  ^ expected 3 fields, found 4
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:28:10
+  --> $DIR/pat-tuple-overfield.rs:28:11
    |
 LL | struct S(u8, u8, u8);
-   | --------------------- tuple struct defined here
+   |          --  --  -- tuple struct has 3 fields
 ...
 LL |         S(1, 2, .., 3, 4) => {}
-   |         -^^^^^^^^^^^^^^^^ expected 3 fields, found 4
-   |         |
-   |         this tuple struct
+   |         - ^  ^      ^  ^ expected 3 fields, found 4
 
 error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields
-  --> $DIR/pat-tuple-overfield.rs:33:10
-   |
-LL | / struct M(
-LL | |     u8,
-LL | |     u8,
-LL | |     u8,
-LL | |     u8,
-LL | |     u8,
-LL | | );
-   | |__- tuple struct defined here
+  --> $DIR/pat-tuple-overfield.rs:33:11
+   |
+LL | struct M(
+   |        - tuple struct defined here
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     -- tuple struct has 5 fields
 ...
-LL |           M(1, 2, 3, 4, 5, 6) => {}
-   |           -^^^^^^^^^^^^^^^^^^ expected 5 fields, found 6
-   |           |
-   |           this tuple struct
+LL |         M(1, 2, 3, 4, 5, 6) => {}
+   |         - ^  ^  ^  ^  ^  ^ expected 5 fields, found 6
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:45:11
+  --> $DIR/pat-tuple-overfield.rs:45:12
    |
 LL | struct Z1();
-   | ------------ tuple struct defined here
+   |          --- tuple struct has 0 fields
 ...
 LL |         Z1(_) => {}
-   |         --^^^ expected 0 fields, found 1
-   |         |
-   |         this tuple struct
+   |         -- ^ expected 0 fields, found 1
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:46:11
+  --> $DIR/pat-tuple-overfield.rs:46:12
    |
 LL | struct Z1();
-   | ------------ tuple struct defined here
+   |          --- tuple struct has 0 fields
 ...
 LL |         Z1(_, _) => {}
-   |         --^^^^^^ expected 0 fields, found 2
-   |         |
-   |         this tuple struct
+   |         -- ^  ^ expected 0 fields, found 2
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:57:15
+  --> $DIR/pat-tuple-overfield.rs:57:16
    |
 LL |     Z1(),
-   |     ---- tuple variant defined here
+   |       -- tuple variant has 0 fields
 ...
 LL |         E1::Z1(_) => {}
-   |         ------^^^ expected 0 fields, found 1
-   |         |
-   |         this tuple variant
+   |         ------ ^ expected 0 fields, found 1
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:58:15
+  --> $DIR/pat-tuple-overfield.rs:58:16
    |
 LL |     Z1(),
-   |     ---- tuple variant defined here
+   |       -- tuple variant has 0 fields
 ...
 LL |         E1::Z1(_, _) => {}
-   |         ------^^^^^^ expected 0 fields, found 2
-   |         |
-   |         this tuple variant
+   |         ------ ^  ^ expected 0 fields, found 2
 
 error: aborting due to 17 previous errors
 
diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr
index 4cc20a4ac0ef7..4c21ad0be3eb4 100644
--- a/src/test/ui/pattern/pat-tuple-underfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-underfield.stderr
@@ -8,15 +8,13 @@ LL |         E::S => {}
    |         ^^^^ help: use the tuple variant pattern syntax instead: `E::S(_, _)`
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:9:10
+  --> $DIR/pat-tuple-underfield.rs:9:11
    |
 LL | struct S(i32, f32);
-   | ------------------- tuple struct defined here
+   |          ---  --- tuple struct has 2 fields
 ...
 LL |         S(x) => {}
-   |         -^^^ expected 2 fields, found 1
-   |         |
-   |         this tuple struct
+   |         - ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -24,15 +22,13 @@ LL |         S(x, _) => {}
    |            +++
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:14:10
+  --> $DIR/pat-tuple-underfield.rs:14:11
    |
 LL | struct S(i32, f32);
-   | ------------------- tuple struct defined here
+   |          ---  --- tuple struct has 2 fields
 ...
 LL |         S(_) => {}
-   |         -^^^ expected 2 fields, found 1
-   |         |
-   |         this tuple struct
+   |         - ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -47,12 +43,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has
   --> $DIR/pat-tuple-underfield.rs:20:10
    |
 LL | struct S(i32, f32);
-   | ------------------- tuple struct defined here
+   |          ---  --- tuple struct has 2 fields
 ...
 LL |         S() => {}
    |         -^^ expected 2 fields, found 0
-   |         |
-   |         this tuple struct
    |
 help: use `_` to explicitly ignore each field
    |
@@ -64,15 +58,13 @@ LL |         S(..) => {}
    |           ++
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:27:13
+  --> $DIR/pat-tuple-underfield.rs:27:14
    |
 LL |     S(i32, f32),
-   |     ----------- tuple variant defined here
+   |       ---  --- tuple variant has 2 fields
 ...
 LL |         E::S(x) => {}
-   |         ----^^^ expected 2 fields, found 1
-   |         |
-   |         this tuple variant
+   |         ---- ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -80,15 +72,13 @@ LL |         E::S(x, _) => {}
    |               +++
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:32:13
+  --> $DIR/pat-tuple-underfield.rs:32:14
    |
 LL |     S(i32, f32),
-   |     ----------- tuple variant defined here
+   |       ---  --- tuple variant has 2 fields
 ...
 LL |         E::S(_) => {}
-   |         ----^^^ expected 2 fields, found 1
-   |         |
-   |         this tuple variant
+   |         ---- ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -103,12 +93,10 @@ error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has
   --> $DIR/pat-tuple-underfield.rs:38:13
    |
 LL |     S(i32, f32),
-   |     ----------- tuple variant defined here
+   |       ---  --- tuple variant has 2 fields
 ...
 LL |         E::S() => {}
    |         ----^^ expected 2 fields, found 0
-   |         |
-   |         this tuple variant
    |
 help: use `_` to explicitly ignore each field
    |
@@ -120,15 +108,13 @@ LL |         E::S(..) => {}
    |              ++
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 4 fields
-  --> $DIR/pat-tuple-underfield.rs:50:15
+  --> $DIR/pat-tuple-underfield.rs:50:19
    |
 LL | struct Point4(i32, i32, i32, i32);
-   | ---------------------------------- tuple struct defined here
+   |               ---  ---  ---  --- tuple struct has 4 fields
 ...
 LL |         Point4(   a   ,     _    ) => {}
-   |         ------^^^^^^^^^^^^^^^^^^^^ expected 4 fields, found 2
-   |         |
-   |         this tuple struct
+   |         ------    ^         ^ expected 4 fields, found 2
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr
index 216c3ca47d393..efc6723e9ef8e 100644
--- a/src/test/ui/pattern/pattern-error-continue.stderr
+++ b/src/test/ui/pattern/pattern-error-continue.stderr
@@ -26,15 +26,13 @@ LL |         A::B(_) => (),
    |            ~
 
 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/pattern-error-continue.rs:17:13
+  --> $DIR/pattern-error-continue.rs:17:14
    |
 LL |     B(isize, isize),
-   |     --------------- tuple variant defined here
+   |       -----  ----- tuple variant has 2 fields
 ...
 LL |         A::B(_, _, _) => (),
-   |         ----^^^^^^^^^ expected 2 fields, found 3
-   |         |
-   |         this tuple variant
+   |         ---- ^  ^  ^ expected 2 fields, found 3
 
 error[E0308]: mismatched types
   --> $DIR/pattern-error-continue.rs:22:9

From 02ed23c0318da7f1125f01b5437ae9e809587f0c Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Wed, 18 Aug 2021 16:09:52 -0700
Subject: [PATCH 05/32] Use an exhaustive match in `Node::ident()` and add docs

This should cause a compiler error in the future if more variants are
added without `Node::ident()` being updated.
---
 compiler/rustc_hir/src/hir.rs | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 4e233ed14577d..dd5dfe978a477 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3182,6 +3182,20 @@ pub enum Node<'hir> {
 }
 
 impl<'hir> Node<'hir> {
+    /// Get the identifier of this `Node`, if applicable.
+    ///
+    /// # Edge cases
+    ///
+    /// Calling `.ident()` on a [`Node::Ctor`] will return `None`
+    /// because `Ctor`s do not have identifiers themselves.
+    /// Instead, call `.ident()` on the parent struct/variant, like so:
+    ///
+    /// ```ignore (illustrative)
+    /// ctor
+    ///     .ctor_hir_id()
+    ///     .and_then(|ctor_id| tcx.hir().find(tcx.hir().get_parent_node(ctor_id)))
+    ///     .and_then(|parent| parent.ident())
+    /// ```
     pub fn ident(&self) -> Option<Ident> {
         match self {
             Node::TraitItem(TraitItem { ident, .. })
@@ -3190,8 +3204,25 @@ impl<'hir> Node<'hir> {
             | Node::Field(FieldDef { ident, .. })
             | Node::Variant(Variant { ident, .. })
             | Node::MacroDef(MacroDef { ident, .. })
-            | Node::Item(Item { ident, .. }) => Some(*ident),
-            _ => None,
+            | Node::Item(Item { ident, .. })
+            | Node::PathSegment(PathSegment { ident, .. }) => Some(*ident),
+            Node::Lifetime(lt) => Some(lt.name.ident()),
+            Node::GenericParam(p) => Some(p.name.ident()),
+            Node::Param(..)
+            | Node::AnonConst(..)
+            | Node::Expr(..)
+            | Node::Stmt(..)
+            | Node::Block(..)
+            | Node::Ctor(..)
+            | Node::Pat(..)
+            | Node::Binding(..)
+            | Node::Arm(..)
+            | Node::Local(..)
+            | Node::Visibility(..)
+            | Node::Crate(..)
+            | Node::Ty(..)
+            | Node::TraitRef(..)
+            | Node::Infer(..) => None,
         }
     }
 

From 08ceac8ee3d740c48e6bb250de0798fcbe0824f4 Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Sat, 21 Aug 2021 12:29:11 -0700
Subject: [PATCH 06/32] Add cross-crate tuple field count error test

---
 ...clarations-for-tuple-field-count-errors.rs |  20 +
 .../ui/pattern/pat-tuple-field-count-cross.rs |  57 ++
 .../pat-tuple-field-count-cross.stderr        | 536 ++++++++++++++++++
 3 files changed, 613 insertions(+)
 create mode 100644 src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs
 create mode 100644 src/test/ui/pattern/pat-tuple-field-count-cross.rs
 create mode 100644 src/test/ui/pattern/pat-tuple-field-count-cross.stderr

diff --git a/src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs b/src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs
new file mode 100644
index 0000000000000..f7373c453966c
--- /dev/null
+++ b/src/test/ui/pattern/auxiliary/declarations-for-tuple-field-count-errors.rs
@@ -0,0 +1,20 @@
+pub struct Z0;
+pub struct Z1();
+
+pub struct S(pub u8, pub u8, pub u8);
+pub struct M(
+    pub u8,
+    pub u8,
+    pub u8,
+);
+
+pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+
+pub enum E2 {
+    S(u8, u8, u8),
+    M(
+        u8,
+        u8,
+        u8,
+    ),
+}
diff --git a/src/test/ui/pattern/pat-tuple-field-count-cross.rs b/src/test/ui/pattern/pat-tuple-field-count-cross.rs
new file mode 100644
index 0000000000000..b63da4e154f73
--- /dev/null
+++ b/src/test/ui/pattern/pat-tuple-field-count-cross.rs
@@ -0,0 +1,57 @@
+// aux-build:declarations-for-tuple-field-count-errors.rs
+
+extern crate declarations_for_tuple_field_count_errors;
+
+use declarations_for_tuple_field_count_errors::*;
+
+fn main() {
+    match Z0 {
+        Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0`
+        Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0`
+    }
+    match Z1() {
+        Z1 => {} //~ ERROR match bindings cannot shadow tuple structs
+        Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 0 fields
+    }
+
+    match S(1, 2, 3) {
+        S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields
+        S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields
+        S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields
+        S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields
+    }
+    match M(1, 2, 3) {
+        M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields
+        M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields
+        M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields
+        M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields
+    }
+
+    match E1::Z0 {
+        E1::Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0`
+        E1::Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0`
+    }
+    match E1::Z1() {
+        E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
+        E1::Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 0 fields
+    }
+    match E1::S(1, 2, 3) {
+        E1::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields
+        E1::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields
+        E1::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields
+        E1::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields
+    }
+
+    match E2::S(1, 2, 3) {
+        E2::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields
+        E2::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields
+        E2::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields
+        E2::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields
+    }
+    match E2::M(1, 2, 3) {
+        E2::M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields
+        E2::M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields
+        E2::M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields
+        E2::M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields
+    }
+}
diff --git a/src/test/ui/pattern/pat-tuple-field-count-cross.stderr b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr
new file mode 100644
index 0000000000000..570bf0cbc0810
--- /dev/null
+++ b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr
@@ -0,0 +1,536 @@
+error[E0530]: match bindings cannot shadow tuple structs
+  --> $DIR/pat-tuple-field-count-cross.rs:13:9
+   |
+LL | use declarations_for_tuple_field_count_errors::*;
+   |     -------------------------------------------- the tuple struct `Z1` is imported here
+...
+LL |         Z1 => {}
+   |         ^^ cannot be named the same as a tuple struct
+
+error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
+  --> $DIR/pat-tuple-field-count-cross.rs:9:9
+   |
+LL |         Z0() => {}
+   |         ^^^^
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:1:1
+   |
+LL | pub struct Z0;
+   | -------------- `Z0` defined here
+LL | pub struct Z1();
+   | ---------------- similarly named tuple struct `Z1` defined here
+   |
+help: use this syntax instead
+   |
+LL |         Z0 => {}
+   |         ~~
+help: a tuple struct with a similar name exists
+   |
+LL |         Z1() => {}
+   |         ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
+  --> $DIR/pat-tuple-field-count-cross.rs:10:9
+   |
+LL |         Z0(x) => {}
+   |         ^^^^^
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:1:1
+   |
+LL | pub struct Z0;
+   | -------------- `Z0` defined here
+LL | pub struct Z1();
+   | ---------------- similarly named tuple struct `Z1` defined here
+   |
+help: use this syntax instead
+   |
+LL |         Z0 => {}
+   |         ~~
+help: a tuple struct with a similar name exists
+   |
+LL |         Z1(x) => {}
+   |         ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
+  --> $DIR/pat-tuple-field-count-cross.rs:31:9
+   |
+LL |         E1::Z0() => {}
+   |         ^^^^^^^^
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |               --  ---- similarly named tuple variant `Z1` defined here
+   |               |
+   |               `E1::Z0` defined here
+   |
+help: use this syntax instead
+   |
+LL |         E1::Z0 => {}
+   |         ~~~~~~
+help: a tuple variant with a similar name exists
+   |
+LL |         E1::Z1() => {}
+   |             ~~
+
+error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
+  --> $DIR/pat-tuple-field-count-cross.rs:32:9
+   |
+LL |         E1::Z0(x) => {}
+   |         ^^^^^^^^^
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |               --  ---- similarly named tuple variant `Z1` defined here
+   |               |
+   |               `E1::Z0` defined here
+   |
+help: use this syntax instead
+   |
+LL |         E1::Z0 => {}
+   |         ~~~~~~
+help: a tuple variant with a similar name exists
+   |
+LL |         E1::Z1(x) => {}
+   |             ~~
+
+error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
+  --> $DIR/pat-tuple-field-count-cross.rs:35:9
+   |
+LL |         E1::Z1 => {}
+   |         ^^^^^^
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |               --  ---- `E1::Z1` defined here
+   |               |
+   |               similarly named unit variant `Z0` defined here
+   |
+help: use the tuple variant pattern syntax instead
+   |
+LL |         E1::Z1(/* fields */) => {}
+   |         ~~~~~~~~~~~~~~~~~~~~
+help: a unit variant with a similar name exists
+   |
+LL |         E1::Z0 => {}
+   |             ~~
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:14:12
+   |
+LL |         Z1(x) => {}
+   |         -- ^ expected 0 fields, found 1
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:2:1
+   |
+LL | pub struct Z1();
+   | ---------------- tuple struct has 0 fields
+
+error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:18:10
+   |
+LL |         S() => {}
+   |         -^^ expected 3 fields, found 0
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
+   |
+LL | pub struct S(pub u8, pub u8, pub u8);
+   |              ------  ------  ------ tuple struct has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         S(_, _, _) => {}
+   |           +++++++
+help: use `..` to ignore all fields
+   |
+LL |         S(..) => {}
+   |           ++
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:19:11
+   |
+LL |         S(1) => {}
+   |         - ^ expected 3 fields, found 1
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
+   |
+LL | pub struct S(pub u8, pub u8, pub u8);
+   |              ------  ------  ------ tuple struct has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         S(1, _, _) => {}
+   |            ++++++
+help: use `..` to ignore the rest of the fields
+   |
+LL |         S(1, ..) => {}
+   |            ++++
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:20:11
+   |
+LL |         S(xyz, abc) => {}
+   |         - ^^^  ^^^ expected 3 fields, found 2
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
+   |
+LL | pub struct S(pub u8, pub u8, pub u8);
+   |              ------  ------  ------ tuple struct has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         S(xyz, abc, _) => {}
+   |                   +++
+
+error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:21:11
+   |
+LL |         S(1, 2, 3, 4) => {}
+   |         - ^  ^  ^  ^ expected 3 fields, found 4
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
+   |
+LL | pub struct S(pub u8, pub u8, pub u8);
+   |              ------  ------  ------ tuple struct has 3 fields
+
+error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:24:10
+   |
+LL |           M() => {}
+   |           -^^ expected 3 fields, found 0
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
+   |
+LL | / pub struct M(
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------ tuple struct has 3 fields
+LL | | );
+   | |__- tuple struct defined here
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         M(_, _, _) => {}
+   |           +++++++
+help: use `..` to ignore all fields
+   |
+LL |         M(..) => {}
+   |           ++
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:25:11
+   |
+LL |           M(1) => {}
+   |           - ^ expected 3 fields, found 1
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
+   |
+LL | / pub struct M(
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------ tuple struct has 3 fields
+LL | | );
+   | |__- tuple struct defined here
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         M(1, _, _) => {}
+   |            ++++++
+help: use `..` to ignore the rest of the fields
+   |
+LL |         M(1, ..) => {}
+   |            ++++
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:26:11
+   |
+LL |           M(xyz, abc) => {}
+   |           - ^^^  ^^^ expected 3 fields, found 2
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
+   |
+LL | / pub struct M(
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------ tuple struct has 3 fields
+LL | | );
+   | |__- tuple struct defined here
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         M(xyz, abc, _) => {}
+   |                   +++
+
+error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:27:11
+   |
+LL |           M(1, 2, 3, 4) => {}
+   |           - ^  ^  ^  ^ expected 3 fields, found 4
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
+   |
+LL | / pub struct M(
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------
+LL | |     pub u8,
+   | |     ------ tuple struct has 3 fields
+LL | | );
+   | |__- tuple struct defined here
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:36:16
+   |
+LL |         E1::Z1(x) => {}
+   |         ------ ^ expected 0 fields, found 1
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |                   ---- tuple variant has 0 fields
+
+error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:39:14
+   |
+LL |         E1::S() => {}
+   |         -----^^ expected 3 fields, found 0
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |                           --  --  -- tuple variant has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E1::S(_, _, _) => {}
+   |               +++++++
+help: use `..` to ignore all fields
+   |
+LL |         E1::S(..) => {}
+   |               ++
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:40:15
+   |
+LL |         E1::S(1) => {}
+   |         ----- ^ expected 3 fields, found 1
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |                           --  --  -- tuple variant has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E1::S(1, _, _) => {}
+   |                ++++++
+help: use `..` to ignore the rest of the fields
+   |
+LL |         E1::S(1, ..) => {}
+   |                ++++
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:41:15
+   |
+LL |         E1::S(xyz, abc) => {}
+   |         ----- ^^^  ^^^ expected 3 fields, found 2
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |                           --  --  -- tuple variant has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E1::S(xyz, abc, _) => {}
+   |                       +++
+
+error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:42:15
+   |
+LL |         E1::S(1, 2, 3, 4) => {}
+   |         ----- ^  ^  ^  ^ expected 3 fields, found 4
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
+   |
+LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
+   |                           --  --  -- tuple variant has 3 fields
+
+error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:46:14
+   |
+LL |         E2::S() => {}
+   |         -----^^ expected 3 fields, found 0
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
+   |
+LL |     S(u8, u8, u8),
+   |       --  --  -- tuple variant has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E2::S(_, _, _) => {}
+   |               +++++++
+help: use `..` to ignore all fields
+   |
+LL |         E2::S(..) => {}
+   |               ++
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:47:15
+   |
+LL |         E2::S(1) => {}
+   |         ----- ^ expected 3 fields, found 1
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
+   |
+LL |     S(u8, u8, u8),
+   |       --  --  -- tuple variant has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E2::S(1, _, _) => {}
+   |                ++++++
+help: use `..` to ignore the rest of the fields
+   |
+LL |         E2::S(1, ..) => {}
+   |                ++++
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:48:15
+   |
+LL |         E2::S(xyz, abc) => {}
+   |         ----- ^^^  ^^^ expected 3 fields, found 2
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
+   |
+LL |     S(u8, u8, u8),
+   |       --  --  -- tuple variant has 3 fields
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E2::S(xyz, abc, _) => {}
+   |                       +++
+
+error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:49:15
+   |
+LL |         E2::S(1, 2, 3, 4) => {}
+   |         ----- ^  ^  ^  ^ expected 3 fields, found 4
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
+   |
+LL |     S(u8, u8, u8),
+   |       --  --  -- tuple variant has 3 fields
+
+error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:52:14
+   |
+LL |           E2::M() => {}
+   |           -----^^ expected 3 fields, found 0
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
+   |
+LL | /     M(
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         -- tuple variant has 3 fields
+LL | |     ),
+   | |_____- tuple variant defined here
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E2::M(_, _, _) => {}
+   |               +++++++
+help: use `..` to ignore all fields
+   |
+LL |         E2::M(..) => {}
+   |               ++
+
+error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:53:15
+   |
+LL |           E2::M(1) => {}
+   |           ----- ^ expected 3 fields, found 1
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
+   |
+LL | /     M(
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         -- tuple variant has 3 fields
+LL | |     ),
+   | |_____- tuple variant defined here
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E2::M(1, _, _) => {}
+   |                ++++++
+help: use `..` to ignore the rest of the fields
+   |
+LL |         E2::M(1, ..) => {}
+   |                ++++
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:54:15
+   |
+LL |           E2::M(xyz, abc) => {}
+   |           ----- ^^^  ^^^ expected 3 fields, found 2
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
+   |
+LL | /     M(
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         -- tuple variant has 3 fields
+LL | |     ),
+   | |_____- tuple variant defined here
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E2::M(xyz, abc, _) => {}
+   |                       +++
+
+error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has 3 fields
+  --> $DIR/pat-tuple-field-count-cross.rs:55:15
+   |
+LL |           E2::M(1, 2, 3, 4) => {}
+   |           ----- ^  ^  ^  ^ expected 3 fields, found 4
+   |
+  ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
+   |
+LL | /     M(
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         --
+LL | |         u8,
+   | |         -- tuple variant has 3 fields
+LL | |     ),
+   | |_____- tuple variant defined here
+
+error: aborting due to 28 previous errors
+
+Some errors have detailed explanations: E0023, E0530, E0532.
+For more information about an error, try `rustc --explain E0023`.

From 19f45101e72ed6880b0fd1ebee73d74ea782c8c4 Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Sat, 21 Aug 2021 18:41:34 -0700
Subject: [PATCH 07/32] Bless tests

---
 .../ui/pattern/pat-tuple-overfield.stderr     | 34 +++++++++----------
 ...priority-higher-than-other-inherent.stderr |  6 ++++
 .../ui/typeck/struct-enum-wrong-args.stderr   | 30 ++++++++++++++++
 3 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr
index 1df9c1c11b8a5..646ac4e661897 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-overfield.stderr
@@ -1,5 +1,5 @@
 error[E0530]: match bindings cannot shadow tuple structs
-  --> $DIR/pat-tuple-overfield.rs:43:9
+  --> $DIR/pat-tuple-overfield.rs:41:9
    |
 LL | struct Z1();
    | ------------ the tuple struct `Z1` is defined here
@@ -8,7 +8,7 @@ LL |         Z1 => {}
    |         ^^ cannot be named the same as a tuple struct
 
 error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
-  --> $DIR/pat-tuple-overfield.rs:38:9
+  --> $DIR/pat-tuple-overfield.rs:36:9
    |
 LL | struct Z0;
    | ---------- `Z0` defined here
@@ -28,7 +28,7 @@ LL |         Z1() => {}
    |         ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
-  --> $DIR/pat-tuple-overfield.rs:39:9
+  --> $DIR/pat-tuple-overfield.rs:37:9
    |
 LL | struct Z0;
    | ---------- `Z0` defined here
@@ -48,7 +48,7 @@ LL |         Z1(_) => {}
    |         ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
-  --> $DIR/pat-tuple-overfield.rs:40:9
+  --> $DIR/pat-tuple-overfield.rs:38:9
    |
 LL | struct Z0;
    | ---------- `Z0` defined here
@@ -68,7 +68,7 @@ LL |         Z1(_, _) => {}
    |         ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
-  --> $DIR/pat-tuple-overfield.rs:50:9
+  --> $DIR/pat-tuple-overfield.rs:48:9
    |
 LL |     Z0,
    |     -- `E1::Z0` defined here
@@ -88,7 +88,7 @@ LL |         E1::Z1() => {}
    |             ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
-  --> $DIR/pat-tuple-overfield.rs:51:9
+  --> $DIR/pat-tuple-overfield.rs:49:9
    |
 LL |     Z0,
    |     -- `E1::Z0` defined here
@@ -108,7 +108,7 @@ LL |         E1::Z1(_) => {}
    |             ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
-  --> $DIR/pat-tuple-overfield.rs:52:9
+  --> $DIR/pat-tuple-overfield.rs:50:9
    |
 LL |     Z0,
    |     -- `E1::Z0` defined here
@@ -128,7 +128,7 @@ LL |         E1::Z1(_, _) => {}
    |             ~~
 
 error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
-  --> $DIR/pat-tuple-overfield.rs:55:9
+  --> $DIR/pat-tuple-overfield.rs:53:9
    |
 LL |     Z0,
    |     -- similarly named unit variant `Z0` defined here
@@ -148,7 +148,7 @@ LL |         E1::Z0 => {}
    |             ~~
 
 error[E0308]: mismatched types
-  --> $DIR/pat-tuple-overfield.rs:21:9
+  --> $DIR/pat-tuple-overfield.rs:19:9
    |
 LL |     match (1, 2, 3) {
    |           --------- this expression has type `({integer}, {integer}, {integer})`
@@ -159,7 +159,7 @@ LL |         (1, 2, 3, 4) => {}
               found tuple `(_, _, _, _)`
 
 error[E0308]: mismatched types
-  --> $DIR/pat-tuple-overfield.rs:22:9
+  --> $DIR/pat-tuple-overfield.rs:20:9
    |
 LL |     match (1, 2, 3) {
    |           --------- this expression has type `({integer}, {integer}, {integer})`
@@ -171,7 +171,7 @@ LL |         (1, 2, .., 3, 4) => {}
               found tuple `(_, _, _, _)`
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:26:11
+  --> $DIR/pat-tuple-overfield.rs:24:11
    |
 LL | struct S(u8, u8, u8);
    |          --  --  -- tuple struct has 3 fields
@@ -180,7 +180,7 @@ LL |         S(1, 2, 3, 4) => {}
    |         - ^  ^  ^  ^ expected 3 fields, found 4
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-overfield.rs:28:11
+  --> $DIR/pat-tuple-overfield.rs:26:11
    |
 LL | struct S(u8, u8, u8);
    |          --  --  -- tuple struct has 3 fields
@@ -189,7 +189,7 @@ LL |         S(1, 2, .., 3, 4) => {}
    |         - ^  ^      ^  ^ expected 3 fields, found 4
 
 error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields
-  --> $DIR/pat-tuple-overfield.rs:33:11
+  --> $DIR/pat-tuple-overfield.rs:31:11
    |
 LL | struct M(
    |        - tuple struct defined here
@@ -208,7 +208,7 @@ LL |         M(1, 2, 3, 4, 5, 6) => {}
    |         - ^  ^  ^  ^  ^  ^ expected 5 fields, found 6
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:45:12
+  --> $DIR/pat-tuple-overfield.rs:43:12
    |
 LL | struct Z1();
    |          --- tuple struct has 0 fields
@@ -217,7 +217,7 @@ LL |         Z1(_) => {}
    |         -- ^ expected 0 fields, found 1
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:46:12
+  --> $DIR/pat-tuple-overfield.rs:44:12
    |
 LL | struct Z1();
    |          --- tuple struct has 0 fields
@@ -226,7 +226,7 @@ LL |         Z1(_, _) => {}
    |         -- ^  ^ expected 0 fields, found 2
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:57:16
+  --> $DIR/pat-tuple-overfield.rs:55:16
    |
 LL |     Z1(),
    |       -- tuple variant has 0 fields
@@ -235,7 +235,7 @@ LL |         E1::Z1(_) => {}
    |         ------ ^ expected 0 fields, found 1
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:58:16
+  --> $DIR/pat-tuple-overfield.rs:56:16
    |
 LL |     Z1(),
    |       -- tuple variant has 0 fields
diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
index 1d520613a288f..37543c137f66f 100644
--- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
+++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-higher-than-other-inherent.stderr
@@ -5,6 +5,12 @@ LL |     <E>::V();
    |     ^^^^^^-- supplied 0 arguments
    |     |
    |     expected 1 argument
+   |
+note: tuple variant defined here
+  --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:5:5
+   |
+LL |     V(u8)
+   |     ^
 
 error[E0308]: mismatched types
   --> $DIR/enum-variant-priority-higher-than-other-inherent.rs:22:17
diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr
index d77ef73028b0c..6e99feed33f9c 100644
--- a/src/test/ui/typeck/struct-enum-wrong-args.stderr
+++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr
@@ -29,6 +29,12 @@ LL |     let _ = Wrapper();
    |             ^^^^^^^-- supplied 0 arguments
    |             |
    |             expected 1 argument
+   |
+note: tuple struct defined here
+  --> $DIR/struct-enum-wrong-args.rs:2:8
+   |
+LL | struct Wrapper(i32);
+   |        ^^^^^^^
 
 error[E0061]: this struct takes 1 argument but 2 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:10:13
@@ -37,6 +43,12 @@ LL |     let _ = Wrapper(5, 2);
    |             ^^^^^^^ -  - supplied 2 arguments
    |             |
    |             expected 1 argument
+   |
+note: tuple struct defined here
+  --> $DIR/struct-enum-wrong-args.rs:2:8
+   |
+LL | struct Wrapper(i32);
+   |        ^^^^^^^
 
 error[E0061]: this struct takes 2 arguments but 0 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:11:13
@@ -45,6 +57,12 @@ LL |     let _ = DoubleWrapper();
    |             ^^^^^^^^^^^^^-- supplied 0 arguments
    |             |
    |             expected 2 arguments
+   |
+note: tuple struct defined here
+  --> $DIR/struct-enum-wrong-args.rs:3:8
+   |
+LL | struct DoubleWrapper(i32, i32);
+   |        ^^^^^^^^^^^^^
 
 error[E0061]: this struct takes 2 arguments but 1 argument was supplied
   --> $DIR/struct-enum-wrong-args.rs:12:13
@@ -53,6 +71,12 @@ LL |     let _ = DoubleWrapper(5);
    |             ^^^^^^^^^^^^^ - supplied 1 argument
    |             |
    |             expected 2 arguments
+   |
+note: tuple struct defined here
+  --> $DIR/struct-enum-wrong-args.rs:3:8
+   |
+LL | struct DoubleWrapper(i32, i32);
+   |        ^^^^^^^^^^^^^
 
 error[E0061]: this struct takes 2 arguments but 3 arguments were supplied
   --> $DIR/struct-enum-wrong-args.rs:13:13
@@ -61,6 +85,12 @@ LL |     let _ = DoubleWrapper(5, 2, 7);
    |             ^^^^^^^^^^^^^ -  -  - supplied 3 arguments
    |             |
    |             expected 2 arguments
+   |
+note: tuple struct defined here
+  --> $DIR/struct-enum-wrong-args.rs:3:8
+   |
+LL | struct DoubleWrapper(i32, i32);
+   |        ^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 

From f28793dd13e8a8132d559629728e6ca9514dbe36 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Fri, 6 Aug 2021 17:53:29 -0400
Subject: [PATCH 08/32] Feat: added inline asm support for s390x

---
 compiler/rustc_codegen_llvm/src/asm.rs |   6 +
 compiler/rustc_target/src/asm/mod.rs   |  25 ++++
 compiler/rustc_target/src/asm/s390x.rs | 156 +++++++++++++++++++++++++
 3 files changed, 187 insertions(+)
 create mode 100644 compiler/rustc_target/src/asm/s390x.rs

diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 4387f5301a58d..938f036da0e4a 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -314,6 +314,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {}
                 InlineAsmArch::Hexagon => {}
                 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
+                InlineAsmArch::s390 => {}
                 InlineAsmArch::SpirV => {}
                 InlineAsmArch::Wasm32 => {}
                 InlineAsmArch::Bpf => {}
@@ -633,6 +634,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
             InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
             InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
             InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
+            InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => "r",
+            InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => "f",
             InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
                 bug!("LLVM backend does not support SPIR-V")
             }
@@ -711,6 +714,7 @@ fn modifier_to_llvm(
         }
         InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
         InlineAsmRegClass::Bpf(_) => None,
+        InlineAsmRegClass::s390x(_) => None,
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
@@ -769,6 +773,8 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
         InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
         InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
         InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
+        InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => cx.type_i32(),
+        InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => cx.type_f64(),
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 9ebf8235e2098..3ce5a8195d601 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -154,6 +154,7 @@ mod mips;
 mod nvptx;
 mod powerpc;
 mod riscv;
+mod s390x;
 mod spirv;
 mod wasm;
 mod x86;
@@ -166,6 +167,7 @@ pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
 pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
 pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass};
 pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
+pub use s390x::{s390xInlineAsmReg, s390xInlineAsmRegClass};
 pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
 pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
 pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
@@ -184,6 +186,7 @@ pub enum InlineAsmArch {
     Mips64,
     PowerPC,
     PowerPC64,
+    s390x,
     SpirV,
     Wasm32,
     Bpf,
@@ -206,6 +209,7 @@ impl FromStr for InlineAsmArch {
             "hexagon" => Ok(Self::Hexagon),
             "mips" => Ok(Self::Mips),
             "mips64" => Ok(Self::Mips64),
+            "s390x" => Ok(Self::s390x),
             "spirv" => Ok(Self::SpirV),
             "wasm32" => Ok(Self::Wasm32),
             "bpf" => Ok(Self::Bpf),
@@ -235,6 +239,7 @@ pub enum InlineAsmReg {
     PowerPC(PowerPCInlineAsmReg),
     Hexagon(HexagonInlineAsmReg),
     Mips(MipsInlineAsmReg),
+    s390x(InlineAsmReg),
     SpirV(SpirVInlineAsmReg),
     Wasm(WasmInlineAsmReg),
     Bpf(BpfInlineAsmReg),
@@ -252,6 +257,7 @@ impl InlineAsmReg {
             Self::PowerPC(r) => r.name(),
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
+	        Self::s390x(r) => r.name(),
             Self::Bpf(r) => r.name(),
             Self::Err => "<reg>",
         }
@@ -266,6 +272,7 @@ impl InlineAsmReg {
             Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
             Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
             Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
+            Self::s390x(r) => InlineAsmRegClass::s390x(r.reg_class()),
             Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
             Self::Err => InlineAsmRegClass::Err,
         }
@@ -305,6 +312,9 @@ impl InlineAsmReg {
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
+    	    InlineAsmArch::s390x => {
+                Self::s390x(s390xInlineAsmReg::parse(arch, has_feature, target, &name)?)
+            }
             InlineAsmArch::SpirV => {
                 Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
@@ -333,6 +343,7 @@ impl InlineAsmReg {
             Self::PowerPC(r) => r.emit(out, arch, modifier),
             Self::Hexagon(r) => r.emit(out, arch, modifier),
             Self::Mips(r) => r.emit(out, arch, modifier),
+            Self::s390x(r) => r.emit(out, arch, modifier),
             Self::Bpf(r) => r.emit(out, arch, modifier),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
@@ -347,6 +358,7 @@ impl InlineAsmReg {
             Self::PowerPC(_) => cb(self),
             Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
             Self::Mips(_) => cb(self),
+            Self::s390x(_) => cb(self),
             Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
@@ -374,6 +386,7 @@ pub enum InlineAsmRegClass {
     PowerPC(PowerPCInlineAsmRegClass),
     Hexagon(HexagonInlineAsmRegClass),
     Mips(MipsInlineAsmRegClass),
+    s390x(s390xInlineAsmRegClass),
     SpirV(SpirVInlineAsmRegClass),
     Wasm(WasmInlineAsmRegClass),
     Bpf(BpfInlineAsmRegClass),
@@ -392,6 +405,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.name(),
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
+            Self::s390x(r) => r.name(),
             Self::SpirV(r) => r.name(),
             Self::Wasm(r) => r.name(),
             Self::Bpf(r) => r.name(),
@@ -412,6 +426,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC),
             Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
             Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
+            Self::s390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::s390x),
             Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
             Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
             Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf),
@@ -439,6 +454,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.suggest_modifier(arch, ty),
             Self::Hexagon(r) => r.suggest_modifier(arch, ty),
             Self::Mips(r) => r.suggest_modifier(arch, ty),
+            Self::s390x(r) => r.suggest_modifier(arch, ty),
             Self::SpirV(r) => r.suggest_modifier(arch, ty),
             Self::Wasm(r) => r.suggest_modifier(arch, ty),
             Self::Bpf(r) => r.suggest_modifier(arch, ty),
@@ -462,6 +478,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.default_modifier(arch),
             Self::Hexagon(r) => r.default_modifier(arch),
             Self::Mips(r) => r.default_modifier(arch),
+            Self::s390x(r) => r.default_modifier(arch),
             Self::SpirV(r) => r.default_modifier(arch),
             Self::Wasm(r) => r.default_modifier(arch),
             Self::Bpf(r) => r.default_modifier(arch),
@@ -484,6 +501,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.supported_types(arch),
             Self::Hexagon(r) => r.supported_types(arch),
             Self::Mips(r) => r.supported_types(arch),
+            Self::s390x(r) => r.supported_types(arch),
             Self::SpirV(r) => r.supported_types(arch),
             Self::Wasm(r) => r.supported_types(arch),
             Self::Bpf(r) => r.supported_types(arch),
@@ -509,6 +527,7 @@ impl InlineAsmRegClass {
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
             }
+            InlineAsmArch::s390x => Self::s390x(s390xInlineAsmRegClass::parse(arch, name)?),
             InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
             InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
             InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?),
@@ -527,6 +546,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.valid_modifiers(arch),
             Self::Hexagon(r) => r.valid_modifiers(arch),
             Self::Mips(r) => r.valid_modifiers(arch),
+            Self::s390x(r) => r.valid_modifiers(arch),
             Self::SpirV(r) => r.valid_modifiers(arch),
             Self::Wasm(r) => r.valid_modifiers(arch),
             Self::Bpf(r) => r.valid_modifiers(arch),
@@ -695,6 +715,11 @@ pub fn allocatable_registers(
             mips::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
+	InlineAsmArch::s390x => {
+	    let mut map = s390x::regclass_map();
+            s390x::fill_reg_map(arch, has_feature, target, &mut map);
+            map
+	}
         InlineAsmArch::SpirV => {
             let mut map = spirv::regclass_map();
             spirv::fill_reg_map(arch, has_feature, target, &mut map);
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
new file mode 100644
index 0000000000000..ad07e20de8a02
--- /dev/null
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -0,0 +1,156 @@
+use super::{InlineAsmArch, InlineAsmType};
+use rustc_macros::HashStable_Generic;
+use std::fmt;
+
+def_reg_class! {
+    s390x s390xInlineAsmRegClass {
+        reg,
+        freg,
+    }
+}
+
+impl s390xInlineAsmRegClass {
+    pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
+        &[]
+    }
+
+    pub fn suggest_class(self, _arch: InlineAsmArch, _ty: InlineAsmType) -> Option<Self> {
+        None
+    }
+
+    pub fn suggest_modifier(
+        self,
+        _arch: InlineAsmArch,
+        _ty: InlineAsmType,
+    ) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn default_modifier(self, _arch: InlineAsmArch) -> Option<(char, &'static str)> {
+        None
+    }
+
+    pub fn supported_types(
+        self,
+        arch: InlineAsmArch,
+    ) -> &'static [(InlineAsmType, Option<&'static str>)] {
+        match (self, arch) {
+            (Self::reg, _) => types! { _: I8, I16, I32; },
+            (Self::freg, _) => types! { _: F32, F64; },
+        }
+    }
+}
+
+def_regs! {
+    s390x s390xInlineAsmReg s390xInlineAsmRegClass {
+        r0: req = ["r0"],
+        r1: reg = ["r1"],
+        r2: reg = ["r2"],
+        r3: reg = ["r3"],
+        r4: reg = ["r4"],
+        r5: reg = ["r5"],
+        r6: reg = ["r6"],
+        r7: reg = ["r7"],
+        r8: reg = ["r8"],
+        r9: reg = ["r9"],
+        r10: reg = ["r10"],
+        r11: reg = ["r11"],
+        r12: reg = ["r12"],
+        r14: reg = ["r14"],
+        f0: freg = ["f0"],
+        f1: freg = ["f1"],
+        f2: freg = ["f2"],
+        f3: freg = ["f3"],
+        f4: freg = ["f4"],
+        f5: freg = ["f5"],
+        f6: freg = ["f6"],
+        f7: freg = ["f7"],
+        f8: freg = ["f8"],
+        f9: freg = ["f9"],
+        f10: freg = ["f10"],
+        f11: freg = ["f11"],
+        f12: freg = ["f12"],
+        f13: freg = ["f13"],
+        f14: freg = ["f14"],
+        f15: freg = ["f15"],
+        #error = ["r13"] =>
+            "The base pointer cannot be used as an operand for inline asm",
+        #error = ["r15"] =>
+            "The stack pointer cannot be used as an operand for inline asm",
+        #error = ["a0"] =>
+            "This pointer is reserved on s390x and cannot be used as an operand for inline asm",
+        #error = ["a1"] =>
+            "This pointer is reserved on z/Arch and cannot be used as an operand for inline asm",
+        #error = ["c0"] =>
+            "c0 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c1"] =>
+            "c1 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c2"] =>
+            "c2 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c3"] =>
+            "c3 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c4"] =>
+            "c4 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c5"] =>
+            "c5 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c6"] =>
+            "c6 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c7"] =>
+            "c7 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c8"] =>
+            "c8 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c9"] =>
+            "c9 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c10"] =>
+            "c10 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c11"] =>
+            "c11 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c12"] =>
+            "c12 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c13"] =>
+            "c13 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c14"] =>
+            "c14 is reserved by the kernel and cannot be used as an operand for inline asm",
+        #error = ["c15"] =>
+            "c15 is reserved by the kernel and cannot be used as an operand for inline asm",
+	    #error = ["a2"] =>
+            "a2 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a3"] =>
+            "a3 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a4"] =>
+            "a4 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a5"] =>
+            "a5 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a6"] =>
+            "a6 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a7"] =>
+            "a7 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a8"] =>
+            "a8 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a9"] =>
+            "a9 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a10"] =>
+            "a10 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a11"] =>
+            "a11 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a12"] =>
+            "a12 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a13"] =>
+            "a13 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a14"] =>
+            "a14 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = ["a15"] =>
+            "a15 is not supported by LLVM and cannot be used as an operand for inline asm",
+    }
+}
+
+impl s390xInlineAsmReg {
+    pub fn emit(
+        self,
+        out: &mut dyn fmt::Write,
+        _arch: InlineAsmArch,
+        _modifier: Option<char>,
+    ) -> fmt::Result {
+        out.write_str(self.name())
+    }
+}

From 5f5afba5fbb869db26c4f9e88c29bad94007dfd1 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Wed, 18 Aug 2021 11:25:50 -0400
Subject: [PATCH 09/32] Feat: added s390x reg-definitions, constraint codes,
 and tests

---
 compiler/rustc_codegen_llvm/src/asm.rs | 12 ++--
 compiler/rustc_target/src/asm/mod.rs   | 42 ++++++-------
 compiler/rustc_target/src/asm/s390x.rs | 10 +--
 src/test/assembly/asm/s390x-types.rs   | 86 ++++++++++++++++++++++++++
 4 files changed, 118 insertions(+), 32 deletions(-)
 create mode 100644 src/test/assembly/asm/s390x-types.rs

diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 938f036da0e4a..1689fdd4f2e81 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -314,7 +314,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
                 InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => {}
                 InlineAsmArch::Hexagon => {}
                 InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
-                InlineAsmArch::s390 => {}
+                InlineAsmArch::S390x => {}
                 InlineAsmArch::SpirV => {}
                 InlineAsmArch::Wasm32 => {}
                 InlineAsmArch::Bpf => {}
@@ -634,8 +634,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
             InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
             InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
             InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
-            InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => "f",
+            InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
+            InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
             InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
                 bug!("LLVM backend does not support SPIR-V")
             }
@@ -714,7 +714,7 @@ fn modifier_to_llvm(
         }
         InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
         InlineAsmRegClass::Bpf(_) => None,
-        InlineAsmRegClass::s390x(_) => None,
+        InlineAsmRegClass::S390x(_) => None,
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
@@ -773,8 +773,8 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
         InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
         InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
         InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
-        InlineAsmRegClass::s390x(s390xInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::s390x(s390xInlineAsmRegClass::freg) => cx.type_f64(),
+        InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => cx.type_i32(),
+        InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
         InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
             bug!("LLVM backend does not support SPIR-V")
         }
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 3ce5a8195d601..015faa14e28af 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -167,7 +167,7 @@ pub use mips::{MipsInlineAsmReg, MipsInlineAsmRegClass};
 pub use nvptx::{NvptxInlineAsmReg, NvptxInlineAsmRegClass};
 pub use powerpc::{PowerPCInlineAsmReg, PowerPCInlineAsmRegClass};
 pub use riscv::{RiscVInlineAsmReg, RiscVInlineAsmRegClass};
-pub use s390x::{s390xInlineAsmReg, s390xInlineAsmRegClass};
+pub use s390x::{S390xInlineAsmReg, S390xInlineAsmRegClass};
 pub use spirv::{SpirVInlineAsmReg, SpirVInlineAsmRegClass};
 pub use wasm::{WasmInlineAsmReg, WasmInlineAsmRegClass};
 pub use x86::{X86InlineAsmReg, X86InlineAsmRegClass};
@@ -186,7 +186,7 @@ pub enum InlineAsmArch {
     Mips64,
     PowerPC,
     PowerPC64,
-    s390x,
+    S390x,
     SpirV,
     Wasm32,
     Bpf,
@@ -209,7 +209,7 @@ impl FromStr for InlineAsmArch {
             "hexagon" => Ok(Self::Hexagon),
             "mips" => Ok(Self::Mips),
             "mips64" => Ok(Self::Mips64),
-            "s390x" => Ok(Self::s390x),
+            "s390x" => Ok(Self::S390x),
             "spirv" => Ok(Self::SpirV),
             "wasm32" => Ok(Self::Wasm32),
             "bpf" => Ok(Self::Bpf),
@@ -239,7 +239,7 @@ pub enum InlineAsmReg {
     PowerPC(PowerPCInlineAsmReg),
     Hexagon(HexagonInlineAsmReg),
     Mips(MipsInlineAsmReg),
-    s390x(InlineAsmReg),
+    S390x(S390xInlineAsmReg),
     SpirV(SpirVInlineAsmReg),
     Wasm(WasmInlineAsmReg),
     Bpf(BpfInlineAsmReg),
@@ -257,7 +257,7 @@ impl InlineAsmReg {
             Self::PowerPC(r) => r.name(),
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
-	        Self::s390x(r) => r.name(),
+	        Self::S390x(r) => r.name(),
             Self::Bpf(r) => r.name(),
             Self::Err => "<reg>",
         }
@@ -272,7 +272,7 @@ impl InlineAsmReg {
             Self::PowerPC(r) => InlineAsmRegClass::PowerPC(r.reg_class()),
             Self::Hexagon(r) => InlineAsmRegClass::Hexagon(r.reg_class()),
             Self::Mips(r) => InlineAsmRegClass::Mips(r.reg_class()),
-            Self::s390x(r) => InlineAsmRegClass::s390x(r.reg_class()),
+            Self::S390x(r) => InlineAsmRegClass::S390x(r.reg_class()),
             Self::Bpf(r) => InlineAsmRegClass::Bpf(r.reg_class()),
             Self::Err => InlineAsmRegClass::Err,
         }
@@ -312,8 +312,8 @@ impl InlineAsmReg {
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
-    	    InlineAsmArch::s390x => {
-                Self::s390x(s390xInlineAsmReg::parse(arch, has_feature, target, &name)?)
+    	    InlineAsmArch::S390x => {
+                Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
             InlineAsmArch::SpirV => {
                 Self::SpirV(SpirVInlineAsmReg::parse(arch, has_feature, target, &name)?)
@@ -343,7 +343,7 @@ impl InlineAsmReg {
             Self::PowerPC(r) => r.emit(out, arch, modifier),
             Self::Hexagon(r) => r.emit(out, arch, modifier),
             Self::Mips(r) => r.emit(out, arch, modifier),
-            Self::s390x(r) => r.emit(out, arch, modifier),
+            Self::S390x(r) => r.emit(out, arch, modifier),
             Self::Bpf(r) => r.emit(out, arch, modifier),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
@@ -358,7 +358,7 @@ impl InlineAsmReg {
             Self::PowerPC(_) => cb(self),
             Self::Hexagon(r) => r.overlapping_regs(|r| cb(Self::Hexagon(r))),
             Self::Mips(_) => cb(self),
-            Self::s390x(_) => cb(self),
+            Self::S390x(_) => cb(self),
             Self::Bpf(r) => r.overlapping_regs(|r| cb(Self::Bpf(r))),
             Self::Err => unreachable!("Use of InlineAsmReg::Err"),
         }
@@ -386,7 +386,7 @@ pub enum InlineAsmRegClass {
     PowerPC(PowerPCInlineAsmRegClass),
     Hexagon(HexagonInlineAsmRegClass),
     Mips(MipsInlineAsmRegClass),
-    s390x(s390xInlineAsmRegClass),
+    S390x(S390xInlineAsmRegClass),
     SpirV(SpirVInlineAsmRegClass),
     Wasm(WasmInlineAsmRegClass),
     Bpf(BpfInlineAsmRegClass),
@@ -405,7 +405,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.name(),
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
-            Self::s390x(r) => r.name(),
+            Self::S390x(r) => r.name(),
             Self::SpirV(r) => r.name(),
             Self::Wasm(r) => r.name(),
             Self::Bpf(r) => r.name(),
@@ -426,7 +426,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::PowerPC),
             Self::Hexagon(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Hexagon),
             Self::Mips(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Mips),
-            Self::s390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::s390x),
+            Self::S390x(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::S390x),
             Self::SpirV(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::SpirV),
             Self::Wasm(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Wasm),
             Self::Bpf(r) => r.suggest_class(arch, ty).map(InlineAsmRegClass::Bpf),
@@ -454,7 +454,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.suggest_modifier(arch, ty),
             Self::Hexagon(r) => r.suggest_modifier(arch, ty),
             Self::Mips(r) => r.suggest_modifier(arch, ty),
-            Self::s390x(r) => r.suggest_modifier(arch, ty),
+            Self::S390x(r) => r.suggest_modifier(arch, ty),
             Self::SpirV(r) => r.suggest_modifier(arch, ty),
             Self::Wasm(r) => r.suggest_modifier(arch, ty),
             Self::Bpf(r) => r.suggest_modifier(arch, ty),
@@ -478,7 +478,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.default_modifier(arch),
             Self::Hexagon(r) => r.default_modifier(arch),
             Self::Mips(r) => r.default_modifier(arch),
-            Self::s390x(r) => r.default_modifier(arch),
+            Self::S390x(r) => r.default_modifier(arch),
             Self::SpirV(r) => r.default_modifier(arch),
             Self::Wasm(r) => r.default_modifier(arch),
             Self::Bpf(r) => r.default_modifier(arch),
@@ -501,7 +501,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.supported_types(arch),
             Self::Hexagon(r) => r.supported_types(arch),
             Self::Mips(r) => r.supported_types(arch),
-            Self::s390x(r) => r.supported_types(arch),
+            Self::S390x(r) => r.supported_types(arch),
             Self::SpirV(r) => r.supported_types(arch),
             Self::Wasm(r) => r.supported_types(arch),
             Self::Bpf(r) => r.supported_types(arch),
@@ -527,7 +527,7 @@ impl InlineAsmRegClass {
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmRegClass::parse(arch, name)?)
             }
-            InlineAsmArch::s390x => Self::s390x(s390xInlineAsmRegClass::parse(arch, name)?),
+            InlineAsmArch::S390x => Self::S390x(S390xInlineAsmRegClass::parse(arch, name)?),
             InlineAsmArch::SpirV => Self::SpirV(SpirVInlineAsmRegClass::parse(arch, name)?),
             InlineAsmArch::Wasm32 => Self::Wasm(WasmInlineAsmRegClass::parse(arch, name)?),
             InlineAsmArch::Bpf => Self::Bpf(BpfInlineAsmRegClass::parse(arch, name)?),
@@ -546,7 +546,7 @@ impl InlineAsmRegClass {
             Self::PowerPC(r) => r.valid_modifiers(arch),
             Self::Hexagon(r) => r.valid_modifiers(arch),
             Self::Mips(r) => r.valid_modifiers(arch),
-            Self::s390x(r) => r.valid_modifiers(arch),
+            Self::S390x(r) => r.valid_modifiers(arch),
             Self::SpirV(r) => r.valid_modifiers(arch),
             Self::Wasm(r) => r.valid_modifiers(arch),
             Self::Bpf(r) => r.valid_modifiers(arch),
@@ -715,11 +715,11 @@ pub fn allocatable_registers(
             mips::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
-	InlineAsmArch::s390x => {
-	    let mut map = s390x::regclass_map();
+	    InlineAsmArch::S390x => {
+	        let mut map = s390x::regclass_map();
             s390x::fill_reg_map(arch, has_feature, target, &mut map);
             map
-	}
+	    }
         InlineAsmArch::SpirV => {
             let mut map = spirv::regclass_map();
             spirv::fill_reg_map(arch, has_feature, target, &mut map);
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index ad07e20de8a02..0acbea800930c 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -3,13 +3,13 @@ use rustc_macros::HashStable_Generic;
 use std::fmt;
 
 def_reg_class! {
-    s390x s390xInlineAsmRegClass {
+    S390x S390xInlineAsmRegClass {
         reg,
         freg,
     }
 }
 
-impl s390xInlineAsmRegClass {
+impl S390xInlineAsmRegClass {
     pub fn valid_modifiers(self, _arch: super::InlineAsmArch) -> &'static [char] {
         &[]
     }
@@ -42,8 +42,8 @@ impl s390xInlineAsmRegClass {
 }
 
 def_regs! {
-    s390x s390xInlineAsmReg s390xInlineAsmRegClass {
-        r0: req = ["r0"],
+    S390x S390xInlineAsmReg S390xInlineAsmRegClass {
+        r0: reg = ["r0"],
         r1: reg = ["r1"],
         r2: reg = ["r2"],
         r3: reg = ["r3"],
@@ -144,7 +144,7 @@ def_regs! {
     }
 }
 
-impl s390xInlineAsmReg {
+impl S390xInlineAsmReg {
     pub fn emit(
         self,
         out: &mut dyn fmt::Write,
diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs
new file mode 100644
index 0000000000000..5f1a5f2de56be
--- /dev/null
+++ b/src/test/assembly/asm/s390x-types.rs
@@ -0,0 +1,86 @@
+// min-llvm-version: 10.0.1
+// revisions: s390x
+// assembly-output: emit-asm
+//[s390x] compile-flags: --target s390x-unknown-linux-gnu
+//[s390x] needs-llvm-components: systemz
+
+#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
+#![crate_type = "rlib"]
+#![no_core]
+#![allow(asm_sub_register, non_camel_case_types)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+#[rustc_builtin_macro]
+macro_rules! concat {
+    () => {};
+}
+#[rustc_builtin_macro]
+macro_rules! stringify {
+    () => {};
+}
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
+
+type ptr = *const i32;
+
+impl Copy for i8 {}
+impl Copy for u8 {}
+impl Copy for i16 {}
+impl Copy for i32 {}
+impl Copy for i64 {}
+impl Copy for f32 {}
+impl Copy for f64 {}
+impl Copy for ptr {}
+
+extern "C" {
+    fn extern_func();
+    static extern_static: u8;
+}
+
+// Hack to avoid function merging
+extern "Rust" {
+    fn dont_merge(s: &str);
+}
+
+macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
+    
+    pub unsafe fn $func(x: $ty) -> $ty {
+        dont_merge(stringify!(func));
+
+        let y;
+        asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
+        y
+    }
+};}
+
+macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
+    
+    pub unsafe fn $func(x: $ty) -> $ty {
+        dont_merge(stringify!(func));
+
+        let y;
+        asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
+        y
+    }
+};}
+
+// systemz-LABEL: sym_fn_32:
+// systemz: #APP
+// systemz: brasl %r14, extern_func@PLT
+// systemz: #NO_APP
+#[cfg(s390x)]
+pub unsafe fn sym_fn_32() {
+    asm!("brasl %r14, {}", sym extern_func);
+}
+
+// CHECK-LABEL: reg_i32:
+// CHECK: #APP
+// CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}}
+// CHECK: #NO_APP
+check!(reg_i32, i32, reg, "lgr");

From 7095dfffc3bde0fc56a837241db84e414e3d9b25 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Wed, 18 Aug 2021 12:14:26 -0400
Subject: [PATCH 10/32] Refactor: added #[no_mangle]

---
 src/test/assembly/asm/s390x-types.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs
index 5f1a5f2de56be..7b2ef9bda3478 100644
--- a/src/test/assembly/asm/s390x-types.rs
+++ b/src/test/assembly/asm/s390x-types.rs
@@ -75,6 +75,7 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
 // systemz: brasl %r14, extern_func@PLT
 // systemz: #NO_APP
 #[cfg(s390x)]
+#[no_mangle]
 pub unsafe fn sym_fn_32() {
     asm!("brasl %r14, {}", sym extern_func);
 }
@@ -83,4 +84,5 @@ pub unsafe fn sym_fn_32() {
 // CHECK: #APP
 // CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}}
 // CHECK: #NO_APP
+#[no_mangle]
 check!(reg_i32, i32, reg, "lgr");

From 66e95b17ecfc93e39b1846436a86f0e924ab30b3 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Wed, 18 Aug 2021 12:40:18 -0400
Subject: [PATCH 11/32] Fix: moved #[no_mangle]

---
 src/test/assembly/asm/s390x-types.rs | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs
index 7b2ef9bda3478..0fbb77b96175e 100644
--- a/src/test/assembly/asm/s390x-types.rs
+++ b/src/test/assembly/asm/s390x-types.rs
@@ -49,7 +49,7 @@ extern "Rust" {
 }
 
 macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
-    
+    #[no_mangle]     
     pub unsafe fn $func(x: $ty) -> $ty {
         dont_merge(stringify!(func));
 
@@ -75,7 +75,6 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
 // systemz: brasl %r14, extern_func@PLT
 // systemz: #NO_APP
 #[cfg(s390x)]
-#[no_mangle]
 pub unsafe fn sym_fn_32() {
     asm!("brasl %r14, {}", sym extern_func);
 }
@@ -84,5 +83,4 @@ pub unsafe fn sym_fn_32() {
 // CHECK: #APP
 // CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}}
 // CHECK: #NO_APP
-#[no_mangle]
 check!(reg_i32, i32, reg, "lgr");

From eeb0b52bf852b902b2bd1adaf919c35e2387ce28 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Sun, 22 Aug 2021 17:26:18 -0400
Subject: [PATCH 12/32] Feat: further testing & support for i64 general
 register use

---
 compiler/rustc_target/src/asm/s390x.rs |  2 +-
 src/test/assembly/asm/s390x-types.rs   | 52 +++++++++++++++++++++++---
 2 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index 0acbea800930c..dbf4168e4a80f 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -35,7 +35,7 @@ impl S390xInlineAsmRegClass {
         arch: InlineAsmArch,
     ) -> &'static [(InlineAsmType, Option<&'static str>)] {
         match (self, arch) {
-            (Self::reg, _) => types! { _: I8, I16, I32; },
+            (Self::reg, _) => types! { _: I8, I16, I32, I64; },
             (Self::freg, _) => types! { _: F32, F64; },
         }
     }
diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs
index 0fbb77b96175e..692193158405f 100644
--- a/src/test/assembly/asm/s390x-types.rs
+++ b/src/test/assembly/asm/s390x-types.rs
@@ -60,7 +60,7 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
 };}
 
 macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
-    
+    #[no_mangle]    
     pub unsafe fn $func(x: $ty) -> $ty {
         dont_merge(stringify!(func));
 
@@ -70,17 +70,57 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
     }
 };}
 
-// systemz-LABEL: sym_fn_32:
-// systemz: #APP
-// systemz: brasl %r14, extern_func@PLT
-// systemz: #NO_APP
+// CHECK-LABEL: sym_fn_32:
+// CHECK: #APP
+// CHECK: brasl %r14, extern_func
+// CHECK: #NO_APP
 #[cfg(s390x)]
+#[no_mangle]
 pub unsafe fn sym_fn_32() {
     asm!("brasl %r14, {}", sym extern_func);
 }
 
+// CHECK-LABEL: sym_static:
+// CHECK: #APP
+// CHECK: brasl %r14, extern_static
+// CHECK: #NO_APP
+#[no_mangle]
+pub unsafe fn sym_static() {
+    asm!("brasl %r14, {}", sym extern_static);
+}
+
+// CHECK-LABEL: reg_i8:
+// CHECK: #APP
+// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
+// CHECK: #NO_APP
+check!(reg_i8, i8, reg, "lgr");
+
+// CHECK-LABEL: reg_i16:
+// CHECK: #APP
+// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
+// CHECK: #NO_APP
+check!(reg_i16, i16, reg, "lgr");
+
 // CHECK-LABEL: reg_i32:
 // CHECK: #APP
-// CHECK: lgr r{{[0-15]+}}, r{{[0-15]+}}
+// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
 // CHECK: #NO_APP
 check!(reg_i32, i32, reg, "lgr");
+
+// CHECK-LABEL: reg_i64:
+// CHECK: #APP
+// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
+// CHECK: #NO_APP
+check!(reg_i64, i64, reg, "lgr");
+
+// CHECK-LABEL: reg_f32:
+// CHECK: #APP
+// CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}}
+// CHECK: #NO_APP
+check!(reg_f32, f32, freg, "ler");
+
+// CHECK-LABEL: reg_f64:
+// CHECK: #APP
+// CHECK: ldr %f{{[0-9]+}}, %f{{[0-9]+}}
+// CHECK: #NO_APP
+check!(reg_f64, f64, freg, "ldr");

From 0c9e23c7ce964438b107d064533b89f024e7ccf8 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Sun, 22 Aug 2021 17:38:22 -0400
Subject: [PATCH 13/32] Fix: appeased x.py test tidy --bless

---
 compiler/rustc_target/src/asm/mod.rs   | 10 +++++-----
 compiler/rustc_target/src/asm/s390x.rs |  2 +-
 src/test/assembly/asm/s390x-types.rs   |  4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 015faa14e28af..3b3017e37c1f0 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -257,7 +257,7 @@ impl InlineAsmReg {
             Self::PowerPC(r) => r.name(),
             Self::Hexagon(r) => r.name(),
             Self::Mips(r) => r.name(),
-	        Self::S390x(r) => r.name(),
+            Self::S390x(r) => r.name(),
             Self::Bpf(r) => r.name(),
             Self::Err => "<reg>",
         }
@@ -312,7 +312,7 @@ impl InlineAsmReg {
             InlineAsmArch::Mips | InlineAsmArch::Mips64 => {
                 Self::Mips(MipsInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
-    	    InlineAsmArch::S390x => {
+            InlineAsmArch::S390x => {
                 Self::S390x(S390xInlineAsmReg::parse(arch, has_feature, target, &name)?)
             }
             InlineAsmArch::SpirV => {
@@ -715,11 +715,11 @@ pub fn allocatable_registers(
             mips::fill_reg_map(arch, has_feature, target, &mut map);
             map
         }
-	    InlineAsmArch::S390x => {
-	        let mut map = s390x::regclass_map();
+        InlineAsmArch::S390x => {
+            let mut map = s390x::regclass_map();
             s390x::fill_reg_map(arch, has_feature, target, &mut map);
             map
-	    }
+        }
         InlineAsmArch::SpirV => {
             let mut map = spirv::regclass_map();
             spirv::fill_reg_map(arch, has_feature, target, &mut map);
diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index dbf4168e4a80f..29f370928713b 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -113,7 +113,7 @@ def_regs! {
             "c14 is reserved by the kernel and cannot be used as an operand for inline asm",
         #error = ["c15"] =>
             "c15 is reserved by the kernel and cannot be used as an operand for inline asm",
-	    #error = ["a2"] =>
+        #error = ["a2"] =>
             "a2 is not supported by LLVM and cannot be used as an operand for inline asm",
         #error = ["a3"] =>
             "a3 is not supported by LLVM and cannot be used as an operand for inline asm",
diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs
index 692193158405f..dd8a256516e6f 100644
--- a/src/test/assembly/asm/s390x-types.rs
+++ b/src/test/assembly/asm/s390x-types.rs
@@ -49,7 +49,7 @@ extern "Rust" {
 }
 
 macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
-    #[no_mangle]     
+    #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
         dont_merge(stringify!(func));
 
@@ -60,7 +60,7 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
 };}
 
 macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
-    #[no_mangle]    
+    #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
         dont_merge(stringify!(func));
 

From 820e2680ec2f7f5f1b42dc94374986d251a22aff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Mon, 23 Aug 2021 23:31:01 +0200
Subject: [PATCH 14/32] handle ascription type op in NLL HRTB diagnostics

Refactors the `type_op_ascribe_user_type` query into a version which
accepts a span, and uses it in the nicer NLL HRTB bound region errors.
---
 .../diagnostics/bound_region_errors.rs        | 42 ++++++++++++++--
 compiler/rustc_traits/src/lib.rs              |  2 +-
 compiler/rustc_traits/src/type_op.rs          | 48 +++++++++++++------
 3 files changed, 72 insertions(+), 20 deletions(-)

diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
index d0284dd030236..ac30093ba8260 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/bound_region_errors.rs
@@ -9,7 +9,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_span::Span;
 use rustc_trait_selection::traits::query::type_op;
 use rustc_trait_selection::traits::{SelectionContext, TraitEngineExt as _};
-use rustc_traits::type_op_prove_predicate_with_span;
+use rustc_traits::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_span};
 
 use std::fmt;
 use std::rc::Rc;
@@ -104,10 +104,11 @@ impl<'tcx, T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx> ToUniverseInfo<'t
 impl<'tcx> ToUniverseInfo<'tcx>
     for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>
 {
-    fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
-        // Ascribe user type isn't usually called on types that have different
-        // bound regions.
-        UniverseInfo::other()
+    fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
+        UniverseInfo(UniverseInfoInner::TypeOp(Rc::new(AscribeUserTypeQuery {
+            canonical_query: self,
+            base_universe,
+        })))
     }
 }
 
@@ -267,6 +268,37 @@ where
     }
 }
 
+struct AscribeUserTypeQuery<'tcx> {
+    canonical_query: Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::AscribeUserType<'tcx>>>,
+    base_universe: ty::UniverseIndex,
+}
+
+impl TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
+    fn fallback_error(&self, tcx: TyCtxt<'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
+        // FIXME: This error message isn't great, but it doesn't show up in the existing UI tests,
+        // and is only the fallback when the nice error fails. Consider improving this some more.
+        tcx.sess.struct_span_err(span, "higher-ranked lifetime error")
+    }
+
+    fn base_universe(&self) -> ty::UniverseIndex {
+        self.base_universe
+    }
+
+    fn nice_error(
+        &self,
+        tcx: TyCtxt<'tcx>,
+        span: Span,
+        placeholder_region: ty::Region<'tcx>,
+        error_region: Option<ty::Region<'tcx>>,
+    ) -> Option<DiagnosticBuilder<'tcx>> {
+        tcx.infer_ctxt().enter_with_canonical(span, &self.canonical_query, |ref infcx, key, _| {
+            let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
+            type_op_ascribe_user_type_with_span(infcx, &mut *fulfill_cx, key, Some(span)).ok()?;
+            try_extract_error_from_fulfill_cx(fulfill_cx, infcx, placeholder_region, error_region)
+        })
+    }
+}
+
 fn try_extract_error_from_fulfill_cx<'tcx>(
     mut fulfill_cx: Box<dyn TraitEngine<'tcx> + 'tcx>,
     infcx: &InferCtxt<'_, 'tcx>,
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index 8dd7c5bdfaebc..48c46c3069328 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -19,7 +19,7 @@ mod normalize_erasing_regions;
 mod normalize_projection_ty;
 mod type_op;
 
-pub use type_op::type_op_prove_predicate_with_span;
+pub use type_op::{type_op_ascribe_user_type_with_span, type_op_prove_predicate_with_span};
 
 use rustc_middle::ty::query::Providers;
 
diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs
index c2e0a9987858e..a76fb84261615 100644
--- a/compiler/rustc_traits/src/type_op.rs
+++ b/compiler/rustc_traits/src/type_op.rs
@@ -40,18 +40,28 @@ fn type_op_ascribe_user_type<'tcx>(
     canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, AscribeUserType<'tcx>>>,
 ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> {
     tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |infcx, fulfill_cx, key| {
-        let (param_env, AscribeUserType { mir_ty, def_id, user_substs }) = key.into_parts();
-
-        debug!(
-            "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}",
-            mir_ty, def_id, user_substs
-        );
+        type_op_ascribe_user_type_with_span(infcx, fulfill_cx, key, None)
+    })
+}
 
-        let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx };
-        cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs)?;
+/// The core of the `type_op_ascribe_user_type` query: for diagnostics purposes in NLL HRTB errors,
+/// this query can be re-run to better track the span of the obligation cause, and improve the error
+/// message. Do not call directly unless you're in that very specific context.
+pub fn type_op_ascribe_user_type_with_span<'a, 'tcx: 'a>(
+    infcx: &'a InferCtxt<'a, 'tcx>,
+    fulfill_cx: &'a mut dyn TraitEngine<'tcx>,
+    key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>,
+    span: Option<Span>,
+) -> Result<(), NoSolution> {
+    let (param_env, AscribeUserType { mir_ty, def_id, user_substs }) = key.into_parts();
+    debug!(
+        "type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}",
+        mir_ty, def_id, user_substs
+    );
 
-        Ok(())
-    })
+    let mut cx = AscribeUserTypeCx { infcx, param_env, fulfill_cx };
+    cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs, span)?;
+    Ok(())
 }
 
 struct AscribeUserTypeCx<'me, 'tcx> {
@@ -85,10 +95,15 @@ impl AscribeUserTypeCx<'me, 'tcx> {
         Ok(())
     }
 
-    fn prove_predicate(&mut self, predicate: Predicate<'tcx>) {
+    fn prove_predicate(&mut self, predicate: Predicate<'tcx>, span: Option<Span>) {
+        let cause = if let Some(span) = span {
+            ObligationCause::dummy_with_span(span)
+        } else {
+            ObligationCause::dummy()
+        };
         self.fulfill_cx.register_predicate_obligation(
             self.infcx,
-            Obligation::new(ObligationCause::dummy(), self.param_env, predicate),
+            Obligation::new(cause, self.param_env, predicate),
         );
     }
 
@@ -108,6 +123,7 @@ impl AscribeUserTypeCx<'me, 'tcx> {
         mir_ty: Ty<'tcx>,
         def_id: DefId,
         user_substs: UserSubsts<'tcx>,
+        span: Option<Span>,
     ) -> Result<(), NoSolution> {
         let UserSubsts { user_self_ty, substs } = user_substs;
         let tcx = self.tcx();
@@ -129,7 +145,7 @@ impl AscribeUserTypeCx<'me, 'tcx> {
         debug!(?instantiated_predicates.predicates);
         for instantiated_predicate in instantiated_predicates.predicates {
             let instantiated_predicate = self.normalize(instantiated_predicate);
-            self.prove_predicate(instantiated_predicate);
+            self.prove_predicate(instantiated_predicate, span);
         }
 
         if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
@@ -141,6 +157,7 @@ impl AscribeUserTypeCx<'me, 'tcx> {
 
             self.prove_predicate(
                 ty::PredicateKind::WellFormed(impl_self_ty.into()).to_predicate(self.tcx()),
+                span,
             );
         }
 
@@ -155,7 +172,10 @@ impl AscribeUserTypeCx<'me, 'tcx> {
         // them?  This would only be relevant if some input
         // type were ill-formed but did not appear in `ty`,
         // which...could happen with normalization...
-        self.prove_predicate(ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()));
+        self.prove_predicate(
+            ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()),
+            span,
+        );
         Ok(())
     }
 }

From 05cd587726b01415f50ab8def30ea07864298e13 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Mon, 23 Aug 2021 17:32:27 -0400
Subject: [PATCH 15/32] Refactor: disabled frame pointer; consolidated
 unsupported register errors; added register prefix

---
 compiler/rustc_target/src/asm/s390x.rs | 86 ++++++--------------------
 1 file changed, 18 insertions(+), 68 deletions(-)

diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index 29f370928713b..5ed93c0c1a9ce 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -54,8 +54,8 @@ def_regs! {
         r8: reg = ["r8"],
         r9: reg = ["r9"],
         r10: reg = ["r10"],
-        r11: reg = ["r11"],
         r12: reg = ["r12"],
+        r13: reg = ["r13"],
         r14: reg = ["r14"],
         f0: freg = ["f0"],
         f1: freg = ["f1"],
@@ -73,74 +73,24 @@ def_regs! {
         f13: freg = ["f13"],
         f14: freg = ["f14"],
         f15: freg = ["f15"],
-        #error = ["r13"] =>
-            "The base pointer cannot be used as an operand for inline asm",
+        #error = ["r11"] =>
+            "The frame pointer cannot be used as an operand for inline asm",
         #error = ["r15"] =>
             "The stack pointer cannot be used as an operand for inline asm",
-        #error = ["a0"] =>
-            "This pointer is reserved on s390x and cannot be used as an operand for inline asm",
-        #error = ["a1"] =>
-            "This pointer is reserved on z/Arch and cannot be used as an operand for inline asm",
-        #error = ["c0"] =>
-            "c0 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c1"] =>
-            "c1 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c2"] =>
-            "c2 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c3"] =>
-            "c3 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c4"] =>
-            "c4 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c5"] =>
-            "c5 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c6"] =>
-            "c6 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c7"] =>
-            "c7 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c8"] =>
-            "c8 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c9"] =>
-            "c9 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c10"] =>
-            "c10 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c11"] =>
-            "c11 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c12"] =>
-            "c12 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c13"] =>
-            "c13 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c14"] =>
-            "c14 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["c15"] =>
-            "c15 is reserved by the kernel and cannot be used as an operand for inline asm",
-        #error = ["a2"] =>
-            "a2 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a3"] =>
-            "a3 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a4"] =>
-            "a4 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a5"] =>
-            "a5 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a6"] =>
-            "a6 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a7"] =>
-            "a7 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a8"] =>
-            "a8 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a9"] =>
-            "a9 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a10"] =>
-            "a10 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a11"] =>
-            "a11 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a12"] =>
-            "a12 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a13"] =>
-            "a13 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a14"] =>
-            "a14 is not supported by LLVM and cannot be used as an operand for inline asm",
-        #error = ["a15"] =>
-            "a15 is not supported by LLVM and cannot be used as an operand for inline asm",
+        #error = [
+            "c0", "c1", "c2", "c3",
+            "c4", "c5", "c6", "c7",
+            "c8", "c9", "c10", "c11",
+            "c12", "c13", "c14", "c15"
+        ] =>
+            "control registers are reserved by the kernel and cannot be used as operands for inline asm",
+        #error = [
+            "a0", "a1", "a2", "a3",
+            "a4", "a5", "a6", "a7",
+            "a8", "a9", "a10", "a11",
+            "a12", "a13", "a14", "a15"
+        ] =>
+            "access registers are not supported and cannot be used as operands for inline asm",
     }
 }
 
@@ -151,6 +101,6 @@ impl S390xInlineAsmReg {
         _arch: InlineAsmArch,
         _modifier: Option<char>,
     ) -> fmt::Result {
-        out.write_str(self.name())
+        out.write_str(&format!("%{}", self.name()))
     }
 }

From a9f623707b8dcaba260b547e1950a4679b3b40eb Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Mon, 23 Aug 2021 17:56:04 -0400
Subject: [PATCH 16/32] Fix: made suggested change

---
 compiler/rustc_target/src/asm/s390x.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_target/src/asm/s390x.rs b/compiler/rustc_target/src/asm/s390x.rs
index 5ed93c0c1a9ce..a74873f17476e 100644
--- a/compiler/rustc_target/src/asm/s390x.rs
+++ b/compiler/rustc_target/src/asm/s390x.rs
@@ -101,6 +101,6 @@ impl S390xInlineAsmReg {
         _arch: InlineAsmArch,
         _modifier: Option<char>,
     ) -> fmt::Result {
-        out.write_str(&format!("%{}", self.name()))
+        write!(out, "%{}", self.name())
     }
 }

From 7b0e564e7cd3bebea7c41165db42a7b15010d2cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?= <remy.rakic+github@gmail.com>
Date: Mon, 23 Aug 2021 23:34:04 +0200
Subject: [PATCH 17/32] Update NLL HRTB type ascription blessed expectations

Some of these tests have reached parity with the migrate-mode output.
---
 src/test/ui/hrtb/due-to-where-clause.nll.stderr    | 8 --------
 src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr | 8 --------
 src/test/ui/hrtb/hrtb-just-for-static.nll.stderr   | 7 +++++--
 src/test/ui/issues/issue-54302.nll.stderr          | 8 --------
 4 files changed, 5 insertions(+), 26 deletions(-)
 delete mode 100644 src/test/ui/hrtb/due-to-where-clause.nll.stderr
 delete mode 100644 src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr
 delete mode 100644 src/test/ui/issues/issue-54302.nll.stderr

diff --git a/src/test/ui/hrtb/due-to-where-clause.nll.stderr b/src/test/ui/hrtb/due-to-where-clause.nll.stderr
deleted file mode 100644
index 90803a0adb01b..0000000000000
--- a/src/test/ui/hrtb/due-to-where-clause.nll.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: higher-ranked subtype error
-  --> $DIR/due-to-where-clause.rs:2:5
-   |
-LL |     test::<FooS>(&mut 42);
-   |     ^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr b/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr
deleted file mode 100644
index 4de35d70c30a3..0000000000000
--- a/src/test/ui/hrtb/hrtb-cache-issue-54302.nll.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: higher-ranked subtype error
-  --> $DIR/hrtb-cache-issue-54302.rs:19:5
-   |
-LL |     assert_deserialize_owned::<&'static str>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr b/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr
index a812282def9a8..17d59bb321a45 100644
--- a/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr
+++ b/src/test/ui/hrtb/hrtb-just-for-static.nll.stderr
@@ -17,11 +17,14 @@ LL |     want_hrtb::<&'a u32>()
    |
    = help: consider replacing `'a` with `'static`
 
-error: higher-ranked subtype error
+error: implementation of `Foo` is not general enough
   --> $DIR/hrtb-just-for-static.rs:30:5
    |
 LL |     want_hrtb::<&'a u32>()
-   |     ^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |
+   = note: `Foo<&'0 isize>` would have to be implemented for the type `&u32`, for any lifetime `'0`...
+   = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/issues/issue-54302.nll.stderr b/src/test/ui/issues/issue-54302.nll.stderr
deleted file mode 100644
index e68de0312824d..0000000000000
--- a/src/test/ui/issues/issue-54302.nll.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: higher-ranked subtype error
-  --> $DIR/issue-54302.rs:13:5
-   |
-LL |     assert_deserialize_owned::<&'static str>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-

From 96381d390d7362e06809ee624dba2cca1bc6776f Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Mon, 23 Aug 2021 21:53:23 -0400
Subject: [PATCH 18/32] Fix: added necessary prefix

---
 src/test/assembly/asm/s390x-types.rs | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs
index dd8a256516e6f..ec0515b20bdfb 100644
--- a/src/test/assembly/asm/s390x-types.rs
+++ b/src/test/assembly/asm/s390x-types.rs
@@ -51,7 +51,7 @@ extern "Rust" {
 macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!(func));
+        dont_merge(stringify!($func));
 
         let y;
         asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
@@ -62,7 +62,7 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
 macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!(func));
+        dont_merge(stringify!($func));
 
         let y;
         asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
@@ -124,3 +124,9 @@ check!(reg_f32, f32, freg, "ler");
 // CHECK: ldr %f{{[0-9]+}}, %f{{[0-9]+}}
 // CHECK: #NO_APP
 check!(reg_f64, f64, freg, "ldr");
+
+// CHECK-LABEL: reg_ptr:
+// CHECK: #APP
+// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
+// CHECK: #NO_APP
+check!(reg_ptr, ptr, reg, "lgr");

From 07d37299eb898a4035a73cdabf731e14ccf9e140 Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Mon, 23 Aug 2021 19:16:44 -0700
Subject: [PATCH 19/32] Update cargo

---
 Cargo.lock      | 4 ++--
 src/tools/cargo | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9e0624c57ae94..424172f500382 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -871,9 +871,9 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.44+curl-7.77.0"
+version = "0.4.45+curl-7.78.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b6d85e9322b193f117c966e79c2d6929ec08c02f339f950044aba12e20bbaf1"
+checksum = "de9e5a72b1c744eb5dd20b2be4d7eb84625070bb5c4ab9b347b70464ab1e62eb"
 dependencies = [
  "cc",
  "libc",
diff --git a/src/tools/cargo b/src/tools/cargo
index e96bdb0c3d0a4..9b81660b79832 160000
--- a/src/tools/cargo
+++ b/src/tools/cargo
@@ -1 +1 @@
-Subproject commit e96bdb0c3d0a418e7fcd7fbd69be08abf830b4bc
+Subproject commit 9b81660b79832f92512edd4c29059a9ff88fcb6c

From 4d8d72f4f9cd971fce3965015d785ecedb256326 Mon Sep 17 00:00:00 2001
From: Roxane <roxane.fruytier@hotmail.com>
Date: Mon, 23 Aug 2021 22:41:03 -0400
Subject: [PATCH 20/32] Handle match with non axhaustive variants in closures

---
 compiler/rustc_typeck/src/expr_use_visitor.rs | 17 +++++-
 .../auxiliary/match_non_exhaustive_lib.rs     | 10 ++++
 .../non-exhaustive-match.rs                   | 54 +++++++++++++++++++
 .../non-exhaustive-match.stderr               | 50 +++++++++++++++++
 4 files changed, 129 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs
 create mode 100644 src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs
 create mode 100644 src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr

diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index 1d7852d964c1d..c5c758255f0aa 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -14,7 +14,7 @@ use rustc_index::vec::Idx;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::mir::FakeReadCause;
-use rustc_middle::ty::{self, adjustment, TyCtxt};
+use rustc_middle::ty::{self, adjustment, AdtKind, TyCtxt};
 use rustc_target::abi::VariantIdx;
 use std::iter;
 
@@ -262,7 +262,20 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                                 let place_ty = place.place.ty();
 
                                 if let ty::Adt(def, _) = place_ty.kind() {
-                                    if def.variants.len() > 1 {
+                                    // Note that if a non-exhaustive SingleVariant is defined in another crate, we need
+                                    // to assume that more cases will be added to the variant in the future. This mean
+                                    // that we should handle non-exhaustive SingleVariant the same way we would handle
+                                    // a MultiVariant.
+                                    // If the variant is not local it must be defined in another crate.
+                                    let is_non_exhaustive = match def.adt_kind() {
+                                        AdtKind::Struct | AdtKind::Union => {
+                                            def.non_enum_variant().is_field_list_non_exhaustive()
+                                        }
+                                        AdtKind::Enum => def.is_variant_list_non_exhaustive(),
+                                    };
+                                    if def.variants.len() > 1
+                                        || (!def.did.is_local() && is_non_exhaustive)
+                                    {
                                         needs_to_be_read = true;
                                     }
                                 }
diff --git a/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs b/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs
new file mode 100644
index 0000000000000..4060c409355a1
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs
@@ -0,0 +1,10 @@
+#[non_exhaustive]
+pub enum E1 {}
+
+#[non_exhaustive]
+pub enum E2 { A, B }
+
+#[non_exhaustive]
+pub enum E3 { C }
+
+pub enum E4 { D }
diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs
new file mode 100644
index 0000000000000..318673ef847e5
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs
@@ -0,0 +1,54 @@
+// edition:2021
+
+// aux-build:match_non_exhaustive_lib.rs
+
+/* The error message for non-exhaustive matches on non-local enums
+ * marked as non-exhaustive should mention the fact that the enum
+ * is marked as non-exhaustive (issue #85227).
+ */
+
+// Ignore non_exhaustive in the same crate
+#[non_exhaustive]
+enum L1 { A, B }
+enum L2 { C }
+
+extern crate match_non_exhaustive_lib;
+use match_non_exhaustive_lib::{E1, E2, E3, E4};
+
+fn foo() -> (L1, L2) {todo!()}
+fn bar() -> (E1, E2, E3, E4) {todo!()}
+
+fn main() {
+    let (l1, l2) = foo();
+    // No error for enums defined in this crate
+    let _a = || { match l1 { L1::A => (), L1::B => () } };
+    // (except if the match is already non-exhaustive)
+    let _b = || { match l1 { L1::A => () } };
+    //~^ ERROR: non-exhaustive patterns: `B` not covered [E0004]
+
+    // l2 should not be captured as it is a non-exhaustive SingleVariant
+    // defined in this crate
+    let _c = || { match l2 { L2::C => (), _ => () }  };
+    let mut mut_l2 = l2;
+    _c();
+
+    // E1 is not visibly uninhabited from here
+    let (e1, e2, e3, e4) = bar();
+    let _d = || { match e1 {} };
+    //~^ ERROR: non-exhaustive patterns: type `E1` is non-empty [E0004]
+    let _e = || { match e2 { E2::A => (), E2::B => () } };
+    //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004]
+    let _f = || { match e2 { E2::A => (), E2::B => (), _ => () }  };
+
+    // e3 should be captured as it is a non-exhaustive SingleVariant
+    // defined in another crate
+    let _g = || { match e3 { E3::C => (), _ => () }  };
+    let mut mut_e3 = e3;
+    //~^ ERROR: cannot move out of `e3` because it is borrowed
+    _g();
+
+    // e4 should not be captured as it is a SingleVariant
+    let _h = || { match e4 { E4::D => (), _ => () }  };
+    let mut mut_e4 = e4;
+    _h();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr
new file mode 100644
index 0000000000000..91ffe1a47f413
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr
@@ -0,0 +1,50 @@
+error[E0004]: non-exhaustive patterns: `B` not covered
+  --> $DIR/non-exhaustive-match.rs:26:25
+   |
+LL | enum L1 { A, B }
+   | ----------------
+   | |            |
+   | |            not covered
+   | `L1` defined here
+...
+LL |     let _b = || { match l1 { L1::A => () } };
+   |                         ^^ pattern `B` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `L1`
+
+error[E0004]: non-exhaustive patterns: type `E1` is non-empty
+  --> $DIR/non-exhaustive-match.rs:37:25
+   |
+LL |     let _d = || { match e1 {} };
+   |                         ^^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `E1`, which is marked as non-exhaustive
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/non-exhaustive-match.rs:39:25
+   |
+LL |     let _e = || { match e2 { E2::A => (), E2::B => () } };
+   |                         ^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `E2`, which is marked as non-exhaustive
+
+error[E0505]: cannot move out of `e3` because it is borrowed
+  --> $DIR/non-exhaustive-match.rs:46:22
+   |
+LL |     let _g = || { match e3 { E3::C => (), _ => () }  };
+   |              --         -- borrow occurs due to use in closure
+   |              |
+   |              borrow of `e3` occurs here
+LL |     let mut mut_e3 = e3;
+   |                      ^^ move out of `e3` occurs here
+LL |
+LL |     _g();
+   |     -- borrow later used here
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0004, E0505.
+For more information about an error, try `rustc --explain E0004`.

From 1335b4cadd66b026be809bbc07f77eb477393043 Mon Sep 17 00:00:00 2001
From: Roxane <roxane.fruytier@hotmail.com>
Date: Mon, 23 Aug 2021 22:41:19 -0400
Subject: [PATCH 21/32] Add additional match test case

---
 .../2229_closure_analysis/match-edge-cases.rs | 35 +++++++++++++++++++
 .../match-edge-cases.stderr                   | 17 +++++++++
 2 files changed, 52 insertions(+)
 create mode 100644 src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs
 create mode 100644 src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr

diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs
new file mode 100644
index 0000000000000..035c658302745
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs
@@ -0,0 +1,35 @@
+// edition:2021
+
+enum SingleVariant {
+    A
+}
+
+struct TestStruct {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
+fn main() {
+    let sv = SingleVariant::A;
+    let condition = true;
+    // sv should not be captured as it is a SingleVariant
+    let _a = || {
+        match sv {
+            SingleVariant::A if condition => (),
+            _ => ()
+        }
+    };
+    let mut mut_sv = sv;
+    _a();
+
+    // ts should be captured
+    let ts = TestStruct { x: 1, y: 1, z: 1 };
+    let _b = || { match ts {
+        TestStruct{ x: 1, .. } => (),
+        _ => ()
+    }};
+    let mut mut_ts = ts;
+    //~^ ERROR: cannot move out of `ts` because it is borrowed
+    _b();
+}
diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr
new file mode 100644
index 0000000000000..b9d2316206ecb
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr
@@ -0,0 +1,17 @@
+error[E0505]: cannot move out of `ts` because it is borrowed
+  --> $DIR/match-edge-cases.rs:32:22
+   |
+LL |     let _b = || { match ts {
+   |              --         -- borrow occurs due to use in closure
+   |              |
+   |              borrow of `ts` occurs here
+...
+LL |     let mut mut_ts = ts;
+   |                      ^^ move out of `ts` occurs here
+LL |
+LL |     _b();
+   |     -- borrow later used here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0505`.

From 68b1bfc9b2d93d778b61c63b6a22847c128fc964 Mon Sep 17 00:00:00 2001
From: Roxane <roxane.fruytier@hotmail.com>
Date: Mon, 23 Aug 2021 22:57:05 -0400
Subject: [PATCH 22/32] Create a specific match folder for match tests

---
 .../{ => match}/auxiliary/match_non_exhaustive_lib.rs             | 0
 .../ui/closures/2229_closure_analysis/{ => match}/issue-87097.rs  | 0
 .../closures/2229_closure_analysis/{ => match}/issue-87097.stderr | 0
 .../ui/closures/2229_closure_analysis/{ => match}/issue-87426.rs  | 0
 .../2229_closure_analysis/{ => match}/match-edge-cases.rs         | 0
 .../2229_closure_analysis/{ => match}/match-edge-cases.stderr     | 0
 .../2229_closure_analysis/{ => match}/non-exhaustive-match.rs     | 0
 .../2229_closure_analysis/{ => match}/non-exhaustive-match.stderr | 0
 .../{ => match}/pattern-matching-should-fail.rs                   | 0
 .../{ => match}/pattern-matching-should-fail.stderr               | 0
 .../{ => match}/patterns-capture-analysis.rs                      | 0
 .../{ => match}/patterns-capture-analysis.stderr                  | 0
 12 files changed, 0 insertions(+), 0 deletions(-)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/auxiliary/match_non_exhaustive_lib.rs (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/issue-87097.rs (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/issue-87097.stderr (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/issue-87426.rs (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/match-edge-cases.rs (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/match-edge-cases.stderr (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/non-exhaustive-match.rs (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/non-exhaustive-match.stderr (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/pattern-matching-should-fail.rs (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/pattern-matching-should-fail.stderr (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/patterns-capture-analysis.rs (100%)
 rename src/test/ui/closures/2229_closure_analysis/{ => match}/patterns-capture-analysis.stderr (100%)

diff --git a/src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs b/src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/auxiliary/match_non_exhaustive_lib.rs
rename to src/test/ui/closures/2229_closure_analysis/match/auxiliary/match_non_exhaustive_lib.rs
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87097.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/issue-87097.rs
rename to src/test/ui/closures/2229_closure_analysis/match/issue-87097.rs
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/issue-87097.stderr
rename to src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-87426.rs b/src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/issue-87426.rs
rename to src/test/ui/closures/2229_closure_analysis/match/issue-87426.rs
diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.rs
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/match-edge-cases.rs
rename to src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.rs
diff --git a/src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr b/src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.stderr
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/match-edge-cases.stderr
rename to src/test/ui/closures/2229_closure_analysis/match/match-edge-cases.stderr
diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.rs
rename to src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.rs
diff --git a/src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr b/src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/non-exhaustive-match.stderr
rename to src/test/ui/closures/2229_closure_analysis/match/non-exhaustive-match.stderr
diff --git a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.rs
rename to src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs
diff --git a/src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/pattern-matching-should-fail.stderr
rename to src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr
diff --git a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.rs
rename to src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.rs
diff --git a/src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr b/src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr
similarity index 100%
rename from src/test/ui/closures/2229_closure_analysis/patterns-capture-analysis.stderr
rename to src/test/ui/closures/2229_closure_analysis/match/patterns-capture-analysis.stderr

From 4a9ba65ca9eaf9db3a010cbf5859b3fdf16ac687 Mon Sep 17 00:00:00 2001
From: linux1 <tmaloney@pdx.edu>
Date: Tue, 24 Aug 2021 12:41:49 -0400
Subject: [PATCH 23/32] Feat: added explicit register tests; added prefix to
 check_reg asm string

---
 src/test/assembly/asm/s390x-types.rs | 38 +++++++++++++++++++++++++++-
 1 file changed, 37 insertions(+), 1 deletion(-)

diff --git a/src/test/assembly/asm/s390x-types.rs b/src/test/assembly/asm/s390x-types.rs
index ec0515b20bdfb..69d9cab23c8ed 100644
--- a/src/test/assembly/asm/s390x-types.rs
+++ b/src/test/assembly/asm/s390x-types.rs
@@ -65,7 +65,7 @@ macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
         dont_merge(stringify!($func));
 
         let y;
-        asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
+        asm!(concat!($mov, " %", $reg, ", %", $reg), lateout($reg) y, in($reg) x);
         y
     }
 };}
@@ -130,3 +130,39 @@ check!(reg_f64, f64, freg, "ldr");
 // CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
 // CHECK: #NO_APP
 check!(reg_ptr, ptr, reg, "lgr");
+
+// CHECK-LABEL: r0_i8:
+// CHECK: #APP
+// CHECK: lr %r0, %r0
+// CHECK: #NO_APP
+check_reg!(r0_i8, i8, "r0", "lr");
+
+// CHECK-LABEL: r0_i16:
+// CHECK: #APP
+// CHECK: lr %r0, %r0
+// CHECK: #NO_APP
+check_reg!(r0_i16, i16, "r0", "lr");
+
+// CHECK-LABEL: r0_i32:
+// CHECK: #APP
+// CHECK: lr %r0, %r0
+// CHECK: #NO_APP
+check_reg!(r0_i32, i32, "r0", "lr");
+
+// CHECK-LABEL: r0_i64:
+// CHECK: #APP
+// CHECK: lr %r0, %r0
+// CHECK: #NO_APP
+check_reg!(r0_i64, i64, "r0", "lr");
+
+// CHECK-LABEL: f0_f32:
+// CHECK: #APP
+// CHECK: ler %f0, %f0
+// CHECK: #NO_APP
+check_reg!(f0_f32, f32, "f0", "ler");
+
+// CHECK-LABEL: f0_f64:
+// CHECK: #APP
+// CHECK: ldr %f0, %f0
+// CHECK: #NO_APP
+check_reg!(f0_f64, f64, "f0", "ldr");

From a216d666ca535d3cfcc8839fd3cb3d5e483e2d7e Mon Sep 17 00:00:00 2001
From: Aman Arora <me@aman-arora.com>
Date: Wed, 25 Aug 2021 03:52:24 -0400
Subject: [PATCH 24/32] type_implements_trait consider obligation failure on
 overflow

---
 compiler/rustc_trait_selection/src/infer.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index ea074192d23b1..c55b379741ee6 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -117,7 +117,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
             recursion_depth: 0,
             predicate: trait_ref.without_const().to_predicate(self.tcx),
         };
-        self.evaluate_obligation_no_overflow(&obligation)
+        self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
     }
 }
 

From d7d122faecfcde3c34ffaa1cfa3f81debb60be59 Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Wed, 25 Aug 2021 11:39:35 -0400
Subject: [PATCH 25/32] update docs for `type_implements_trait`

---
 compiler/rustc_trait_selection/src/infer.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index c55b379741ee6..3e79545d725e7 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -44,6 +44,10 @@ pub trait InferCtxtExt<'tcx> {
     /// - the self type
     /// - the *other* type parameters of the trait, excluding the self-type
     /// - the parameter environment
+    ///
+    /// Invokes `evaluate_obligation`, so in the event that evaluating
+    /// `Ty: Trait` causes overflow, EvaluatedToRecur (or EvaluatedToUnknown) 
+    /// will be returned.
     fn type_implements_trait(
         &self,
         trait_def_id: DefId,

From 88bcd4457be4d37d83d505ad3fe2dc7a5ce7203a Mon Sep 17 00:00:00 2001
From: Niko Matsakis <niko@alum.mit.edu>
Date: Wed, 25 Aug 2021 12:09:48 -0400
Subject: [PATCH 26/32] trailing whitespace

---
 compiler/rustc_trait_selection/src/infer.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs
index 3e79545d725e7..c90649353e80f 100644
--- a/compiler/rustc_trait_selection/src/infer.rs
+++ b/compiler/rustc_trait_selection/src/infer.rs
@@ -46,7 +46,7 @@ pub trait InferCtxtExt<'tcx> {
     /// - the parameter environment
     ///
     /// Invokes `evaluate_obligation`, so in the event that evaluating
-    /// `Ty: Trait` causes overflow, EvaluatedToRecur (or EvaluatedToUnknown) 
+    /// `Ty: Trait` causes overflow, EvaluatedToRecur (or EvaluatedToUnknown)
     /// will be returned.
     fn type_implements_trait(
         &self,

From 33c71ac87d4c4bad82dfd646d7a9254c6b358a26 Mon Sep 17 00:00:00 2001
From: Thom Chiovoloni <chiovolonit@gmail.com>
Date: Wed, 25 Aug 2021 11:25:26 -0700
Subject: [PATCH 27/32] Add `c_size_t` and `c_ssize_t` to `std::os::raw`.

---
 library/std/src/os/raw/mod.rs | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs
index 50464a050c706..7ce58fb1d0ff7 100644
--- a/library/std/src/os/raw/mod.rs
+++ b/library/std/src/os/raw/mod.rs
@@ -151,3 +151,17 @@ type_alias_no_nz! { "double.md", c_double = f64; }
 #[stable(feature = "raw_os", since = "1.1.0")]
 #[doc(no_inline)]
 pub use core::ffi::c_void;
+
+/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
+///
+/// This type is currently always [`usize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "none")]
+pub type c_size_t = usize;
+
+/// Equivalent to C's `ssize_t` type, from `stddef.h` (or `cstddef` for C++).
+///
+/// This type is currently always [`isize`], however in the future there may be
+/// platforms where this is not the case.
+#[unstable(feature = "c_size_t", issue = "none")]
+pub type c_ssize_t = isize;

From 8a6501d28831d864a3af6adf2e0bd83a773062ed Mon Sep 17 00:00:00 2001
From: Noah Lev <camelidcamel@gmail.com>
Date: Wed, 25 Aug 2021 14:40:06 -0700
Subject: [PATCH 28/32] Adjust spans

* Highlight the whole pattern if it has no fields
* Highlight the whole definition if it has no fields
* Only highlight the pattern name if the pattern is multi-line
* Determine whether a pattern is multi-line based on distance from name
  to last field, rather than first field
---
 compiler/rustc_typeck/src/check/pat.rs        |  10 +-
 .../tuple_struct_destructure_fail.stderr      |   8 +-
 src/test/ui/error-codes/E0023.stderr          |  12 +-
 src/test/ui/issues/issue-72574-2.stderr       |   2 +-
 .../match/match-pattern-field-mismatch.stderr |   2 +-
 ...7-pat-tup-scrut-ty-diff-less-fields.stderr |   4 +-
 src/test/ui/pattern/issue-74539.stderr        |   2 +-
 .../pat-tuple-field-count-cross.stderr        |  54 ++++-----
 src/test/ui/pattern/pat-tuple-overfield.rs    |  16 +++
 .../ui/pattern/pat-tuple-overfield.stderr     | 108 ++++++++++++++----
 src/test/ui/pattern/pat-tuple-underfield.rs   |  12 ++
 .../ui/pattern/pat-tuple-underfield.stderr    |  64 ++++++++---
 .../ui/pattern/pattern-error-continue.stderr  |   2 +-
 13 files changed, 211 insertions(+), 85 deletions(-)

diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 341385731e7d2..e1f0d3c436366 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -992,7 +992,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let fields_ending = pluralize!(fields.len());
 
         let subpat_spans = if subpats.is_empty() {
-            vec![pat_span.trim_start(qpath.span()).unwrap_or(pat_span)]
+            vec![pat_span]
         } else {
             subpats.iter().map(|p| p.span).collect()
         };
@@ -1000,7 +1000,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let res_span = self.tcx.def_span(res.def_id());
         let def_ident_span = self.tcx.def_ident_span(res.def_id()).unwrap_or(res_span);
         let field_def_spans = if fields.is_empty() {
-            vec![res_span.trim_start(def_ident_span).unwrap_or(res_span)]
+            vec![res_span]
         } else {
             fields.iter().map(|f| f.ident.span).collect()
         };
@@ -1021,8 +1021,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             last_subpat_span,
             &format!("expected {} field{}, found {}", fields.len(), fields_ending, subpats.len()),
         );
-        err.span_label(qpath.span(), "");
-        if self.tcx.sess.source_map().is_multiline(def_ident_span.between(field_def_spans[0])) {
+        if self.tcx.sess.source_map().is_multiline(qpath.span().between(last_subpat_span)) {
+            err.span_label(qpath.span(), "");
+        }
+        if self.tcx.sess.source_map().is_multiline(def_ident_span.between(last_field_def_span)) {
             err.span_label(def_ident_span, format!("{} defined here", res.descr()));
         }
         for span in &field_def_spans[..field_def_spans.len() - 1] {
diff --git a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
index 9a47ddf047991..9aae4b0a3faed 100644
--- a/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
+++ b/src/test/ui/destructuring-assignment/tuple_struct_destructure_fail.stderr
@@ -21,7 +21,7 @@ LL | struct TupleStruct<S, T>(S, T);
    |                          -  - tuple struct has 2 fields
 ...
 LL |     TupleStruct(a, a, b) = TupleStruct(1, 2);
-   |     ----------- ^  ^  ^ expected 2 fields, found 3
+   |                 ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 2 fields
   --> $DIR/tuple_struct_destructure_fail.rs:32:17
@@ -30,7 +30,7 @@ LL | struct TupleStruct<S, T>(S, T);
    |                          -  - tuple struct has 2 fields
 ...
 LL |     TupleStruct(_) = TupleStruct(1, 2);
-   |     ----------- ^ expected 2 fields, found 1
+   |                 ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -48,7 +48,7 @@ LL |     SingleVariant(S, T)
    |                   -  - tuple variant has 2 fields
 ...
 LL |     Enum::SingleVariant(a, a, b) = Enum::SingleVariant(1, 2);
-   |     ------------------- ^  ^  ^ expected 2 fields, found 3
+   |                         ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
   --> $DIR/tuple_struct_destructure_fail.rs:36:25
@@ -57,7 +57,7 @@ LL |     SingleVariant(S, T)
    |                   -  - tuple variant has 2 fields
 ...
 LL |     Enum::SingleVariant(_) = Enum::SingleVariant(1, 2);
-   |     ------------------- ^ expected 2 fields, found 1
+   |                         ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr
index 85e1b2cb4ceef..3e321b037b2b2 100644
--- a/src/test/ui/error-codes/E0023.stderr
+++ b/src/test/ui/error-codes/E0023.stderr
@@ -5,7 +5,7 @@ LL |     Apple(String, String),
    |           ------  ------ tuple variant has 2 fields
 ...
 LL |         Fruit::Apple(a) => {},
-   |         ------------ ^ expected 2 fields, found 1
+   |                      ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -19,7 +19,7 @@ LL |     Apple(String, String),
    |           ------  ------ tuple variant has 2 fields
 ...
 LL |         Fruit::Apple(a, b, c) => {},
-   |         ------------ ^  ^  ^ expected 2 fields, found 3
+   |                      ^  ^  ^ expected 2 fields, found 3
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
   --> $DIR/E0023.rs:13:21
@@ -28,7 +28,7 @@ LL |     Pear(u32),
    |          --- tuple variant has 1 field
 ...
 LL |         Fruit::Pear(1, 2) => {},
-   |         ----------- ^  ^ expected 1 field, found 2
+   |                     ^  ^ expected 1 field, found 2
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
   --> $DIR/E0023.rs:14:23
@@ -37,7 +37,7 @@ LL |     Orange((String, String)),
    |            ---------------- tuple variant has 1 field
 ...
 LL |         Fruit::Orange(a, b) => {},
-   |         ------------- ^  ^ expected 1 field, found 2
+   |                       ^  ^ expected 1 field, found 2
    |
 help: missing parentheses
    |
@@ -45,13 +45,13 @@ LL |         Fruit::Orange((a, b)) => {},
    |                       +    +
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 1 field
-  --> $DIR/E0023.rs:15:22
+  --> $DIR/E0023.rs:15:9
    |
 LL |     Banana(()),
    |            -- tuple variant has 1 field
 ...
 LL |         Fruit::Banana() => {},
-   |         -------------^^ expected 1 field, found 0
+   |         ^^^^^^^^^^^^^^^ expected 1 field, found 0
    |
 help: missing parentheses
    |
diff --git a/src/test/ui/issues/issue-72574-2.stderr b/src/test/ui/issues/issue-72574-2.stderr
index 3f8ff4f0bacd5..05650f05cbf5b 100644
--- a/src/test/ui/issues/issue-72574-2.stderr
+++ b/src/test/ui/issues/issue-72574-2.stderr
@@ -25,7 +25,7 @@ LL | struct Binder(i32, i32, i32);
    |               ---  ---  --- tuple struct has 3 fields
 ...
 LL |         Binder(_a, _x @ ..) => {}
-   |         ------ ^^  ^^^^^^^ expected 3 fields, found 2
+   |                ^^  ^^^^^^^ expected 3 fields, found 2
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/match/match-pattern-field-mismatch.stderr b/src/test/ui/match/match-pattern-field-mismatch.stderr
index 01d7cf0d054c9..c994ee4f6d4ff 100644
--- a/src/test/ui/match/match-pattern-field-mismatch.stderr
+++ b/src/test/ui/match/match-pattern-field-mismatch.stderr
@@ -5,7 +5,7 @@ LL |         Rgb(usize, usize, usize),
    |             -----  -----  ----- tuple variant has 3 fields
 ...
 LL |           Color::Rgb(_, _) => { }
-   |           ---------- ^  ^ expected 3 fields, found 2
+   |                      ^  ^ expected 3 fields, found 2
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
index c87b70625b40e..75a231f6b4ba3 100644
--- a/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
+++ b/src/test/ui/pattern/issue-67037-pat-tup-scrut-ty-diff-less-fields.stderr
@@ -10,13 +10,13 @@ LL |     let P() = U {};
               found struct `P<_>`
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 1 field
-  --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:10
+  --> $DIR/issue-67037-pat-tup-scrut-ty-diff-less-fields.rs:19:9
    |
 LL | struct P<T>(T); // 1 type parameter wanted
    |             - tuple struct has 1 field
 ...
 LL |     let P() = U {};
-   |         -^^ expected 1 field, found 0
+   |         ^^^ expected 1 field, found 0
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/issue-74539.stderr b/src/test/ui/pattern/issue-74539.stderr
index d7cbcf2cfa109..7443946c013f7 100644
--- a/src/test/ui/pattern/issue-74539.stderr
+++ b/src/test/ui/pattern/issue-74539.stderr
@@ -25,7 +25,7 @@ LL |     A(u8, u8),
    |       --  -- tuple variant has 2 fields
 ...
 LL |         E::A(x @ ..) => {
-   |         ---- ^^^^^^ expected 2 fields, found 1
+   |              ^^^^^^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
diff --git a/src/test/ui/pattern/pat-tuple-field-count-cross.stderr b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr
index 570bf0cbc0810..cab8d4759df64 100644
--- a/src/test/ui/pattern/pat-tuple-field-count-cross.stderr
+++ b/src/test/ui/pattern/pat-tuple-field-count-cross.stderr
@@ -121,7 +121,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0
   --> $DIR/pat-tuple-field-count-cross.rs:14:12
    |
 LL |         Z1(x) => {}
-   |         -- ^ expected 0 fields, found 1
+   |            ^ expected 0 fields, found 1
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:2:1
    |
@@ -129,10 +129,10 @@ LL | pub struct Z1();
    | ---------------- tuple struct has 0 fields
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-field-count-cross.rs:18:10
+  --> $DIR/pat-tuple-field-count-cross.rs:18:9
    |
 LL |         S() => {}
-   |         -^^ expected 3 fields, found 0
+   |         ^^^ expected 3 fields, found 0
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
    |
@@ -152,7 +152,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3
   --> $DIR/pat-tuple-field-count-cross.rs:19:11
    |
 LL |         S(1) => {}
-   |         - ^ expected 3 fields, found 1
+   |           ^ expected 3 fields, found 1
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
    |
@@ -172,7 +172,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has
   --> $DIR/pat-tuple-field-count-cross.rs:20:11
    |
 LL |         S(xyz, abc) => {}
-   |         - ^^^  ^^^ expected 3 fields, found 2
+   |           ^^^  ^^^ expected 3 fields, found 2
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
    |
@@ -188,7 +188,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has
   --> $DIR/pat-tuple-field-count-cross.rs:21:11
    |
 LL |         S(1, 2, 3, 4) => {}
-   |         - ^  ^  ^  ^ expected 3 fields, found 4
+   |           ^  ^  ^  ^ expected 3 fields, found 4
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:4:14
    |
@@ -196,10 +196,10 @@ LL | pub struct S(pub u8, pub u8, pub u8);
    |              ------  ------  ------ tuple struct has 3 fields
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 3 fields
-  --> $DIR/pat-tuple-field-count-cross.rs:24:10
+  --> $DIR/pat-tuple-field-count-cross.rs:24:9
    |
 LL |           M() => {}
-   |           -^^ expected 3 fields, found 0
+   |           ^^^ expected 3 fields, found 0
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
    |
@@ -226,7 +226,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 3
   --> $DIR/pat-tuple-field-count-cross.rs:25:11
    |
 LL |           M(1) => {}
-   |           - ^ expected 3 fields, found 1
+   |             ^ expected 3 fields, found 1
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
    |
@@ -253,7 +253,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has
   --> $DIR/pat-tuple-field-count-cross.rs:26:11
    |
 LL |           M(xyz, abc) => {}
-   |           - ^^^  ^^^ expected 3 fields, found 2
+   |             ^^^  ^^^ expected 3 fields, found 2
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
    |
@@ -276,7 +276,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has
   --> $DIR/pat-tuple-field-count-cross.rs:27:11
    |
 LL |           M(1, 2, 3, 4) => {}
-   |           - ^  ^  ^  ^ expected 3 fields, found 4
+   |             ^  ^  ^  ^ expected 3 fields, found 4
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:5:1
    |
@@ -294,7 +294,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:36:16
    |
 LL |         E1::Z1(x) => {}
-   |         ------ ^ expected 0 fields, found 1
+   |                ^ expected 0 fields, found 1
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19
    |
@@ -302,10 +302,10 @@ LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
    |                   ---- tuple variant has 0 fields
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields
-  --> $DIR/pat-tuple-field-count-cross.rs:39:14
+  --> $DIR/pat-tuple-field-count-cross.rs:39:9
    |
 LL |         E1::S() => {}
-   |         -----^^ expected 3 fields, found 0
+   |         ^^^^^^^ expected 3 fields, found 0
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
    |
@@ -325,7 +325,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:40:15
    |
 LL |         E1::S(1) => {}
-   |         ----- ^ expected 3 fields, found 1
+   |               ^ expected 3 fields, found 1
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
    |
@@ -345,7 +345,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:41:15
    |
 LL |         E1::S(xyz, abc) => {}
-   |         ----- ^^^  ^^^ expected 3 fields, found 2
+   |               ^^^  ^^^ expected 3 fields, found 2
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
    |
@@ -361,7 +361,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:42:15
    |
 LL |         E1::S(1, 2, 3, 4) => {}
-   |         ----- ^  ^  ^  ^ expected 3 fields, found 4
+   |               ^  ^  ^  ^ expected 3 fields, found 4
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:27
    |
@@ -369,10 +369,10 @@ LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
    |                           --  --  -- tuple variant has 3 fields
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields
-  --> $DIR/pat-tuple-field-count-cross.rs:46:14
+  --> $DIR/pat-tuple-field-count-cross.rs:46:9
    |
 LL |         E2::S() => {}
-   |         -----^^ expected 3 fields, found 0
+   |         ^^^^^^^ expected 3 fields, found 0
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
    |
@@ -392,7 +392,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:47:15
    |
 LL |         E2::S(1) => {}
-   |         ----- ^ expected 3 fields, found 1
+   |               ^ expected 3 fields, found 1
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
    |
@@ -412,7 +412,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:48:15
    |
 LL |         E2::S(xyz, abc) => {}
-   |         ----- ^^^  ^^^ expected 3 fields, found 2
+   |               ^^^  ^^^ expected 3 fields, found 2
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
    |
@@ -428,7 +428,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:49:15
    |
 LL |         E2::S(1, 2, 3, 4) => {}
-   |         ----- ^  ^  ^  ^ expected 3 fields, found 4
+   |               ^  ^  ^  ^ expected 3 fields, found 4
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:14:7
    |
@@ -436,10 +436,10 @@ LL |     S(u8, u8, u8),
    |       --  --  -- tuple variant has 3 fields
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 3 fields
-  --> $DIR/pat-tuple-field-count-cross.rs:52:14
+  --> $DIR/pat-tuple-field-count-cross.rs:52:9
    |
 LL |           E2::M() => {}
-   |           -----^^ expected 3 fields, found 0
+   |           ^^^^^^^ expected 3 fields, found 0
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
    |
@@ -466,7 +466,7 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:53:15
    |
 LL |           E2::M(1) => {}
-   |           ----- ^ expected 3 fields, found 1
+   |                 ^ expected 3 fields, found 1
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
    |
@@ -493,7 +493,7 @@ error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:54:15
    |
 LL |           E2::M(xyz, abc) => {}
-   |           ----- ^^^  ^^^ expected 3 fields, found 2
+   |                 ^^^  ^^^ expected 3 fields, found 2
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
    |
@@ -516,7 +516,7 @@ error[E0023]: this pattern has 4 fields, but the corresponding tuple variant has
   --> $DIR/pat-tuple-field-count-cross.rs:55:15
    |
 LL |           E2::M(1, 2, 3, 4) => {}
-   |           ----- ^  ^  ^  ^ expected 3 fields, found 4
+   |                 ^  ^  ^  ^ expected 3 fields, found 4
    |
   ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:15:5
    |
diff --git a/src/test/ui/pattern/pat-tuple-overfield.rs b/src/test/ui/pattern/pat-tuple-overfield.rs
index dd0548a088c72..c863c657514f3 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.rs
+++ b/src/test/ui/pattern/pat-tuple-overfield.rs
@@ -30,6 +30,22 @@ fn main() {
     match M(1, 2, 3, 4, 5) {
         M(1, 2, 3, 4, 5, 6) => {}
         //~^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields
+        M(1,
+          2,
+          3,
+          4,
+          5,
+          6) => {}
+        //~^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields
+        M(
+            1,
+            2,
+            3,
+            4,
+            5,
+            6,
+        ) => {}
+        //~^^ ERROR this pattern has 6 fields, but the corresponding tuple struct has 5 fields
     }
     match Z0 {
         Z0 => {}
diff --git a/src/test/ui/pattern/pat-tuple-overfield.stderr b/src/test/ui/pattern/pat-tuple-overfield.stderr
index 646ac4e661897..1c44f7e5f6f1f 100644
--- a/src/test/ui/pattern/pat-tuple-overfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-overfield.stderr
@@ -1,5 +1,5 @@
 error[E0530]: match bindings cannot shadow tuple structs
-  --> $DIR/pat-tuple-overfield.rs:41:9
+  --> $DIR/pat-tuple-overfield.rs:57:9
    |
 LL | struct Z1();
    | ------------ the tuple struct `Z1` is defined here
@@ -8,7 +8,7 @@ LL |         Z1 => {}
    |         ^^ cannot be named the same as a tuple struct
 
 error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
-  --> $DIR/pat-tuple-overfield.rs:36:9
+  --> $DIR/pat-tuple-overfield.rs:52:9
    |
 LL | struct Z0;
    | ---------- `Z0` defined here
@@ -28,7 +28,7 @@ LL |         Z1() => {}
    |         ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
-  --> $DIR/pat-tuple-overfield.rs:37:9
+  --> $DIR/pat-tuple-overfield.rs:53:9
    |
 LL | struct Z0;
    | ---------- `Z0` defined here
@@ -48,7 +48,7 @@ LL |         Z1(_) => {}
    |         ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit struct `Z0`
-  --> $DIR/pat-tuple-overfield.rs:38:9
+  --> $DIR/pat-tuple-overfield.rs:54:9
    |
 LL | struct Z0;
    | ---------- `Z0` defined here
@@ -68,7 +68,7 @@ LL |         Z1(_, _) => {}
    |         ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
-  --> $DIR/pat-tuple-overfield.rs:48:9
+  --> $DIR/pat-tuple-overfield.rs:64:9
    |
 LL |     Z0,
    |     -- `E1::Z0` defined here
@@ -88,7 +88,7 @@ LL |         E1::Z1() => {}
    |             ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
-  --> $DIR/pat-tuple-overfield.rs:49:9
+  --> $DIR/pat-tuple-overfield.rs:65:9
    |
 LL |     Z0,
    |     -- `E1::Z0` defined here
@@ -108,7 +108,7 @@ LL |         E1::Z1(_) => {}
    |             ~~
 
 error[E0532]: expected tuple struct or tuple variant, found unit variant `E1::Z0`
-  --> $DIR/pat-tuple-overfield.rs:50:9
+  --> $DIR/pat-tuple-overfield.rs:66:9
    |
 LL |     Z0,
    |     -- `E1::Z0` defined here
@@ -128,7 +128,7 @@ LL |         E1::Z1(_, _) => {}
    |             ~~
 
 error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1`
-  --> $DIR/pat-tuple-overfield.rs:53:9
+  --> $DIR/pat-tuple-overfield.rs:69:9
    |
 LL |     Z0,
    |     -- similarly named unit variant `Z0` defined here
@@ -177,7 +177,7 @@ LL | struct S(u8, u8, u8);
    |          --  --  -- tuple struct has 3 fields
 ...
 LL |         S(1, 2, 3, 4) => {}
-   |         - ^  ^  ^  ^ expected 3 fields, found 4
+   |           ^  ^  ^  ^ expected 3 fields, found 4
 
 error[E0023]: this pattern has 4 fields, but the corresponding tuple struct has 3 fields
   --> $DIR/pat-tuple-overfield.rs:26:11
@@ -186,7 +186,7 @@ LL | struct S(u8, u8, u8);
    |          --  --  -- tuple struct has 3 fields
 ...
 LL |         S(1, 2, .., 3, 4) => {}
-   |         - ^  ^      ^  ^ expected 3 fields, found 4
+   |           ^  ^      ^  ^ expected 3 fields, found 4
 
 error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields
   --> $DIR/pat-tuple-overfield.rs:31:11
@@ -205,45 +205,105 @@ LL |     u8,
    |     -- tuple struct has 5 fields
 ...
 LL |         M(1, 2, 3, 4, 5, 6) => {}
-   |         - ^  ^  ^  ^  ^  ^ expected 5 fields, found 6
+   |           ^  ^  ^  ^  ^  ^ expected 5 fields, found 6
+
+error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields
+  --> $DIR/pat-tuple-overfield.rs:33:11
+   |
+LL | struct M(
+   |        - tuple struct defined here
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     -- tuple struct has 5 fields
+...
+LL |         M(1,
+   |         - ^
+LL |           2,
+   |           ^
+LL |           3,
+   |           ^
+LL |           4,
+   |           ^
+LL |           5,
+   |           ^
+LL |           6) => {}
+   |           ^ expected 5 fields, found 6
+
+error[E0023]: this pattern has 6 fields, but the corresponding tuple struct has 5 fields
+  --> $DIR/pat-tuple-overfield.rs:41:13
+   |
+LL | struct M(
+   |        - tuple struct defined here
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     --
+LL |     u8,
+   |     -- tuple struct has 5 fields
+...
+LL |         M(
+   |         -
+LL |             1,
+   |             ^
+LL |             2,
+   |             ^
+LL |             3,
+   |             ^
+LL |             4,
+   |             ^
+LL |             5,
+   |             ^
+LL |             6,
+   |             ^ expected 5 fields, found 6
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple struct has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:43:12
+  --> $DIR/pat-tuple-overfield.rs:59:12
    |
 LL | struct Z1();
-   |          --- tuple struct has 0 fields
+   | ------------ tuple struct has 0 fields
 ...
 LL |         Z1(_) => {}
-   |         -- ^ expected 0 fields, found 1
+   |            ^ expected 0 fields, found 1
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:44:12
+  --> $DIR/pat-tuple-overfield.rs:60:12
    |
 LL | struct Z1();
-   |          --- tuple struct has 0 fields
+   | ------------ tuple struct has 0 fields
 ...
 LL |         Z1(_, _) => {}
-   |         -- ^  ^ expected 0 fields, found 2
+   |            ^  ^ expected 0 fields, found 2
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:55:16
+  --> $DIR/pat-tuple-overfield.rs:71:16
    |
 LL |     Z1(),
-   |       -- tuple variant has 0 fields
+   |     ---- tuple variant has 0 fields
 ...
 LL |         E1::Z1(_) => {}
-   |         ------ ^ expected 0 fields, found 1
+   |                ^ expected 0 fields, found 1
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 0 fields
-  --> $DIR/pat-tuple-overfield.rs:56:16
+  --> $DIR/pat-tuple-overfield.rs:72:16
    |
 LL |     Z1(),
-   |       -- tuple variant has 0 fields
+   |     ---- tuple variant has 0 fields
 ...
 LL |         E1::Z1(_, _) => {}
-   |         ------ ^  ^ expected 0 fields, found 2
+   |                ^  ^ expected 0 fields, found 2
 
-error: aborting due to 17 previous errors
+error: aborting due to 19 previous errors
 
 Some errors have detailed explanations: E0023, E0308, E0530, E0532.
 For more information about an error, try `rustc --explain E0023`.
diff --git a/src/test/ui/pattern/pat-tuple-underfield.rs b/src/test/ui/pattern/pat-tuple-underfield.rs
index ed852a47bb4ee..dac60e3fab2c0 100644
--- a/src/test/ui/pattern/pat-tuple-underfield.rs
+++ b/src/test/ui/pattern/pat-tuple-underfield.rs
@@ -21,6 +21,12 @@ fn main() {
         //~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 2 fields
         //~| HELP use `_` to explicitly ignore each field
         //~| HELP use `..` to ignore all fields
+
+        // Test non-standard formatting
+        S () => {}
+        //~^ ERROR this pattern has 0 fields, but the corresponding tuple struct has 2 fields
+        //~| HELP use `_` to explicitly ignore each field
+        //~| HELP use `..` to ignore all fields
     }
 
     match E::S(0, 1.0) {
@@ -39,6 +45,12 @@ fn main() {
         //~^ ERROR this pattern has 0 fields, but the corresponding tuple variant has 2 fields
         //~| HELP use `_` to explicitly ignore each field
         //~| HELP use `..` to ignore all fields
+
+        // Test non-standard formatting
+        E::S () => {}
+        //~^ ERROR this pattern has 0 fields, but the corresponding tuple variant has 2 fields
+        //~| HELP use `_` to explicitly ignore each field
+        //~| HELP use `..` to ignore all fields
     }
     match E::S(0, 1.0) {
         E::S => {}
diff --git a/src/test/ui/pattern/pat-tuple-underfield.stderr b/src/test/ui/pattern/pat-tuple-underfield.stderr
index 4c21ad0be3eb4..e75f9b38da566 100644
--- a/src/test/ui/pattern/pat-tuple-underfield.stderr
+++ b/src/test/ui/pattern/pat-tuple-underfield.stderr
@@ -1,5 +1,5 @@
 error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E::S`
-  --> $DIR/pat-tuple-underfield.rs:44:9
+  --> $DIR/pat-tuple-underfield.rs:56:9
    |
 LL |     S(i32, f32),
    |     ----------- `E::S` defined here
@@ -14,7 +14,7 @@ LL | struct S(i32, f32);
    |          ---  --- tuple struct has 2 fields
 ...
 LL |         S(x) => {}
-   |         - ^ expected 2 fields, found 1
+   |           ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -28,7 +28,7 @@ LL | struct S(i32, f32);
    |          ---  --- tuple struct has 2 fields
 ...
 LL |         S(_) => {}
-   |         - ^ expected 2 fields, found 1
+   |           ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -40,13 +40,13 @@ LL |         S(..) => {}
    |           ~~
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:20:10
+  --> $DIR/pat-tuple-underfield.rs:20:9
    |
 LL | struct S(i32, f32);
    |          ---  --- tuple struct has 2 fields
 ...
 LL |         S() => {}
-   |         -^^ expected 2 fields, found 0
+   |         ^^^ expected 2 fields, found 0
    |
 help: use `_` to explicitly ignore each field
    |
@@ -57,14 +57,32 @@ help: use `..` to ignore all fields
 LL |         S(..) => {}
    |           ++
 
+error[E0023]: this pattern has 0 fields, but the corresponding tuple struct has 2 fields
+  --> $DIR/pat-tuple-underfield.rs:26:9
+   |
+LL | struct S(i32, f32);
+   |          ---  --- tuple struct has 2 fields
+...
+LL |         S () => {}
+   |         ^^^^ expected 2 fields, found 0
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         S (_, _) => {}
+   |            ++++
+help: use `..` to ignore all fields
+   |
+LL |         S (..) => {}
+   |            ++
+
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:27:14
+  --> $DIR/pat-tuple-underfield.rs:33:14
    |
 LL |     S(i32, f32),
    |       ---  --- tuple variant has 2 fields
 ...
 LL |         E::S(x) => {}
-   |         ---- ^ expected 2 fields, found 1
+   |              ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -72,13 +90,13 @@ LL |         E::S(x, _) => {}
    |               +++
 
 error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:32:14
+  --> $DIR/pat-tuple-underfield.rs:38:14
    |
 LL |     S(i32, f32),
    |       ---  --- tuple variant has 2 fields
 ...
 LL |         E::S(_) => {}
-   |         ---- ^ expected 2 fields, found 1
+   |              ^ expected 2 fields, found 1
    |
 help: use `_` to explicitly ignore each field
    |
@@ -90,13 +108,13 @@ LL |         E::S(..) => {}
    |              ~~
 
 error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields
-  --> $DIR/pat-tuple-underfield.rs:38:13
+  --> $DIR/pat-tuple-underfield.rs:44:9
    |
 LL |     S(i32, f32),
    |       ---  --- tuple variant has 2 fields
 ...
 LL |         E::S() => {}
-   |         ----^^ expected 2 fields, found 0
+   |         ^^^^^^ expected 2 fields, found 0
    |
 help: use `_` to explicitly ignore each field
    |
@@ -107,14 +125,32 @@ help: use `..` to ignore all fields
 LL |         E::S(..) => {}
    |              ++
 
+error[E0023]: this pattern has 0 fields, but the corresponding tuple variant has 2 fields
+  --> $DIR/pat-tuple-underfield.rs:50:9
+   |
+LL |     S(i32, f32),
+   |       ---  --- tuple variant has 2 fields
+...
+LL |         E::S () => {}
+   |         ^^^^^^^ expected 2 fields, found 0
+   |
+help: use `_` to explicitly ignore each field
+   |
+LL |         E::S (_, _) => {}
+   |               ++++
+help: use `..` to ignore all fields
+   |
+LL |         E::S (..) => {}
+   |               ++
+
 error[E0023]: this pattern has 2 fields, but the corresponding tuple struct has 4 fields
-  --> $DIR/pat-tuple-underfield.rs:50:19
+  --> $DIR/pat-tuple-underfield.rs:62:19
    |
 LL | struct Point4(i32, i32, i32, i32);
    |               ---  ---  ---  --- tuple struct has 4 fields
 ...
 LL |         Point4(   a   ,     _    ) => {}
-   |         ------    ^         ^ expected 4 fields, found 2
+   |                   ^         ^ expected 4 fields, found 2
    |
 help: use `_` to explicitly ignore each field
    |
@@ -125,7 +161,7 @@ help: use `..` to ignore the rest of the fields
 LL |         Point4(   a, ..) => {}
    |                    ~~~~
 
-error: aborting due to 8 previous errors
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0023, E0532.
 For more information about an error, try `rustc --explain E0023`.
diff --git a/src/test/ui/pattern/pattern-error-continue.stderr b/src/test/ui/pattern/pattern-error-continue.stderr
index efc6723e9ef8e..c800afdae2afb 100644
--- a/src/test/ui/pattern/pattern-error-continue.stderr
+++ b/src/test/ui/pattern/pattern-error-continue.stderr
@@ -32,7 +32,7 @@ LL |     B(isize, isize),
    |       -----  ----- tuple variant has 2 fields
 ...
 LL |         A::B(_, _, _) => (),
-   |         ---- ^  ^  ^ expected 2 fields, found 3
+   |              ^  ^  ^ expected 2 fields, found 3
 
 error[E0308]: mismatched types
   --> $DIR/pattern-error-continue.rs:22:9

From 5b25de58d6cbfab4fefe3200de8864ab8f6a71d1 Mon Sep 17 00:00:00 2001
From: Thom Chiovoloni <chiovolonit@gmail.com>
Date: Wed, 25 Aug 2021 14:58:17 -0700
Subject: [PATCH 29/32] Reference tracking issue

---
 library/std/src/os/raw/mod.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs
index 7ce58fb1d0ff7..1e220ea30ab95 100644
--- a/library/std/src/os/raw/mod.rs
+++ b/library/std/src/os/raw/mod.rs
@@ -156,12 +156,12 @@ pub use core::ffi::c_void;
 ///
 /// This type is currently always [`usize`], however in the future there may be
 /// platforms where this is not the case.
-#[unstable(feature = "c_size_t", issue = "none")]
+#[unstable(feature = "c_size_t", issue = "88345")]
 pub type c_size_t = usize;
 
 /// Equivalent to C's `ssize_t` type, from `stddef.h` (or `cstddef` for C++).
 ///
 /// This type is currently always [`isize`], however in the future there may be
 /// platforms where this is not the case.
-#[unstable(feature = "c_size_t", issue = "none")]
+#[unstable(feature = "c_size_t", issue = "88345")]
 pub type c_ssize_t = isize;

From 5df5659a6b96436ae55fd6bd8e9a7dbe7e22b37d Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Wed, 25 Aug 2021 19:14:50 -0300
Subject: [PATCH 30/32] Revert "Add type of a let tait test impl trait straight
 in let"

This reverts commit dbadab54df148b55b2e884440bfaeaa38517e6e8.
This is not part of TAITs, so, if tested should probably be done
elsewhere.
---
 .../type-alias-impl-trait/type_of_a_let2.rs   | 25 -------------------
 .../type_of_a_let2.stderr                     | 21 ----------------
 2 files changed, 46 deletions(-)
 delete mode 100644 src/test/ui/type-alias-impl-trait/type_of_a_let2.rs
 delete mode 100644 src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr

diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let2.rs b/src/test/ui/type-alias-impl-trait/type_of_a_let2.rs
deleted file mode 100644
index 33d3f164ce15e..0000000000000
--- a/src/test/ui/type-alias-impl-trait/type_of_a_let2.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-#![feature(type_alias_impl_trait)]
-#![allow(dead_code)]
-
-// FIXME This should be under a feature flag
-
-use std::fmt::Debug;
-
-fn foo1() -> u32 {
-    let x: impl Debug = 22_u32;
-    //~^ ERROR: `impl Trait` not allowed outside of function and method return types [E0562]
-    x // ERROR: we only know x: Debug, we don't know x = u32
-}
-
-fn foo2() -> u32 {
-    let x: impl Debug = 22_u32;
-    //~^ ERROR: `impl Trait` not allowed outside of function and method return types [E0562]
-    let y: impl Debug = x;
-    //~^ ERROR: `impl Trait` not allowed outside of function and method return types [E0562]
-    same_type((x, y)); // ERROR
-    x
-}
-
-fn same_type<T>(x: (T, T)) {}
-
-fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr b/src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr
deleted file mode 100644
index 7a1825a8e2d9a..0000000000000
--- a/src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0562]: `impl Trait` not allowed outside of function and method return types
-  --> $DIR/type_of_a_let2.rs:9:12
-   |
-LL |     let x: impl Debug = 22_u32;
-   |            ^^^^^^^^^^
-
-error[E0562]: `impl Trait` not allowed outside of function and method return types
-  --> $DIR/type_of_a_let2.rs:15:12
-   |
-LL |     let x: impl Debug = 22_u32;
-   |            ^^^^^^^^^^
-
-error[E0562]: `impl Trait` not allowed outside of function and method return types
-  --> $DIR/type_of_a_let2.rs:17:12
-   |
-LL |     let y: impl Debug = x;
-   |            ^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0562`.

From bb583f72e3ac42997eaa3522eca54b5326483351 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Wed, 25 Aug 2021 20:07:12 -0300
Subject: [PATCH 31/32] Add field types tait tests

---
 .../ui/type-alias-impl-trait/field-types.rs   | 20 ++++++++++++++++++
 .../type-alias-impl-trait/field-types.stderr  | 21 +++++++++++++++++++
 2 files changed, 41 insertions(+)
 create mode 100644 src/test/ui/type-alias-impl-trait/field-types.rs
 create mode 100644 src/test/ui/type-alias-impl-trait/field-types.stderr

diff --git a/src/test/ui/type-alias-impl-trait/field-types.rs b/src/test/ui/type-alias-impl-trait/field-types.rs
new file mode 100644
index 0000000000000..91494a82d0fb2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/field-types.rs
@@ -0,0 +1,20 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// FIXME This should compile, but it currently doesn't
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+//~^ ERROR: could not find defining uses
+
+struct Bar {
+    foo: Foo,
+}
+
+fn bar() -> Bar {
+    Bar { foo: "foo" }
+    //~^ ERROR: mismatched types [E0308]
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/field-types.stderr b/src/test/ui/type-alias-impl-trait/field-types.stderr
new file mode 100644
index 0000000000000..18c2abbdf3721
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/field-types.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/field-types.rs:16:16
+   |
+LL | type Foo = impl Debug;
+   |            ---------- the expected opaque type
+...
+LL |     Bar { foo: "foo" }
+   |                ^^^^^ expected opaque type, found `&str`
+   |
+   = note: expected opaque type `impl Debug`
+                found reference `&'static str`
+
+error: could not find defining uses
+  --> $DIR/field-types.rs:8:12
+   |
+LL | type Foo = impl Debug;
+   |            ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.

From 4fcae2c89113e0767ee066a42f418261cebdc4bd Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Wed, 25 Aug 2021 20:32:31 -0300
Subject: [PATCH 32/32] Add const and static TAIT tests

---
 .../static-const-types.rs                     | 16 +++++++++
 .../static-const-types.stderr                 | 33 +++++++++++++++++++
 2 files changed, 49 insertions(+)
 create mode 100644 src/test/ui/type-alias-impl-trait/static-const-types.rs
 create mode 100644 src/test/ui/type-alias-impl-trait/static-const-types.stderr

diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.rs b/src/test/ui/type-alias-impl-trait/static-const-types.rs
new file mode 100644
index 0000000000000..f630d27833503
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/static-const-types.rs
@@ -0,0 +1,16 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// FIXME: This should compile, but it currently doesn't
+
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+//~^ ERROR: could not find defining uses
+
+static FOO1: Foo = 22_u32;
+//~^ ERROR: mismatched types [E0308]
+const FOO2: Foo = 22_u32;
+//~^ ERROR: mismatched types [E0308]
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/static-const-types.stderr b/src/test/ui/type-alias-impl-trait/static-const-types.stderr
new file mode 100644
index 0000000000000..72083d014fe3a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/static-const-types.stderr
@@ -0,0 +1,33 @@
+error[E0308]: mismatched types
+  --> $DIR/static-const-types.rs:11:20
+   |
+LL | type Foo = impl Debug;
+   |            ---------- the expected opaque type
+...
+LL | static FOO1: Foo = 22_u32;
+   |                    ^^^^^^ expected opaque type, found `u32`
+   |
+   = note: expected opaque type `impl Debug`
+                     found type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/static-const-types.rs:13:19
+   |
+LL | type Foo = impl Debug;
+   |            ---------- the expected opaque type
+...
+LL | const FOO2: Foo = 22_u32;
+   |                   ^^^^^^ expected opaque type, found `u32`
+   |
+   = note: expected opaque type `impl Debug`
+                     found type `u32`
+
+error: could not find defining uses
+  --> $DIR/static-const-types.rs:8:12
+   |
+LL | type Foo = impl Debug;
+   |            ^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.