summaryrefslogtreecommitdiffstats
path: root/tests/ui/type-alias-impl-trait
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /tests/ui/type-alias-impl-trait
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-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')
-rw-r--r--tests/ui/type-alias-impl-trait/associated-type-impl-trait-lifetime.rs9
-rw-r--r--tests/ui/type-alias-impl-trait/closure_parent_substs.rs10
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-2.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/different_defining_uses_never_type-3.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.rs16
-rw-r--r--tests/ui/type-alias-impl-trait/invalid_impl_trait_in_assoc_ty.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/issue-65918.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98604.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-98608.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/wf-in-associated-type.fail.stderr25
-rw-r--r--tests/ui/type-alias-impl-trait/wf-in-associated-type.rs45
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.fail.stderr19
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/wf-nested.rs60
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() {}