about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/test')
-rw-r--r--src/test/mir-opt/enum_cast.bar.mir_map.0.mir10
-rw-r--r--src/test/mir-opt/enum_cast.boo.mir_map.0.mir10
-rw-r--r--src/test/mir-opt/enum_cast.droppy.mir_map.0.mir40
-rw-r--r--src/test/mir-opt/enum_cast.foo.mir_map.0.mir10
-rw-r--r--src/test/run-pass-valgrind/cast-enum-with-dtor.rs2
-rw-r--r--src/test/rustdoc-gui/unsafe-fn.goml53
-rw-r--r--src/test/rustdoc-ui/issue-102986.rs4
-rw-r--r--src/test/rustdoc-ui/issue-102986.stderr14
-rw-r--r--src/test/ui/mir/issue-102389.rs8
-rw-r--r--src/test/ui/mir/issue-102389.stderr9
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-1.rs9
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr6
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-2.rs9
-rw-r--r--src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr6
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_parent_substs.rs65
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs65
-rw-r--r--src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr64
17 files changed, 329 insertions, 55 deletions
diff --git a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
index 8b12525b576..e58085f701a 100644
--- a/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.bar.mir_map.0.mir
@@ -3,11 +3,15 @@
 fn bar(_1: Bar) -> usize {
     debug bar => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
-    let mut _2: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let _2: Bar;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _3: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
 
     bb0: {
-        _2 = discriminant(_1);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
     }
 }
diff --git a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
index a77f4d06c23..525c6234ed3 100644
--- a/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.boo.mir_map.0.mir
@@ -3,11 +3,15 @@
 fn boo(_1: Boo) -> usize {
     debug boo => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
-    let mut _2: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let _2: Boo;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _3: u8;                      // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
 
     bb0: {
-        _2 = discriminant(_1);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
     }
 }
diff --git a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
index ae3e71df8c6..bb5faa48047 100644
--- a/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.droppy.mir_map.0.mir
@@ -4,8 +4,9 @@ fn droppy() -> () {
     let mut _0: ();                      // return place in scope 0 at $DIR/enum_cast.rs:+0:13: +0:13
     let _1: ();                          // in scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
     let _2: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
-    let mut _4: isize;                   // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
-    let _5: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+    let _4: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+    let mut _5: isize;                   // in scope 0 at $DIR/enum_cast.rs:+5:17: +5:18
+    let _6: Droppy;                      // in scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
     scope 1 {
         debug x => _2;                   // in scope 1 at $DIR/enum_cast.rs:+2:13: +2:14
         scope 2 {
@@ -16,7 +17,7 @@ fn droppy() -> () {
         }
     }
     scope 4 {
-        debug z => _5;                   // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
+        debug z => _6;                   // in scope 4 at $DIR/enum_cast.rs:+7:9: +7:10
     }
 
     bb0: {
@@ -25,30 +26,41 @@ fn droppy() -> () {
         _2 = Droppy::C;                  // scope 0 at $DIR/enum_cast.rs:+2:17: +2:26
         FakeRead(ForLet(None), _2);      // scope 0 at $DIR/enum_cast.rs:+2:13: +2:14
         StorageLive(_3);                 // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
-        _4 = discriminant(_2);           // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
-        _3 = move _4 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        StorageLive(_4);                 // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+        _4 = move _2;                    // scope 3 at $DIR/enum_cast.rs:+5:17: +5:18
+        _5 = discriminant(_4);           // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        _3 = move _5 as usize (IntToInt); // scope 3 at $DIR/enum_cast.rs:+5:17: +5:27
+        drop(_4) -> [return: bb1, unwind: bb4]; // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
+    }
+
+    bb1: {
+        StorageDead(_4);                 // scope 3 at $DIR/enum_cast.rs:+5:26: +5:27
         FakeRead(ForLet(None), _3);      // scope 3 at $DIR/enum_cast.rs:+5:13: +5:14
         _1 = const ();                   // scope 0 at $DIR/enum_cast.rs:+1:5: +6:6
         StorageDead(_3);                 // scope 1 at $DIR/enum_cast.rs:+6:5: +6:6
-        drop(_2) -> [return: bb1, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+        drop(_2) -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
     }
 
-    bb1: {
+    bb2: {
         StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
         StorageDead(_1);                 // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
-        StorageLive(_5);                 // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
-        _5 = Droppy::B;                  // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
-        FakeRead(ForLet(None), _5);      // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+        StorageLive(_6);                 // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
+        _6 = Droppy::B;                  // scope 0 at $DIR/enum_cast.rs:+7:13: +7:22
+        FakeRead(ForLet(None), _6);      // scope 0 at $DIR/enum_cast.rs:+7:9: +7:10
         _0 = const ();                   // scope 0 at $DIR/enum_cast.rs:+0:13: +8:2
-        drop(_5) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+        drop(_6) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
     }
 
-    bb2: {
-        StorageDead(_5);                 // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
+    bb3: {
+        StorageDead(_6);                 // scope 0 at $DIR/enum_cast.rs:+8:1: +8:2
         return;                          // scope 0 at $DIR/enum_cast.rs:+8:2: +8:2
     }
 
-    bb3 (cleanup): {
+    bb4 (cleanup): {
+        drop(_2) -> bb5;                 // scope 0 at $DIR/enum_cast.rs:+6:5: +6:6
+    }
+
+    bb5 (cleanup): {
         resume;                          // scope 0 at $DIR/enum_cast.rs:+0:1: +8:2
     }
 }
diff --git a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
index 9e44d9158e0..a1d29a0b903 100644
--- a/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
+++ b/src/test/mir-opt/enum_cast.foo.mir_map.0.mir
@@ -3,11 +3,15 @@
 fn foo(_1: Foo) -> usize {
     debug foo => _1;                     // in scope 0 at $DIR/enum_cast.rs:+0:8: +0:11
     let mut _0: usize;                   // return place in scope 0 at $DIR/enum_cast.rs:+0:21: +0:26
-    let mut _2: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let _2: Foo;                         // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+    let mut _3: isize;                   // in scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
 
     bb0: {
-        _2 = discriminant(_1);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
-        _0 = move _2 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageLive(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _2 = move _1;                    // scope 0 at $DIR/enum_cast.rs:+1:5: +1:8
+        _3 = discriminant(_2);           // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        _0 = move _3 as usize (IntToInt); // scope 0 at $DIR/enum_cast.rs:+1:5: +1:17
+        StorageDead(_2);                 // scope 0 at $DIR/enum_cast.rs:+1:16: +1:17
         return;                          // scope 0 at $DIR/enum_cast.rs:+2:2: +2:2
     }
 }
diff --git a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
index f29bc50e84c..f7ef92df8fb 100644
--- a/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
+++ b/src/test/run-pass-valgrind/cast-enum-with-dtor.rs
@@ -28,7 +28,7 @@ fn main() {
     {
         let e = E::C;
         assert_eq!(e as u32, 2);
-        assert_eq!(FLAG.load(Ordering::SeqCst), 0);
+        assert_eq!(FLAG.load(Ordering::SeqCst), 1);
     }
     assert_eq!(FLAG.load(Ordering::SeqCst), 1);
 }
diff --git a/src/test/rustdoc-gui/unsafe-fn.goml b/src/test/rustdoc-gui/unsafe-fn.goml
index 94f128db72e..5e43b85fce0 100644
--- a/src/test/rustdoc-gui/unsafe-fn.goml
+++ b/src/test/rustdoc-gui/unsafe-fn.goml
@@ -1,37 +1,28 @@
+// Check position and color of the `<sup>` for unsafe elements.
 goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
-
-compare-elements-property: (
-	"//a[@title='test_docs::safe_fn fn']/..",
-	"//a[@title='test_docs::unsafe_fn fn']/..",
-	["clientHeight"]
-)
-
 // If the text isn't displayed, the browser doesn't compute color style correctly...
 show-text: true
 
-// Set the theme to dark.
-local-storage: {"rustdoc-theme": "dark", "rustdoc-preferred-dark-theme": "dark", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
-
-assert-css: (".item-left sup", {
-	"color": "rgb(221, 221, 221)"
-})
-
-// Set the theme to ayu.
-local-storage: {"rustdoc-theme": "ayu", "rustdoc-preferred-dark-theme": "ayu", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
-
-assert-css: (".item-left sup", {
-	"color": "rgb(197, 197, 197)"
-})
+compare-elements-property: (
+    "//a[@title='test_docs::safe_fn fn']/..",
+    "//a[@title='test_docs::unsafe_fn fn']/..",
+    ["clientHeight"]
+)
 
-// Set the theme to light.
-local-storage: {"rustdoc-theme": "light", "rustdoc-preferred-dark-theme": "light", "rustdoc-use-system-theme": "false"}
-// We reload the page so the local storage settings are being used.
-reload:
+define-function: (
+    "sup-check",
+    // `theme` is the theme being tested.
+    // `color` is the expected color of the `<sup>` element.
+    (theme, color),
+    [
+        // Set the theme.
+        ("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
+        // We reload the page so the local storage settings are being used.
+        ("reload"),
+        ("assert-css", (".item-left sup", {"color": |color|})),
+    ],
+)
 
-assert-css: (".item-left sup", {
-	"color": "rgb(0, 0, 0)"
-})
+call-function: ("sup-check", ("dark", "rgb(221, 221, 221)"))
+call-function: ("sup-check", ("ayu", "rgb(197, 197, 197)"))
+call-function: ("sup-check", ("light", "rgb(0, 0, 0)"))
diff --git a/src/test/rustdoc-ui/issue-102986.rs b/src/test/rustdoc-ui/issue-102986.rs
new file mode 100644
index 00000000000..001784ac285
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-102986.rs
@@ -0,0 +1,4 @@
+struct Struct {
+    y: (typeof("hey"),),
+    //~^ `typeof` is a reserved keyword but unimplemented
+}
diff --git a/src/test/rustdoc-ui/issue-102986.stderr b/src/test/rustdoc-ui/issue-102986.stderr
new file mode 100644
index 00000000000..3a573726c97
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-102986.stderr
@@ -0,0 +1,14 @@
+error[E0516]: `typeof` is a reserved keyword but unimplemented
+  --> $DIR/issue-102986.rs:2:9
+   |
+LL |     y: (typeof("hey"),),
+   |         ^^^^^^^^^^^^^ reserved keyword
+   |
+help: consider replacing `typeof(...)` with an actual type
+   |
+LL |     y: (&'static str,),
+   |         ~~~~~~~~~~~~
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0516`.
diff --git a/src/test/ui/mir/issue-102389.rs b/src/test/ui/mir/issue-102389.rs
new file mode 100644
index 00000000000..8b27d5e5574
--- /dev/null
+++ b/src/test/ui/mir/issue-102389.rs
@@ -0,0 +1,8 @@
+enum Enum { A, B, C }
+
+fn func(inbounds: &Enum, array: &[i16; 3]) -> i16 {
+    array[*inbounds as usize]
+    //~^ ERROR [E0507]
+}
+
+fn main() {}
diff --git a/src/test/ui/mir/issue-102389.stderr b/src/test/ui/mir/issue-102389.stderr
new file mode 100644
index 00000000000..925dc258a4c
--- /dev/null
+++ b/src/test/ui/mir/issue-102389.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of `*inbounds` which is behind a shared reference
+  --> $DIR/issue-102389.rs:4:11
+   |
+LL |     array[*inbounds as usize]
+   |           ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs
new file mode 100644
index 00000000000..abf988a7c1e
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: --crate-type rlib
+// error-pattern: could not find native static library `libfoo.a`
+// error-pattern: only provide the library name `foo`, not the full filename
+
+#[link(name = "libfoo.a", kind = "static")]
+extern { }
+
+pub fn main() { }
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr
new file mode 100644
index 00000000000..64d0a9077ed
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-1.stderr
@@ -0,0 +1,6 @@
+error: could not find native static library `libfoo.a`, perhaps an -L flag is missing?
+   |
+   = help: only provide the library name `foo`, not the full filename
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs
new file mode 100644
index 00000000000..dfa70e56db7
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.rs
@@ -0,0 +1,9 @@
+// build-fail
+// compile-flags: --crate-type rlib
+// error-pattern: could not find native static library `bar.lib`
+// error-pattern: only provide the library name `bar`, not the full filename
+
+#[link(name = "bar.lib", kind = "static")]
+extern { }
+
+pub fn main() { }
diff --git a/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr
new file mode 100644
index 00000000000..e166af9ed8f
--- /dev/null
+++ b/src/test/ui/native-library-link-flags/suggest-libname-only-2.stderr
@@ -0,0 +1,6 @@
+error: could not find native static library `bar.lib`, perhaps an -L flag is missing?
+   |
+   = help: only provide the library name `bar`, not the full filename
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
new file mode 100644
index 00000000000..475f4724ff2
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_parent_substs.rs
@@ -0,0 +1,65 @@
+// When WF checking the hidden type in the ParamEnv of the opaque type,
+// one complication arises when the hidden type is a closure/generator:
+// the "parent_substs" of the type may reference lifetime parameters
+// not present in the opaque type.
+// These region parameters are not really useful in this check.
+// So here we ignore them and replace them with fresh region variables.
+
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// Basic test
+mod test1 {
+    // Hidden type = Closure['_#0r]
+    type Opaque = impl Sized;
+
+    fn define<'a: 'a>() -> Opaque {
+        || {}
+    }
+}
+
+// the region vars cannot both be equal to `'static` or `'empty`
+mod test2 {
+    trait Trait {}
+
+    // Hidden type = Closure['a, '_#0r, '_#1r]
+    // Constraints = [('_#0r: 'a), ('a: '_#1r)]
+    type Opaque<'a>
+    where
+        &'a (): Trait,
+    = impl Sized + 'a;
+
+    fn define<'a, 'x, 'y>() -> Opaque<'a>
+    where
+        &'a (): Trait,
+        'x: 'a,
+        'a: 'y,
+    {
+        || {}
+    }
+}
+
+// the region var cannot be equal to `'a` or `'b`
+mod test3 {
+    trait Trait {}
+
+    // Hidden type = Closure['a, 'b, '_#0r]
+    // Constraints = [('_#0r: 'a), ('_#0r: 'b)]
+    type Opaque<'a, 'b>
+    where
+        (&'a (), &'b ()): Trait,
+    = impl Sized + 'a + 'b;
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        (&'a (), &'b ()): Trait,
+        'x: 'a,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs
new file mode 100644
index 00000000000..53974dbb36b
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.rs
@@ -0,0 +1,65 @@
+// If the hidden type is a closure, we require the "outlives" bounds that appear on the
+// defining site to also appear on the opaque type.
+//
+// It's not clear if this is the desired behavior but at least
+// it's consistent and has no back-compat risk.
+
+// check-fail
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// requires `'a: 'b` bound
+mod test1 {
+    type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+    //~^ ERROR lifetime bound not satisfied
+
+    fn define<'a, 'b>() -> Opaque<'a, 'b>
+    where
+        'a: 'b,
+    {
+        || {}
+    }
+}
+
+// Same as the above but through indirection `'x`
+mod test2 {
+    type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+    //~^ ERROR cannot infer an appropriate lifetime
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        'a: 'x,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+// fixed version of the above
+mod test2_fixed {
+    type Opaque<'a: 'b, 'b> = impl Sized + 'a + 'b;
+
+    fn define<'a, 'b, 'x>() -> Opaque<'a, 'b>
+    where
+        'a: 'x,
+        'x: 'b,
+    {
+        || {}
+    }
+}
+
+// requires `T: 'static`
+mod test3 {
+    type Opaque<T> = impl Sized;
+    //~^ ERROR the parameter type `T` may not live long enough
+
+    fn define<T>() -> Opaque<T>
+    where
+        T: 'static,
+    {
+        || {}
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr
new file mode 100644
index 00000000000..ae6462bb62c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/closure_wf_outlives.stderr
@@ -0,0 +1,64 @@
+error[E0478]: lifetime bound not satisfied
+  --> $DIR/closure_wf_outlives.rs:14:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+   |
+note: lifetime parameter instantiated with the lifetime `'a` as defined here
+  --> $DIR/closure_wf_outlives.rs:14:17
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                 ^^
+note: but lifetime parameter must outlive the lifetime `'b` as defined here
+  --> $DIR/closure_wf_outlives.rs:14:21
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                     ^^
+
+error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
+  --> $DIR/closure_wf_outlives.rs:27:17
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                 ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+note: but, the lifetime must be valid for the lifetime `'b` as defined here...
+  --> $DIR/closure_wf_outlives.rs:27:21
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                     ^^
+note: ...so that the declared lifetime parameter bounds are satisfied
+  --> $DIR/closure_wf_outlives.rs:27:27
+   |
+LL |     type Opaque<'a, 'b> = impl Sized + 'a + 'b;
+   |                           ^^^^^^^^^^^^^^^^^^^^
+
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/closure_wf_outlives.rs:54:22
+   |
+LL |     type Opaque<T> = impl Sized;
+   |                      ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/closure_wf_outlives.rs:59:12
+   |
+LL |         T: 'static,
+   |            ^^^^^^^
+help: consider adding an explicit lifetime bound...
+   |
+LL |     type Opaque<T: 'static> = impl Sized;
+   |                  +++++++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0310, E0478, E0495.
+For more information about an error, try `rustc --explain E0310`.