From 08e20d9b28685d438839bd695a9309a8947a61fa Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Tue, 24 Aug 2021 22:10:38 -0300
Subject: [PATCH 1/2] Add type of a let tait test

---
 .../ui/type-alias-impl-trait/type_of_a_let.rs | 29 ++++++++
 .../type_of_a_let.stderr                      | 67 +++++++++++++++++++
 2 files changed, 96 insertions(+)
 create mode 100644 src/test/ui/type-alias-impl-trait/type_of_a_let.rs
 create mode 100644 src/test/ui/type-alias-impl-trait/type_of_a_let.stderr

diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.rs b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs
new file mode 100644
index 0000000000000..7f8e6127cca3b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.rs
@@ -0,0 +1,29 @@
+#![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
+
+fn foo1() -> u32 {
+    let x: Foo = 22_u32;
+    //~^ ERROR: mismatched types [E0308]
+    x
+    //~^ ERROR: mismatched types [E0308]
+}
+
+fn foo2() -> u32 {
+    let x: Foo = 22_u32;
+    //~^ ERROR: mismatched types [E0308]
+    let y: Foo = x;
+    same_type((x, y));
+    y
+    //~^ ERROR: mismatched types [E0308]
+}
+
+fn same_type<T>(x: (T, T)) {}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr
new file mode 100644
index 0000000000000..cac8d6841afda
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type_of_a_let.stderr
@@ -0,0 +1,67 @@
+error[E0308]: mismatched types
+  --> $DIR/type_of_a_let.rs:12:18
+   |
+LL | type Foo = impl Debug;
+   |            ---------- the expected opaque type
+...
+LL |     let x: Foo = 22_u32;
+   |            ---   ^^^^^^ expected opaque type, found `u32`
+   |            |
+   |            expected due to this
+   |
+   = note: expected opaque type `impl Debug`
+                     found type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/type_of_a_let.rs:14:5
+   |
+LL | type Foo = impl Debug;
+   |            ---------- the found opaque type
+...
+LL | fn foo1() -> u32 {
+   |              --- expected `u32` because of return type
+...
+LL |     x
+   |     ^ expected `u32`, found opaque type
+   |
+   = note:     expected type `u32`
+           found opaque type `impl Debug`
+
+error[E0308]: mismatched types
+  --> $DIR/type_of_a_let.rs:19:18
+   |
+LL | type Foo = impl Debug;
+   |            ---------- the expected opaque type
+...
+LL |     let x: Foo = 22_u32;
+   |            ---   ^^^^^^ expected opaque type, found `u32`
+   |            |
+   |            expected due to this
+   |
+   = note: expected opaque type `impl Debug`
+                     found type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/type_of_a_let.rs:23:5
+   |
+LL | type Foo = impl Debug;
+   |            ---------- the found opaque type
+...
+LL | fn foo2() -> u32 {
+   |              --- expected `u32` because of return type
+...
+LL |     y
+   |     ^ expected `u32`, found opaque type
+   |
+   = note:     expected type `u32`
+           found opaque type `impl Debug`
+
+error: could not find defining uses
+  --> $DIR/type_of_a_let.rs:8:12
+   |
+LL | type Foo = impl Debug;
+   |            ^^^^^^^^^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.

From dbadab54df148b55b2e884440bfaeaa38517e6e8 Mon Sep 17 00:00:00 2001
From: Santiago Pastorino <spastorino@gmail.com>
Date: Tue, 24 Aug 2021 22:52:41 -0300
Subject: [PATCH 2/2] Add type of a let tait test impl trait straight in let

---
 .../type-alias-impl-trait/type_of_a_let2.rs   | 25 +++++++++++++++++++
 .../type_of_a_let2.stderr                     | 21 ++++++++++++++++
 2 files changed, 46 insertions(+)
 create mode 100644 src/test/ui/type-alias-impl-trait/type_of_a_let2.rs
 create 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
new file mode 100644
index 0000000000000..33d3f164ce15e
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type_of_a_let2.rs
@@ -0,0 +1,25 @@
+#![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
new file mode 100644
index 0000000000000..7a1825a8e2d9a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/type_of_a_let2.stderr
@@ -0,0 +1,21 @@
+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`.