diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-18 02:49:50 +0000 |
commit | 9835e2ae736235810b4ea1c162ca5e65c547e770 (patch) | |
tree | 3fcebf40ed70e581d776a8a4c65923e8ec20e026 /tests/ui/type-alias-impl-trait | |
parent | Releasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff) | |
download | rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip |
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/type-alias-impl-trait')
18 files changed, 282 insertions, 14 deletions
diff --git a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs index 551815d02..58eaa9c2c 100644 --- a/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs +++ b/tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs @@ -5,15 +5,16 @@ trait Trait { type Opaque1; type Opaque2; - fn constrain(self); + fn constrain(self) -> (Self::Opaque1, Self::Opaque2); } impl<'a> Trait for &'a () { type Opaque1 = impl Sized; type Opaque2 = impl Sized + 'a; - fn constrain(self) { - let _: Self::Opaque1 = (); - let _: Self::Opaque2 = self; + fn constrain(self) -> (Self::Opaque1, Self::Opaque2) { + let a: Self::Opaque1 = (); + let b: Self::Opaque2 = self; + (a, b) } } diff --git a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs index 475f4724f..3ff20d99a 100644 --- a/tests/ui/type-alias-impl-trait/closure_parent_substs.rs +++ b/tests/ui/type-alias-impl-trait/closure_parent_substs.rs @@ -12,7 +12,7 @@ // Basic test mod test1 { - // Hidden type = Closure['_#0r] + // Hidden type = Closure['?0] type Opaque = impl Sized; fn define<'a: 'a>() -> Opaque { @@ -24,8 +24,8 @@ mod test1 { mod test2 { trait Trait {} - // Hidden type = Closure['a, '_#0r, '_#1r] - // Constraints = [('_#0r: 'a), ('a: '_#1r)] + // Hidden type = Closure['a, '?0, '?1] + // Constraints = [('?0: 'a), ('a: '?1)] type Opaque<'a> where &'a (): Trait, @@ -45,8 +45,8 @@ mod test2 { mod test3 { trait Trait {} - // Hidden type = Closure['a, 'b, '_#0r] - // Constraints = [('_#0r: 'a), ('_#0r: 'b)] + // Hidden type = Closure['a, 'b, '?0] + // Constraints = [('?0: 'a), ('?0: 'b)] type Opaque<'a, 'b> where (&'a (), &'b ()): Trait, diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs new file mode 100644 index 000000000..e5bfbfdae --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +type Tait<'a> = impl Sized + 'a; + +fn foo<'a, 'b>() { + if false { + if { return } { + let y: Tait<'b> = 1i32; + //~^ ERROR concrete type differs from previous defining opaque type use + } + } + let x: Tait<'a> = (); +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr new file mode 100644 index 000000000..f2eb7bc4d --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/different_defining_uses_never_type-2.rs:8:31 + | +LL | let y: Tait<'b> = 1i32; + | ^^^^ expected `()`, got `i32` + | +note: previous use here + --> $DIR/different_defining_uses_never_type-2.rs:12:23 + | +LL | let x: Tait<'a> = (); + | ^^ + +error: aborting due to previous error + diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs new file mode 100644 index 000000000..2b30a9cd5 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +type Tait<T> = impl Sized; + +fn foo<T, U>() { + if false { + if { return } { + let y: Tait<U> = 1i32; + //~^ ERROR concrete type differs from previous defining opaque type use + } + } + let x: Tait<T> = (); +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr new file mode 100644 index 000000000..8fc2e2284 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/different_defining_uses_never_type-3.rs:8:30 + | +LL | let y: Tait<U> = 1i32; + | ^^^^ expected `()`, got `i32` + | +note: previous use here + --> $DIR/different_defining_uses_never_type-3.rs:12:22 + | +LL | let x: Tait<T> = (); + | ^^ + +error: aborting due to previous error + diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs new file mode 100644 index 000000000..93c52126d --- /dev/null +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs @@ -0,0 +1,16 @@ +#![feature(impl_trait_in_assoc_type)] + +trait Foo { + type Foo; + fn bar(); +} + +impl Foo for () { + type Foo = impl std::fmt::Debug; + fn bar() { + let x: Self::Foo = (); + //~^ ERROR: mismatched types + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr new file mode 100644 index 000000000..2beed73cb --- /dev/null +++ b/tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr @@ -0,0 +1,22 @@ +error[E0308]: mismatched types + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:11:28 + | +LL | type Foo = impl std::fmt::Debug; + | -------------------- the expected opaque type +LL | fn bar() { +LL | let x: Self::Foo = (); + | --------- ^^ expected opaque type, found `()` + | | + | expected due to this + | + = note: expected opaque type `<() as Foo>::Foo` + found unit type `()` +note: this item must have the opaque type in its signature in order to be able to register hidden types + --> $DIR/invalid_impl_trait_in_assoc_ty.rs:10:5 + | +LL | fn bar() { + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/issue-65918.rs b/tests/ui/type-alias-impl-trait/issue-65918.rs index af6d50109..82cc823e4 100644 --- a/tests/ui/type-alias-impl-trait/issue-65918.rs +++ b/tests/ui/type-alias-impl-trait/issue-65918.rs @@ -1,5 +1,3 @@ -// ignore-test: This now ICEs again. - // build-pass #![feature(type_alias_impl_trait)] diff --git a/tests/ui/type-alias-impl-trait/issue-98604.stderr b/tests/ui/type-alias-impl-trait/issue-98604.stderr index fa16d3218..af758d809 100644 --- a/tests/ui/type-alias-impl-trait/issue-98604.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98604.stderr @@ -4,7 +4,7 @@ error[E0271]: expected `test` to be a fn item that returns `Pin<Box<dyn Future<O LL | Box::new(test) as AsyncFnPtr; | ^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = ()>>>`, found future | - = note: required for the cast from `fn() -> impl Future<Output = ()> {test}` to the object type `dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>>` + = note: required for the cast from `Box<fn() -> impl Future<Output = ()> {test}>` to `Box<(dyn Fn() -> Pin<Box<(dyn Future<Output = ()> + 'static)>> + 'static)>` error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/issue-98608.stderr b/tests/ui/type-alias-impl-trait/issue-98608.stderr index 506d40cb7..9b6510083 100644 --- a/tests/ui/type-alias-impl-trait/issue-98608.stderr +++ b/tests/ui/type-alias-impl-trait/issue-98608.stderr @@ -9,7 +9,7 @@ LL | let b: Box<dyn Fn() -> Box<u8>> = Box::new(hi); | = note: expected struct `Box<u8>` found opaque type `impl Sized` - = note: required for the cast from `fn() -> impl Sized {hi}` to the object type `dyn Fn() -> Box<u8>` + = note: required for the cast from `Box<fn() -> impl Sized {hi}>` to `Box<dyn Fn() -> Box<u8>>` error: aborting due to previous error diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs index da845e861..9ae2c34b9 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs @@ -8,6 +8,7 @@ type X<A, B> = impl Into<&'static A>; fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) { //~^ ERROR the trait bound `&'static B: From<&A>` is not satisfied + //~| ERROR concrete type differs from previous defining opaque type use (a, a) } diff --git a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr index 66a6b0bbf..0d24d42ba 100644 --- a/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr +++ b/tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr @@ -10,6 +10,15 @@ help: consider introducing a `where` clause, but there might be an alternative b LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) where &'static B: From<&A> { | ++++++++++++++++++++++++++ -error: aborting due to previous error +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn.rs:9:45 + | +LL | fn f<A, B: 'static>(a: &'static A, b: B) -> (X<A, B>, X<B, A>) { + | ^^^^^^^^^^^^^^^^^^ + | | + | expected `&B`, got `&A` + | this expression supplies two conflicting concrete types for the same opaque type + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr b/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr new file mode 100644 index 000000000..9e96323ab --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr @@ -0,0 +1,25 @@ +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/wf-in-associated-type.rs:36:23 + | +LL | type Opaque = impl Sized + 'a; + | ^^^^^^^^^^^^^^^ ...so that the type `&'a T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for () { + | ++++ + +error[E0309]: the parameter type `T` may not live long enough + --> $DIR/wf-in-associated-type.rs:36:23 + | +LL | type Opaque = impl Sized + 'a; + | ^^^^^^^^^^^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for () { + | ++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0309`. diff --git a/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs new file mode 100644 index 000000000..31fbef9f7 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-in-associated-type.rs @@ -0,0 +1,45 @@ +// WF check for impl Trait in associated type position. +// +// revisions: pass fail +// [pass] check-pass +// [fail] check-fail + +#![feature(impl_trait_in_assoc_type)] + +// The hidden type here (`&'a T`) requires proving `T: 'a`. +// We know it holds because of implied bounds from the impl header. +#[cfg(pass)] +mod pass { + trait Trait<Req> { + type Opaque1; + fn constrain_opaque1(req: Req) -> Self::Opaque1; + } + + impl<'a, T> Trait<&'a T> for () { + type Opaque1 = impl IntoIterator<Item = impl Sized + 'a>; + fn constrain_opaque1(req: &'a T) -> Self::Opaque1 { + [req] + } + } +} + +// The hidden type here (`&'a T`) requires proving `T: 'a`, +// but that is not known to hold in the impl. +#[cfg(fail)] +mod fail { + trait Trait<'a, T> { + type Opaque; + fn constrain_opaque(req: &'a T) -> Self::Opaque; + } + + impl<'a, T> Trait<'a, T> for () { + type Opaque = impl Sized + 'a; + //[fail]~^ ERROR the parameter type `T` may not live long enough + //[fail]~| ERROR the parameter type `T` may not live long enough + fn constrain_opaque(req: &'a T) -> Self::Opaque { + req + } + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr new file mode 100644 index 000000000..753a46e88 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr @@ -0,0 +1,19 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/wf-nested.rs:55:27 + | +LL | type InnerOpaque<T> = impl Sized; + | ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/wf-nested.rs:12:20 + | +LL | struct IsStatic<T: 'static>(T); + | ^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | type InnerOpaque<T: 'static> = impl Sized; + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr new file mode 100644 index 000000000..9ab6685a7 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr @@ -0,0 +1,14 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/wf-nested.rs:46:17 + | +LL | let _ = outer.get(); + | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn test<T: 'static>() { + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/wf-nested.rs b/tests/ui/type-alias-impl-trait/wf-nested.rs new file mode 100644 index 000000000..de3883294 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/wf-nested.rs @@ -0,0 +1,60 @@ +// 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-pass +// [pass_sound] check-fail +// [fail] check-fail + +#![feature(type_alias_impl_trait)] + +struct IsStatic<T: 'static>(T); + +trait Trait<In> { + type Out; + + fn get(&self) -> Result<Self::Out, ()> { + Err(()) + } +} + +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> {} +} + +// 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> {} + + fn test<T>() { + let outer = define::<T>(); + let _ = outer.get(); //[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; //[fail]~ ERROR `T` may not live long enough + type OuterOpaque<T> = impl Trait<&'static T, Out = InnerOpaque<T>>; + fn define<T>() -> OuterOpaque<T> {} +} + +fn main() {} |