Skip to content

Commit

Permalink
Rollup merge of rust-lang#98933 - oli-obk:opaque_type_late_bound_life…
Browse files Browse the repository at this point in the history
…times, r=lcnr

Opaque types' generic params do not imply anything about their hidden type's lifetimes

fixes rust-lang#97104

cc ```@aliemjay```
  • Loading branch information
Dylan-DPC authored Sep 8, 2022
2 parents ccb5595 + 64d11fc commit d392838
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 9 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_typeck/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/associated-types/issue-62200.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
3 changes: 2 additions & 1 deletion src/test/ui/associated-types/issue-62200.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/issues/issue-47511.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 20 additions & 4 deletions src/test/ui/type-alias-impl-trait/constrain_inputs.rs
Original file line number Diff line number Diff line change
@@ -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() {}
58 changes: 58 additions & 0 deletions src/test/ui/type-alias-impl-trait/constrain_inputs.stderr
Original file line number Diff line number Diff line change
@@ -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`.
31 changes: 31 additions & 0 deletions src/test/ui/type-alias-impl-trait/constrain_inputs_unsound.rs
Original file line number Diff line number Diff line change
@@ -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());
}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit d392838

Please sign in to comment.