From 2bf63a50115efad7a474e50b7a4330b506da2578 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Feb 2022 13:55:58 +0000 Subject: [PATCH] Add regression tests --- src/test/ui/impl-trait/issues/issue-54895.rs | 23 ++++++++ src/test/ui/impl-trait/issues/issue-62742.rs | 32 +++++++++++ .../ui/impl-trait/issues/issue-62742.stderr | 54 +++++++++++++++++++ .../impl-trait/issues/issue-67830.nll.stderr | 20 +++++++ src/test/ui/impl-trait/issues/issue-67830.rs | 26 +++++++++ .../ui/impl-trait/issues/issue-67830.stderr | 15 ++++++ src/test/ui/impl-trait/issues/issue-74282.rs | 11 ++++ .../ui/impl-trait/issues/issue-74282.stderr | 33 ++++++++++++ src/test/ui/impl-trait/issues/issue-77987.rs | 21 ++++++++ src/test/ui/impl-trait/issues/issue-82139.rs | 19 +++++++ .../ui/impl-trait/issues/issue-82139.stderr | 9 ++++ src/test/ui/impl-trait/issues/issue-83919.rs | 31 +++++++++++ .../ui/impl-trait/issues/issue-83919.stderr | 17 ++++++ src/test/ui/impl-trait/issues/issue-84073.rs | 33 ++++++++++++ .../ui/impl-trait/issues/issue-84073.stderr | 9 ++++ src/test/ui/impl-trait/issues/issue-86719.rs | 12 +++++ .../ui/impl-trait/issues/issue-86719.stderr | 24 +++++++++ src/test/ui/impl-trait/issues/issue-86800.rs | 48 +++++++++++++++++ .../ui/impl-trait/issues/issue-86800.stderr | 10 ++++ src/test/ui/impl-trait/issues/issue-87340.rs | 14 +++++ .../ui/impl-trait/issues/issue-87340.stderr | 9 ++++ src/test/ui/impl-trait/issues/issue-89312.rs | 24 +++++++++ 22 files changed, 494 insertions(+) create mode 100644 src/test/ui/impl-trait/issues/issue-54895.rs create mode 100644 src/test/ui/impl-trait/issues/issue-62742.rs create mode 100644 src/test/ui/impl-trait/issues/issue-62742.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-67830.nll.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-67830.rs create mode 100644 src/test/ui/impl-trait/issues/issue-67830.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-74282.rs create mode 100644 src/test/ui/impl-trait/issues/issue-74282.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-77987.rs create mode 100644 src/test/ui/impl-trait/issues/issue-82139.rs create mode 100644 src/test/ui/impl-trait/issues/issue-82139.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-83919.rs create mode 100644 src/test/ui/impl-trait/issues/issue-83919.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-84073.rs create mode 100644 src/test/ui/impl-trait/issues/issue-84073.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-86719.rs create mode 100644 src/test/ui/impl-trait/issues/issue-86719.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-86800.rs create mode 100644 src/test/ui/impl-trait/issues/issue-86800.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-87340.rs create mode 100644 src/test/ui/impl-trait/issues/issue-87340.stderr create mode 100644 src/test/ui/impl-trait/issues/issue-89312.rs diff --git a/src/test/ui/impl-trait/issues/issue-54895.rs b/src/test/ui/impl-trait/issues/issue-54895.rs new file mode 100644 index 00000000000..a70166e03a7 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-54895.rs @@ -0,0 +1,23 @@ +// check-pass + +trait Trait<'a> { + type Out; + fn call(&'a self) -> Self::Out; +} + +struct X(()); + +impl<'a> Trait<'a> for X { + type Out = (); + fn call(&'a self) -> Self::Out { + () + } +} + +fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { + X(()) +} + +fn main() { + let _ = f(); +} diff --git a/src/test/ui/impl-trait/issues/issue-62742.rs b/src/test/ui/impl-trait/issues/issue-62742.rs new file mode 100644 index 00000000000..041bd0e3855 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-62742.rs @@ -0,0 +1,32 @@ +use std::marker::PhantomData; + +fn _alias_check() { + WrongImpl::foo(0i32); + //~^ ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied + WrongImpl::<()>::foo(0i32); + //~^ ERROR the trait bound `RawImpl<()>: Raw<()>` is not satisfied + //~| ERROR trait bounds were not satisfied + CorrectImpl::foo(0i32); +} + +pub trait Raw { + type Value; +} + +pub type WrongImpl = SafeImpl>; + +pub type CorrectImpl = SafeImpl<[T], RawImpl>; + +pub struct RawImpl(PhantomData); + +impl Raw<[T]> for RawImpl { + type Value = T; +} + +pub struct SafeImpl>(PhantomData<(A, T)>); + +impl> SafeImpl { + pub fn foo(value: A::Value) {} +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-62742.stderr b/src/test/ui/impl-trait/issues/issue-62742.stderr new file mode 100644 index 00000000000..28068b7548c --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-62742.stderr @@ -0,0 +1,54 @@ +error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied + --> $DIR/issue-62742.rs:4:5 + | +LL | WrongImpl::foo(0i32); + | ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>` + | + = help: the following implementations were found: + as Raw<[T]>> +note: required by a bound in `SafeImpl` + --> $DIR/issue-62742.rs:26:35 + | +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | ^^^^^^ required by this bound in `SafeImpl` + +error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied + --> $DIR/issue-62742.rs:6:22 + | +LL | WrongImpl::<()>::foo(0i32); + | ^^^ function or associated item cannot be called on `SafeImpl<(), RawImpl<()>>` due to unsatisfied trait bounds +... +LL | pub struct RawImpl(PhantomData); + | -------------------------------------- doesn't satisfy `RawImpl<()>: Raw<()>` +... +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | --------------------------------------------------------------- function or associated item `foo` not found for this + | + = note: the following trait bounds were not satisfied: + `RawImpl<()>: Raw<()>` +note: the following trait must be implemented + --> $DIR/issue-62742.rs:12:1 + | +LL | / pub trait Raw { +LL | | type Value; +LL | | } + | |_^ + +error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied + --> $DIR/issue-62742.rs:6:5 + | +LL | WrongImpl::<()>::foo(0i32); + | ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>` + | + = help: the following implementations were found: + as Raw<[T]>> +note: required by a bound in `SafeImpl` + --> $DIR/issue-62742.rs:26:35 + | +LL | pub struct SafeImpl>(PhantomData<(A, T)>); + | ^^^^^^ required by this bound in `SafeImpl` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0599. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issues/issue-67830.nll.stderr b/src/test/ui/impl-trait/issues/issue-67830.nll.stderr new file mode 100644 index 00000000000..17fbe046e3a --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-67830.nll.stderr @@ -0,0 +1,20 @@ +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-67830.rs:23:5 + | +LL | Wrap(|a| Some(a).into_iter()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` + +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-67830.rs:23:5 + | +LL | Wrap(|a| Some(a).into_iter()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-trait/issues/issue-67830.rs b/src/test/ui/impl-trait/issues/issue-67830.rs new file mode 100644 index 00000000000..a308d975b43 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-67830.rs @@ -0,0 +1,26 @@ +trait MyFn { + type Output; + fn call(&self, arg: Arg) -> Self::Output; +} + +struct Wrap(F); + +impl MyFn for Wrap +where + F: Fn(A) -> B +{ + type Output = B; + + fn call(&self, arg: A) -> Self::Output { + (self.0)(arg) + } +} + + +struct A; +fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { + //~^ ERROR implementation of `FnOnce` is not general enough + Wrap(|a| Some(a).into_iter()) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-67830.stderr b/src/test/ui/impl-trait/issues/issue-67830.stderr new file mode 100644 index 00000000000..74e2f99cd33 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-67830.stderr @@ -0,0 +1,15 @@ +error: implementation of `FnOnce` is not general enough + --> $DIR/issue-67830.rs:21:66 + | +LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { + | __________________________________________________________________^ +LL | | +LL | | Wrap(|a| Some(a).into_iter()) +LL | | } + | |_^ implementation of `FnOnce` is not general enough + | + = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... + = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/issues/issue-74282.rs b/src/test/ui/impl-trait/issues/issue-74282.rs new file mode 100644 index 00000000000..654de0cd025 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-74282.rs @@ -0,0 +1,11 @@ +#![feature(type_alias_impl_trait)] + +type Closure = impl Fn() -> u64; +struct Anonymous(Closure); + +fn main() { + let y = || -> Closure { || 3 }; + Anonymous(|| { //~ ERROR mismatched types + 3 //~^ ERROR mismatched types + }) +} diff --git a/src/test/ui/impl-trait/issues/issue-74282.stderr b/src/test/ui/impl-trait/issues/issue-74282.stderr new file mode 100644 index 00000000000..6e02a6b2b87 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-74282.stderr @@ -0,0 +1,33 @@ +error[E0308]: mismatched types + --> $DIR/issue-74282.rs:8:15 + | +LL | type Closure = impl Fn() -> u64; + | ---------------- the expected opaque type +... +LL | Anonymous(|| { + | _______________^ +LL | | 3 +LL | | }) + | |_____^ expected closure, found a different closure + | + = note: expected opaque type `Closure` + found closure `[closure@$DIR/issue-74282.rs:8:15: 10:6]` + = note: no two closures, even if identical, have the same type + = help: consider boxing your closure and/or using it as a trait object + +error[E0308]: mismatched types + --> $DIR/issue-74282.rs:8:5 + | +LL | fn main() { + | - expected `()` because of default return type +LL | let y = || -> Closure { || 3 }; +LL | / Anonymous(|| { +LL | | 3 +LL | | }) + | | ^- help: consider using a semicolon here: `;` + | |______| + | expected `()`, found struct `Anonymous` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/issues/issue-77987.rs b/src/test/ui/impl-trait/issues/issue-77987.rs new file mode 100644 index 00000000000..d29710b6f54 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-77987.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +trait Foo {} +impl Foo for U {} + +type Scope = impl Foo<()>; + +#[allow(unused)] +fn infer_scope() -> Scope { + () +} + +#[allow(unused)] +fn ice() -> impl Foo +{ + loop {} +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-82139.rs b/src/test/ui/impl-trait/issues/issue-82139.rs new file mode 100644 index 00000000000..cc9167b340a --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-82139.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +trait Trait { + type Associated; + fn func() -> Self::Associated; +} + +trait Bound {} +pub struct Struct; + +impl Trait for Struct { + type Associated = impl Bound; + + fn func() -> Self::Associated { + Some(42).map(|_| j) //~ ERROR cannot find value `j` in this scope + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-82139.stderr b/src/test/ui/impl-trait/issues/issue-82139.stderr new file mode 100644 index 00000000000..0adcd4a7a2f --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-82139.stderr @@ -0,0 +1,9 @@ +error[E0425]: cannot find value `j` in this scope + --> $DIR/issue-82139.rs:15:26 + | +LL | Some(42).map(|_| j) + | ^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/impl-trait/issues/issue-83919.rs b/src/test/ui/impl-trait/issues/issue-83919.rs new file mode 100644 index 00000000000..58aca77fdf1 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-83919.rs @@ -0,0 +1,31 @@ +#![feature(type_alias_impl_trait)] + +// edition:2021 + +use std::future::Future; + +trait Foo { + type T; + type Fut2: Future; // ICE got triggered with traits other than Future here + type Fut: Future; + fn get_fut(&self) -> Self::Fut; +} + +struct Implementor; + +impl Foo for Implementor { + type T = u64; + type Fut2 = impl Future; + type Fut = impl Future; + + fn get_fut(&self) -> Self::Fut { + async move { + 42 //~^ ERROR `{integer}` is not a future + // 42 does not impl Future and rustc does actually point out the error, + // but rustc used to panic. + // Putting a valid Future here always worked fine. + } + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-83919.stderr b/src/test/ui/impl-trait/issues/issue-83919.stderr new file mode 100644 index 00000000000..ebd0130be8d --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-83919.stderr @@ -0,0 +1,17 @@ +error[E0277]: `{integer}` is not a future + --> $DIR/issue-83919.rs:22:9 + | +LL | / async move { +LL | | 42 +LL | | // 42 does not impl Future and rustc does actually point out the error, +LL | | // but rustc used to panic. +LL | | // Putting a valid Future here always worked fine. +LL | | } + | |_________^ `{integer}` is not a future + | + = help: the trait `Future` is not implemented for `{integer}` + = note: {integer} must be a future or must implement `IntoFuture` to be awaited + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issues/issue-84073.rs b/src/test/ui/impl-trait/issues/issue-84073.rs new file mode 100644 index 00000000000..49a34ccfa3b --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-84073.rs @@ -0,0 +1,33 @@ +use std::marker::PhantomData; + +pub trait StatefulFuture {} +pub struct Never(PhantomData); +impl StatefulFuture for Never {} + +pub struct RaceBuilder { + future: F, + _phantom: PhantomData, +} + +impl RaceBuilder +where + F: StatefulFuture>, +{ + pub fn when(self) {} +} + +pub struct Race { + race: R, + _phantom: PhantomData, +} + +impl Race +where + R: Fn(RaceBuilder>), +{ + pub fn new(race: R) {} +} + +fn main() { + Race::new(|race| race.when()); //~ ERROR type annotations needed +} diff --git a/src/test/ui/impl-trait/issues/issue-84073.stderr b/src/test/ui/impl-trait/issues/issue-84073.stderr new file mode 100644 index 00000000000..36047d23fed --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-84073.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed for `RaceBuilder>` + --> $DIR/issue-84073.rs:32:16 + | +LL | Race::new(|race| race.when()); + | ^^^^ consider giving this closure parameter the explicit type `RaceBuilder>`, where the type parameter `T` is specified + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/issues/issue-86719.rs b/src/test/ui/impl-trait/issues/issue-86719.rs new file mode 100644 index 00000000000..f4b0b3f33fc --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-86719.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +trait Bar { + type E; +} +impl Bar for S { + type E = impl ; //~ ERROR at least one trait must be specified + fn foo() -> Self::E { //~ ERROR `foo` is not a member + |_| true //~ ERROR type annotations needed + } +} +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-86719.stderr b/src/test/ui/impl-trait/issues/issue-86719.stderr new file mode 100644 index 00000000000..e2abf71c110 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-86719.stderr @@ -0,0 +1,24 @@ +error: at least one trait must be specified + --> $DIR/issue-86719.rs:7:14 + | +LL | type E = impl ; + | ^^^^ + +error[E0407]: method `foo` is not a member of trait `Bar` + --> $DIR/issue-86719.rs:8:5 + | +LL | / fn foo() -> Self::E { +LL | | |_| true +LL | | } + | |_____^ not a member of trait `Bar` + +error[E0282]: type annotations needed + --> $DIR/issue-86719.rs:9:10 + | +LL | |_| true + | ^ consider giving this closure parameter a type + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0282, E0407. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/issues/issue-86800.rs b/src/test/ui/impl-trait/issues/issue-86800.rs new file mode 100644 index 00000000000..e8cef42f208 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-86800.rs @@ -0,0 +1,48 @@ +#![feature(type_alias_impl_trait)] + +// edition:2021 + +use std::future::Future; + +struct Connection { +} + +trait Transaction { +} + +struct TestTransaction<'conn> { + conn: &'conn Connection +} + +impl<'conn> Transaction for TestTransaction<'conn> { +} + +struct Context { +} + +type TransactionResult = Result; + +type TransactionFuture<'__, O> = impl '__ + Future>; +//~^ ERROR unconstrained opaque type + +fn execute_transaction_fut<'f, F, O>( + f: F, +) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture +where + F: FnOnce(&mut dyn Transaction) -> TransactionFuture + 'f +{ + f +} + +impl Context { + async fn do_transaction( + &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture + ) -> TransactionResult + { + let mut conn = Connection {}; + let mut transaction = TestTransaction { conn: &mut conn }; + f(&mut transaction).await + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-86800.stderr b/src/test/ui/impl-trait/issues/issue-86800.stderr new file mode 100644 index 00000000000..787aecc5b84 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-86800.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/issue-86800.rs:25:34 + | +LL | type TransactionFuture<'__, O> = impl '__ + Future>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `TransactionFuture` must be used in combination with a concrete type within the same module + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/issues/issue-87340.rs b/src/test/ui/impl-trait/issues/issue-87340.rs new file mode 100644 index 00000000000..f0f6d2bb61c --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-87340.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +trait X { + type I; + fn f() -> Self::I; +} + +impl X for () { +//~^ ERROR `T` is not constrained by the impl trait, self type, or predicates + type I = impl Sized; + fn f() -> Self::I {} +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-87340.stderr b/src/test/ui/impl-trait/issues/issue-87340.stderr new file mode 100644 index 00000000000..2ab1e6a0312 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-87340.stderr @@ -0,0 +1,9 @@ +error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-87340.rs:8:6 + | +LL | impl X for () { + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/src/test/ui/impl-trait/issues/issue-89312.rs b/src/test/ui/impl-trait/issues/issue-89312.rs new file mode 100644 index 00000000000..d685a6f1201 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-89312.rs @@ -0,0 +1,24 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +trait T { type Item; } + +type Alias<'a> = impl T; + +struct S; +impl<'a> T for &'a S { + type Item = &'a (); +} + +fn filter_positive<'a>() -> Alias<'a> { + &S +} + +fn with_positive(fun: impl Fn(Alias<'_>)) { + fun(filter_positive()); +} + +fn main() { + with_positive(|_| ()); +}