diff options
Diffstat (limited to 'tests/ui/impl-trait/issues')
75 files changed, 1493 insertions, 0 deletions
diff --git a/tests/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs b/tests/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs new file mode 100644 index 000000000..451ddb3cc --- /dev/null +++ b/tests/ui/impl-trait/issues/infinite-impl-trait-issue-38064.rs @@ -0,0 +1,25 @@ +// Test that attempts to construct infinite types via impl trait fail +// in a graceful way. +// +// Regression test for #38064. + +trait Quux {} + +fn foo() -> impl Quux { //~ ERROR cannot resolve opaque type + struct Foo<T>(T); + impl<T> Quux for Foo<T> {} + Foo(bar()) +} + +fn bar() -> impl Quux { //~ ERROR cannot resolve opaque type + struct Bar<T>(T); + impl<T> Quux for Bar<T> {} + Bar(foo()) +} + +// effectively: +// struct Foo(Bar); +// struct Bar(Foo); +// should produce an error about infinite size + +fn main() { foo(); } diff --git a/tests/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr b/tests/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr new file mode 100644 index 000000000..16a1262ec --- /dev/null +++ b/tests/ui/impl-trait/issues/infinite-impl-trait-issue-38064.stderr @@ -0,0 +1,27 @@ +error[E0720]: cannot resolve opaque type + --> $DIR/infinite-impl-trait-issue-38064.rs:8:13 + | +LL | fn foo() -> impl Quux { + | ^^^^^^^^^ recursive opaque type +... +LL | Foo(bar()) + | ---------- returning here with type `Foo<impl Quux>` +... +LL | fn bar() -> impl Quux { + | --------- returning this opaque type `Foo<impl Quux>` + +error[E0720]: cannot resolve opaque type + --> $DIR/infinite-impl-trait-issue-38064.rs:14:13 + | +LL | fn foo() -> impl Quux { + | --------- returning this opaque type `Bar<impl Quux>` +... +LL | fn bar() -> impl Quux { + | ^^^^^^^^^ recursive opaque type +... +LL | Bar(foo()) + | ---------- returning here with type `Bar<impl Quux>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0720`. diff --git a/tests/ui/impl-trait/issues/issue-104815.rs b/tests/ui/impl-trait/issues/issue-104815.rs new file mode 100644 index 000000000..7a9826a8d --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-104815.rs @@ -0,0 +1,66 @@ +// check-pass + +struct It; + +struct Data { + items: Vec<It>, +} + +impl Data { + fn new() -> Self { + Self { + items: vec![It, It], + } + } + + fn content(&self) -> impl Iterator<Item = &It> { + self.items.iter() + } +} + +struct Container<'a> { + name: String, + resolver: Box<dyn Resolver + 'a>, +} + +impl<'a> Container<'a> { + fn new<R: Resolver + 'a>(name: &str, resolver: R) -> Self { + Self { + name: name.to_owned(), + resolver: Box::new(resolver), + } + } +} + +trait Resolver {} + +impl<R: Resolver> Resolver for &R {} + +impl Resolver for It {} + +fn get<'a>(mut items: impl Iterator<Item = &'a It>) -> impl Resolver + 'a { + items.next().unwrap() +} + +fn get2<'a, 'b: 'b>(mut items: impl Iterator<Item = &'a It>) -> impl Resolver + 'a { + items.next().unwrap() +} + +fn main() { + let data = Data::new(); + let resolver = get(data.content()); + + let _ = ["a", "b"] + .iter() + .map(|&n| Container::new(n, &resolver)) + .map(|c| c.name) + .collect::<Vec<_>>(); + + let resolver = get2(data.content()); + + let _ = ["a", "b"] + .iter() + .map(|&n| Container::new(n, &resolver)) + .map(|c| c.name) + .collect::<Vec<_>>(); +} diff --git a/tests/ui/impl-trait/issues/issue-105826.rs b/tests/ui/impl-trait/issues/issue-105826.rs new file mode 100644 index 000000000..06dc2d4c8 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-105826.rs @@ -0,0 +1,39 @@ +// check-pass + +use std::io::Write; + +struct A(Vec<u8>); + +struct B<'a> { + one: &'a mut A, + two: &'a mut Vec<u8>, + three: Vec<u8>, +} + +impl<'a> B<'a> { + fn one(&mut self) -> &mut impl Write { + &mut self.one.0 + } + fn two(&mut self) -> &mut impl Write { + &mut *self.two + } + fn three(&mut self) -> &mut impl Write { + &mut self.three + } +} + +struct C<'a>(B<'a>); + +impl<'a> C<'a> { + fn one(&mut self) -> &mut impl Write { + self.0.one() + } + fn two(&mut self) -> &mut impl Write { + self.0.two() + } + fn three(&mut self) -> &mut impl Write { + self.0.three() + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs b/tests/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs new file mode 100644 index 000000000..41f48cb56 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.rs @@ -0,0 +1,22 @@ +trait Foo<A> { + fn foo(&self, a: A) -> A { + a + } +} + +trait NotRelevant<A> { + fn nr(&self, a: A) -> A { + a + } +} + +struct Bar; + +impl NotRelevant<usize> for Bar {} + +fn main() { + let f1 = Bar; + + f1.foo(1usize); + //~^ error: method named `foo` found for struct `Bar` in the current scope +} diff --git a/tests/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr b/tests/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr new file mode 100644 index 000000000..9150d957d --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-21659-show-relevant-trait-impls-3.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `foo` found for struct `Bar` in the current scope + --> $DIR/issue-21659-show-relevant-trait-impls-3.rs:20:8 + | +LL | struct Bar; + | ---------- method `foo` not found for this struct +... +LL | f1.foo(1usize); + | ^^^ method not found in `Bar` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Foo` defines an item `foo`, perhaps you need to implement it + --> $DIR/issue-21659-show-relevant-trait-impls-3.rs:1:1 + | +LL | trait Foo<A> { + | ^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/impl-trait/issues/issue-42479.rs b/tests/ui/impl-trait/issues/issue-42479.rs new file mode 100644 index 000000000..efc1f975d --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-42479.rs @@ -0,0 +1,17 @@ +// check-pass + +use std::iter::once; + +struct Foo { + x: i32, +} + +impl Foo { + fn inside(&self) -> impl Iterator<Item = &i32> { + once(&self.x) + } +} + +fn main() { + println!("hi"); +} diff --git a/tests/ui/impl-trait/issues/issue-49376.rs b/tests/ui/impl-trait/issues/issue-49376.rs new file mode 100644 index 000000000..e4472fcc1 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-49376.rs @@ -0,0 +1,23 @@ +// check-pass + +// Tests for nested self-reference which caused a stack overflow. + +use std::fmt::Debug; +use std::ops::*; + +fn gen() -> impl PartialOrd + PartialEq + Debug { } + +struct Bar {} +trait Foo<T = Self> {} +trait FooNested<T = Option<Self>> {} +impl Foo for Bar {} +impl FooNested for Bar {} + +fn foo() -> impl Foo + FooNested { + Bar {} +} + +fn test_impl_ops() -> impl Add + Sub + Mul + Div { 1 } +fn test_impl_assign_ops() -> impl AddAssign + SubAssign + MulAssign + DivAssign { 1 } + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-52128.rs b/tests/ui/impl-trait/issues/issue-52128.rs new file mode 100644 index 000000000..5afd380dd --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-52128.rs @@ -0,0 +1,25 @@ +// check-pass + +#![deny(warnings)] + +use std::collections::BTreeMap; + +pub struct RangeMap { + map: BTreeMap<Range, u8>, +} + +#[derive(Eq, PartialEq, Ord, PartialOrd)] +struct Range; + +impl RangeMap { + fn iter_with_range<'a>(&'a self) -> impl Iterator<Item = (&'a Range, &'a u8)> + 'a { + self.map.range(Range..Range) + } + + pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'a u8> + 'a { + self.iter_with_range().map(|(_, data)| data) + } + +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-53457.rs b/tests/ui/impl-trait/issues/issue-53457.rs new file mode 100644 index 000000000..7b9c2c53a --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-53457.rs @@ -0,0 +1,14 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +type X = impl Clone; + +fn bar<F: Fn(&i32) + Clone>(f: F) -> F { + f +} + +fn foo() -> X { + bar(|_| ()) +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-54600.rs b/tests/ui/impl-trait/issues/issue-54600.rs new file mode 100644 index 000000000..3024fedf7 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-54600.rs @@ -0,0 +1,7 @@ +use std::fmt::Debug; + +fn main() { + let x: Option<impl Debug> = Some(44_u32); + //~^ `impl Trait` only allowed in function and inherent method return types + println!("{:?}", x); +} diff --git a/tests/ui/impl-trait/issues/issue-54600.stderr b/tests/ui/impl-trait/issues/issue-54600.stderr new file mode 100644 index 000000000..316566a57 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-54600.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-54600.rs:4:19 + | +LL | let x: Option<impl Debug> = Some(44_u32); + | ^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-54840.rs b/tests/ui/impl-trait/issues/issue-54840.rs new file mode 100644 index 000000000..8f1e0ece0 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-54840.rs @@ -0,0 +1,7 @@ +use std::ops::Add; + +fn main() { + let i: i32 = 0; + let j: &impl Add = &i; + //~^ `impl Trait` only allowed in function and inherent method return types +} diff --git a/tests/ui/impl-trait/issues/issue-54840.stderr b/tests/ui/impl-trait/issues/issue-54840.stderr new file mode 100644 index 000000000..8d82133ac --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-54840.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-54840.rs:5:13 + | +LL | let j: &impl Add = &i; + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-54895.rs b/tests/ui/impl-trait/issues/issue-54895.rs new file mode 100644 index 000000000..8d7a1d56f --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-54895.rs @@ -0,0 +1,22 @@ +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> { + //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + X(()) +} + +fn main() { + let _ = f(); +} diff --git a/tests/ui/impl-trait/issues/issue-54895.stderr b/tests/ui/impl-trait/issues/issue-54895.stderr new file mode 100644 index 000000000..7d22f027a --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-54895.stderr @@ -0,0 +1,14 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-54895.rs:15:53 + | +LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-54895.rs:15:20 + | +LL | fn f() -> impl for<'a> Trait<'a, Out = impl Sized + 'a> { + | ^^ + +error: aborting due to previous error + diff --git a/tests/ui/impl-trait/issues/issue-55608-captures-empty-region.rs b/tests/ui/impl-trait/issues/issue-55608-captures-empty-region.rs new file mode 100644 index 000000000..0c34c97e2 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-55608-captures-empty-region.rs @@ -0,0 +1,22 @@ +// This used to ICE because it creates an `impl Trait` that captures a +// hidden empty region. + +// check-pass + +fn server() -> impl FilterBase2 { + segment2(|| { loop { } }).map2(|| "") +} + +trait FilterBase2 { + fn map2<F>(self, _fn: F) -> Map2<F> where Self: Sized { loop { } } +} + +struct Map2<F> { _func: F } + +impl<F> FilterBase2 for Map2<F> { } + +fn segment2<F>(_fn: F) -> Map2<F> where F: Fn() -> Result<(), ()> { + loop { } +} + +fn main() { server(); } diff --git a/tests/ui/impl-trait/issues/issue-57464-unexpected-regions.rs b/tests/ui/impl-trait/issues/issue-57464-unexpected-regions.rs new file mode 100644 index 000000000..c4f738a34 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-57464-unexpected-regions.rs @@ -0,0 +1,29 @@ +// Regression test for issue 57464. +// +// Closure are (surprisingly) allowed to outlive their signature. As such it +// was possible to end up with `ReScope`s appearing in the concrete type of an +// opaque type. As all regions are now required to outlive the bound in an +// opaque type we avoid the issue here. + +// check-pass + +struct A<F>(F); + +unsafe impl <'a, 'b, F: Fn(&'a i32) -> &'b i32> Send for A<F> {} + +fn wrapped_closure() -> impl Sized { + let f = |x| x; + f(&0); + A(f) +} + +fn wrapped_closure_with_bound() -> impl Sized + 'static { + let f = |x| x; + f(&0); + A(f) +} + +fn main() { + let x: Box<dyn Send> = Box::new(wrapped_closure()); + let y: Box<dyn Send> = Box::new(wrapped_closure_with_bound()); +} diff --git a/tests/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs b/tests/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs new file mode 100644 index 000000000..0daec3305 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs @@ -0,0 +1,17 @@ +// rust-lang/rust#57979 : the initial support for `impl Trait` didn't +// properly check syntax hidden behind an associated type projection, +// but it did catch *some cases*. This is checking that we continue to +// properly emit errors for those. +// +// issue-57979-nested-impl-trait-in-assoc-proj.rs shows the main case +// that we were previously failing to catch. + +struct Deeper<T>(T); + +pub trait Foo<T> { } +pub trait Bar { } +pub trait Quux { type Assoc; } +pub fn demo(_: impl Quux<Assoc=Deeper<impl Foo<impl Bar>>>) { } +//~^ ERROR nested `impl Trait` is not allowed + +fn main() { } diff --git a/tests/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr b/tests/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr new file mode 100644 index 000000000..6bebbc01f --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-57979-deeply-nested-impl-trait-in-assoc-proj.stderr @@ -0,0 +1,12 @@ +error[E0666]: nested `impl Trait` is not allowed + --> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:14:48 + | +LL | pub fn demo(_: impl Quux<Assoc=Deeper<impl Foo<impl Bar>>>) { } + | ---------^^^^^^^^- + | | | + | | nested `impl Trait` here + | outer `impl Trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0666`. diff --git a/tests/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs b/tests/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs new file mode 100644 index 000000000..c5ecd1caa --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-57979-impl-trait-in-path.rs @@ -0,0 +1,12 @@ +// rust-lang/rust#57979 : the initial support for `impl Trait` didn't +// properly check syntax hidden behind an associated type projection. +// Here we test behavior of occurrences of `impl Trait` within a path +// component in that context. + +pub trait Bar { } +pub trait Quux<T> { type Assoc; } +pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { } +//~^ ERROR `impl Trait` is not allowed in path parameters +impl<T> Quux<T> for () { type Assoc = u32; } + +fn main() { } diff --git a/tests/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr b/tests/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr new file mode 100644 index 000000000..e31393181 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-57979-impl-trait-in-path.stderr @@ -0,0 +1,9 @@ +error[E0667]: `impl Trait` is not allowed in path parameters + --> $DIR/issue-57979-impl-trait-in-path.rs:8:48 + | +LL | pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { } + | ^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0667`. diff --git a/tests/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs b/tests/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs new file mode 100644 index 000000000..5a444d3df --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.rs @@ -0,0 +1,12 @@ +// rust-lang/rust#57979 : the initial support for `impl Trait` didn't +// properly check syntax hidden behind an associated type projection. +// Here we test behavior of occurrences of `impl Trait` within an +// `impl Trait` in that context. + +pub trait Foo<T> { } +pub trait Bar { } +pub trait Quux { type Assoc; } +pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { } +//~^ ERROR nested `impl Trait` is not allowed + +fn main() { } diff --git a/tests/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr b/tests/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr new file mode 100644 index 000000000..8d3d4b5e2 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-57979-nested-impl-trait-in-assoc-proj.stderr @@ -0,0 +1,12 @@ +error[E0666]: nested `impl Trait` is not allowed + --> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:9:41 + | +LL | pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { } + | ---------^^^^^^^^- + | | | + | | nested `impl Trait` here + | outer `impl Trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0666`. diff --git a/tests/ui/impl-trait/issues/issue-58504.rs b/tests/ui/impl-trait/issues/issue-58504.rs new file mode 100644 index 000000000..e5865d0df --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-58504.rs @@ -0,0 +1,12 @@ +#![feature(generators, generator_trait, never_type)] + +use std::ops::Generator; + +fn mk_gen() -> impl Generator<Return=!, Yield=()> { + || { loop { yield; } } +} + +fn main() { + let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ]; + //~^ `impl Trait` only allowed in function and inherent method return types +} diff --git a/tests/ui/impl-trait/issues/issue-58504.stderr b/tests/ui/impl-trait/issues/issue-58504.stderr new file mode 100644 index 000000000..6656e9fc3 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-58504.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-58504.rs:10:16 + | +LL | let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-58956.rs b/tests/ui/impl-trait/issues/issue-58956.rs new file mode 100644 index 000000000..68cfcd9ba --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-58956.rs @@ -0,0 +1,14 @@ +trait Lam {} + +pub struct B; +impl Lam for B {} +pub struct Wrap<T>(T); + +const _A: impl Lam = { + //~^ `impl Trait` only allowed in function and inherent method return types + let x: Wrap<impl Lam> = Wrap(B); + //~^ `impl Trait` only allowed in function and inherent method return types + x.0 +}; + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr new file mode 100644 index 000000000..123fb4df4 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-58956.stderr @@ -0,0 +1,15 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type + --> $DIR/issue-58956.rs:7:11 + | +LL | const _A: impl Lam = { + | ^^^^^^^^ + +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-58956.rs:9:17 + | +LL | let x: Wrap<impl Lam> = Wrap(B); + | ^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-62742.rs b/tests/ui/impl-trait/issues/issue-62742.rs new file mode 100644 index 000000000..041bd0e38 --- /dev/null +++ b/tests/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<T: ?Sized> { + type Value; +} + +pub type WrongImpl<T> = SafeImpl<T, RawImpl<T>>; + +pub type CorrectImpl<T> = SafeImpl<[T], RawImpl<T>>; + +pub struct RawImpl<T>(PhantomData<T>); + +impl<T> Raw<[T]> for RawImpl<T> { + type Value = T; +} + +pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>); + +impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> { + pub fn foo(value: A::Value) {} +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr new file mode 100644 index 000000000..d872291c8 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-62742.stderr @@ -0,0 +1,55 @@ +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 trait `Raw<[T]>` is implemented for `RawImpl<T>` +note: required by a bound in `SafeImpl` + --> $DIR/issue-62742.rs:26:35 + | +LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(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<T>(PhantomData<T>); + | --------------------- doesn't satisfy `RawImpl<()>: Raw<()>` +... +LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>); + | ----------------------------------------- function or associated item `foo` not found for this struct + | +note: trait bound `RawImpl<()>: Raw<()>` was not satisfied + --> $DIR/issue-62742.rs:28:20 + | +LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> { + | ^^^^^^ -------------- + | | + | unsatisfied trait bound introduced here +note: the trait `Raw` must be implemented + --> $DIR/issue-62742.rs:12:1 + | +LL | pub trait Raw<T: ?Sized> { + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +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 trait `Raw<[T]>` is implemented for `RawImpl<T>` +note: required by a bound in `SafeImpl` + --> $DIR/issue-62742.rs:26:35 + | +LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(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/tests/ui/impl-trait/issues/issue-65581.rs b/tests/ui/impl-trait/issues/issue-65581.rs new file mode 100644 index 000000000..b947fc1d2 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-65581.rs @@ -0,0 +1,34 @@ +// check-pass +// ignore-compare-mode-chalk + +#![allow(dead_code)] + +trait Trait1<T, U> { + fn f1(self) -> U; +} + +trait Trait2 { + type T; + type U: Trait2<T = Self::T>; + fn f2(f: impl FnOnce(&Self::U)); +} + +fn f3<T: Trait2>() -> impl Trait1<T, T::T> { + Struct1 +} + +struct Struct1; + +impl<T: Trait2> Trait1<T, T::T> for Struct1 { + fn f1(self) -> T::T { + unimplemented!() + } +} + +fn f4<T: Trait2>() { + T::f2(|_| { + f3::<T::U>().f1(); + }); +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-67830.rs b/tests/ui/impl-trait/issues/issue-67830.rs new file mode 100644 index 000000000..92f7e005d --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-67830.rs @@ -0,0 +1,26 @@ +trait MyFn<Arg> { + type Output; + fn call(&self, arg: Arg) -> Self::Output; +} + +struct Wrap<F>(F); + +impl<A, B, F> MyFn<A> for Wrap<F> +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 higher kinded lifetime bounds on nested opaque types are not supported yet + Wrap(|a| Some(a).into_iter()) +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-67830.stderr b/tests/ui/impl-trait/issues/issue-67830.stderr new file mode 100644 index 000000000..d3ea8cb03 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-67830.stderr @@ -0,0 +1,14 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-67830.rs:21:62 + | +LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-67830.rs:21:23 + | +LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { + | ^^ + +error: aborting due to previous error + diff --git a/tests/ui/impl-trait/issues/issue-70877.rs b/tests/ui/impl-trait/issues/issue-70877.rs new file mode 100644 index 000000000..8169cfafa --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-70877.rs @@ -0,0 +1,36 @@ +#![feature(type_alias_impl_trait)] + +type FooArg<'a> = &'a dyn ToString; +type FooRet = impl std::fmt::Debug; + +type FooItem = Box<dyn Fn(FooArg) -> FooRet>; +type Foo = impl Iterator<Item = FooItem>; + +#[repr(C)] +struct Bar(u8); + +impl Iterator for Bar { + type Item = FooItem; + + fn next(&mut self) -> Option<Self::Item> { + Some(Box::new(quux)) + } +} + +fn quux(st: FooArg) -> FooRet { + Some(st.to_string()) +} + +fn ham() -> Foo { + Bar(1) +} + +fn oof() -> impl std::fmt::Debug { + let mut bar = ham(); + let func = bar.next().unwrap(); + return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type +} + +fn main() { + let _ = oof(); +} diff --git a/tests/ui/impl-trait/issues/issue-70877.stderr b/tests/ui/impl-trait/issues/issue-70877.stderr new file mode 100644 index 000000000..8813bff3c --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-70877.stderr @@ -0,0 +1,19 @@ +error: opaque type's hidden type cannot be another opaque type from the same scope + --> $DIR/issue-70877.rs:31:12 + | +LL | return func(&"oof"); + | ^^^^^^^^^^^^ one of the two opaque types used here has to be outside its defining scope + | +note: opaque type whose hidden type is being assigned + --> $DIR/issue-70877.rs:28:13 + | +LL | fn oof() -> impl std::fmt::Debug { + | ^^^^^^^^^^^^^^^^^^^^ +note: opaque type being used as hidden type + --> $DIR/issue-70877.rs:4:15 + | +LL | type FooRet = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/impl-trait/issues/issue-70971.rs b/tests/ui/impl-trait/issues/issue-70971.rs new file mode 100644 index 000000000..f8ae18bac --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-70971.rs @@ -0,0 +1,4 @@ +fn main() { + let x : (impl Copy,) = (true,); + //~^ `impl Trait` only allowed in function and inherent method return types +} diff --git a/tests/ui/impl-trait/issues/issue-70971.stderr b/tests/ui/impl-trait/issues/issue-70971.stderr new file mode 100644 index 000000000..4dda4c22a --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-70971.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-70971.rs:2:14 + | +LL | let x : (impl Copy,) = (true,); + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-74282.rs b/tests/ui/impl-trait/issues/issue-74282.rs new file mode 100644 index 000000000..654de0cd0 --- /dev/null +++ b/tests/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/tests/ui/impl-trait/issues/issue-74282.stderr b/tests/ui/impl-trait/issues/issue-74282.stderr new file mode 100644 index 000000000..5b05fb281 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-74282.stderr @@ -0,0 +1,40 @@ +error[E0308]: mismatched types + --> $DIR/issue-74282.rs:8:15 + | +LL | type Closure = impl Fn() -> u64; + | ---------------- the expected opaque type +... +LL | Anonymous(|| { + | _____---------_^ + | | | + | | arguments to this struct are incorrect +LL | | 3 +LL | | }) + | |_____^ expected closure, found a different closure + | + = note: expected opaque type `Closure` + found closure `[closure@$DIR/issue-74282.rs:8:15: 8:17]` + = note: no two closures, even if identical, have the same type + = help: consider boxing your closure and/or using it as a trait object +note: tuple struct defined here + --> $DIR/issue-74282.rs:4:8 + | +LL | struct Anonymous(Closure); + | ^^^^^^^^^ + +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/tests/ui/impl-trait/issues/issue-77987.rs b/tests/ui/impl-trait/issues/issue-77987.rs new file mode 100644 index 000000000..d29710b6f --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-77987.rs @@ -0,0 +1,21 @@ +#![feature(type_alias_impl_trait)] + +// check-pass + +trait Foo<T> {} +impl<T, U> Foo<T> for U {} + +type Scope = impl Foo<()>; + +#[allow(unused)] +fn infer_scope() -> Scope { + () +} + +#[allow(unused)] +fn ice() -> impl Foo<Scope> +{ + loop {} +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-78722.rs b/tests/ui/impl-trait/issues/issue-78722.rs new file mode 100644 index 000000000..78233f300 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-78722.rs @@ -0,0 +1,20 @@ +// edition:2018 + +#![feature(type_alias_impl_trait)] + +type F = impl core::future::Future<Output = u8>; + +struct Bug { + V1: [(); { + fn concrete_use() -> F { + //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()` + async {} + } + let f: F = async { 1 }; + //~^ ERROR `async` blocks are not allowed in constants + //~| ERROR destructor of + 1 + }], +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-78722.stderr b/tests/ui/impl-trait/issues/issue-78722.stderr new file mode 100644 index 000000000..c00df8087 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-78722.stderr @@ -0,0 +1,28 @@ +error[E0658]: `async` blocks are not allowed in constants + --> $DIR/issue-78722.rs:13:20 + | +LL | let f: F = async { 1 }; + | ^^^^^^^^^^^ + | + = note: see issue #85368 <https://github.com/rust-lang/rust/issues/85368> for more information + = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable + +error[E0493]: destructor of `F` cannot be evaluated at compile-time + --> $DIR/issue-78722.rs:13:13 + | +LL | let f: F = async { 1 }; + | ^ the destructor for this type cannot be evaluated in constants +... +LL | }], + | - value is dropped here + +error[E0271]: expected `[async block@$DIR/issue-78722.rs:11:13: 11:21]` to be a future that resolves to `u8`, but it resolves to `()` + --> $DIR/issue-78722.rs:9:30 + | +LL | fn concrete_use() -> F { + | ^ expected `()`, found `u8` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0271, E0493, E0658. +For more information about an error, try `rustc --explain E0271`. diff --git a/tests/ui/impl-trait/issues/issue-79099.rs b/tests/ui/impl-trait/issues/issue-79099.rs new file mode 100644 index 000000000..da53594f3 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-79099.rs @@ -0,0 +1,10 @@ +struct Bug { + V1: [(); { + let f: impl core::future::Future<Output = u8> = async { 1 }; + //~^ `impl Trait` only allowed in function and inherent method return types + //~| expected identifier + 1 + }], +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr new file mode 100644 index 000000000..362c67daf --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-79099.stderr @@ -0,0 +1,20 @@ +error: expected identifier, found `1` + --> $DIR/issue-79099.rs:3:65 + | +LL | let f: impl core::future::Future<Output = u8> = async { 1 }; + | ----- ^ expected identifier + | | + | `async` blocks are only allowed in Rust 2018 or later + | + = help: pass `--edition 2021` to `rustc` + = note: for more on editions, read https://doc.rust-lang.org/edition-guide + +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-79099.rs:3:16 + | +LL | let f: impl core::future::Future<Output = u8> = async { 1 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-82139.rs b/tests/ui/impl-trait/issues/issue-82139.rs new file mode 100644 index 000000000..cc9167b34 --- /dev/null +++ b/tests/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/tests/ui/impl-trait/issues/issue-82139.stderr b/tests/ui/impl-trait/issues/issue-82139.stderr new file mode 100644 index 000000000..0adcd4a7a --- /dev/null +++ b/tests/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/tests/ui/impl-trait/issues/issue-83919.rs b/tests/ui/impl-trait/issues/issue-83919.rs new file mode 100644 index 000000000..e76443a65 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-83919.rs @@ -0,0 +1,32 @@ +#![feature(type_alias_impl_trait)] + +// edition:2021 + +use std::future::Future; + +trait Foo { + type T; + type Fut2: Future<Output=Self::T>; // ICE got triggered with traits other than Future here + type Fut: Future<Output=Self::Fut2>; + fn get_fut(&self) -> Self::Fut; +} + +struct Implementor; + +impl Foo for Implementor { + type T = u64; + type Fut2 = impl Future<Output=u64>; + type Fut = impl Future<Output=Self::Fut2>; + + fn get_fut(&self) -> Self::Fut { + //~^ ERROR `{integer}` is not a future + async move { + 42 + // 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/tests/ui/impl-trait/issues/issue-83919.stderr b/tests/ui/impl-trait/issues/issue-83919.stderr new file mode 100644 index 000000000..d39dcf7fb --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-83919.stderr @@ -0,0 +1,12 @@ +error[E0277]: `{integer}` is not a future + --> $DIR/issue-83919.rs:21:26 + | +LL | fn get_fut(&self) -> Self::Fut { + | ^^^^^^^^^ `{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/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs new file mode 100644 index 000000000..344f35952 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.rs @@ -0,0 +1,12 @@ +struct Foo<T = impl Copy>(T); +//~^ ERROR `impl Trait` only allowed in function and inherent method return types + +type Result<T, E = impl std::error::Error> = std::result::Result<T, E>; +//~^ ERROR `impl Trait` only allowed in function and inherent method return types + +// should not cause ICE +fn x() -> Foo { + Foo(0) +} + +fn main() -> Result<()> {} diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr new file mode 100644 index 000000000..e635e554e --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr @@ -0,0 +1,15 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type + --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16 + | +LL | struct Foo<T = impl Copy>(T); + | ^^^^^^^^^ + +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type + --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20 + | +LL | type Result<T, E = impl std::error::Error> = std::result::Result<T, E>; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-84073.rs b/tests/ui/impl-trait/issues/issue-84073.rs new file mode 100644 index 000000000..49a34ccfa --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-84073.rs @@ -0,0 +1,33 @@ +use std::marker::PhantomData; + +pub trait StatefulFuture<S> {} +pub struct Never<T>(PhantomData<T>); +impl<T> StatefulFuture<T> for Never<T> {} + +pub struct RaceBuilder<F, S> { + future: F, + _phantom: PhantomData<S>, +} + +impl<T, F> RaceBuilder<T, F> +where + F: StatefulFuture<Option<T>>, +{ + pub fn when(self) {} +} + +pub struct Race<T, R> { + race: R, + _phantom: PhantomData<T>, +} + +impl<T, R> Race<T, R> +where + R: Fn(RaceBuilder<T, Never<T>>), +{ + pub fn new(race: R) {} +} + +fn main() { + Race::new(|race| race.when()); //~ ERROR type annotations needed +} diff --git a/tests/ui/impl-trait/issues/issue-84073.stderr b/tests/ui/impl-trait/issues/issue-84073.stderr new file mode 100644 index 000000000..3c39aa6ce --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-84073.stderr @@ -0,0 +1,14 @@ +error[E0282]: type annotations needed for `RaceBuilder<T, Never<T>>` + --> $DIR/issue-84073.rs:32:16 + | +LL | Race::new(|race| race.when()); + | ^^^^ + | +help: consider giving this closure parameter an explicit type, where the type for type parameter `T` is specified + | +LL | Race::new(|race: RaceBuilder<T, Never<T>>| race.when()); + | ++++++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/issues/issue-84919.rs b/tests/ui/impl-trait/issues/issue-84919.rs new file mode 100644 index 000000000..a0b73743a --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-84919.rs @@ -0,0 +1,9 @@ +trait Trait {} +impl Trait for () {} + +fn foo<'a: 'a>() { + let _x: impl Trait = (); + //~^ `impl Trait` only allowed in function and inherent method return types +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-84919.stderr b/tests/ui/impl-trait/issues/issue-84919.stderr new file mode 100644 index 000000000..5abe1bd87 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-84919.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-84919.rs:5:13 + | +LL | let _x: impl Trait = (); + | ^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-86201.rs b/tests/ui/impl-trait/issues/issue-86201.rs new file mode 100644 index 000000000..0786e66ca --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-86201.rs @@ -0,0 +1,13 @@ +#![feature(unboxed_closures)] +#![feature(type_alias_impl_trait)] + +// check-pass + +type FunType = impl Fn<()>; +static STATIC_FN: FunType = some_fn; + +fn some_fn() {} + +fn main() { + let _: <FunType as FnOnce<()>>::Output = STATIC_FN(); +} diff --git a/tests/ui/impl-trait/issues/issue-86642.rs b/tests/ui/impl-trait/issues/issue-86642.rs new file mode 100644 index 000000000..e6e957714 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-86642.rs @@ -0,0 +1,8 @@ +static x: impl Fn(&str) -> Result<&str, ()> = move |source| { + //~^ `impl Trait` only allowed in function and inherent method return types + let res = (move |source| Ok(source))(source); + let res = res.or((move |source| Ok(source))(source)); + res +}; + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-86642.stderr b/tests/ui/impl-trait/issues/issue-86642.stderr new file mode 100644 index 000000000..0ec118d5b --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-86642.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in type + --> $DIR/issue-86642.rs:1:11 + | +LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-86719.rs b/tests/ui/impl-trait/issues/issue-86719.rs new file mode 100644 index 000000000..f4b0b3f33 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-86719.rs @@ -0,0 +1,12 @@ +#![feature(type_alias_impl_trait)] + +trait Bar { + type E; +} +impl<S> 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/tests/ui/impl-trait/issues/issue-86719.stderr b/tests/ui/impl-trait/issues/issue-86719.stderr new file mode 100644 index 000000000..7592418fd --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-86719.stderr @@ -0,0 +1,29 @@ +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 + | ^ + | +help: consider giving this closure parameter an explicit type + | +LL | |_: /* Type */| true + | ++++++++++++ + +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/tests/ui/impl-trait/issues/issue-86800.rs b/tests/ui/impl-trait/issues/issue-86800.rs new file mode 100644 index 000000000..351243c67 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-86800.rs @@ -0,0 +1,55 @@ +#![feature(type_alias_impl_trait)] + +// edition:2021 +// unset-rustc-env:RUST_BACKTRACE +// compile-flags:-Z treat-err-as-bug=1 +// error-pattern:stack backtrace: +// failure-status:101 +// normalize-stderr-test "note: .*" -> "" +// normalize-stderr-test "thread 'rustc' .*" -> "" +// normalize-stderr-test " +[0-9]+:.*\n" -> "" +// normalize-stderr-test " +at .*\n" -> "" + +use std::future::Future; + +struct Connection { +} + +trait Transaction { +} + +struct TestTransaction<'conn> { + conn: &'conn Connection +} + +impl<'conn> Transaction for TestTransaction<'conn> { +} + +struct Context { +} + +type TransactionResult<O> = Result<O, ()>; + +type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; + +fn execute_transaction_fut<'f, F, O>( + f: F, +) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> +where + F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f +{ + f +} + +impl Context { + async fn do_transaction<O>( + &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + ) -> TransactionResult<O> + { + let mut conn = Connection {}; + let mut transaction = TestTransaction { conn: &mut conn }; + f(&mut transaction).await + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-86800.stderr b/tests/ui/impl-trait/issues/issue-86800.stderr new file mode 100644 index 000000000..6c4aa3567 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-86800.stderr @@ -0,0 +1,26 @@ +error: unconstrained opaque type + --> $DIR/issue-86800.rs:33:34 + | +LL | type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O>>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = + + +stack backtrace: + +error: internal compiler error: unexpected panic + + + + + + + + + +query stack during panic: +#0 [type_of] computing type of `TransactionFuture::{opaque#0}` +#1 [check_mod_item_types] checking item types in top-level module +#2 [analysis] running analysis passes on this crate +end of query stack diff --git a/tests/ui/impl-trait/issues/issue-87295.rs b/tests/ui/impl-trait/issues/issue-87295.rs new file mode 100644 index 000000000..aeb8f8332 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-87295.rs @@ -0,0 +1,18 @@ +trait Trait { + type Output; +} +impl Trait for () { + type Output = i32; +} + +struct Struct<F>(F); +impl<F> Struct<F> { + pub fn new(_: F) -> Self { + todo!() + } +} + +fn main() { + let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(()); + //~^ `impl Trait` only allowed in function and inherent method return types +} diff --git a/tests/ui/impl-trait/issues/issue-87295.stderr b/tests/ui/impl-trait/issues/issue-87295.stderr new file mode 100644 index 000000000..0b043056b --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-87295.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding + --> $DIR/issue-87295.rs:16:31 + | +LL | let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/tests/ui/impl-trait/issues/issue-87340.rs b/tests/ui/impl-trait/issues/issue-87340.rs new file mode 100644 index 000000000..f0f6d2bb6 --- /dev/null +++ b/tests/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<T> 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/tests/ui/impl-trait/issues/issue-87340.stderr b/tests/ui/impl-trait/issues/issue-87340.stderr new file mode 100644 index 000000000..2ab1e6a03 --- /dev/null +++ b/tests/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<T> X for () { + | ^ unconstrained type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0207`. diff --git a/tests/ui/impl-trait/issues/issue-88236-2.rs b/tests/ui/impl-trait/issues/issue-88236-2.rs new file mode 100644 index 000000000..fde8a6704 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-88236-2.rs @@ -0,0 +1,28 @@ +// this used to cause stack overflows + +trait Hrtb<'a> { + type Assoc; +} + +impl<'a> Hrtb<'a> for () { + type Assoc = (); +} + +impl<'a> Hrtb<'a> for &'a () { + type Assoc = (); +} + +fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} +//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + +fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + &() +} + +fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + //~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + x +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-88236-2.stderr b/tests/ui/impl-trait/issues/issue-88236-2.stderr new file mode 100644 index 000000000..8605d07ab --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-88236-2.stderr @@ -0,0 +1,38 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236-2.rs:15:61 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236-2.rs:15:28 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^ + +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236-2.rs:18:80 + | +LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236-2.rs:18:47 + | +LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^ + +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236-2.rs:23:78 + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236-2.rs:23:45 + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/impl-trait/issues/issue-88236.rs b/tests/ui/impl-trait/issues/issue-88236.rs new file mode 100644 index 000000000..36d124173 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-88236.rs @@ -0,0 +1,18 @@ +// this used to cause stack overflows + +trait Hrtb<'a> { + type Assoc; +} + +impl<'a> Hrtb<'a> for () { + type Assoc = (); +} + +impl<'a> Hrtb<'a> for &'a () { + type Assoc = (); +} + +fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} +//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-88236.stderr b/tests/ui/impl-trait/issues/issue-88236.stderr new file mode 100644 index 000000000..7a4cc57b0 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-88236.stderr @@ -0,0 +1,14 @@ +error: higher kinded lifetime bounds on nested opaque types are not supported yet + --> $DIR/issue-88236.rs:15:61 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^ + | +note: lifetime declared here + --> $DIR/issue-88236.rs:15:28 + | +LL | fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} + | ^^ + +error: aborting due to previous error + diff --git a/tests/ui/impl-trait/issues/issue-89312.rs b/tests/ui/impl-trait/issues/issue-89312.rs new file mode 100644 index 000000000..d685a6f12 --- /dev/null +++ b/tests/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<Item = &'a ()>; + +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(|_| ()); +} diff --git a/tests/ui/impl-trait/issues/issue-92305.rs b/tests/ui/impl-trait/issues/issue-92305.rs new file mode 100644 index 000000000..4a89238d0 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-92305.rs @@ -0,0 +1,14 @@ +// edition:2021 + +use std::iter; + +fn f<T>(data: &[T]) -> impl Iterator<Item = Vec> { + //~^ ERROR: missing generics for struct `Vec` [E0107] + iter::empty() +} + +fn g<T>(data: &[T], target: T) -> impl Iterator<Item = Vec<T>> { + f(data).filter(|x| x == target) +} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-92305.stderr b/tests/ui/impl-trait/issues/issue-92305.stderr new file mode 100644 index 000000000..86d7184da --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-92305.stderr @@ -0,0 +1,14 @@ +error[E0107]: missing generics for struct `Vec` + --> $DIR/issue-92305.rs:5:45 + | +LL | fn f<T>(data: &[T]) -> impl Iterator<Item = Vec> { + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | fn f<T>(data: &[T]) -> impl Iterator<Item = Vec<T>> { + | +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/impl-trait/issues/issue-93788.rs b/tests/ui/impl-trait/issues/issue-93788.rs new file mode 100644 index 000000000..6924931cd --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-93788.rs @@ -0,0 +1,27 @@ +// check-pass + +struct D; + +trait Tr { + type It; + fn foo(self) -> Option<Self::It>; +} + +impl<'a> Tr for &'a D { + type It = (); + fn foo(self) -> Option<()> { None } +} + +fn run<F>(f: F) + where for<'a> &'a D: Tr, + F: Fn(<&D as Tr>::It), +{ + let d = &D; + while let Some(i) = d.foo() { + f(i); + } +} + +fn main() { + run(|_| {}); +} diff --git a/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs new file mode 100644 index 000000000..b05579f21 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.rs @@ -0,0 +1,26 @@ +#![feature(type_alias_impl_trait)] + +struct Concrete; + +type Tait = impl Sized; + +impl Foo for Concrete { + type Item = Concrete; + //~^ type mismatch resolving +} + +impl Bar for Concrete { + type Other = Tait; +} + +trait Foo { + type Item: Bar<Other = Self>; +} + +trait Bar { + type Other; +} + +fn tait() -> Tait {} + +fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.stderr b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.stderr new file mode 100644 index 000000000..f0dceb1b1 --- /dev/null +++ b/tests/ui/impl-trait/issues/issue-99348-impl-compatibility.stderr @@ -0,0 +1,25 @@ +error[E0271]: type mismatch resolving `<Concrete as Bar>::Other == Concrete` + --> $DIR/issue-99348-impl-compatibility.rs:8:17 + | +LL | type Tait = impl Sized; + | ---------- the found opaque type +... +LL | type Item = Concrete; + | ^^^^^^^^ type mismatch resolving `<Concrete as Bar>::Other == Concrete` + | +note: expected this to be `Concrete` + --> $DIR/issue-99348-impl-compatibility.rs:13:18 + | +LL | type Other = Tait; + | ^^^^ + = note: expected struct `Concrete` + found opaque type `Tait` +note: required by a bound in `Foo::Item` + --> $DIR/issue-99348-impl-compatibility.rs:17:20 + | +LL | type Item: Bar<Other = Self>; + | ^^^^^^^^^^^^ required by this bound in `Foo::Item` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. |