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<&'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)]
|
||||
|
||||
struct Static<T: 'static>(T);
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
// Well-formedness of nested opaque types, i.e. `impl Sized` in
|
||||
// `type Outer = impl Trait<Assoc = impl Sized>`.
|
||||
// See the comments below.
|
||||
//
|
||||
//@ revisions: pass pass_sound fail
|
||||
//@ [pass] check-fail
|
||||
//@ [pass_sound] check-fail
|
||||
//@ [fail] check-fail
|
||||
|
||||
// `type Outer = impl Trait<Assoc = impl Sized>`. We check that
|
||||
// the nested type is well-formed, even though this would also
|
||||
// be implied by the item bounds of the opaque being
|
||||
// well-formed. See the comments below.
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
struct IsStatic<T: 'static>(T);
|
||||
|
@ -23,46 +19,26 @@ impl<T> Trait<&'static T> for () {
|
|||
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> {}
|
||||
//[pass]~^ ERROR the parameter type `T` may not live long enough
|
||||
}
|
||||
// We could theoretically allow this (and previously did), as even
|
||||
// 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.
|
||||
#[cfg(pass_sound)]
|
||||
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 define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
|
||||
//~^ ERROR the parameter type `T` may not live long enough
|
||||
|
||||
fn test<T>() {
|
||||
let outer = define::<T>();
|
||||
let _ = outer.get();
|
||||
//[pass_sound]~^ ERROR `T` may not live long enough
|
||||
//[pass_sound]~| ERROR `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
|
||||
}
|
||||
// Similar to `define` but here `impl Sized` can be referenced directly as
|
||||
// InnerOpaque<T>, so the `'static` bound is definitely required for
|
||||
// soundness.
|
||||
type InnerOpaque<T> = impl Sized;
|
||||
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
|
||||
|
||||
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