diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2024-06-11 14:16:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-11 14:16:47 +0100 |
| commit | 2a94a5bc218c6af1667a856f9fee1fdfe892fdc7 (patch) | |
| tree | a272adc2cb991f17a7b3eceedcc4796d33ea16fd | |
| parent | 8240d566ab140343ef0c06ad6a0826eea2bf2c61 (diff) | |
| parent | 03fa9b807379dbce92b346b489acecff6082e283 (diff) | |
| download | rust-2a94a5bc218c6af1667a856f9fee1fdfe892fdc7.tar.gz rust-2a94a5bc218c6af1667a856f9fee1fdfe892fdc7.zip | |
Rollup merge of #126258 - oli-obk:recursive_rpit, r=lcnr
Do not define opaque types when selecting impls fixes #126117 r? `@lcnr` for inconsistency with next solver
22 files changed, 140 insertions, 70 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4a935f4a64a..4306a803524 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2563,7 +2563,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&cause, obligation.param_env) - .eq(DefineOpaqueTypes::Yes, placeholder_obligation_trait_ref, impl_trait_ref) + .eq(DefineOpaqueTypes::No, placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) })?; diff --git a/tests/ui/impl-trait/equality.rs b/tests/ui/impl-trait/equality.rs index 952f81f1978..828b5aac896 100644 --- a/tests/ui/impl-trait/equality.rs +++ b/tests/ui/impl-trait/equality.rs @@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo { 0 } else { n + sum_to(n - 1) - //~^ ERROR cannot satisfy `<u32 as Add<impl Foo>>::Output == i32` + //~^ ERROR cannot add `impl Foo` to `u32` } } @@ -32,15 +32,12 @@ trait Leak: Sized { } impl<T> Leak for T { default type T = (); - default fn leak(self) -> Self::T { - panic!() - } + default fn leak(self) -> Self::T { panic!() } } impl Leak for i32 { type T = i32; - fn leak(self) -> i32 { - self - } + fn leak(self) -> i32 { self } } -fn main() {} +fn main() { +} diff --git a/tests/ui/impl-trait/equality.stderr b/tests/ui/impl-trait/equality.stderr index c9ba1a5ba32..69f4cbbbf42 100644 --- a/tests/ui/impl-trait/equality.stderr +++ b/tests/ui/impl-trait/equality.stderr @@ -22,13 +22,20 @@ help: change the type of the numeric literal from `u32` to `i32` LL | 0_i32 | ~~~ -error[E0284]: type annotations needed: cannot satisfy `<u32 as Add<impl Foo>>::Output == i32` +error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 | LL | n + sum_to(n - 1) - | ^ cannot satisfy `<u32 as Add<impl Foo>>::Output == i32` + | ^ no implementation for `u32 + impl Foo` + | + = help: the trait `Add<impl Foo>` is not implemented for `u32` + = help: the following other types implement trait `Add<Rhs>`: + <&'a u32 as Add<u32>> + <&u32 as Add<&u32>> + <u32 as Add<&u32>> + <u32 as Add> error: aborting due to 2 previous errors; 1 warning emitted -Some errors have detailed explanations: E0284, E0308. -For more information about an error, try `rustc --explain E0284`. +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index f7c708a1dfa..1f9a2a5e9d6 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -46,23 +46,19 @@ error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfie --> $DIR/nested_impl_trait.rs:6:46 | LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into<u32>` + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl 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 } - | +++++++++++++++++ + = help: the trait `Into<U>` is implemented for `T` + = note: required for `impl Into<u32>` to implement `Into<impl Debug>` error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied --> $DIR/nested_impl_trait.rs:19:34 | LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } - | ^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `impl Into<u32>` - | -help: consider further restricting this bound + | ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>` | -LL | fn bad(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x } - | +++++++++++++++++ + = help: the trait `Into<U>` is implemented for `T` + = note: required for `impl Into<u32>` to implement `Into<impl Debug>` error: aborting due to 7 previous errors diff --git a/tests/ui/impl-trait/recursive-bound-eval.next.stderr b/tests/ui/impl-trait/recursive-bound-eval.next.stderr new file mode 100644 index 00000000000..4bab290d71c --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.next.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-bound-eval.rs:20:13 + | +LL | move || recursive_fn().parse() + | ^^^^^^^^^^^^^^ cannot infer type + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/impl-trait/recursive-bound-eval.rs b/tests/ui/impl-trait/recursive-bound-eval.rs new file mode 100644 index 00000000000..7859c8983fc --- /dev/null +++ b/tests/ui/impl-trait/recursive-bound-eval.rs @@ -0,0 +1,24 @@ +//! Test that we can evaluate nested obligations when invoking methods on recursive calls on +//! an RPIT. + +//@revisions: next current +//@[next] compile-flags: -Znext-solver + +//@[current] check-pass + +pub trait Parser<E> { + fn parse(&self) -> E; +} + +impl<E, T: Fn() -> E> Parser<E> for T { + fn parse(&self) -> E { + self() + } +} + +pub fn recursive_fn<E>() -> impl Parser<E> { + move || recursive_fn().parse() + //[next]~^ ERROR: type annotations needed +} + +fn main() {} diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs index 7874a21f3ae..aab10be2de2 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.rs @@ -11,7 +11,7 @@ impl PartialEq<(Bar, i32)> for Bar { } fn foo() -> Foo { - //~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` + //~^ ERROR can't compare `Bar` with `(Foo, i32)` Bar } diff --git a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr index 2d4707f8a27..bc810c0f88f 100644 --- a/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr +++ b/tests/ui/impl-trait/recursive-type-alias-impl-trait-declaration.stderr @@ -1,9 +1,15 @@ -error[E0275]: overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` +error[E0277]: can't compare `Bar` with `(Foo, i32)` --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13 | LL | fn foo() -> Foo { - | ^^^ + | ^^^ no implementation for `Bar == (Foo, i32)` +LL | +LL | Bar + | --- return type was inferred to be `Bar` here + | + = help: the trait `PartialEq<(Foo, i32)>` is not implemented for `Bar` + = help: the trait `PartialEq<(Bar, i32)>` is implemented for `Bar` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr new file mode 100644 index 00000000000..c215d197db4 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.current.stderr @@ -0,0 +1,11 @@ +error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied + --> $DIR/constrain_in_projection.rs:24:14 + | +LL | let x = <Foo as Trait<Bar>>::Assoc::default(); + | ^^^ the trait `Trait<Bar>` is not implemented for `Foo` + | + = help: the trait `Trait<()>` is implemented for `Foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs index 2a246900106..7d7d16361ae 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@check-pass +//@[next]check-pass #![feature(type_alias_impl_trait)] @@ -22,6 +22,7 @@ impl Trait<()> for Foo { fn bop(_: Bar) { let x = <Foo as Trait<Bar>>::Assoc::default(); + //[current]~^ `Foo: Trait<Bar>` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr index 0d6eac4216b..69df5c77f9d 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.current.stderr @@ -1,19 +1,13 @@ -error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>` +error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied --> $DIR/constrain_in_projection2.rs:27:14 | LL | let x = <Foo as Trait<Bar>>::Assoc::default(); - | ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc` + | ^^^ the trait `Trait<Bar>` is not implemented for `Foo` | -note: multiple `impl`s satisfying `Foo: Trait<Bar>` found - --> $DIR/constrain_in_projection2.rs:18:1 - | -LL | impl Trait<()> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^ -... -LL | impl Trait<u32> for Foo { - | ^^^^^^^^^^^^^^^^^^^^^^^ - = note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl` + = help: the following other types implement trait `Trait<T>`: + <Foo as Trait<()>> + <Foo as Trait<u32>> error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs index 0066131f015..af222f6c153 100644 --- a/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs +++ b/tests/ui/type-alias-impl-trait/constrain_in_projection2.rs @@ -25,7 +25,8 @@ impl Trait<u32> for Foo { fn bop(_: Bar) { let x = <Foo as Trait<Bar>>::Assoc::default(); - //~^ ERROR: cannot satisfy `Foo: Trait<Bar>` + //[next]~^ ERROR: cannot satisfy `Foo: Trait<Bar>` + //[current]~^^ ERROR: `Foo: Trait<Bar>` is not satisfied } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs index 99a5d36066b..fd1f3c6353c 100644 --- a/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs +++ b/tests/ui/type-alias-impl-trait/issue-84660-unsoundness.rs @@ -20,7 +20,7 @@ trait Trait<T, In> { impl<In, Out> Trait<Bar, In> for Out { type Out = Out; fn convert(_i: In) -> Self::Out { - //[next]~^ ERROR: type annotations needed + //[next]~^ ERROR: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()` unreachable!(); } } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr index 172ecded7a2..34532afcbba 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied - --> $DIR/nested-tait-inference.rs:12:13 + --> $DIR/nested-tait-inference.rs:17:13 | LL | fn foo() -> impl Foo<FooX> { | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()` diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs index 70495c44706..50d51c7faf9 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -4,7 +4,7 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@check-pass +//@[next] check-pass use std::fmt::Debug; @@ -15,6 +15,8 @@ trait Foo<A> {} impl Foo<()> for () {} fn foo() -> impl Foo<FooX> { + //[current]~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied + // FIXME(type-alias-impl-trait): We could probably make this work. () } diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr index c7b7af152ab..614bc09872f 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.current.stderr @@ -1,17 +1,16 @@ -error[E0283]: type annotations needed: cannot satisfy `(): Foo<FooX>` +error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied --> $DIR/nested-tait-inference2.rs:17:13 | LL | fn foo() -> impl Foo<FooX> { - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()` +LL | +LL | () + | -- return type was inferred to be `()` here | -note: multiple `impl`s satisfying `(): Foo<FooX>` found - --> $DIR/nested-tait-inference2.rs:14:1 - | -LL | impl Foo<()> for () {} - | ^^^^^^^^^^^^^^^^^^^ -LL | impl Foo<u32> for () {} - | ^^^^^^^^^^^^^^^^^^^^ + = help: the following other types implement trait `Foo<A>`: + <() as Foo<()>> + <() as Foo<u32>> error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs index fe2f76e552a..28d72b0cbee 100644 --- a/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/tests/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -15,7 +15,7 @@ impl Foo<()> for () {} impl Foo<u32> for () {} fn foo() -> impl Foo<FooX> { - //[current]~^ ERROR: cannot satisfy `(): Foo<FooX>` + //[current]~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied () //[next]~^ ERROR: cannot satisfy `impl Foo<FooX> == ()` } diff --git a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr index eff29303bf1..a40dac06a01 100644 --- a/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr +++ b/tests/ui/type-alias-impl-trait/normalize-hidden-types.current.stderr @@ -22,17 +22,21 @@ note: previous use here LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } | ^^^^^^^^^^^^^^^^^ -error: concrete type differs from previous defining opaque type use +error[E0308]: mismatched types --> $DIR/normalize-hidden-types.rs:43:25 | +LL | type Opaque = impl Sized; + | ---------- the expected opaque type +... LL | let _: Opaque = dyn_hoops::<u8>(0); - | ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)` - | -note: previous use here - --> $DIR/normalize-hidden-types.rs:44:9 - | -LL | None - | ^^^^ + | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())` + | | + | expected due to this + | + = note: expected opaque type `typeck::Opaque` + found raw pointer `*const (dyn FnOnce(()) + 'static)` + = help: consider constraining the associated type `<u8 as Trait>::Gat<'_>` to `()` or calling a method that returns `<u8 as Trait>::Gat<'_>` + = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html error: concrete type differs from previous defining opaque type use --> $DIR/normalize-hidden-types.rs:52:25 @@ -48,3 +52,4 @@ LL | None error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr new file mode 100644 index 00000000000..3ae3590ca7f --- /dev/null +++ b/tests/ui/type-alias-impl-trait/self-referential-2.current.stderr @@ -0,0 +1,14 @@ +error[E0277]: can't compare `i32` with `Foo` + --> $DIR/self-referential-2.rs:10:13 + | +LL | fn bar() -> Bar { + | ^^^ no implementation for `i32 == Foo` +LL | 42_i32 + | ------ return type was inferred to be `i32` here + | + = help: the trait `PartialEq<Foo>` is not implemented for `i32` + = help: the trait `PartialEq` is implemented for `i32` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/type-alias-impl-trait/self-referential-2.rs b/tests/ui/type-alias-impl-trait/self-referential-2.rs index f4102f2e2cb..f96364ccfcd 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-2.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-2.rs @@ -1,14 +1,14 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -//@ check-pass +//@[next] check-pass #![feature(type_alias_impl_trait)] type Foo = impl std::fmt::Debug; type Bar = impl PartialEq<Foo>; fn bar() -> Bar { - 42_i32 + 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo` } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.rs b/tests/ui/type-alias-impl-trait/self-referential-3.rs index 3b015ab322a..b33051da2d7 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.rs +++ b/tests/ui/type-alias-impl-trait/self-referential-3.rs @@ -5,7 +5,7 @@ type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug; fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - //~^ ERROR overflow normalizing the type alias `Bar<'a, 'b>` + //~^ ERROR can't compare `&i32` with `Bar<'a, 'b>` i } diff --git a/tests/ui/type-alias-impl-trait/self-referential-3.stderr b/tests/ui/type-alias-impl-trait/self-referential-3.stderr index caa9f9691dd..32eac622e51 100644 --- a/tests/ui/type-alias-impl-trait/self-referential-3.stderr +++ b/tests/ui/type-alias-impl-trait/self-referential-3.stderr @@ -1,11 +1,15 @@ -error[E0275]: overflow normalizing the type alias `Bar<'a, 'b>` +error[E0277]: can't compare `&i32` with `Bar<'a, 'b>` --> $DIR/self-referential-3.rs:7:31 | LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ no implementation for `&i32 == Bar<'a, 'b>` +LL | +LL | i + | - return type was inferred to be `&i32` here | - = note: in case this is a recursive type alias, consider using a struct, enum, or union instead + = help: the trait `PartialEq<Bar<'a, 'b>>` is not implemented for `&i32` + = help: the trait `PartialEq` is implemented for `i32` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0277`. |
