Revert "When checking whether an impl applies, constrain hidden types of opaque types."

This reverts commit 29a630eb72.
This commit is contained in:
Oli Scherer 2024-06-11 06:49:12 +00:00
parent fe55c0091d
commit 6cca6da126
25 changed files with 120 additions and 171 deletions

View File

@ -2563,7 +2563,7 @@ fn match_impl(
let InferOk { obligations, .. } = self let InferOk { obligations, .. } = self
.infcx .infcx
.at(&cause, obligation.param_env) .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| { .map_err(|e| {
debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx()))
})?; })?;

View File

@ -22,7 +22,7 @@ fn sum_to(n: u32) -> impl Foo {
0 0
} else { } else {
n + sum_to(n - 1) 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 { impl<T> Leak for T {
default type T = (); default type T = ();
default fn leak(self) -> Self::T { default fn leak(self) -> Self::T { panic!() }
panic!()
}
} }
impl Leak for i32 { impl Leak for i32 {
type T = i32; type T = i32;
fn leak(self) -> i32 { fn leak(self) -> i32 { self }
self
}
} }
fn main() {} fn main() {
}

View File

@ -22,13 +22,20 @@ help: change the type of the numeric literal from `u32` to `i32`
LL | 0_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 --> $DIR/equality.rs:24:11
| |
LL | n + sum_to(n - 1) 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 error: aborting due to 2 previous errors; 1 warning emitted
Some errors have detailed explanations: E0284, E0308. Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0284`. For more information about an error, try `rustc --explain E0277`.

View File

@ -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 --> $DIR/nested_impl_trait.rs:6:46
| |
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x } 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 = help: the trait `Into<U>` is implemented for `T`
| = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
LL | fn bad_in_ret_position(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++
error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
--> $DIR/nested_impl_trait.rs:19:34 --> $DIR/nested_impl_trait.rs:19:34
| |
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } LL | fn bad(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 = help: the trait `Into<U>` is implemented for `T`
| = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
LL | fn bad(x: impl Into<u32> + std::fmt::Debug) -> impl Into<impl Debug> { x }
| +++++++++++++++++
error: aborting due to 7 previous errors error: aborting due to 7 previous errors

View File

@ -1,3 +1,8 @@
//! Test that we can evaluate nested obligations when invoking methods on recursive calls on
//! an RPIT.
//@ check-pass
pub trait Parser<E> { pub trait Parser<E> {
fn parse(&self) -> E; fn parse(&self) -> E;
} }
@ -9,10 +14,7 @@ fn parse(&self) -> E {
} }
pub fn recursive_fn<E>() -> impl Parser<E> { pub fn recursive_fn<E>() -> impl Parser<E> {
//~^ ERROR: cycle detected
move || recursive_fn().parse() move || recursive_fn().parse()
//~^ ERROR: type annotations needed
//~| ERROR: no method named `parse` found for opaque type
} }
fn main() {} fn main() {}

View File

@ -1,42 +0,0 @@
error[E0282]: type annotations needed
--> $DIR/recursive-bound-eval.rs:13:28
|
LL | move || recursive_fn().parse()
| ^^^^^ cannot infer type
error[E0599]: no method named `parse` found for opaque type `impl Parser<_>` in the current scope
--> $DIR/recursive-bound-eval.rs:13:28
|
LL | move || recursive_fn().parse()
| ^^^^^ method not found in `impl Parser<_>`
|
= help: items from traits can only be used if the trait is implemented and in scope
help: trait `Parser` which provides `parse` is implemented but not in scope; perhaps you want to import it
|
LL + use Parser;
|
error[E0391]: cycle detected when computing type of opaque `recursive_fn::{opaque#0}`
--> $DIR/recursive-bound-eval.rs:11:29
|
LL | pub fn recursive_fn<E>() -> impl Parser<E> {
| ^^^^^^^^^^^^^^
|
note: ...which requires type-checking `recursive_fn`...
--> $DIR/recursive-bound-eval.rs:13:13
|
LL | move || recursive_fn().parse()
| ^^^^^^^^^^^^^^
= note: ...which requires evaluating trait selection obligation `recursive_fn::{opaque#0}: core::marker::Unpin`...
= note: ...which again requires computing type of opaque `recursive_fn::{opaque#0}`, completing the cycle
note: cycle used when computing type of `recursive_fn::{opaque#0}`
--> $DIR/recursive-bound-eval.rs:11:29
|
LL | pub fn recursive_fn<E>() -> impl Parser<E> {
| ^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0282, E0391, E0599.
For more information about an error, try `rustc --explain E0282`.

View File

@ -11,7 +11,7 @@ fn eq(&self, _other: &(Bar, i32)) -> bool {
} }
fn foo() -> Foo { fn foo() -> Foo {
//~^ ERROR overflow evaluating the requirement `Bar: PartialEq<(Foo, i32)>` //~^ ERROR can't compare `Bar` with `(Foo, i32)`
Bar Bar
} }

View File

@ -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 --> $DIR/recursive-type-alias-impl-trait-declaration.rs:13:13
| |
LL | fn foo() -> Foo { 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 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`.

View File

@ -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`.

View File

@ -4,7 +4,7 @@
//@ revisions: current next //@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
//@check-pass //@[next]check-pass
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
@ -22,6 +22,7 @@ impl Trait<()> for Foo {
fn bop(_: Bar) { fn bop(_: Bar) {
let x = <Foo as Trait<Bar>>::Assoc::default(); let x = <Foo as Trait<Bar>>::Assoc::default();
//[current]~^ `Foo: Trait<Bar>` is not satisfied
} }
fn main() {} fn main() {}

View File

@ -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 --> $DIR/constrain_in_projection2.rs:27:14
| |
LL | let x = <Foo as Trait<Bar>>::Assoc::default(); 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 = help: the following other types implement trait `Trait<T>`:
--> $DIR/constrain_in_projection2.rs:18:1 <Foo as Trait<()>>
| <Foo as Trait<u32>>
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`
error: aborting due to 1 previous error 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`.

View File

@ -25,7 +25,8 @@ impl Trait<u32> for Foo {
fn bop(_: Bar) { fn bop(_: Bar) {
let x = <Foo as Trait<Bar>>::Assoc::default(); 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() {} fn main() {}

View File

@ -1,23 +0,0 @@
error[E0284]: type annotations needed: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
--> $DIR/issue-84660-unsoundness.rs:22:37
|
LL | fn convert(_i: In) -> Self::Out {
| _____________________________________^
LL | |
LL | | unreachable!();
LL | | }
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:28:1
|
LL | impl<In, Out> Trait<Bar, In> for Out {
| ------------------------------------ first implementation here
...
LL | impl<In, Out> Trait<(), In> for Out {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0119, E0284.
For more information about an error, try `rustc --explain E0119`.

View File

@ -1,10 +1,6 @@
// Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an // Another example from issue #84660, this time weaponized as a safe transmute: an opaque type in an
// impl header being accepted was used to create unsoundness. // impl header being accepted was used to create unsoundness.
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
trait Foo {} trait Foo {}
@ -20,13 +16,11 @@ trait Trait<T, In> {
impl<In, Out> Trait<Bar, In> for Out { impl<In, Out> Trait<Bar, In> for Out {
type Out = Out; type Out = Out;
fn convert(_i: In) -> Self::Out { fn convert(_i: In) -> Self::Out {
//[next]~^ ERROR: type annotations needed
unreachable!(); unreachable!();
} }
} }
impl<In, Out> Trait<(), In> for Out { impl<In, Out> Trait<(), In> for Out { //~ ERROR conflicting implementations of trait `Trait<Bar, _>`
//~^ ERROR conflicting implementations of trait `Trait<Bar, _>`
type Out = In; type Out = In;
fn convert(i: In) -> Self::Out { fn convert(i: In) -> Self::Out {
i i

View File

@ -1,5 +1,5 @@
error[E0119]: conflicting implementations of trait `Trait<Bar, _>` error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:28:1 --> $DIR/issue-84660-unsoundness.rs:23:1
| |
LL | impl<In, Out> Trait<Bar, In> for Out { LL | impl<In, Out> Trait<Bar, In> for Out {
| ------------------------------------ first implementation here | ------------------------------------ first implementation here

View File

@ -1,21 +1,18 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
#![allow(dead_code)] #![allow(dead_code)]
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
//@check-pass
use std::fmt::Debug; use std::fmt::Debug;
type FooX = impl Debug; type FooX = impl Debug;
trait Foo<A> {} trait Foo<A> { }
impl Foo<()> for () {} impl Foo<()> for () { }
fn foo() -> impl Foo<FooX> { fn foo() -> impl Foo<FooX> {
//~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
// FIXME(type-alias-impl-trait): We could probably make this work.
() ()
} }
fn main() {} fn main() { }

View File

@ -1,17 +0,0 @@
error[E0283]: type annotations needed: cannot satisfy `(): Foo<FooX>`
--> $DIR/nested-tait-inference2.rs:17:13
|
LL | fn foo() -> impl Foo<FooX> {
| ^^^^^^^^^^^^^^
|
note: multiple `impl`s satisfying `(): Foo<FooX>` found
--> $DIR/nested-tait-inference2.rs:14:1
|
LL | impl Foo<()> for () {}
| ^^^^^^^^^^^^^^^^^^^
LL | impl Foo<u32> for () {}
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -1,9 +0,0 @@
error[E0284]: type annotations needed: cannot satisfy `impl Foo<FooX> == ()`
--> $DIR/nested-tait-inference2.rs:19:5
|
LL | ()
| ^^ cannot satisfy `impl Foo<FooX> == ()`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0284`.

View File

@ -1,10 +1,6 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
#![allow(dead_code)] #![allow(dead_code)]
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
use std::fmt::Debug; use std::fmt::Debug;
type FooX = impl Debug; type FooX = impl Debug;
@ -15,9 +11,8 @@ impl Foo<()> for () {}
impl Foo<u32> for () {} impl Foo<u32> for () {}
fn foo() -> impl Foo<FooX> { fn foo() -> impl Foo<FooX> {
//[current]~^ ERROR: cannot satisfy `(): Foo<FooX>` //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied
() ()
//[next]~^ ERROR: cannot satisfy `impl Foo<FooX> == ()`
} }
fn main() {} fn main() {}

View File

@ -0,0 +1,16 @@
error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
--> $DIR/nested-tait-inference2.rs:13:13
|
LL | fn foo() -> impl Foo<FooX> {
| ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
LL |
LL | ()
| -- return type was inferred to be `()` here
|
= 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 E0277`.

View File

@ -22,17 +22,21 @@ note: previous use here
LL | fn define_1() -> Opaque { dyn_hoops::<_>(0) } 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 --> $DIR/normalize-hidden-types.rs:43:25
| |
LL | type Opaque = impl Sized;
| ---------- the expected opaque type
...
LL | let _: Opaque = dyn_hoops::<u8>(0); LL | let _: Opaque = dyn_hoops::<u8>(0);
| ^^^^^^^^^^^^^^^^^^ expected `*const (dyn FnOnce(()) + 'static)`, got `*const dyn for<'a> FnOnce(<u8 as Trait>::Gat<'a>)` | ------ ^^^^^^^^^^^^^^^^^^ expected opaque type, found `*const dyn FnOnce(())`
| |
| expected due to this
| |
note: previous use here = note: expected opaque type `typeck::Opaque`
--> $DIR/normalize-hidden-types.rs:44:9 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<'_>`
LL | None = 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 error: concrete type differs from previous defining opaque type use
--> $DIR/normalize-hidden-types.rs:52:25 --> $DIR/normalize-hidden-types.rs:52:25
@ -48,3 +52,4 @@ LL | None
error: aborting due to 4 previous errors error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -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`.

View File

@ -1,14 +1,14 @@
//@ revisions: current next //@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions) //@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver //@[next] compile-flags: -Znext-solver
//@ check-pass //@[next] check-pass
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
type Foo = impl std::fmt::Debug; type Foo = impl std::fmt::Debug;
type Bar = impl PartialEq<Foo>; type Bar = impl PartialEq<Foo>;
fn bar() -> Bar { fn bar() -> Bar {
42_i32 42_i32 //[current]~^ ERROR can't compare `i32` with `Foo`
} }
fn main() {} fn main() {}

View File

@ -5,7 +5,7 @@
type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug; type Bar<'a, 'b> = impl PartialEq<Bar<'a, 'b>> + std::fmt::Debug;
fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { 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 i
} }

View File

@ -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 --> $DIR/self-referential-3.rs:7:31
| |
LL | fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> { 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 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`.