diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 5e042c3acfce2..5f8cb57820210 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 801063583e633..d66cf6d099ad5 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 9d18690e96049..499bbd6b6fad2 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(>::A) -> >::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 f14cd81fdfe1f..04f0728f58ea8 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(>::A) -> >::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 5b84f7ed62c3a..9998ee0e8d0c6 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 c32174288ee68..03fb64b7b94d7 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 = impl Sized; + fn define(s: T) -> Ty { 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 0000000000000..93953fd06d1fd --- /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 0000000000000..3bae0f1730994 --- /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 = impl Static; +fn _defining() -> Gal {} + +trait Callable { type Output; } + +/// We can infer `>::Output: 'static`, +/// because we know `C: 'static` and `Arg: 'static`, +fn box_str(s: C::Output) -> Box + 'static> +where + Arg: Static, + C: ?Sized + Callable + 'static, + C::Output: AsRef, +{ + Box::new(s) +} + +fn extend_lifetime(s: &str) -> Box + 'static> { + type MalformedTy = dyn for<'a> Callable, Output = &'a str>; + //~^ ERROR binding for associated type `Output` references lifetime `'a` + box_str::(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 0000000000000..d5fc46cb1f596 --- /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, Output = &'a str>; + | ^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0582`.