about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs55
-rw-r--r--tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr130
2 files changed, 100 insertions, 85 deletions
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
index a8ad014fc5d..3114b9d3bf8 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.rs
@@ -11,20 +11,34 @@
 #![cfg_attr(structural2024, feature(ref_pat_eat_one_layer_2024_structural))]
 
 pub fn main() {
-    if let Some(Some(&x)) = &Some(&Some(0)) {
-        //[stable2021]~^ mismatched types
-        //[stable2021]~| expected integer, found `&_`
-        let _: u32 = x;
+    // Tests not using match ergonomics. These should always succeed with the same bindings.
+    if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
+        let _: &u32 = x;
     }
+
+    // Tests for differences in how many layers of reference are eaten by reference patterns
     if let Some(Some(&x)) = &Some(Some(&0)) {
         #[cfg(stable2021)] let _: u32 = x;
         #[cfg(any(classic2024, structural2024))] let _: &u32 = x;
     }
+    if let Some(&Some(x)) = &mut Some(&Some(0)) {
+        // This additionally tests that `&` patterns can eat inherited `&mut` refs.
+        // This is possible on stable when the real reference being eaten is of a `&` type.
+        #[cfg(stable2021)] let _: u32 = x;
+        #[cfg(any(classic2024, structural2024))] let _: &u32 = x;
+    }
     if let Some(Some(&&x)) = &Some(Some(&0)) {
         //[stable2021]~^ mismatched types
         //[stable2021]~| expected integer, found `&_`
         let _: u32 = x;
     }
+
+    // Tests for eating a lone inherited reference
+    if let Some(Some(&x)) = &Some(&Some(0)) {
+        //[stable2021]~^ mismatched types
+        //[stable2021]~| expected integer, found `&_`
+        let _: u32 = x;
+    }
     if let Some(&Some(x)) = &Some(Some(0)) {
         //[stable2021]~^ mismatched types
         //[stable2021]~| expected `Option<{integer}>`, found `&_`
@@ -35,41 +49,42 @@ pub fn main() {
         //[stable2021]~| expected integer, found `&mut _`
         let _: u32 = x;
     }
-    if let Some(&Some(&x)) = &mut Some(&Some(0)) {
-        //[stable2021]~^ mismatched types
-        //[stable2021]~| expected integer, found `&_`
-        let _: u32 = x;
-    }
-    if let Some(&Some(x)) = &mut Some(&Some(0)) {
-        #[cfg(stable2021)] let _: u32 = x;
-        #[cfg(any(classic2024, structural2024))] let _: &u32 = x;
-    }
-    if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) {
-        let _: &u32 = x;
-    }
-    if let Some(&Some(&x)) = &Some(&mut Some(0)) {
+
+    // Tests for `&` patterns matching real `&mut` reference types
+    if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
         //[stable2021]~^ mismatched types
         //[stable2021]~| types differ in mutability
         let _: u32 = x;
     }
+
+    // Tests for eating only one layer and also eating a lone inherited reference
     if let Some(&Some(&x)) = &Some(&Some(0)) {
         //[stable2021]~^ mismatched types
         //[stable2021]~| expected integer, found `&_`
         let _: u32 = x;
     }
+
+    // Tests for `&` matching a lone inherited possibly-`&mut` reference
     if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
         //[stable2021]~^ mismatched types
         //[stable2021]~| expected `Option<&mut Option<{integer}>>`, found `&_`
         let _: u32 = x;
     }
-    if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
+    if let Some(&Some(x)) = &mut Some(Some(0)) {
+        //[stable2021]~^ mismatched types
+        //[stable2021]~| expected `Option<{integer}>`, found `&_`
+        let _: u32 = x;
+    }
+
+    // Tests eating one layer, eating a lone inherited ref, and `&` eating `&mut` (realness varies)
+    if let Some(&Some(&x)) = &Some(&mut Some(0)) {
         //[stable2021]~^ mismatched types
         //[stable2021]~| types differ in mutability
         let _: u32 = x;
     }
-    if let Some(&Some(x)) = &mut Some(Some(0)) {
+    if let Some(&Some(&x)) = &mut Some(&Some(0)) {
         //[stable2021]~^ mismatched types
-        //[stable2021]~| expected `Option<{integer}>`, found `&_`
+        //[stable2021]~| expected integer, found `&_`
         let _: u32 = x;
     }
 
diff --git a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr
index c78459bb21c..e9c338de243 100644
--- a/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr
+++ b/tests/ui/pattern/rfc-3627-match-ergonomics-2024/experimental/well-typed-edition-2024.stable2021.stderr
@@ -1,36 +1,36 @@
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:14:22
+  --> $DIR/well-typed-edition-2024.rs:30:23
    |
-LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
-   |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
-   |                      |
-   |                      expected integer, found `&_`
+LL |     if let Some(Some(&&x)) = &Some(Some(&0)) {
+   |                       ^^     --------------- this expression has type `&Option<Option<&{integer}>>`
+   |                       |
+   |                       expected integer, found `&_`
    |
    = note:   expected type `{integer}`
            found reference `&_`
 help: consider removing `&` from the pattern
    |
-LL |     if let Some(Some(x)) = &Some(&Some(0)) {
-   |                      ~
+LL -     if let Some(Some(&&x)) = &Some(Some(&0)) {
+LL +     if let Some(Some(&x)) = &Some(Some(&0)) {
+   |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:23:23
+  --> $DIR/well-typed-edition-2024.rs:37:22
    |
-LL |     if let Some(Some(&&x)) = &Some(Some(&0)) {
-   |                       ^^     --------------- this expression has type `&Option<Option<&{integer}>>`
-   |                       |
-   |                       expected integer, found `&_`
+LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
+   |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
+   |                      |
+   |                      expected integer, found `&_`
    |
    = note:   expected type `{integer}`
            found reference `&_`
 help: consider removing `&` from the pattern
    |
-LL -     if let Some(Some(&&x)) = &Some(Some(&0)) {
-LL +     if let Some(Some(&x)) = &Some(Some(&0)) {
-   |
+LL |     if let Some(Some(x)) = &Some(&Some(0)) {
+   |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:28:17
+  --> $DIR/well-typed-edition-2024.rs:42:17
    |
 LL |     if let Some(&Some(x)) = &Some(Some(0)) {
    |                 ^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
@@ -41,7 +41,7 @@ LL |     if let Some(&Some(x)) = &Some(Some(0)) {
            found reference `&_`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:33:22
+  --> $DIR/well-typed-edition-2024.rs:47:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^     ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
@@ -51,7 +51,7 @@ LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    = note:           expected type `{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:33:22
+  --> $DIR/well-typed-edition-2024.rs:47:22
    |
 LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
    |                      ^^^^^^
@@ -61,33 +61,22 @@ LL |     if let Some(Some(x)) = &mut Some(&mut Some(0)) {
    |                      ~
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:38:23
+  --> $DIR/well-typed-edition-2024.rs:54:23
    |
-LL |     if let Some(&Some(&x)) = &mut Some(&Some(0)) {
-   |                       ^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
+LL |     if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
+   |                       ^^     ------------------- this expression has type `Option<&Option<&mut {integer}>>`
    |                       |
-   |                       expected integer, found `&_`
+   |                       types differ in mutability
    |
-   = note:   expected type `{integer}`
-           found reference `&_`
+   = note: expected mutable reference `&mut {integer}`
+                      found reference `&_`
 help: consider removing `&` from the pattern
    |
-LL |     if let Some(&Some(x)) = &mut Some(&Some(0)) {
+LL |     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
    |                       ~
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:50:17
-   |
-LL |     if let Some(&Some(&x)) = &Some(&mut Some(0)) {
-   |                 ^^^^^^^^^    ------------------- this expression has type `&Option<&mut Option<{integer}>>`
-   |                 |
-   |                 types differ in mutability
-   |
-   = note: expected mutable reference `&mut Option<{integer}>`
-                      found reference `&_`
-
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:55:23
+  --> $DIR/well-typed-edition-2024.rs:61:23
    |
 LL |     if let Some(&Some(&x)) = &Some(&Some(0)) {
    |                       ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
@@ -102,7 +91,7 @@ LL |     if let Some(&Some(x)) = &Some(&Some(0)) {
    |                       ~
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:60:17
+  --> $DIR/well-typed-edition-2024.rs:68:17
    |
 LL |     if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
    |                 ^^^^^^^^^^^^^^^    ------------------------- this expression has type `&Option<Option<&mut Option<{integer}>>>`
@@ -113,22 +102,7 @@ LL |     if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) {
            found reference `&_`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:65:23
-   |
-LL |     if let Some(&Some(&x)) = Some(&Some(&mut 0)) {
-   |                       ^^     ------------------- this expression has type `Option<&Option<&mut {integer}>>`
-   |                       |
-   |                       types differ in mutability
-   |
-   = note: expected mutable reference `&mut {integer}`
-                      found reference `&_`
-help: consider removing `&` from the pattern
-   |
-LL |     if let Some(&Some(x)) = Some(&Some(&mut 0)) {
-   |                       ~
-
-error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:70:17
+  --> $DIR/well-typed-edition-2024.rs:73:17
    |
 LL |     if let Some(&Some(x)) = &mut Some(Some(0)) {
    |                 ^^^^^^^^    ------------------ this expression has type `&mut Option<Option<{integer}>>`
@@ -139,7 +113,33 @@ LL |     if let Some(&Some(x)) = &mut Some(Some(0)) {
            found reference `&_`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:78:10
+  --> $DIR/well-typed-edition-2024.rs:80:17
+   |
+LL |     if let Some(&Some(&x)) = &Some(&mut Some(0)) {
+   |                 ^^^^^^^^^    ------------------- this expression has type `&Option<&mut Option<{integer}>>`
+   |                 |
+   |                 types differ in mutability
+   |
+   = note: expected mutable reference `&mut Option<{integer}>`
+                      found reference `&_`
+
+error[E0308]: mismatched types
+  --> $DIR/well-typed-edition-2024.rs:85:23
+   |
+LL |     if let Some(&Some(&x)) = &mut Some(&Some(0)) {
+   |                       ^^     ------------------- this expression has type `&mut Option<&Option<{integer}>>`
+   |                       |
+   |                       expected integer, found `&_`
+   |
+   = note:   expected type `{integer}`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL |     if let Some(&Some(x)) = &mut Some(&Some(0)) {
+   |                       ~
+
+error[E0308]: mismatched types
+  --> $DIR/well-typed-edition-2024.rs:93:10
    |
 LL |     let [&mut x] = &mut [&0];
    |          ^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -149,7 +149,7 @@ LL |     let [&mut x] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:78:10
+  --> $DIR/well-typed-edition-2024.rs:93:10
    |
 LL |     let [&mut x] = &mut [&0];
    |          ^^^^^^
@@ -160,7 +160,7 @@ LL +     let [x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:83:10
+  --> $DIR/well-typed-edition-2024.rs:98:10
    |
 LL |     let [&mut ref x] = &mut [&0];
    |          ^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -170,7 +170,7 @@ LL |     let [&mut ref x] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:83:10
+  --> $DIR/well-typed-edition-2024.rs:98:10
    |
 LL |     let [&mut ref x] = &mut [&0];
    |          ^^^^^^^^^^
@@ -181,7 +181,7 @@ LL +     let [ref x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:88:10
+  --> $DIR/well-typed-edition-2024.rs:103:10
    |
 LL |     let [&mut ref mut x] = &mut [&0];
    |          ^^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -191,7 +191,7 @@ LL |     let [&mut ref mut x] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:88:10
+  --> $DIR/well-typed-edition-2024.rs:103:10
    |
 LL |     let [&mut ref mut x] = &mut [&0];
    |          ^^^^^^^^^^^^^^
@@ -202,7 +202,7 @@ LL +     let [ref mut x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:93:10
+  --> $DIR/well-typed-edition-2024.rs:108:10
    |
 LL |     let [&mut mut x] = &mut [&0];
    |          ^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -212,7 +212,7 @@ LL |     let [&mut mut x] = &mut [&0];
    = note:      expected reference `&{integer}`
            found mutable reference `&mut _`
 note: to declare a mutable binding use: `mut x`
-  --> $DIR/well-typed-edition-2024.rs:93:10
+  --> $DIR/well-typed-edition-2024.rs:108:10
    |
 LL |     let [&mut mut x] = &mut [&0];
    |          ^^^^^^^^^^
@@ -223,7 +223,7 @@ LL +     let [mut x] = &mut [&0];
    |
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:98:10
+  --> $DIR/well-typed-edition-2024.rs:113:10
    |
 LL |     let [&mut &x] = &mut [&0];
    |          ^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -234,7 +234,7 @@ LL |     let [&mut &x] = &mut [&0];
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:103:10
+  --> $DIR/well-typed-edition-2024.rs:118:10
    |
 LL |     let [&mut &ref x] = &mut [&0];
    |          ^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`
@@ -245,7 +245,7 @@ LL |     let [&mut &ref x] = &mut [&0];
            found mutable reference `&mut _`
 
 error[E0308]: mismatched types
-  --> $DIR/well-typed-edition-2024.rs:108:10
+  --> $DIR/well-typed-edition-2024.rs:123:10
    |
 LL |     let [&mut &(mut x)] = &mut [&0];
    |          ^^^^^^^^^^^^^    --------- this expression has type `&mut [&{integer}; 1]`