about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-10-14 00:45:18 +0200
committerGitHub <noreply@github.com>2022-10-14 00:45:18 +0200
commit059bbf7ea945d5c6dc2ca5af5abd3eb5c6677ece (patch)
tree1fed6adec27c7fa5d54a72c2c971542f9eea0bdc /src/test
parent9692d98e4f3ed8e6076ad1e741d9ed106f40bc3e (diff)
parentd2d3d9433228adb35cfec0de8f3747879e38751f (diff)
downloadrust-059bbf7ea945d5c6dc2ca5af5abd3eb5c6677ece.tar.gz
rust-059bbf7ea945d5c6dc2ca5af5abd3eb5c6677ece.zip
Rollup merge of #103008 - aliemjay:opaque-parent-substs, r=oli-obk
replace ReErased with fresh region vars in opaque types

See inline comments.

Prior art #102943. cc ``@compiler-errors`` ``@oli-obk``

Fixes #100267
Fixes #101940
Fixes #102649
Fixes #102510
Diffstat (limited to 'src/test')
-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
3 files changed, 194 insertions, 0 deletions
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`.