about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-09-08 20:48:34 +0530
committerGitHub <noreply@github.com>2022-09-08 20:48:34 +0530
commitd392838b69a4f9d2c4a109412820f454a1dfa2cf (patch)
tree5e7d88f006650886e25130f43be4a6b9424447de
parentccb5595df2ed412eda6444edc7eaf06f709fa79d (diff)
parent64d11fc8e336344a8b8a55a55131ded4be26cebd (diff)
downloadrust-d392838b69a4f9d2c4a109412820f454a1dfa2cf.tar.gz
rust-d392838b69a4f9d2c4a109412820f454a1dfa2cf.zip
Rollup merge of #98933 - oli-obk:opaque_type_late_bound_lifetimes, r=lcnr
Opaque types' generic params do not imply anything about their hidden type's lifetimes

fixes #97104

cc ```@aliemjay```
-rw-r--r--compiler/rustc_middle/src/ty/visit.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs3
-rw-r--r--src/test/ui/associated-types/issue-62200.rs3
-rw-r--r--src/test/ui/associated-types/issue-62200.stderr3
-rw-r--r--src/test/ui/issues/issue-47511.stderr3
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs.rs24
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs.stderr58
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs31
-rw-r--r--src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr9
9 files changed, 127 insertions, 9 deletions
diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs
index 5e042c3acfc..5f8cb578202 100644
--- a/compiler/rustc_middle/src/ty/visit.rs
+++ b/compiler/rustc_middle/src/ty/visit.rs
@@ -666,7 +666,7 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
         // ignore the inputs to a projection, as they may not appear
         // in the normalized form
         if self.just_constrained {
-            if let ty::Projection(..) = t.kind() {
+            if let ty::Projection(..) | ty::Opaque(..) = t.kind() {
                 return ControlFlow::CONTINUE;
             }
         }
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 801063583e6..d66cf6d099a 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2940,8 +2940,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 // though we can easily give a hint that ought to be
                 // relevant.
                 err.note(
-                    "lifetimes appearing in an associated type are not considered constrained",
+                    "lifetimes appearing in an associated or opaque type are not considered constrained",
                 );
+                err.note("consider introducing a named lifetime parameter");
             }
 
             err.emit();
diff --git a/src/test/ui/associated-types/issue-62200.rs b/src/test/ui/associated-types/issue-62200.rs
index 9d18690e960..499bbd6b6fa 100644
--- a/src/test/ui/associated-types/issue-62200.rs
+++ b/src/test/ui/associated-types/issue-62200.rs
@@ -10,6 +10,7 @@ impl T<'_> for S {
 
 fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
 //~^ ERROR binding for associated type `Output` references an anonymous lifetime
-//~^^ NOTE lifetimes appearing in an associated type are not considered constrained
+//~| NOTE lifetimes appearing in an associated or opaque type are not considered constrained
+//~| NOTE consider introducing a named lifetime parameter
 
 fn main() {}
diff --git a/src/test/ui/associated-types/issue-62200.stderr b/src/test/ui/associated-types/issue-62200.stderr
index f14cd81fdfe..04f0728f58e 100644
--- a/src/test/ui/associated-types/issue-62200.stderr
+++ b/src/test/ui/associated-types/issue-62200.stderr
@@ -4,7 +4,8 @@ error[E0582]: binding for associated type `Output` references an anonymous lifet
 LL | fn foo(x: impl Fn(<S as T<'_>>::A) -> <S as T<'_>>::A) {}
    |                                       ^^^^^^^^^^^^^^^
    |
-   = note: lifetimes appearing in an associated type are not considered constrained
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-47511.stderr b/src/test/ui/issues/issue-47511.stderr
index 5b84f7ed62c..9998ee0e8d0 100644
--- a/src/test/ui/issues/issue-47511.stderr
+++ b/src/test/ui/issues/issue-47511.stderr
@@ -4,7 +4,8 @@ error[E0581]: return type references an anonymous lifetime, which is not constra
 LL | fn f(_: X) -> X {
    |               ^
    |
-   = note: lifetimes appearing in an associated type are not considered constrained
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
 
 error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
   --> $DIR/issue-47511.rs:12:23
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs.rs b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
index c32174288ee..03fb64b7b94 100644
--- a/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs.rs
@@ -1,17 +1,33 @@
-// check-pass
-
 #![feature(type_alias_impl_trait)]
 
-mod foo {
+mod lifetime_params {
     type Ty<'a> = impl Sized;
     fn defining(s: &str) -> Ty<'_> { s }
     fn execute(ty: Ty<'_>) -> &str { todo!() }
+    //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+
+    type BadFnSig = fn(Ty<'_>) -> &str;
+    //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+    type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
+    //~^ ERROR binding for associated type `Output` references an anonymous lifetime
 }
 
-mod bar {
+mod lifetime_params_2 {
     type Ty<'a> = impl FnOnce() -> &'a str;
     fn defining(s: &str) -> Ty<'_> { move || s }
     fn execute(ty: Ty<'_>) -> &str { ty() }
+    //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+}
+
+// regression test for https://github.com/rust-lang/rust/issues/97104
+mod type_params {
+    type Ty<T> = impl Sized;
+    fn define<T>(s: T) -> Ty<T> { s }
+
+    type BadFnSig = fn(Ty<&str>) -> &str;
+    //~^ ERROR return type references an anonymous lifetime, which is not constrained by the fn input types
+    type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
+    //~^ ERROR binding for associated type `Output` references an anonymous lifetime
 }
 
 fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs.stderr b/src/test/ui/type-alias-impl-trait/constrain_inputs.stderr
new file mode 100644
index 00000000000..93953fd06d1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs.stderr
@@ -0,0 +1,58 @@
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+  --> $DIR/constrain_inputs.rs:6:31
+   |
+LL |     fn execute(ty: Ty<'_>) -> &str { todo!() }
+   |                               ^^^^
+   |
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+  --> $DIR/constrain_inputs.rs:9:35
+   |
+LL |     type BadFnSig = fn(Ty<'_>) -> &str;
+   |                                   ^^^^
+   |
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
+
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+  --> $DIR/constrain_inputs.rs:11:42
+   |
+LL |     type BadTraitRef = dyn Fn(Ty<'_>) -> &str;
+   |                                          ^^^^
+   |
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+  --> $DIR/constrain_inputs.rs:18:31
+   |
+LL |     fn execute(ty: Ty<'_>) -> &str { ty() }
+   |                               ^^^^
+   |
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
+
+error[E0581]: return type references an anonymous lifetime, which is not constrained by the fn input types
+  --> $DIR/constrain_inputs.rs:27:37
+   |
+LL |     type BadFnSig = fn(Ty<&str>) -> &str;
+   |                                     ^^^^
+   |
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
+
+error[E0582]: binding for associated type `Output` references an anonymous lifetime, which does not appear in the trait input types
+  --> $DIR/constrain_inputs.rs:29:44
+   |
+LL |     type BadTraitRef = dyn Fn(Ty<&str>) -> &str;
+   |                                            ^^^^
+   |
+   = note: lifetimes appearing in an associated or opaque type are not considered constrained
+   = note: consider introducing a named lifetime parameter
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0581, E0582.
+For more information about an error, try `rustc --explain E0581`.
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
new file mode 100644
index 00000000000..3bae0f17309
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
@@ -0,0 +1,31 @@
+#![feature(type_alias_impl_trait)]
+
+trait Static: 'static {}
+impl Static for () {}
+
+type Gal<T> = impl Static;
+fn _defining<T>() -> Gal<T> {}
+
+trait Callable<Arg> { type Output; }
+
+/// We can infer `<C as Callable<Arg>>::Output: 'static`,
+/// because we know `C: 'static` and `Arg: 'static`,
+fn box_str<C, Arg>(s: C::Output) -> Box<dyn AsRef<str> + 'static>
+where
+    Arg: Static,
+    C: ?Sized + Callable<Arg> + 'static,
+    C::Output: AsRef<str>,
+{
+    Box::new(s)
+}
+
+fn extend_lifetime(s: &str) -> Box<dyn AsRef<str> + 'static> {
+    type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
+    //~^ ERROR binding for associated type `Output` references lifetime `'a`
+    box_str::<MalformedTy, _>(s)
+}
+
+fn main() {
+    let extended = extend_lifetime(&String::from("hello"));
+    println!("{}", extended.as_ref().as_ref());
+}
diff --git a/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
new file mode 100644
index 00000000000..d5fc46cb1f5
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.stderr
@@ -0,0 +1,9 @@
+error[E0582]: binding for associated type `Output` references lifetime `'a`, which does not appear in the trait input types
+  --> $DIR/constrain_inputs_unsound.rs:23:58
+   |
+LL |     type MalformedTy = dyn for<'a> Callable<Gal<&'a ()>, Output = &'a str>;
+   |                                                          ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0582`.