diff options
Diffstat (limited to '')
41 files changed, 677 insertions, 24 deletions
diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index 634ff1486..b6e283647 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -29,6 +29,11 @@ note: ...which requires building MIR for `cycle1`... | LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building THIR 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:14:5 | @@ -65,6 +70,11 @@ note: ...which requires building MIR for `cycle2`... | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ +note: ...which requires building THIR for `cycle2`... + --> $DIR/auto-trait-leak.rs:19:1 + | +LL | fn cycle2() -> impl Clone { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... --> $DIR/auto-trait-leak.rs:20:5 | diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index f14b447b0..d4a349551 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,10 +12,15 @@ error[E0308]: mismatched types --> $DIR/equality.rs:15:5 | LL | fn two(x: bool) -> impl Foo { - | -------- expected `_` because of return type + | -------- expected `i32` because of return type ... LL | 0_u32 | ^^^^^ expected `i32`, found `u32` + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | 0_i32 + | ~~~ error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 diff --git a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr index c01c33a89..8f4092273 100644 --- a/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr +++ b/src/test/ui/impl-trait/generic-with-implicit-hrtb-without-dyn.edition2021.stderr @@ -6,9 +6,8 @@ LL | fn ice() -> impl AsRef<Fn(&())> { | help: add `dyn` keyword before this trait | -LL - fn ice() -> impl AsRef<Fn(&())> { -LL + fn ice() -> impl AsRef<dyn Fn(&())> { - | +LL | fn ice() -> impl AsRef<dyn Fn(&())> { + | +++ error[E0277]: the trait bound `(): AsRef<(dyn for<'r> Fn(&'r ()) + 'static)>` is not satisfied --> $DIR/generic-with-implicit-hrtb-without-dyn.rs:6:13 diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.rs b/src/test/ui/impl-trait/impl-generic-mismatch.rs index ba678bb03..fb8bde0d0 100644 --- a/src/test/ui/impl-trait/impl-generic-mismatch.rs +++ b/src/test/ui/impl-trait/impl-generic-mismatch.rs @@ -18,6 +18,15 @@ impl Bar for () { //~^ Error method `bar` has incompatible signature for trait } +trait Baz { + fn baz<U: Debug, T: Debug>(&self, _: &U, _: &T); +} + +impl Baz for () { + fn baz<T: Debug>(&self, _: &impl Debug, _: &T) { } + //~^ Error method `baz` has incompatible signature for trait +} + // With non-local trait (#49841): use std::hash::{Hash, Hasher}; diff --git a/src/test/ui/impl-trait/impl-generic-mismatch.stderr b/src/test/ui/impl-trait/impl-generic-mismatch.stderr index 489afd761..542f02d7e 100644 --- a/src/test/ui/impl-trait/impl-generic-mismatch.stderr +++ b/src/test/ui/impl-trait/impl-generic-mismatch.stderr @@ -27,8 +27,22 @@ help: try changing the `impl Trait` argument to a generic parameter LL | fn bar<U: Debug>(&self, _: &U) { } | ++++++++++ ~ +error[E0643]: method `baz` has incompatible signature for trait + --> $DIR/impl-generic-mismatch.rs:26:33 + | +LL | fn baz<U: Debug, T: Debug>(&self, _: &U, _: &T); + | - declaration in trait here +... +LL | fn baz<T: Debug>(&self, _: &impl Debug, _: &T) { } + | ^^^^^^^^^^ expected generic parameter, found `impl Trait` + | +help: try changing the `impl Trait` argument to a generic parameter + | +LL | fn baz<U: Debug, T: Debug>(&self, _: &T, _: &T) { } + | ~~~~~~~~~~~~~~~~~~~~ ~ + error[E0643]: method `hash` has incompatible signature for trait - --> $DIR/impl-generic-mismatch.rs:28:33 + --> $DIR/impl-generic-mismatch.rs:37:33 | LL | fn hash(&self, hasher: &mut impl Hasher) {} | ^^^^^^^^^^^ expected generic parameter, found `impl Trait` @@ -38,6 +52,6 @@ LL | fn hash(&self, hasher: &mut impl Hasher) {} LL | fn hash<H: Hasher>(&self, state: &mut H); | - declaration in trait here -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0643`. diff --git a/src/test/ui/impl-trait/in-trait/deep-match-works.rs b/src/test/ui/impl-trait/in-trait/deep-match-works.rs new file mode 100644 index 000000000..772da845e --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/deep-match-works.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +struct Wrapper<T>(T); + +trait Foo { + fn bar() -> Wrapper<impl Sized>; +} + +impl Foo for () { + fn bar() -> Wrapper<i32> { Wrapper(0) } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-trait/deep-match.rs b/src/test/ui/impl-trait/in-trait/deep-match.rs new file mode 100644 index 000000000..a6385147c --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/deep-match.rs @@ -0,0 +1,15 @@ +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +struct Wrapper<T>(T); + +trait Foo { + fn bar() -> Wrapper<impl Sized>; +} + +impl Foo for () { + fn bar() -> i32 { 0 } + //~^ ERROR method `bar` has an incompatible return type for trait +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-trait/deep-match.stderr b/src/test/ui/impl-trait/in-trait/deep-match.stderr new file mode 100644 index 000000000..034ee5ea4 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/deep-match.stderr @@ -0,0 +1,15 @@ +error[E0053]: method `bar` has an incompatible return type for trait + --> $DIR/deep-match.rs:11:17 + | +LL | fn bar() -> i32 { 0 } + | ^^^ + | | + | expected struct `Wrapper`, found `i32` + | return type in trait + | + = note: expected struct `Wrapper<_>` + found type `i32` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0053`. diff --git a/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs new file mode 100644 index 000000000..bb4e0d44f --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.rs @@ -0,0 +1,13 @@ +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Foo { + fn bar() -> impl std::fmt::Display; +} + +impl Foo for () { + fn bar() -> () {} + //~^ ERROR `()` doesn't implement `std::fmt::Display` +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr new file mode 100644 index 000000000..aa5492d28 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/doesnt-satisfy.stderr @@ -0,0 +1,17 @@ +error[E0277]: `()` doesn't implement `std::fmt::Display` + --> $DIR/doesnt-satisfy.rs:9:17 + | +LL | fn bar() -> () {} + | ^^ `()` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `()` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead +note: required by a bound in `Foo::bar::{opaque#0}` + --> $DIR/doesnt-satisfy.rs:5:22 + | +LL | fn bar() -> impl std::fmt::Display; + | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::bar::{opaque#0}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/in-trait/encode.rs b/src/test/ui/impl-trait/in-trait/encode.rs new file mode 100644 index 000000000..efb9f6498 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/encode.rs @@ -0,0 +1,9 @@ +// build-pass +// compile-flags: --crate-type=lib + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Foo { + fn bar() -> impl Sized; +} diff --git a/src/test/ui/impl-trait/in-trait/nested-rpitit.rs b/src/test/ui/impl-trait/in-trait/nested-rpitit.rs new file mode 100644 index 000000000..65285e3a3 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/nested-rpitit.rs @@ -0,0 +1,32 @@ +// check-pass + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Display; +use std::ops::Deref; + +trait Foo { + fn bar(self) -> impl Deref<Target = impl Display + ?Sized>; +} + +struct A; + +impl Foo for A { + fn bar(self) -> &'static str { + "Hello, world" + } +} + +struct B; + +impl Foo for B { + fn bar(self) -> Box<i32> { + Box::new(42) + } +} + +fn main() { + println!("Message for you: {:?}", &*A.bar()); + println!("Another for you: {:?}", &*B.bar()); +} diff --git a/src/test/ui/impl-trait/in-trait/object-safety.rs b/src/test/ui/impl-trait/in-trait/object-safety.rs new file mode 100644 index 000000000..dd35b9a2d --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/object-safety.rs @@ -0,0 +1,22 @@ +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +trait Foo { + fn baz(&self) -> impl Debug; +} + +impl Foo for u32 { + fn baz(&self) -> u32 { + 32 + } +} + +fn main() { + let i = Box::new(42_u32) as Box<dyn Foo>; + //~^ ERROR the trait `Foo` cannot be made into an object + //~| ERROR the trait `Foo` cannot be made into an object + let s = i.baz(); + //~^ ERROR the trait `Foo` cannot be made into an object +} diff --git a/src/test/ui/impl-trait/in-trait/object-safety.stderr b/src/test/ui/impl-trait/in-trait/object-safety.stderr new file mode 100644 index 000000000..9a1554b5e --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/object-safety.stderr @@ -0,0 +1,50 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:17:33 + | +LL | let i = Box::new(42_u32) as Box<dyn Foo>; + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety.rs:7:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:20:13 + | +LL | let s = i.baz(); + | ^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety.rs:7:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety.rs:17:13 + | +LL | let i = Box::new(42_u32) as Box<dyn Foo>; + | ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> + --> $DIR/object-safety.rs:7:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> impl Debug; + | ^^^ ...because method `baz` references an `impl Trait` type in its return type + = help: consider moving `baz` to another trait + = note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>` + = note: required by cast to type `Box<dyn Foo>` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs new file mode 100644 index 000000000..3ac264e8e --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.rs @@ -0,0 +1,19 @@ +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Display; + +trait Foo { + fn bar(&self) -> impl Display; +} + +impl Foo for () { + fn bar(&self) -> impl Display { + "Hello, world" + } +} + +fn main() { + let x: &str = ().bar(); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr new file mode 100644 index 000000000..15edda483 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl-is-opaque.stderr @@ -0,0 +1,17 @@ +error[E0308]: mismatched types + --> $DIR/opaque-in-impl-is-opaque.rs:17:19 + | +LL | fn bar(&self) -> impl Display { + | ------------ the found opaque type +... +LL | let x: &str = ().bar(); + | ---- ^^^^^^^^ expected `&str`, found opaque type + | | + | expected due to this + | + = note: expected reference `&str` + found opaque type `impl std::fmt::Display` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs new file mode 100644 index 000000000..2e0662969 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/opaque-in-impl.rs @@ -0,0 +1,48 @@ +// check-pass + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Debug; + +trait Foo { + fn foo(&self) -> impl Debug; +} + +impl Foo for () { + fn foo(&self) -> impl Debug { + "Hello, world" + } +} + +impl<T: Default + Debug> Foo for std::marker::PhantomData<T> { + fn foo(&self) -> impl Debug { + T::default() + } +} + +trait Bar { + fn bar<T>(&self) -> impl Debug; +} + +impl Bar for () { + fn bar<T>(&self) -> impl Debug { + format!("Hello with generic {}", std::any::type_name::<T>()) + } +} + +trait Baz { + fn baz(&self) -> impl Debug + '_; +} + +impl Baz for String { + fn baz(&self) -> impl Debug + '_ { + (self,) + } +} + +fn main() { + println!("{:?}", ().foo()); + println!("{:?}", ().bar::<u64>()); + println!("{:?}", "hi".to_string().baz()); +} diff --git a/src/test/ui/impl-trait/in-trait/reveal.rs b/src/test/ui/impl-trait/in-trait/reveal.rs new file mode 100644 index 000000000..d6ede1cc4 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/reveal.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Foo { + fn f() -> Box<impl Sized>; +} + +impl Foo for () { + fn f() -> Box<String> { + Box::new(String::new()) + } +} + +fn main() { + let x: Box<String> = <() as Foo>::f(); +} diff --git a/src/test/ui/impl-trait/in-trait/success.rs b/src/test/ui/impl-trait/in-trait/success.rs new file mode 100644 index 000000000..4cbe682b4 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/success.rs @@ -0,0 +1,40 @@ +// check-pass + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Display; + +trait Foo { + fn bar(&self) -> impl Display; +} + +impl Foo for i32 { + fn bar(&self) -> i32 { + *self + } +} + +impl Foo for &'static str { + fn bar(&self) -> &'static str { + *self + } +} + +struct Yay; + +impl Foo for Yay { + fn bar(&self) -> String { + String::from(":^)") + } +} + +fn foo_generically<T: Foo>(t: T) { + println!("{}", t.bar()); +} + +fn main() { + println!("{}", "Hello, world.".bar()); + println!("The answer is {}!", 42.bar()); + foo_generically(Yay); +} diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.rs b/src/test/ui/impl-trait/in-trait/wf-bounds.rs new file mode 100644 index 000000000..2c71583b3 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/wf-bounds.rs @@ -0,0 +1,16 @@ +// issue #101663 + +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +trait Wf<T> {} + +trait Uwu { + fn nya() -> impl Wf<Vec<[u8]>>; + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + + fn nya2() -> impl Wf<[u8]>; + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-trait/wf-bounds.stderr b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr new file mode 100644 index 000000000..92e36841b --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/wf-bounds.stderr @@ -0,0 +1,33 @@ +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:9:22 + | +LL | fn nya() -> impl Wf<Vec<[u8]>>; + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + | +LL | pub struct Vec<T, #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global> { + | ^ required by this bound in `Vec` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:12:23 + | +LL | fn nya2() -> impl Wf<[u8]>; + | ^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Wf` + --> $DIR/wf-bounds.rs:6:10 + | +LL | trait Wf<T> {} + | ^ required by this bound in `Wf` +help: consider relaxing the implicit `Sized` restriction + | +LL | trait Wf<T: ?Sized> {} + | ++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-100075-2.rs b/src/test/ui/impl-trait/issue-100075-2.rs new file mode 100644 index 000000000..cf059af19 --- /dev/null +++ b/src/test/ui/impl-trait/issue-100075-2.rs @@ -0,0 +1,8 @@ +fn opaque<T>(t: T) -> impl Sized { + //~^ ERROR cannot resolve opaque type + //~| WARNING function cannot return without recursing + opaque(Some(t)) +} + +#[allow(dead_code)] +fn main() {} diff --git a/src/test/ui/impl-trait/issue-100075-2.stderr b/src/test/ui/impl-trait/issue-100075-2.stderr new file mode 100644 index 000000000..5a1f1a97d --- /dev/null +++ b/src/test/ui/impl-trait/issue-100075-2.stderr @@ -0,0 +1,24 @@ +warning: function cannot return without recursing + --> $DIR/issue-100075-2.rs:1:1 + | +LL | fn opaque<T>(t: T) -> impl Sized { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +... +LL | opaque(Some(t)) + | --------------- recursive call site + | + = note: `#[warn(unconditional_recursion)]` on by default + = help: a `loop` may express intention better if this is on purpose + +error[E0720]: cannot resolve opaque type + --> $DIR/issue-100075-2.rs:1:23 + | +LL | fn opaque<T>(t: T) -> impl Sized { + | ^^^^^^^^^^ recursive opaque type +... +LL | opaque(Some(t)) + | --------------- returning here with type `impl Sized` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0720`. diff --git a/src/test/ui/impl-trait/issue-100075.rs b/src/test/ui/impl-trait/issue-100075.rs new file mode 100644 index 000000000..ea30abb48 --- /dev/null +++ b/src/test/ui/impl-trait/issue-100075.rs @@ -0,0 +1,21 @@ +trait Marker {} +impl<T> Marker for T {} + +fn maybe<T>( + _t: T, +) -> Option< + //removing the line below makes it compile + &'static T, +> { + None +} + +fn _g<T>(t: &'static T) -> &'static impl Marker { + //~^ ERROR cannot resolve opaque type + if let Some(t) = maybe(t) { + return _g(t); + } + todo!() +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-100075.stderr b/src/test/ui/impl-trait/issue-100075.stderr new file mode 100644 index 000000000..267ecfdae --- /dev/null +++ b/src/test/ui/impl-trait/issue-100075.stderr @@ -0,0 +1,12 @@ +error[E0720]: cannot resolve opaque type + --> $DIR/issue-100075.rs:13:37 + | +LL | fn _g<T>(t: &'static T) -> &'static impl Marker { + | ^^^^^^^^^^^ recursive opaque type +... +LL | return _g(t); + | ----- returning here with type `&impl Marker` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0720`. diff --git a/src/test/ui/impl-trait/issue-103599.rs b/src/test/ui/impl-trait/issue-103599.rs new file mode 100644 index 000000000..043ae67f2 --- /dev/null +++ b/src/test/ui/impl-trait/issue-103599.rs @@ -0,0 +1,10 @@ +// check-pass + +trait T {} + +fn wrap(x: impl T) -> impl T { + //~^ WARN function cannot return without recursing + wrap(wrap(x)) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-103599.stderr b/src/test/ui/impl-trait/issue-103599.stderr new file mode 100644 index 000000000..79fb355dd --- /dev/null +++ b/src/test/ui/impl-trait/issue-103599.stderr @@ -0,0 +1,14 @@ +warning: function cannot return without recursing + --> $DIR/issue-103599.rs:5:1 + | +LL | fn wrap(x: impl T) -> impl T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing +LL | +LL | wrap(wrap(x)) + | ------- recursive call site + | + = note: `#[warn(unconditional_recursion)]` on by default + = help: a `loop` may express intention better if this is on purpose + +warning: 1 warning emitted + diff --git a/src/test/ui/impl-trait/issue-99914.rs b/src/test/ui/impl-trait/issue-99914.rs new file mode 100644 index 000000000..4324a0229 --- /dev/null +++ b/src/test/ui/impl-trait/issue-99914.rs @@ -0,0 +1,13 @@ +// edition:2021 + +fn main() {} + +struct Error; +struct Okay; + +fn foo(t: Result<Okay, Error>) { + t.and_then(|t| -> _ { bar(t) }); + //~^ ERROR mismatched types +} + +async fn bar(t: Okay) {} diff --git a/src/test/ui/impl-trait/issue-99914.stderr b/src/test/ui/impl-trait/issue-99914.stderr new file mode 100644 index 000000000..074d5d58d --- /dev/null +++ b/src/test/ui/impl-trait/issue-99914.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-99914.rs:9:27 + | +LL | t.and_then(|t| -> _ { bar(t) }); + | ^^^^^^ expected enum `Result`, found opaque type + | +note: while checking the return type of the `async fn` + --> $DIR/issue-99914.rs:13:23 + | +LL | async fn bar(t: Okay) {} + | ^ checked the `Output` of this `async fn`, found opaque type + = note: expected enum `Result<_, Error>` + found opaque type `impl Future<Output = ()>` +help: try wrapping the expression in `Ok` + | +LL | t.and_then(|t| -> _ { Ok(bar(t)) }); + | +++ + + +error: aborting due to previous error + +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 002e4cde4..90d1cd379 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.rs +++ b/src/test/ui/impl-trait/issues/issue-78722.rs @@ -7,7 +7,7 @@ type F = impl core::future::Future<Output = u8>; struct Bug { V1: [(); { fn concrete_use() -> F { - //~^ ERROR type mismatch + //~^ ERROR expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()` async {} } let f: F = async { 1 }; diff --git a/src/test/ui/impl-trait/issues/issue-78722.stderr b/src/test/ui/impl-trait/issues/issue-78722.stderr index 690d6abc7..9a0ffbc89 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.stderr +++ b/src/test/ui/impl-trait/issues/issue-78722.stderr @@ -16,7 +16,7 @@ LL | let f: F = async { 1 }; LL | }], | - value is dropped here -error[E0271]: type mismatch resolving `<impl Future<Output = ()> as Future>::Output == u8` +error[E0271]: expected `impl Future<Output = ()>` to be a future that resolves to `u8`, but it resolves to `()` --> $DIR/issue-78722.rs:9:30 | LL | fn concrete_use() -> F { diff --git a/src/test/ui/impl-trait/nested-return-type2-tait2.stderr b/src/test/ui/impl-trait/nested-return-type2-tait2.stderr index fe1ae4fcb..348c737b0 100644 --- a/src/test/ui/impl-trait/nested-return-type2-tait2.stderr +++ b/src/test/ui/impl-trait/nested-return-type2-tait2.stderr @@ -5,7 +5,7 @@ LL | || 42 | ^^^^^ the trait `Duh` is not implemented for `Sendable` | = help: the trait `Duh` is implemented for `i32` -note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]` +note: required for `[closure@$DIR/nested-return-type2-tait2.rs:27:5: 27:7]` to implement `Trait` --> $DIR/nested-return-type2-tait2.rs:14:31 | LL | impl<R: Duh, F: FnMut() -> R> Trait for F { diff --git a/src/test/ui/impl-trait/nested-return-type2-tait3.stderr b/src/test/ui/impl-trait/nested-return-type2-tait3.stderr index c0695d627..6ac671415 100644 --- a/src/test/ui/impl-trait/nested-return-type2-tait3.stderr +++ b/src/test/ui/impl-trait/nested-return-type2-tait3.stderr @@ -5,7 +5,7 @@ LL | || 42 | ^^^^^ the trait `Duh` is not implemented for `impl Send` | = help: the trait `Duh` is implemented for `i32` -note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]` +note: required for `[closure@$DIR/nested-return-type2-tait3.rs:26:5: 26:7]` to implement `Trait` --> $DIR/nested-return-type2-tait3.rs:14:31 | LL | impl<R: Duh, F: FnMut() -> R> Trait for F { diff --git a/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs new file mode 100644 index 000000000..287a030cf --- /dev/null +++ b/src/test/ui/impl-trait/nested-rpit-with-anonymous-lifetimes.rs @@ -0,0 +1,23 @@ +// check-pass + +pub struct VecNumber<'s> { + pub vec_number: Vec<Number<'s>>, + pub auxiliary_object: &'s Vec<usize>, +} + +pub struct Number<'s> { + pub number: &'s usize, +} + +impl<'s> VecNumber<'s> { + pub fn vec_number_iterable_per_item_in_auxiliary_object( + &self, + ) -> impl Iterator<Item = (&'s usize, impl Iterator<Item = &Number<'s>>)> { + self.auxiliary_object.iter().map(move |n| { + let iter_number = self.vec_number.iter(); + (n, iter_number) + }) + } +} + +fn main() {} diff --git a/src/test/ui/impl-trait/nested_impl_trait.stderr b/src/test/ui/impl-trait/nested_impl_trait.stderr index bb4ae5e82..3291cad68 100644 --- a/src/test/ui/impl-trait/nested_impl_trait.stderr +++ b/src/test/ui/impl-trait/nested_impl_trait.stderr @@ -53,7 +53,7 @@ LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` | = help: the trait `Into<U>` is implemented for `T` - = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>` + = note: required for `impl Into<u32>` to implement `Into<impl Debug>` error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied --> $DIR/nested_impl_trait.rs:18:34 @@ -62,7 +62,7 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug` | = help: the trait `Into<U>` is implemented for `T` - = note: required because of the requirements on the impl of `Into<impl Debug>` for `impl Into<u32>` + = note: required for `impl Into<u32>` to implement `Into<impl Debug>` error: aborting due to 8 previous errors diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 365ecd9fc..687dbe65e 100644 --- a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -21,10 +21,10 @@ LL | fn foo() -> Self where Self: Sized; | +++++++++++++++++ error[E0038]: the trait `NotObjectSafe` cannot be made into an object - --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:13 + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:17 | LL | fn cat() -> Box<dyn NotObjectSafe> { - | ^^^^^^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object + | ^^^^^^^^^^^^^^^^^ `NotObjectSafe` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:3:8 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 5ca01a593..d6f5a1ac2 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,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5 | LL | fn can() -> impl NotObjectSafe { - | ------------------ expected `_` because of return type + | ------------------ expected `A` because of return type ... LL | B | ^ expected struct `A`, found struct `B` @@ -11,7 +11,7 @@ error[E0308]: mismatched types --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5 | LL | fn cat() -> impl ObjectSafe { - | --------------- expected `_` because of return type + | --------------- expected `A` because of return type ... LL | B | ^ expected struct `A`, found struct `B` 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 10510c175..3c65fd998 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,28 +2,43 @@ 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 of return type + | ---------------------- expected `i32` because of return type ... LL | 1u32 | ^^^^ expected `i32`, found `u32` + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | 1i32 + | ~~~ 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 of return type + | ---------------------- expected `i32` because of return type ... LL | return 1u32; | ^^^^ expected `i32`, found `u32` + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | return 1i32; + | ~~~ 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 of return type + | ---------------------- expected `i32` because of return type ... LL | 1u32 | ^^^^ expected `i32`, found `u32` + | +help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit + | +LL | }.try_into().unwrap() + | ++++++++++++++++++++ error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:28:9 @@ -36,36 +51,66 @@ 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 qux() -> 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) + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | 1i32 + | ~~~ 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 of return type + | ---------------------- expected `i32` because of return type ... LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` + | +help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit + | +LL | }.try_into().unwrap() + | ++++++++++++++++++++ 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 of return type + | ---------------------- expected `i32` because of return type LL | / match 13 { LL | | 0 => return 0i32, LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` + | +help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit + | +LL | }.try_into().unwrap() + | ++++++++++++++++++++ error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:53:13 | LL | fn cat() -> impl std::fmt::Display { - | ---------------------- expected `_` because of return type + | ---------------------- expected `i32` because of return type ... LL | 1u32 | ^^^^ expected `i32`, found `u32` + | +help: you can convert a `u32` to an `i32` and panic if the converted value doesn't fit + | +LL | }.try_into().unwrap() + | ++++++++++++++++++++ error[E0308]: `match` arms have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:61:14 @@ -78,6 +123,20 @@ 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), + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | 1 => 1i32, + | ~~~ error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:97:9 @@ -90,6 +149,21 @@ 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) + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | 1i32 + | ~~~ error[E0746]: return type cannot have an unboxed trait object --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:66:13 @@ -125,6 +199,11 @@ LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____- `match` arms have incompatible types + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | 1 => 1i32, + | ~~~ error[E0746]: return type cannot have an unboxed trait object --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:77:13 @@ -164,6 +243,11 @@ LL | | 1u32 | | ^^^^ expected `i32`, found `u32` LL | | } | |_____- `if` and `else` have incompatible types + | +help: change the type of the numeric literal from `u32` to `i32` + | +LL | 1i32 + | ~~~ error[E0746]: return type cannot have an unboxed trait object --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:85:13 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 ade0dfa1b..cf2998bbf 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 @@ -9,7 +9,7 @@ note: expected this to be `u8` | LL | type Assoc = u8; | ^^ -note: required because of the requirements on the impl of `Test` for `()` +note: required for `()` to implement `Test` --> $DIR/projection-mismatch-in-impl-where-clause.rs:11:9 | LL | impl<T> Test for T where T: Super<Assoc = ()> {} diff --git a/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr b/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr index 2a328a0e6..c10a856d8 100644 --- a/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr +++ b/src/test/ui/impl-trait/suggest-calling-rpit-closure.stderr @@ -11,7 +11,7 @@ LL | fn opaque() -> impl Fn() -> i32 { | = note: expected type `i32` found opaque type `impl Fn() -> i32` -help: use parentheses to call this closure +help: use parentheses to call this opaque type | LL | opaque()() | ++ diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index 58a2f79ef..9b346387d 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -162,12 +162,18 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t | LL | fn in_return() -> impl Debug; | ^^^^^^^^^^ + | + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return --> $DIR/where-allowed.rs:125:34 | LL | fn in_trait_impl_return() -> impl Debug { () } | ^^^^^^^^^^ + | + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param --> $DIR/where-allowed.rs:138:33 |