diff options
| author | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-02-14 16:10:22 +0000 |
|---|---|---|
| committer | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2022-03-28 16:27:14 +0000 |
| commit | 264cd05b16198c2838ec6cd585bd122491e3f7a9 (patch) | |
| tree | 133ca794d093e515a783cd92db831ff51e197820 /src/test/ui/impl-trait | |
| parent | 0e4524e5b4a9c5656fef69f532f96eb9959a1803 (diff) | |
| download | rust-264cd05b16198c2838ec6cd585bd122491e3f7a9.tar.gz rust-264cd05b16198c2838ec6cd585bd122491e3f7a9.zip | |
Revert "Auto merge of #93893 - oli-obk:sad_revert, r=oli-obk"
This reverts commit 6499c5e7fc173a3f55b7a3bd1e6a50e9edef782d, reversing changes made to 78450d2d602b06d9b94349aaf8cece1a4acaf3a8.
Diffstat (limited to 'src/test/ui/impl-trait')
76 files changed, 848 insertions, 504 deletions
diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index c2fbbf94fd6..d2452abab02 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -11,6 +11,7 @@ fn main() { // return type, which can't depend on the obligation. fn cycle1() -> impl Clone { //~^ ERROR cycle detected + //~| ERROR cycle detected send(cycle2().clone()); Rc::new(Cell::new(5)) diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 634ff14869e..14db864f1c2 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -30,47 +30,129 @@ note: ...which requires building MIR for `cycle1`... LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle1`... - --> $DIR/auto-trait-leak.rs:14:5 + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires computing type of `cycle2::{opaque#0}`... + --> $DIR/auto-trait-leak.rs:20:16 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^ +note: ...which requires borrow-checking `cycle2`... + --> $DIR/auto-trait-leak.rs:20:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing `cycle2`... + --> $DIR/auto-trait-leak.rs:20:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing MIR for `cycle2`... + --> $DIR/auto-trait-leak.rs:20:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires unsafety-checking `cycle2`... + --> $DIR/auto-trait-leak.rs:20:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building MIR for `cycle2`... + --> $DIR/auto-trait-leak.rs:20:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires type-checking `cycle2`... + --> $DIR/auto-trait-leak.rs:20:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle +note: cycle used when checking item types in top-level module + --> $DIR/auto-trait-leak.rs:1:1 + | +LL | / use std::cell::Cell; +LL | | use std::rc::Rc; +LL | | +LL | | fn send<T: Send>(_: T) {} +... | +LL | | Rc::new(String::from("foo")) +LL | | } + | |_^ + +error[E0391]: cycle detected when computing type of `cycle1::{opaque#0}` + --> $DIR/auto-trait-leak.rs:12:16 | -LL | send(cycle2().clone()); - | ^^^^ - = note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`... +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^ + | +note: ...which requires borrow-checking `cycle1`... + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing `cycle1`... + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires processing MIR for `cycle1`... + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires unsafety-checking `cycle1`... + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building MIR for `cycle1`... + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires type-checking `cycle1`... + --> $DIR/auto-trait-leak.rs:12:1 + | +LL | fn cycle1() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires computing type of `cycle2::{opaque#0}`... - --> $DIR/auto-trait-leak.rs:19:16 + --> $DIR/auto-trait-leak.rs:20:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:19:1 + --> $DIR/auto-trait-leak.rs:20:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:5 + --> $DIR/auto-trait-leak.rs:20:1 | -LL | send(cycle1().clone()); - | ^^^^ - = note: ...which requires evaluating trait selection obligation `impl core::clone::Clone: core::marker::Send`... +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which again requires computing type of `cycle1::{opaque#0}`, completing the cycle note: cycle used when checking item types in top-level module --> $DIR/auto-trait-leak.rs:1:1 @@ -84,6 +166,6 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/impl-trait/auto-trait.rs b/src/test/ui/impl-trait/auto-trait.rs index cf2773f4ef5..35994e4a5ba 100644 --- a/src/test/ui/impl-trait/auto-trait.rs +++ b/src/test/ui/impl-trait/auto-trait.rs @@ -19,7 +19,7 @@ impl<T: Send> AnotherTrait for T {} // (We treat opaque types as "foreign types" that could grow more impls // in the future.) impl AnotherTrait for D<OpaqueType> { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<impl OpaqueTrait>` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>` } fn main() {} diff --git a/src/test/ui/impl-trait/auto-trait.stderr b/src/test/ui/impl-trait/auto-trait.stderr index 26cd8fb6a9b..81009413c9a 100644 --- a/src/test/ui/impl-trait/auto-trait.stderr +++ b/src/test/ui/impl-trait/auto-trait.stderr @@ -1,11 +1,11 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<impl OpaqueTrait>` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>` --> $DIR/auto-trait.rs:21:1 | LL | impl<T: Send> AnotherTrait for T {} | -------------------------------- first implementation here ... LL | impl AnotherTrait for D<OpaqueType> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<impl OpaqueTrait>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>` error: aborting due to previous error diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index 8ec06e534d1..20ddad0547e 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -23,8 +23,8 @@ mod impl_trait { /// `T::Assoc` can't be normalized any further here. fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> { - //~^ ERROR: type mismatch Foo(()) + //~^ ERROR: type mismatch } } @@ -39,9 +39,9 @@ mod lifetimes { /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further. fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { - //~^ ERROR: type mismatch - //~^^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope + //~^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope Foo(()) + //~^ ERROR: type mismatch } } diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index afa21c1a858..01fb853e1d1 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -1,16 +1,16 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` - --> $DIR/bound-normalization-fail.rs:25:32 + --> $DIR/bound-normalization-fail.rs:26:9 | -LL | fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` +LL | Foo(()) + | ^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` | -note: expected this to be `<T as impl_trait::Trait>::Assoc` +note: expected this to be `()` --> $DIR/bound-normalization-fail.rs:14:19 | LL | type Output = T; | ^ - = note: expected associated type `<T as impl_trait::Trait>::Assoc` - found unit type `()` + = note: expected unit type `()` + found associated type `<T as impl_trait::Trait>::Assoc` help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()` | LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { @@ -23,18 +23,18 @@ LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` - --> $DIR/bound-normalization-fail.rs:41:41 + --> $DIR/bound-normalization-fail.rs:43:9 | -LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` +LL | Foo(()) + | ^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` | -note: expected this to be `<T as lifetimes::Trait<'static>>::Assoc` +note: expected this to be `()` --> $DIR/bound-normalization-fail.rs:14:19 | LL | type Output = T; | ^ - = note: expected associated type `<T as lifetimes::Trait<'static>>::Assoc` - found unit type `()` + = note: expected unit type `()` + found associated type `<T as lifetimes::Trait<'static>>::Assoc` help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()` | LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { diff --git a/src/test/ui/impl-trait/does-not-live-long-enough.stderr b/src/test/ui/impl-trait/does-not-live-long-enough.stderr index f4bd0fde3b6..750687e2322 100644 --- a/src/test/ui/impl-trait/does-not-live-long-enough.stderr +++ b/src/test/ui/impl-trait/does-not-live-long-enough.stderr @@ -7,10 +7,10 @@ LL | self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref | may outlive borrowed value `prefix` | note: closure is returned here - --> $DIR/does-not-live-long-enough.rs:5:55 + --> $DIR/does-not-live-long-enough.rs:6:9 | -LL | fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator<Item=&'a str> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | self.data.iter().filter(|s| s.starts_with(prefix)).map(|s| s.as_ref()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: to force the closure to take ownership of `prefix` (and any other referenced variables), use the `move` keyword | LL | self.data.iter().filter(move |s| s.starts_with(prefix)).map(|s| s.as_ref()) diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 536a4726c6d..185a3f53f65 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,19 +12,13 @@ error[E0308]: mismatched types --> $DIR/equality.rs:15:5 | LL | fn two(x: bool) -> impl Foo { - | -------- expected because this return type... -LL | if x { -LL | return 1_i32; - | ----- ...is found to be `i32` here -LL | } + | -------- the expected opaque type +... LL | 0_u32 | ^^^^^ expected `i32`, found `u32` | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = help: if the trait `Foo` were object safe, you could return a boxed trait object - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type + = note: expected opaque type `impl Foo` + found type `u32` error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index 46053c6e7c1..fd33fa7c674 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -15,9 +15,7 @@ LL | fn hide<T: Foo>(x: T) -> impl Foo { | -------- the found opaque type ... LL | let _: u32 = hide(0_u32); - | --- ^^^^^^^^^^^ expected `u32`, found opaque type - | | - | expected due to this + | ^^^^^^^^^^^ expected `u32`, found opaque type | = note: expected type `u32` found opaque type `impl Foo` diff --git a/src/test/ui/impl-trait/fallback.rs b/src/test/ui/impl-trait/fallback.rs new file mode 100644 index 00000000000..1e6eb5bb355 --- /dev/null +++ b/src/test/ui/impl-trait/fallback.rs @@ -0,0 +1,9 @@ +// check-pass + +fn take_edge_counters( + x: &mut Option<Vec<i32>>, +) -> Option<impl Iterator<Item = i32>> { + x.take().map_or(None, |m| Some(m.into_iter())) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/hidden-lifetimes.rs b/src/test/ui/impl-trait/hidden-lifetimes.rs index 2ee004a37a6..ae07c892768 100644 --- a/src/test/ui/impl-trait/hidden-lifetimes.rs +++ b/src/test/ui/impl-trait/hidden-lifetimes.rs @@ -26,8 +26,8 @@ impl<T> Swap for Rc<RefCell<T>> { // Here we are hiding `'b` making the caller believe that `&'a mut &'s T` and // `&'a mut &'l T` are the same type. fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { - //~^ ERROR hidden type x + //~^ ERROR hidden type } fn dangle_ref() -> &'static [i32; 3] { @@ -43,8 +43,8 @@ fn dangle_ref() -> &'static [i32; 3] { // This is different to the previous example because the concrete return type // only has a single lifetime. fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a { - //~^ ERROR hidden type x + //~^ ERROR hidden type } fn dangle_rc_refcell() -> &'static [i32; 3] { diff --git a/src/test/ui/impl-trait/hidden-lifetimes.stderr b/src/test/ui/impl-trait/hidden-lifetimes.stderr index c6d11293eec..97652f5462e 100644 --- a/src/test/ui/impl-trait/hidden-lifetimes.stderr +++ b/src/test/ui/impl-trait/hidden-lifetimes.stderr @@ -1,10 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/hidden-lifetimes.rs:28:54 + --> $DIR/hidden-lifetimes.rs:29:5 | LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a { - | -- ^^^^^^^^^^^^^^ - | | - | hidden type `&'a mut &'b T` captures the lifetime `'b` as defined here + | -- hidden type `&'a mut &'b T` captures the lifetime `'b` as defined here +LL | x + | ^ | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | @@ -12,12 +12,12 @@ LL | fn hide_ref<'a, 'b, T: 'static>(x: &'a mut &'b T) -> impl Swap + 'a + 'b { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/hidden-lifetimes.rs:45:70 + --> $DIR/hidden-lifetimes.rs:46:5 | LL | fn hide_rc_refcell<'a, 'b: 'a, T: 'static>(x: Rc<RefCell<&'b T>>) -> impl Swap + 'a { - | -- ^^^^^^^^^^^^^^ - | | - | hidden type `Rc<RefCell<&'b T>>` captures the lifetime `'b` as defined here + | -- hidden type `Rc<RefCell<&'b T>>` captures the lifetime `'b` as defined here +LL | x + | ^ | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/impl-trait/hidden-type-is-opaque-2.rs b/src/test/ui/impl-trait/hidden-type-is-opaque-2.rs new file mode 100644 index 00000000000..1b65685a6c0 --- /dev/null +++ b/src/test/ui/impl-trait/hidden-type-is-opaque-2.rs @@ -0,0 +1,34 @@ +// This doesn't work, because we don't flow information from opaque types +// into function arguments via the function's generic parameters +// FIXME(oli-obk): make `expected_inputs_for_expected_output` support this + +fn reify_as() -> Thunk<impl FnOnce(Continuation) -> Continuation> { + Thunk::new(|mut cont| { //~ ERROR type annotations needed + cont.reify_as(); + cont + }) +} + +#[must_use] +struct Thunk<F>(F); + +impl<F> Thunk<F> { + fn new(f: F) -> Self + where + F: ContFn, + { + Thunk(f) + } +} + +trait ContFn {} + +impl<F: FnOnce(Continuation) -> Continuation> ContFn for F {} + +struct Continuation; + +impl Continuation { + fn reify_as(&mut self) {} +} + +fn main() {} diff --git a/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr b/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr new file mode 100644 index 00000000000..e538aaeb4c5 --- /dev/null +++ b/src/test/ui/impl-trait/hidden-type-is-opaque-2.stderr @@ -0,0 +1,11 @@ +error[E0282]: type annotations needed + --> $DIR/hidden-type-is-opaque-2.rs:6:17 + | +LL | Thunk::new(|mut cont| { + | ^^^^^^^^ consider giving this closure parameter a type + | + = note: type must be known at this point + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/hidden-type-is-opaque.rs b/src/test/ui/impl-trait/hidden-type-is-opaque.rs new file mode 100644 index 00000000000..b302ae36ef4 --- /dev/null +++ b/src/test/ui/impl-trait/hidden-type-is-opaque.rs @@ -0,0 +1,32 @@ +// check-pass + +fn reify_as() -> Thunk<impl ContFn> { + Thunk::new(|mut cont| { + cont.reify_as(); + cont + }) +} + +#[must_use] +struct Thunk<F>(F); + +impl<F> Thunk<F> { + fn new(f: F) -> Self + where + F: FnOnce(Continuation) -> Continuation, + { + Thunk(f) + } +} + +trait ContFn {} + +impl<F: FnOnce(Continuation) -> Continuation> ContFn for F {} + +struct Continuation; + +impl Continuation { + fn reify_as(&mut self) {} +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-1.rs b/src/test/ui/impl-trait/issue-55872-1.rs index 46188636475..a75b9b43b3e 100644 --- a/src/test/ui/impl-trait/issue-55872-1.rs +++ b/src/test/ui/impl-trait/issue-55872-1.rs @@ -10,11 +10,10 @@ impl<S: Default> Bar for S { type E = impl Copy; fn foo<T: Default>() -> Self::E { - //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - //~| ERROR impl has stricter requirements than trait - //~| ERROR the trait bound `S: Copy` is not satisfied in `(S, T)` [E0277] - //~| ERROR the trait bound `T: Copy` is not satisfied in `(S, T)` [E0277] + //~^ ERROR impl has stricter requirements than trait (S::default(), T::default()) + //~^ ERROR the trait bound `S: Copy` is not satisfied in `(S, T)` [E0277] + //~| ERROR the trait bound `T: Copy` is not satisfied in `(S, T)` [E0277] } } diff --git a/src/test/ui/impl-trait/issue-55872-1.stderr b/src/test/ui/impl-trait/issue-55872-1.stderr index 2d1142fd0c5..efc57da7461 100644 --- a/src/test/ui/impl-trait/issue-55872-1.stderr +++ b/src/test/ui/impl-trait/issue-55872-1.stderr @@ -8,10 +8,10 @@ LL | fn foo<T: Default>() -> Self::E { | ^^^^^^^ impl has extra requirement `T: Default` error[E0277]: the trait bound `S: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:12:29 + --> $DIR/issue-55872-1.rs:14:9 | -LL | fn foo<T: Default>() -> Self::E { - | ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S` +LL | (S::default(), T::default()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `S` | = note: required because it appears within the type `(S, T)` help: consider further restricting this bound @@ -20,10 +20,10 @@ LL | impl<S: Default + std::marker::Copy> Bar for S { | +++++++++++++++++++ error[E0277]: the trait bound `T: Copy` is not satisfied in `(S, T)` - --> $DIR/issue-55872-1.rs:12:29 + --> $DIR/issue-55872-1.rs:14:9 | -LL | fn foo<T: Default>() -> Self::E { - | ^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T` +LL | (S::default(), T::default()) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `(S, T)`, the trait `Copy` is not implemented for `T` | = note: required because it appears within the type `(S, T)` help: consider further restricting this bound @@ -31,20 +31,7 @@ help: consider further restricting this bound LL | fn foo<T: Default + std::marker::Copy>() -> Self::E { | +++++++++++++++++++ -error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-1.rs:12:37 - | -LL | fn foo<T: Default>() -> Self::E { - | _____________________________________^ -LL | | -LL | | -LL | | -LL | | -LL | | (S::default(), T::default()) -LL | | } - | |_____^ - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0276, E0277. For more information about an error, try `rustc --explain E0276`. diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs index 1841d7b3d37..4443d3c4d0d 100644 --- a/src/test/ui/impl-trait/issue-55872-2.rs +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -3,17 +3,16 @@ #![feature(type_alias_impl_trait)] pub trait Bar { - type E: Copy; + type E: Send; fn foo<T>() -> Self::E; } impl<S> Bar for S { - type E = impl std::marker::Copy; + type E = impl std::marker::Send; fn foo<T>() -> Self::E { - //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - //~| ERROR the trait bound `impl Future: Copy` is not satisfied async {} + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias } } diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr index 76122e60c4c..11b8485c8bb 100644 --- a/src/test/ui/impl-trait/issue-55872-2.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -1,20 +1,8 @@ -error[E0277]: the trait bound `impl Future: Copy` is not satisfied - --> $DIR/issue-55872-2.rs:13:20 - | -LL | fn foo<T>() -> Self::E { - | ^^^^^^^ the trait `Copy` is not implemented for `impl Future` - error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:13:28 + --> $DIR/issue-55872-2.rs:14:9 | -LL | fn foo<T>() -> Self::E { - | ____________________________^ -LL | | -LL | | -LL | | async {} -LL | | } - | |_____^ +LL | async {} + | ^^^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872-3.rs b/src/test/ui/impl-trait/issue-55872-3.rs new file mode 100644 index 00000000000..bc2d0b1d757 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-3.rs @@ -0,0 +1,20 @@ +// edition:2018 +// ignore-compare-mode-chalk + +#![feature(type_alias_impl_trait)] + +pub trait Bar { + type E: Copy; + + fn foo<T>() -> Self::E; +} + +impl<S> Bar for S { + type E = impl std::marker::Copy; + fn foo<T>() -> Self::E { + async {} + //~^ ERROR the trait bound `impl Future: Copy` is not satisfied [E0277] + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-55872-3.stderr b/src/test/ui/impl-trait/issue-55872-3.stderr new file mode 100644 index 00000000000..69a5c8d6135 --- /dev/null +++ b/src/test/ui/impl-trait/issue-55872-3.stderr @@ -0,0 +1,9 @@ +error[E0277]: the trait bound `impl Future: Copy` is not satisfied + --> $DIR/issue-55872-3.rs:15:9 + | +LL | async {} + | ^^^^^^^^ the trait `Copy` is not implemented for `impl Future` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-55872.rs b/src/test/ui/impl-trait/issue-55872.rs index 183728b0f7f..c4e6f643608 100644 --- a/src/test/ui/impl-trait/issue-55872.rs +++ b/src/test/ui/impl-trait/issue-55872.rs @@ -10,8 +10,8 @@ impl<S> Bar for S { type E = impl Copy; fn foo<T>() -> Self::E { - //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias || () + //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias } } diff --git a/src/test/ui/impl-trait/issue-55872.stderr b/src/test/ui/impl-trait/issue-55872.stderr index 39d870dc003..cb370fbe1c4 100644 --- a/src/test/ui/impl-trait/issue-55872.stderr +++ b/src/test/ui/impl-trait/issue-55872.stderr @@ -1,12 +1,8 @@ error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872.rs:12:28 + --> $DIR/issue-55872.rs:13:9 | -LL | fn foo<T>() -> Self::E { - | ____________________________^ -LL | | -LL | | || () -LL | | } - | |_____^ +LL | || () + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/issue-72911.rs b/src/test/ui/impl-trait/issue-72911.rs index dee5a41f6de..cf2c8b7e415 100644 --- a/src/test/ui/impl-trait/issue-72911.rs +++ b/src/test/ui/impl-trait/issue-72911.rs @@ -5,7 +5,7 @@ pub struct Lint {} impl Lint {} pub fn gather_all() -> impl Iterator<Item = Lint> { - //~^ ERROR: cannot resolve opaque type + //~^ ERROR `()` is not an iterator lint_files().flat_map(|f| gather_from_file(&f)) } diff --git a/src/test/ui/impl-trait/issue-72911.stderr b/src/test/ui/impl-trait/issue-72911.stderr index e57fbf104dc..4a990286d96 100644 --- a/src/test/ui/impl-trait/issue-72911.stderr +++ b/src/test/ui/impl-trait/issue-72911.stderr @@ -10,25 +10,15 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo` LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> { | ^^^ use of undeclared crate or module `foo` -error[E0720]: cannot resolve opaque type +error[E0277]: `()` is not an iterator --> $DIR/issue-72911.rs:7:24 | LL | pub fn gather_all() -> impl Iterator<Item = Lint> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type -LL | -LL | lint_files().flat_map(|f| gather_from_file(&f)) - | ----------------------------------------------- - | | - | returning here with type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` - | returning here with type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` -... -LL | fn gather_from_file(dir_entry: &foo::MissingItem) -> impl Iterator<Item = Lint> { - | -------------------------- returning this opaque type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` -... -LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> { - | -------------------------------------- returning this opaque type `FlatMap<impl Iterator<Item = [type error]>, [type error], [closure@$DIR/issue-72911.rs:9:27: 9:51]>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator + | + = help: the trait `Iterator` is not implemented for `()` error: aborting due to 3 previous errors -Some errors have detailed explanations: E0433, E0720. -For more information about an error, try `rustc --explain E0433`. +Some errors have detailed explanations: E0277, E0433. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issues/issue-70877.rs b/src/test/ui/impl-trait/issues/issue-70877.rs index 853c2a82bed..1a86fa00ed1 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.rs +++ b/src/test/ui/impl-trait/issues/issue-70877.rs @@ -4,7 +4,7 @@ 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>; //~ ERROR: type mismatch +type Foo = impl Iterator<Item = FooItem>; #[repr(C)] struct Bar(u8); @@ -13,7 +13,7 @@ impl Iterator for Bar { type Item = FooItem; fn next(&mut self) -> Option<Self::Item> { - Some(Box::new(quux)) + Some(Box::new(quux)) //~ ERROR mismatched types } } @@ -28,7 +28,7 @@ fn ham() -> Foo { fn oof() -> impl std::fmt::Debug { let mut bar = ham(); let func = bar.next().unwrap(); - return func(&"oof"); + return func(&"oof"); //~ ERROR opaque type's hidden type cannot be another opaque type } fn main() { diff --git a/src/test/ui/impl-trait/issues/issue-70877.stderr b/src/test/ui/impl-trait/issues/issue-70877.stderr index fe48e92da5e..7cbd58bdabf 100644 --- a/src/test/ui/impl-trait/issues/issue-70877.stderr +++ b/src/test/ui/impl-trait/issues/issue-70877.stderr @@ -1,20 +1,34 @@ -error[E0271]: type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>` - --> $DIR/issue-70877.rs:7:12 +error[E0308]: mismatched types + --> $DIR/issue-70877.rs:16:9 | LL | type FooRet = impl std::fmt::Debug; - | -------------------- the found opaque type + | -------------------- the expected opaque type ... -LL | type Foo = impl Iterator<Item = FooItem>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Bar as Iterator>::Item == Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>` +LL | fn next(&mut self) -> Option<Self::Item> { + | ------------------ expected `Option<Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> FooRet + 'static)>>` because of return type +LL | Some(Box::new(quux)) + | ^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn Fn`, found fn item | -note: expected this to be `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>` - --> $DIR/issue-70877.rs:13:17 + = note: expected enum `Option<Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> FooRet + 'static)>>` + found enum `Option<Box<for<'r> fn(&'r (dyn ToString + 'r)) -> FooRet {quux}>>` + +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 | type Item = FooItem; - | ^^^^^^^ - = note: expected struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> Option<String> + 'static)>` - found struct `Box<(dyn for<'r> Fn(&'r (dyn ToString + 'r)) -> impl Debug + 'static)>` +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 +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0271`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/issues/issue-78722.rs b/src/test/ui/impl-trait/issues/issue-78722.rs index bdbd20f9d2b..5498793bc28 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.rs +++ b/src/test/ui/impl-trait/issues/issue-78722.rs @@ -7,10 +7,11 @@ type F = impl core::future::Future<Output = u8>; struct Bug { V1: [(); { fn concrete_use() -> F { - async {} + async {} //~ ERROR type mismatch } let f: F = async { 1 }; - //~^ ERROR mismatched types [E0308] + //~^ ERROR `async` blocks are not allowed in constants + //~| ERROR destructors cannot be evaluated at compile-time 1 }], } diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr index 86bde9a0cdd..624d85570c7 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.stderr +++ b/src/test/ui/impl-trait/issues/issue-78722.stderr @@ -1,23 +1,28 @@ -error[E0308]: mismatched types +error[E0658]: `async` blocks are not allowed in constants --> $DIR/issue-78722.rs:12:20 | -LL | type F = impl core::future::Future<Output = u8>; - | -------------------------------------- the expected opaque type -... LL | let f: F = async { 1 }; - | - ^^^^^^^^^^^ expected opaque type, found a different opaque type - | | - | expected due to this + | ^^^^^^^^^^^ | - ::: $SRC_DIR/core/src/future/mod.rs:LL:COL + = 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]: destructors cannot be evaluated at compile-time + --> $DIR/issue-78722.rs:12:13 | -LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return> - | ------------------------------- the found opaque type +LL | let f: F = async { 1 }; + | ^ constants cannot evaluate destructors +... +LL | }], + | - value is dropped here + +error[E0271]: type mismatch resolving `<impl Future as Future>::Output == u8` + --> $DIR/issue-78722.rs:10:13 | - = note: expected opaque type `impl Future<Output = u8>` - found opaque type `impl Future` - = note: distinct uses of `impl Trait` result in different opaque types +LL | async {} + | ^^^^^^^^ expected `()`, found `u8` -error: aborting due to previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0308`. +Some errors have detailed explanations: E0271, E0493, E0658. +For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/impl-trait/issues/issue-86201.rs b/src/test/ui/impl-trait/issues/issue-86201.rs index e3386d29def..0786e66ca8b 100644 --- a/src/test/ui/impl-trait/issues/issue-86201.rs +++ b/src/test/ui/impl-trait/issues/issue-86201.rs @@ -1,10 +1,10 @@ #![feature(unboxed_closures)] #![feature(type_alias_impl_trait)] +// check-pass + type FunType = impl Fn<()>; -//~^ ERROR could not find defining uses static STATIC_FN: FunType = some_fn; -//~^ ERROR mismatched types fn some_fn() {} diff --git a/src/test/ui/impl-trait/issues/issue-86201.stderr b/src/test/ui/impl-trait/issues/issue-86201.stderr deleted file mode 100644 index b1460096ded..00000000000 --- a/src/test/ui/impl-trait/issues/issue-86201.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-86201.rs:6:29 - | -LL | type FunType = impl Fn<()>; - | ----------- the expected opaque type -LL | -LL | static STATIC_FN: FunType = some_fn; - | ^^^^^^^ expected opaque type, found fn item - | - = note: expected opaque type `impl Fn<()>` - found fn item `fn() {some_fn}` - -error: could not find defining uses - --> $DIR/issue-86201.rs:4:16 - | -LL | type FunType = impl Fn<()>; - | ^^^^^^^^^^^ - -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-88236-2.nll.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr new file mode 100644 index 00000000000..9cf8ff76c87 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr @@ -0,0 +1,51 @@ +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:17:5 + | +LL | &() + | ^^^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:17:5 + | +LL | &() + | ^^^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: lifetime may not live long enough + --> $DIR/issue-88236-2.rs:20:5 + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | -- lifetime `'b` defined here +LL | x + | ^ returning this value requires that `'b` must outlive `'static` + | +help: to allow this `impl Trait` to capture borrowed data with lifetime `'b`, add `'b` as a bound + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b { + | ++++ + +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:20:5 + | +LL | x + | ^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:20:5 + | +LL | x + | ^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.rs b/src/test/ui/impl-trait/issues/issue-88236-2.rs new file mode 100644 index 00000000000..f89ab7fbd36 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-88236-2.rs @@ -0,0 +1,23 @@ +// 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> {} +fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + &() //~ ERROR implementation of `Hrtb` is not general enough +} +fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + x //~ ERROR implementation of `Hrtb` is not general enough +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr new file mode 100644 index 00000000000..95c4a528036 --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-88236-2.stderr @@ -0,0 +1,20 @@ +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:17:5 + | +LL | &() + | ^^^ implementation of `Hrtb` is not general enough + | + = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... + = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` + +error: implementation of `Hrtb` is not general enough + --> $DIR/issue-88236-2.rs:20:5 + | +LL | x + | ^ implementation of `Hrtb` is not general enough + | + = note: `&()` must implement `Hrtb<'0>`, for any lifetime `'0`... + = note: ...but `Hrtb<'_>` is actually implemented for the type `&()` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-trait/issues/issue-88236.rs b/src/test/ui/impl-trait/issues/issue-88236.rs new file mode 100644 index 00000000000..2ea35270a7e --- /dev/null +++ b/src/test/ui/impl-trait/issues/issue-88236.rs @@ -0,0 +1,19 @@ +// check-pass + +// 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> {} + +fn main() {} diff --git a/src/test/ui/impl-trait/lifetimes2.rs b/src/test/ui/impl-trait/lifetimes2.rs new file mode 100644 index 00000000000..834f2dc6cb5 --- /dev/null +++ b/src/test/ui/impl-trait/lifetimes2.rs @@ -0,0 +1,10 @@ +// check-pass + +pub fn keys<'a>(x: &'a Result<u32, u32>) -> impl std::fmt::Debug + 'a { + match x { + Ok(map) => Ok(map), + Err(map) => Err(map), + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs index 72e9d96da36..f5aaf118521 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.rs @@ -8,7 +8,6 @@ impl<T: Copy> Copy for CopyIfEq<T, T> {} type E<'a, 'b> = impl Sized; fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds let v = CopyIfEq::<*mut _, *mut _>(&mut { x }, &mut y); // This assignment requires that `x` and `y` have the same type due to the @@ -21,6 +20,7 @@ fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { let _: &'b i32 = *u.0; } u.0 + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds } fn main() {} diff --git a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr index 40bec0da270..b837b641103 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/error-handling-2.stderr @@ -1,10 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/error-handling-2.rs:10:60 + --> $DIR/error-handling-2.rs:22:5 | LL | fn foo<'a: 'b, 'b, 'c>(x: &'static i32, mut y: &'a i32) -> E<'b, 'c> { - | -- ^^^^^^^^^ - | | - | hidden type `*mut &'a i32` captures the lifetime `'a` as defined here + | -- hidden type `*mut &'a i32` captures the lifetime `'a` as defined here +... +LL | u.0 + | ^^^ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs index 3a97624647e..47e05bce0f8 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.rs @@ -14,7 +14,6 @@ struct Ordinary<'a>(&'a u8); // by both `'a` and `'b`. fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> -//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds where 'a: 'e, 'b: 'd, @@ -27,6 +26,7 @@ where // 'a in ['d, 'e] // ``` if condition() { a } else { b } + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds } fn condition() -> bool { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr index 32829a0a1b2..15476c706a7 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unrelated.stderr @@ -1,10 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unrelated.rs:16:74 + --> $DIR/ordinary-bounds-unrelated.rs:28:33 | LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e> - | -- ^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here + | -- hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here +... +LL | if condition() { a } else { b } + | ^ | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs index d4c60a4e892..321cb8c92a1 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.rs @@ -16,7 +16,6 @@ struct Ordinary<'a>(&'a u8); // consider the loans for both `'a` and `'b` alive. fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> -//~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds { // We return a value: // @@ -30,6 +29,7 @@ fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> // // We are forced to pick that '0 = 'e, because only 'e is outlived by *both* 'a and 'b. if condition() { a } else { b } + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds } fn condition() -> bool { diff --git a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr index 83ad23b253b..7315aa8e9d4 100644 --- a/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr +++ b/src/test/ui/impl-trait/multiple-lifetimes/ordinary-bounds-unsuited.stderr @@ -1,10 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ordinary-bounds-unsuited.rs:18:62 + --> $DIR/ordinary-bounds-unsuited.rs:31:33 | LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b> - | -- ^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here + | -- hidden type `Ordinary<'b>` captures the lifetime `'b` as defined here +... +LL | if condition() { a } else { b } + | ^ | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 2f6bd8ff377..eb38f84d4af 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -1,8 +1,8 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:3:23 + --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- ^^^^^^^^^ + | ---- ^ | | | hidden type `&i32` captures the anonymous lifetime defined here | @@ -12,10 +12,10 @@ LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:6:32 + --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | -- ^^^^^^^^^ + | -- ^ | | | hidden type `&'a i32` captures the lifetime `'a` as defined here | @@ -67,12 +67,12 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } = help: consider replacing `'a` with `'static` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:33:61 + --> $DIR/must_outlive_least_region_or_bound.rs:34:5 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - | -- ^^^^^^^^^^^^^^^^ - | | - | hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:35:5: 35:31]` captures the lifetime `'b` as defined here + | -- hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:34:5: 34:31]` captures the lifetime `'b` as defined here +LL | move |_| println!("{}", y) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | @@ -80,10 +80,10 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:38:51 + --> $DIR/must_outlive_least_region_or_bound.rs:39:5 | -LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { - | ^^^^^^^^^^^^^^^^^^^^ +LL | x + | ^ | = help: consider adding an explicit lifetime bound `T: 'static`... diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index 69d2843ff3f..02ea0255912 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -31,13 +31,13 @@ fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } //~ ERRO // Tests that a closure type containing 'b cannot be returned from a type where // only 'a was expected. fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - //~^ ERROR: captures lifetime that does not appear in bounds move |_| println!("{}", y) + //~^ ERROR: captures lifetime that does not appear in bounds } fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { - //~^ ERROR the parameter type `T` may not live long enough x + //~^ ERROR the parameter type `T` may not live long enough } fn main() {} diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 07ac0a8db35..77ba0bf9087 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -1,8 +1,8 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:3:23 + --> $DIR/must_outlive_least_region_or_bound.rs:3:35 | LL | fn elided(x: &i32) -> impl Copy { x } - | ---- ^^^^^^^^^ + | ---- ^ | | | hidden type `&i32` captures the anonymous lifetime defined here | @@ -12,10 +12,10 @@ LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:6:32 + --> $DIR/must_outlive_least_region_or_bound.rs:6:44 | LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } - | -- ^^^^^^^^^ + | -- ^ | | | hidden type `&'a i32` captures the lifetime `'a` as defined here | @@ -28,15 +28,10 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } - | ---- ^ ...is used here... + | ---- ^ ...is used and required to live as long as `'static` here | | | this data with an anonymous lifetime `'_`... | -note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:9:24 - | -LL | fn elided2(x: &i32) -> impl Copy + 'static { x } - | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn elided2(x: &i32) -> impl Copy + '_ { x } @@ -50,15 +45,10 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:11:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } - | ------- ^ ...is used here... + | ------- ^ ...is used and required to live as long as `'static` here | | | this data with lifetime `'a`... | -note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:11:33 - | -LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } - | ^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } @@ -69,10 +59,10 @@ LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } | ~~~~~~~~~~~~ error[E0621]: explicit lifetime required in the type of `x` - --> $DIR/must_outlive_least_region_or_bound.rs:13:24 + --> $DIR/must_outlive_least_region_or_bound.rs:13:41 | LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x } - | ---- ^^^^^^^^^^^^^^ lifetime `'a` required + | ---- ^ lifetime `'a` required | | | help: add explicit lifetime `'a` to the type of `x`: `&'a i32` @@ -95,13 +85,8 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:29:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } - | ------- this data with lifetime `'a`... ^ ...is used here... - | -note: ...and is required to live as long as `'static` here - --> $DIR/must_outlive_least_region_or_bound.rs:29:34 + | ------- this data with lifetime `'a`... ^ ...is used and required to live as long as `'static` here | -LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } @@ -112,12 +97,12 @@ LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x | ~~~~~~~~~~~~ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/must_outlive_least_region_or_bound.rs:33:61 + --> $DIR/must_outlive_least_region_or_bound.rs:34:5 | LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { - | -- ^^^^^^^^^^^^^^^^ - | | - | hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:35:5: 35:31]` captures the lifetime `'b` as defined here + | -- hidden type `[closure@$DIR/must_outlive_least_region_or_bound.rs:34:5: 34:31]` captures the lifetime `'b` as defined here +LL | move |_| println!("{}", y) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: to declare that the `impl Trait` captures `'b`, you can add an explicit `'b` lifetime bound | @@ -125,12 +110,12 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:38:51 + --> $DIR/must_outlive_least_region_or_bound.rs:39:5 | LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { - | -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `T: 'static +` + | -- help: consider adding an explicit lifetime bound...: `T: 'static +` +LL | x + | ^ ...so that the type `T` will meet its required lifetime bounds error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/must_outlive_least_region_or_bound.rs:16:50 diff --git a/src/test/ui/impl-trait/negative-reasoning.rs b/src/test/ui/impl-trait/negative-reasoning.rs index d173fe83fb7..70e24a3a9d0 100644 --- a/src/test/ui/impl-trait/negative-reasoning.rs +++ b/src/test/ui/impl-trait/negative-reasoning.rs @@ -17,7 +17,7 @@ impl<T: std::fmt::Debug> AnotherTrait for T {} // This is in error, because we cannot assume that `OpaqueType: !Debug` impl AnotherTrait for D<OpaqueType> { - //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<impl OpaqueTrait>` + //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>` } fn main() {} diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr index e39a8e53f79..6b8cc9e7374 100644 --- a/src/test/ui/impl-trait/negative-reasoning.stderr +++ b/src/test/ui/impl-trait/negative-reasoning.stderr @@ -1,13 +1,13 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<impl OpaqueTrait>` +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>` --> $DIR/negative-reasoning.rs:19:1 | LL | impl<T: std::fmt::Debug> AnotherTrait for T {} | ------------------------------------------- first implementation here ... LL | impl AnotherTrait for D<OpaqueType> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<impl OpaqueTrait>` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>` | - = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `impl OpaqueTrait` in future versions + = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions error: aborting due to previous error diff --git a/src/test/ui/impl-trait/nested_impl_trait.rs b/src/test/ui/impl-trait/nested_impl_trait.rs index 06a2191a017..ec2d49d9367 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.rs +++ b/src/test/ui/impl-trait/nested_impl_trait.rs @@ -4,6 +4,7 @@ fn fine(x: impl Into<u32>) -> impl Into<u32> { x } fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } //~^ ERROR nested `impl Trait` is not allowed +//~| ERROR `impl Into<u32>` doesn't implement `Debug` fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} //~^ ERROR nested `impl Trait` is not allowed @@ -16,6 +17,7 @@ struct X; impl X { fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } //~^ ERROR nested `impl Trait` is not allowed + //~| ERROR `impl Into<u32>` doesn't implement `Debug` } fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> { diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr index 4444e6a454f..248d1254ef7 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.stderr +++ b/src/test/ui/impl-trait/nested_impl_trait.stderr @@ -8,7 +8,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:8:42 + --> $DIR/nested_impl_trait.rs:9:42 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} | ----------^^^^^^^^^^- @@ -17,7 +17,7 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:12:37 + --> $DIR/nested_impl_trait.rs:13:37 | LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { } | ----------^^^^^^^^^^- @@ -26,7 +26,7 @@ LL | fn bad_in_arg_position(_: impl Into<impl Debug>) { } | outer `impl Trait` error[E0666]: nested `impl Trait` is not allowed - --> $DIR/nested_impl_trait.rs:17:44 + --> $DIR/nested_impl_trait.rs:18:44 | LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } | ----------^^^^^^^^^^- @@ -35,18 +35,40 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } | outer `impl Trait` error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return - --> $DIR/nested_impl_trait.rs:8:32 + --> $DIR/nested_impl_trait.rs:9:32 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} | ^^^^^^^^^^^^^^^^^^^^^ error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return - --> $DIR/nested_impl_trait.rs:25:42 + --> $DIR/nested_impl_trait.rs:27:42 | LL | fn allowed_in_ret_type() -> impl Fn() -> impl Into<u32> { | ^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error[E0277]: `impl Into<u32>` doesn't implement `Debug` + --> $DIR/nested_impl_trait.rs:5:70 + | +LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } + | ^ `impl Into<u32>` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider further restricting this bound + | +LL | fn bad_in_ret_position(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x } + | +++++++++++++++++ + +error[E0277]: `impl Into<u32>` doesn't implement `Debug` + --> $DIR/nested_impl_trait.rs:18:58 + | +LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } + | ^ `impl Into<u32>` cannot be formatted using `{:?}` because it doesn't implement `Debug` + | +help: consider further restricting this bound + | +LL | fn bad(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x } + | +++++++++++++++++ + +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0562, E0666. -For more information about an error, try `rustc --explain E0562`. +Some errors have detailed explanations: E0277, E0562, E0666. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr index 357166d1123..b2f7166f0ae 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr @@ -2,46 +2,25 @@ error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5 | LL | fn can() -> impl NotObjectSafe { - | ------------------ expected because this return type... -LL | if true { -LL | return A; - | - ...is found to be `A` here -LL | } + | ------------------ the expected opaque type +... LL | B | ^ expected struct `A`, found struct `B` | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = help: if the trait `NotObjectSafe` were object safe, you could return a boxed trait object - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type + = note: expected opaque type `impl NotObjectSafe` + found struct `B` error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5 | LL | fn cat() -> impl ObjectSafe { - | --------------- expected because this return type... -LL | if true { -LL | return A; - | - ...is found to be `A` here -LL | } + | --------------- the expected opaque type +... LL | B | ^ expected struct `A`, found struct `B` | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type -help: you could change the return type to be a boxed trait object - | -LL | fn cat() -> Box<dyn ObjectSafe> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ return Box::new(A); -LL | } -LL ~ Box::new(B) - | + = note: expected opaque type `impl ObjectSafe` + found struct `B` error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs index fa7664a83ee..9f9a6c784e6 100644 --- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs +++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.rs @@ -14,10 +14,10 @@ fn bar() -> impl std::fmt::Display { } fn baz() -> impl std::fmt::Display { - if false { + if false { //~ ERROR mismatched types return 0i32; } else { - 1u32 //~ ERROR mismatched types + 1u32 } } @@ -30,9 +30,9 @@ fn qux() -> impl std::fmt::Display { } fn bat() -> impl std::fmt::Display { - match 13 { + match 13 { //~ ERROR mismatched types 0 => return 0i32, - _ => 1u32, //~ ERROR mismatched types + _ => 1u32, } } @@ -45,12 +45,12 @@ fn can() -> impl std::fmt::Display { } fn cat() -> impl std::fmt::Display { - match 13 { + match 13 { //~ ERROR mismatched types 0 => { return 0i32; } _ => { - 1u32 //~ ERROR mismatched types + 1u32 } } } diff --git a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr index 970abad5c72..db0d446e559 100644 --- a/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/impl-trait/point-to-type-err-cause-on-impl-trait-return.stderr @@ -2,82 +2,40 @@ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:5:5 | LL | fn foo() -> impl std::fmt::Display { - | ---------------------- expected because this return type... -LL | if false { -LL | return 0i32; - | ---- ...is found to be `i32` here -LL | } + | ---------------------- the expected opaque type +... LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type -help: you could change the return type to be a boxed trait object - | -LL | fn foo() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ return Box::new(0i32); -LL | } -LL ~ Box::new(1u32) - | + = note: expected opaque type `impl std::fmt::Display` + found type `u32` error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:12:16 | LL | fn bar() -> impl std::fmt::Display { - | ---------------------- expected because this return type... -LL | if false { -LL | return 0i32; - | ---- ...is found to be `i32` here -LL | } else { + | ---------------------- the expected opaque type +... LL | return 1u32; | ^^^^ expected `i32`, found `u32` | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type -help: you could change the return type to be a boxed trait object - | -LL | fn bar() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ return Box::new(0i32); -LL | } else { -LL ~ return Box::new(1u32); - | + = note: expected opaque type `impl std::fmt::Display` + found type `u32` error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:20:9 - | -LL | fn baz() -> impl std::fmt::Display { - | ---------------------- expected because this return type... -LL | if false { -LL | return 0i32; - | ---- ...is found to be `i32` here -LL | } else { -LL | 1u32 - | ^^^^ expected `i32`, found `u32` - | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type -help: you could change the return type to be a boxed trait object - | -LL | fn baz() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:17:5 | -LL ~ return Box::new(0i32); -LL | } else { -LL ~ Box::new(1u32) +LL | fn baz() -> impl std::fmt::Display { + | ---------------------- the expected opaque type +LL | / if false { +LL | | return 0i32; +LL | | } else { +LL | | 1u32 +LL | | } + | |_____^ expected `i32`, found `u32` | + = note: expected opaque type `impl std::fmt::Display` + found type `u32` error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9 @@ -103,87 +61,50 @@ LL ~ Box::new(1u32) | error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:35:14 - | -LL | fn bat() -> impl std::fmt::Display { - | ---------------------- expected because this return type... -LL | match 13 { -LL | 0 => return 0i32, - | ---- ...is found to be `i32` here -LL | _ => 1u32, - | ^^^^ expected `i32`, found `u32` - | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type -help: you could change the return type to be a boxed trait object - | -LL | fn bat() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:33:5 | -LL ~ 0 => return Box::new(0i32), -LL ~ _ => Box::new(1u32), +LL | fn bat() -> impl std::fmt::Display { + | ---------------------- the expected opaque type +LL | / match 13 { +LL | | 0 => return 0i32, +LL | | _ => 1u32, +LL | | } + | |_____^ expected `i32`, found `u32` | + = note: expected opaque type `impl std::fmt::Display` + found type `u32` error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:40:5 | LL | fn can() -> impl std::fmt::Display { - | ---------------------- expected because this return type... + | ---------------------- the expected opaque type LL | / match 13 { LL | | 0 => return 0i32, - | | ---- ...is found to be `i32` here LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type -help: you could change the return type to be a boxed trait object - | -LL | fn can() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ Box::new(match 13 { -LL ~ 0 => return Box::new(0i32), -LL | 1 => 1u32, -LL | _ => 2u32, -LL ~ }) - | + = note: expected opaque type `impl std::fmt::Display` + found type `u32` error[E0308]: mismatched types - --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13 + --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:48:5 | -LL | fn cat() -> impl std::fmt::Display { - | ---------------------- expected because this return type... -... -LL | return 0i32; - | ---- ...is found to be `i32` here -... -LL | 1u32 - | ^^^^ expected `i32`, found `u32` - | - = note: to return `impl Trait`, all returned values must be of the same type - = note: for information on `impl Trait`, see <https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits> - = note: for information on trait objects, see <https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types> - = help: you could instead create a new `enum` with a variant for each returned type -help: you could change the return type to be a boxed trait object - | -LL | fn cat() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ return Box::new(0i32); -LL | } -LL | _ => { -LL ~ Box::new(1u32) +LL | fn cat() -> impl std::fmt::Display { + | ---------------------- the expected opaque type +LL | / match 13 { +LL | | 0 => { +LL | | return 0i32; +LL | | } +... | +LL | | } +LL | | } + | |_____^ expected `i32`, found `u32` | + = note: expected opaque type `impl std::fmt::Display` + found type `u32` error[E0308]: `match` arms have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14 @@ -196,16 +117,6 @@ LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____- `match` arms have incompatible types - | -help: you could change the return type to be a boxed trait object - | -LL | fn dog() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ 0 => Box::new(0i32), -LL ~ 1 => Box::new(1u32), - | error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:97:9 @@ -218,17 +129,6 @@ LL | | 1u32 | | ^^^^ expected `i32`, found `u32` LL | | } | |_____- `if` and `else` have incompatible types - | -help: you could change the return type to be a boxed trait object - | -LL | fn apt() -> Box<dyn std::fmt::Display> { - | ~~~~~~~ + -help: if you change the return type to expect trait objects, box the returned expressions - | -LL ~ Box::new(0i32) -LL | } else { -LL ~ Box::new(1u32) - | error[E0746]: return type cannot have an unboxed trait object --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13 diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs index b4fd6b3e743..2e7cb21592c 100644 --- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.rs @@ -11,8 +11,8 @@ pub trait Test {} impl<T> Test for T where T: Super<Assoc = ()> {} fn test() -> impl Test { - //~^ERROR type mismatch resolving `<() as Super>::Assoc == ()` () + //~^ERROR type mismatch resolving `<() as Super>::Assoc == ()` } fn main() { diff --git a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr index 65daabe419d..5ef1e9abef6 100644 --- a/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr +++ b/src/test/ui/impl-trait/projection-mismatch-in-impl-where-clause.stderr @@ -1,10 +1,10 @@ error[E0271]: type mismatch resolving `<() as Super>::Assoc == ()` - --> $DIR/projection-mismatch-in-impl-where-clause.rs:13:14 + --> $DIR/projection-mismatch-in-impl-where-clause.rs:14:5 | -LL | fn test() -> impl Test { - | ^^^^^^^^^ type mismatch resolving `<() as Super>::Assoc == ()` +LL | () + | ^^ type mismatch resolving `<() as Super>::Assoc == ()` | -note: expected this to be `()` +note: expected this to be `u8` --> $DIR/projection-mismatch-in-impl-where-clause.rs:6:18 | LL | type Assoc = u8; diff --git a/src/test/ui/impl-trait/question_mark.rs b/src/test/ui/impl-trait/question_mark.rs new file mode 100644 index 00000000000..211f7972dbc --- /dev/null +++ b/src/test/ui/impl-trait/question_mark.rs @@ -0,0 +1,13 @@ +// check-pass + +fn foo() -> impl MyTrait { + panic!(); + MyStruct +} + +struct MyStruct; +trait MyTrait {} + +impl MyTrait for MyStruct {} + +fn main() {} diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs index 3cc53744097..540a280f0a3 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.rs @@ -1,9 +1,8 @@ -// Test that an `impl Trait` type that expands to itself is an error. +// check-pass #![allow(unconditional_recursion)] fn test() -> impl Sized { - //~^ ERROR E0720 test() } diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr deleted file mode 100644 index 5a3027ec751..00000000000 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-direct.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0720]: cannot resolve opaque type - --> $DIR/recursive-impl-trait-type-direct.rs:5:14 - | -LL | fn test() -> impl Sized { - | ^^^^^^^^^^ recursive opaque type -LL | -LL | test() - | ------ returning here with type `impl Sized` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0720`. diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs index e3c621f0c57..ffc0cd9d10c 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.rs @@ -5,7 +5,7 @@ #![allow(unconditional_recursion)] fn option(i: i32) -> impl Sized { - //~^ ERROR + //~^ ERROR cannot resolve opaque type if i < 0 { None } else { Some((option(i - 1), i)) } } diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs new file mode 100644 index 00000000000..a60e34c17b6 --- /dev/null +++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.rs @@ -0,0 +1,29 @@ +#![feature(type_alias_impl_trait)] + +mod a { + type Foo = impl PartialEq<(Foo, i32)>; + //~^ ERROR unconstrained opaque type + + struct Bar; + + impl PartialEq<(Bar, i32)> for Bar { + fn eq(&self, _other: &(Foo, i32)) -> bool { + true + } + } +} + +mod b { + type Foo = impl PartialEq<(Foo, i32)>; + //~^ ERROR unconstrained opaque type + + struct Bar; + + impl PartialEq<(Foo, i32)> for Bar { + fn eq(&self, _other: &(Bar, i32)) -> bool { + true + } + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr new file mode 100644 index 00000000000..eae7d38d116 --- /dev/null +++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration-too-subtle.stderr @@ -0,0 +1,18 @@ +error: unconstrained opaque type + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:4:16 + | +LL | type Foo = impl PartialEq<(Foo, i32)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error: unconstrained opaque type + --> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:17:16 + | +LL | type Foo = impl PartialEq<(Foo, i32)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs new file mode 100644 index 00000000000..bdabc13c36a --- /dev/null +++ b/src/test/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -0,0 +1,37 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +mod direct { + type Foo = impl PartialEq<(Foo, i32)>; + + struct Bar; + + impl PartialEq<(Foo, i32)> for Bar { + fn eq(&self, _other: &(Foo, i32)) -> bool { + true + } + } + + fn foo() -> Foo { + Bar + } +} + +mod indirect { + type Foo = impl PartialEq<(Foo, i32)>; + + struct Bar; + + impl PartialEq<(Bar, i32)> for Bar { + fn eq(&self, _other: &(Bar, i32)) -> bool { + true + } + } + + fn foo() -> Foo { + Bar + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/region-escape-via-bound.rs b/src/test/ui/impl-trait/region-escape-via-bound.rs index e834f96dbbe..a04cb1702b6 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.rs +++ b/src/test/ui/impl-trait/region-escape-via-bound.rs @@ -12,10 +12,10 @@ trait Trait<'a> { } impl<'a, 'b> Trait<'b> for Cell<&'a u32> { } fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> - //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700] where 'x: 'y { x + //~^ ERROR hidden type for `impl Trait` captures lifetime that does not appear in bounds [E0700] } fn main() { } diff --git a/src/test/ui/impl-trait/region-escape-via-bound.stderr b/src/test/ui/impl-trait/region-escape-via-bound.stderr index ecec34e0115..bc02f7694d7 100644 --- a/src/test/ui/impl-trait/region-escape-via-bound.stderr +++ b/src/test/ui/impl-trait/region-escape-via-bound.stderr @@ -1,10 +1,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/region-escape-via-bound.rs:14:37 + --> $DIR/region-escape-via-bound.rs:17:5 | LL | fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> - | -- ^^^^^^^^^^^^^^ - | | - | hidden type `Cell<&'x u32>` captures the lifetime `'x` as defined here + | -- hidden type `Cell<&'x u32>` captures the lifetime `'x` as defined here +... +LL | x + | ^ | help: to declare that the `impl Trait` captures `'x`, you can add an explicit `'x` lifetime bound | diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.rs b/src/test/ui/impl-trait/static-return-lifetime-infered.rs index d792c6eafb3..f940c1949d0 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.rs +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.rs @@ -4,14 +4,14 @@ struct A { impl A { fn iter_values_anon(&self) -> impl Iterator<Item=u32> { + self.x.iter().map(|a| a.0) //~^ ERROR: captures lifetime that does not appear in bounds //~| ERROR: captures lifetime that does not appear in bounds - self.x.iter().map(|a| a.0) } fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> { + self.x.iter().map(|a| a.0) //~^ ERROR: captures lifetime that does not appear in bounds //~| ERROR: captures lifetime that does not appear in bounds - self.x.iter().map(|a| a.0) } } diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr index 7424da76182..bc8e39f9c50 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.stderr @@ -1,10 +1,10 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:6:35 + --> $DIR/static-return-lifetime-infered.rs:7:9 | LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> { - | ----- ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:9:27: 9:34]>` captures the anonymous lifetime defined here + | ----- hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:7:27: 7:34]>` captures the anonymous lifetime defined here +LL | self.x.iter().map(|a| a.0) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound | @@ -12,12 +12,12 @@ LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:6:35 + --> $DIR/static-return-lifetime-infered.rs:7:9 | LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> { - | ----- ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:9:27: 9:34]>` captures the anonymous lifetime defined here + | ----- hidden type `Map<std::slice::Iter<'_, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:7:27: 7:34]>` captures the anonymous lifetime defined here +LL | self.x.iter().map(|a| a.0) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: to declare that the `impl Trait` captures `'_`, you can add an explicit `'_` lifetime bound | @@ -25,12 +25,12 @@ LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:11:37 + --> $DIR/static-return-lifetime-infered.rs:12:9 | LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> { - | -- ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:14:27: 14:34]>` captures the lifetime `'a` as defined here + | -- hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:12:27: 12:34]>` captures the lifetime `'a` as defined here +LL | self.x.iter().map(|a| a.0) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: to declare that the `impl Trait` captures `'a`, you can add an explicit `'a` lifetime bound | @@ -38,12 +38,12 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a { | ++++ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/static-return-lifetime-infered.rs:11:37 + --> $DIR/static-return-lifetime-infered.rs:12:9 | LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> { - | -- ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:14:27: 14:34]>` captures the lifetime `'a` as defined here + | -- hidden type `Map<std::slice::Iter<'a, (u32, u32)>, [closure@$DIR/static-return-lifetime-infered.rs:12:27: 12:34]>` captures the lifetime `'a` as defined here +LL | self.x.iter().map(|a| a.0) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | help: to declare that the `impl Trait` captures `'a`, you can add an explicit `'a` lifetime bound | diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other.rs b/src/test/ui/impl-trait/two_tait_defining_each_other.rs new file mode 100644 index 00000000000..6eb2a11b22c --- /dev/null +++ b/src/test/ui/impl-trait/two_tait_defining_each_other.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +type A = impl Foo; +type B = impl Foo; + +trait Foo {} + +fn muh(x: A) -> B { + if false { + return Bar; // B's hidden type is Bar + } + x // A's hidden type is `Bar`, because all the hidden types of `B` are compared with each other + //~^ ERROR opaque type's hidden type cannot be another opaque type +} + +struct Bar; +impl Foo for Bar {} + +fn main() {} diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other.stderr b/src/test/ui/impl-trait/two_tait_defining_each_other.stderr new file mode 100644 index 00000000000..1a42ac525a6 --- /dev/null +++ b/src/test/ui/impl-trait/two_tait_defining_each_other.stderr @@ -0,0 +1,19 @@ +error: opaque type's hidden type cannot be another opaque type from the same scope + --> $DIR/two_tait_defining_each_other.rs:12:5 + | +LL | x // A's hidden type is `Bar`, because all the hidden types of `B` are compared with each other + | ^ 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/two_tait_defining_each_other.rs:4:10 + | +LL | type B = impl Foo; + | ^^^^^^^^ +note: opaque type being used as hidden type + --> $DIR/two_tait_defining_each_other.rs:3:10 + | +LL | type A = impl Foo; + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other2.rs b/src/test/ui/impl-trait/two_tait_defining_each_other2.rs new file mode 100644 index 00000000000..3b16d0f5e04 --- /dev/null +++ b/src/test/ui/impl-trait/two_tait_defining_each_other2.rs @@ -0,0 +1,16 @@ +#![feature(type_alias_impl_trait)] + +type A = impl Foo; +type B = impl Foo; + +trait Foo {} + +fn muh(x: A) -> B { + x // B's hidden type is A (opaquely) + //~^ ERROR opaque type's hidden type cannot be another opaque type +} + +struct Bar; +impl Foo for Bar {} + +fn main() {} diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr b/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr new file mode 100644 index 00000000000..ef2089a6c5b --- /dev/null +++ b/src/test/ui/impl-trait/two_tait_defining_each_other2.stderr @@ -0,0 +1,19 @@ +error: opaque type's hidden type cannot be another opaque type from the same scope + --> $DIR/two_tait_defining_each_other2.rs:9:5 + | +LL | x // B's hidden type is A (opaquely) + | ^ 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/two_tait_defining_each_other2.rs:4:10 + | +LL | type B = impl Foo; + | ^^^^^^^^ +note: opaque type being used as hidden type + --> $DIR/two_tait_defining_each_other2.rs:3:10 + | +LL | type A = impl Foo; + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other3.rs b/src/test/ui/impl-trait/two_tait_defining_each_other3.rs new file mode 100644 index 00000000000..37f8ae1b84b --- /dev/null +++ b/src/test/ui/impl-trait/two_tait_defining_each_other3.rs @@ -0,0 +1,19 @@ +#![feature(type_alias_impl_trait)] + +type A = impl Foo; +type B = impl Foo; + +trait Foo {} + +fn muh(x: A) -> B { + if false { + return x; // B's hidden type is A (opaquely) + //~^ ERROR opaque type's hidden type cannot be another opaque type + } + Bar // A's hidden type is `Bar`, because all the return types are compared with each other +} + +struct Bar; +impl Foo for Bar {} + +fn main() {} diff --git a/src/test/ui/impl-trait/two_tait_defining_each_other3.stderr b/src/test/ui/impl-trait/two_tait_defining_each_other3.stderr new file mode 100644 index 00000000000..b06dc16d5e7 --- /dev/null +++ b/src/test/ui/impl-trait/two_tait_defining_each_other3.stderr @@ -0,0 +1,19 @@ +error: opaque type's hidden type cannot be another opaque type from the same scope + --> $DIR/two_tait_defining_each_other3.rs:10:16 + | +LL | return x; // B's hidden type is A (opaquely) + | ^ 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/two_tait_defining_each_other3.rs:4:10 + | +LL | type B = impl Foo; + | ^^^^^^^^ +note: opaque type being used as hidden type + --> $DIR/two_tait_defining_each_other3.rs:3:10 + | +LL | type A = impl Foo; + | ^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr index 039cb62f866..e0b77544d43 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr @@ -1,8 +1,8 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:7:20 + --> $DIR/type_parameters_captured.rs:8:5 | -LL | fn foo<T>(x: T) -> impl Any + 'static { - | ^^^^^^^^^^^^^^^^^^ +LL | x + | ^ | = help: consider adding an explicit lifetime bound `T: 'static`... diff --git a/src/test/ui/impl-trait/type_parameters_captured.rs b/src/test/ui/impl-trait/type_parameters_captured.rs index 6c9c9d4a42a..81ee7d3f8a5 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.rs +++ b/src/test/ui/impl-trait/type_parameters_captured.rs @@ -5,8 +5,8 @@ impl<T> Any for T {} // Check that type parameters are captured and not considered 'static fn foo<T>(x: T) -> impl Any + 'static { - //~^ ERROR the parameter type `T` may not live long enough x + //~^ ERROR the parameter type `T` may not live long enough } fn main() {} diff --git a/src/test/ui/impl-trait/type_parameters_captured.stderr b/src/test/ui/impl-trait/type_parameters_captured.stderr index 40e50b9922f..c0de4f4b4a0 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.stderr @@ -1,10 +1,10 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:7:20 + --> $DIR/type_parameters_captured.rs:8:5 | LL | fn foo<T>(x: T) -> impl Any + 'static { - | - ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `T: 'static` + | - help: consider adding an explicit lifetime bound...: `T: 'static` +LL | x + | ^ ...so that the type `T` will meet its required lifetime bounds error: aborting due to previous error diff --git a/src/test/ui/impl-trait/where-allowed-2.rs b/src/test/ui/impl-trait/where-allowed-2.rs index 462508f306e..d5a87b5d468 100644 --- a/src/test/ui/impl-trait/where-allowed-2.rs +++ b/src/test/ui/impl-trait/where-allowed-2.rs @@ -1,8 +1,7 @@ -//! Ideally, these tests would go in `where-allowed.rs`, but we bail out -//! too early to display them. use std::fmt::Debug; -// Disallowed -fn in_adt_in_return() -> Vec<impl Debug> { panic!() } //~ ERROR cannot resolve opaque type +// check-pass + +fn in_adt_in_return() -> Vec<impl Debug> { panic!() } fn main() {} diff --git a/src/test/ui/impl-trait/where-allowed-2.stderr b/src/test/ui/impl-trait/where-allowed-2.stderr deleted file mode 100644 index b8e06725cbc..00000000000 --- a/src/test/ui/impl-trait/where-allowed-2.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error[E0720]: cannot resolve opaque type - --> $DIR/where-allowed-2.rs:6:30 - | -LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() } - | ^^^^^^^^^^ -------- this returned value is of `!` type - | | - | cannot resolve opaque type - | - = help: this error will resolve once the item's body returns a concrete type - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0720`. |
