update comments
This commit is contained in:
parent
300cffa2d5
commit
af0d5082ee
3 changed files with 72 additions and 46 deletions
|
@ -4,6 +4,11 @@
|
||||||
//
|
//
|
||||||
// `Opaque<'a> = Static<&'a str>`, vs
|
// `Opaque<'a> = Static<&'a str>`, vs
|
||||||
// `Opaque<'a> = Static<&'static str>`.
|
// `Opaque<'a> = Static<&'static str>`.
|
||||||
|
//
|
||||||
|
// The hidden type of the opaque ends up as `Static<'?0 str>`. When
|
||||||
|
// computing member constraints we end up choosing `'a` for `?0` unless
|
||||||
|
// `?0` is already required to outlive `'a`. We achieve this by checking
|
||||||
|
// that `Static<'?0 str>` is well-formed.
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
struct Static<T: 'static>(T);
|
struct Static<T: 'static>(T);
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
// Well-formedness of nested opaque types, i.e. `impl Sized` in
|
// Well-formedness of nested opaque types, i.e. `impl Sized` in
|
||||||
// `type Outer = impl Trait<Assoc = impl Sized>`.
|
// `type Outer = impl Trait<Assoc = impl Sized>`. We check that
|
||||||
// See the comments below.
|
// the nested type is well-formed, even though this would also
|
||||||
//
|
// be implied by the item bounds of the opaque being
|
||||||
//@ revisions: pass pass_sound fail
|
// well-formed. See the comments below.
|
||||||
//@ [pass] check-fail
|
|
||||||
//@ [pass_sound] check-fail
|
|
||||||
//@ [fail] check-fail
|
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
struct IsStatic<T: 'static>(T);
|
struct IsStatic<T: 'static>(T);
|
||||||
|
@ -23,46 +19,26 @@ impl<T> Trait<&'static T> for () {
|
||||||
type Out = IsStatic<T>;
|
type Out = IsStatic<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The hidden type for `impl Sized` is `IsStatic<T>`, which requires `T: 'static`.
|
|
||||||
// We know it is well-formed because it can *only* be referenced as a projection:
|
|
||||||
// <OuterOpaque<T> as Trait<&'static T>>::Out`.
|
|
||||||
// So any instantiation of the type already requires proving `T: 'static`.
|
|
||||||
#[cfg(pass)]
|
|
||||||
mod pass {
|
|
||||||
use super::*;
|
|
||||||
type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>;
|
|
||||||
fn define<T>() -> OuterOpaque<T> {}
|
|
||||||
//[pass]~^ ERROR `T` may not live long enough
|
|
||||||
|
|
||||||
fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
|
// We could theoretically allow this (and previously did), as even
|
||||||
//[pass]~^ ERROR the parameter type `T` may not live long enough
|
// though the nested opaque is not well-formed, it can only be
|
||||||
}
|
// used by normalizing the projection
|
||||||
|
// <OuterOpaque1<T> as Trait<&'static T>>::Out
|
||||||
|
// Assuming that we check that this projection is well-formed, the wf
|
||||||
|
// of the nested opaque is implied.
|
||||||
|
type OuterOpaque1<T> = impl Trait<&'static T, Out = impl Sized>;
|
||||||
|
fn define<T>() -> OuterOpaque1<T> {}
|
||||||
|
//~^ ERROR `T` may not live long enough
|
||||||
|
|
||||||
// Test the soundness of `pass` - We should require `T: 'static` at the use site.
|
fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
|
||||||
#[cfg(pass_sound)]
|
//~^ ERROR the parameter type `T` may not live long enough
|
||||||
mod pass_sound {
|
|
||||||
use super::*;
|
|
||||||
type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>;
|
|
||||||
fn define<T>() -> OuterOpaque<T> {}
|
|
||||||
//[pass_sound]~^ ERROR `T` may not live long enough
|
|
||||||
|
|
||||||
fn test<T>() {
|
// Similar to `define` but here `impl Sized` can be referenced directly as
|
||||||
let outer = define::<T>();
|
// InnerOpaque<T>, so the `'static` bound is definitely required for
|
||||||
let _ = outer.get();
|
// soundness.
|
||||||
//[pass_sound]~^ ERROR `T` may not live long enough
|
type InnerOpaque<T> = impl Sized;
|
||||||
//[pass_sound]~| ERROR `T` may not live long enough
|
type OuterOpaque2<T> = impl Trait<&'static T, Out = InnerOpaque<T>>;
|
||||||
}
|
fn define_nested_rpit<T>() -> OuterOpaque2<T> {}
|
||||||
}
|
//~^ ERROR the parameter type `T` may not live long enough
|
||||||
|
|
||||||
// Similar to `pass` but here `impl Sized` can be referenced directly as
|
|
||||||
// InnerOpaque<T>, so we require an explicit bound `T: 'static`.
|
|
||||||
#[cfg(fail)]
|
|
||||||
mod fail {
|
|
||||||
use super::*;
|
|
||||||
type InnerOpaque<T> = impl Sized;
|
|
||||||
type OuterOpaque<T> = impl Trait<&'static T, Out = InnerOpaque<T>>;
|
|
||||||
fn define<T>() -> OuterOpaque<T> {}
|
|
||||||
//[fail]~^ ERROR the parameter type `T` may not live long enough
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
45
tests/ui/type-alias-impl-trait/wf-nested.stderr
Normal file
45
tests/ui/type-alias-impl-trait/wf-nested.stderr
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
error[E0310]: the parameter type `T` may not live long enough
|
||||||
|
--> $DIR/wf-nested.rs:30:35
|
||||||
|
|
|
||||||
|
LL | fn define<T>() -> OuterOpaque1<T> {}
|
||||||
|
| ^^
|
||||||
|
| |
|
||||||
|
| the parameter type `T` must be valid for the static lifetime...
|
||||||
|
| ...so that the type `T` will meet its required lifetime bounds
|
||||||
|
|
|
||||||
|
help: consider adding an explicit lifetime bound
|
||||||
|
|
|
||||||
|
LL | fn define<T: 'static>() -> OuterOpaque1<T> {}
|
||||||
|
| +++++++++
|
||||||
|
|
||||||
|
error[E0310]: the parameter type `T` may not live long enough
|
||||||
|
--> $DIR/wf-nested.rs:33:65
|
||||||
|
|
|
||||||
|
LL | fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
|
||||||
|
| ^^
|
||||||
|
| |
|
||||||
|
| the parameter type `T` must be valid for the static lifetime...
|
||||||
|
| ...so that the type `T` will meet its required lifetime bounds
|
||||||
|
|
|
||||||
|
help: consider adding an explicit lifetime bound
|
||||||
|
|
|
||||||
|
LL | fn define_rpit<T: 'static>() -> impl Trait<&'static T, Out = impl Sized> {}
|
||||||
|
| +++++++++
|
||||||
|
|
||||||
|
error[E0310]: the parameter type `T` may not live long enough
|
||||||
|
--> $DIR/wf-nested.rs:41:47
|
||||||
|
|
|
||||||
|
LL | fn define_nested_rpit<T>() -> OuterOpaque2<T> {}
|
||||||
|
| ^^
|
||||||
|
| |
|
||||||
|
| the parameter type `T` must be valid for the static lifetime...
|
||||||
|
| ...so that the type `T` will meet its required lifetime bounds
|
||||||
|
|
|
||||||
|
help: consider adding an explicit lifetime bound
|
||||||
|
|
|
||||||
|
LL | fn define_nested_rpit<T: 'static>() -> OuterOpaque2<T> {}
|
||||||
|
| +++++++++
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0310`.
|
Loading…
Add table
Add a link
Reference in a new issue