Rollup merge of #125447 - oli-obk:eq_opaque_pred, r=compiler-errors

Allow constraining opaque types during subtyping in the trait system

Previous attempt: https://github.com/rust-lang/rust/pull/123979

Sometimes we don't immediately perform subtyping, but instead register a subtyping obligation and solve that obligation when its inference variables become resolved. Unlike immediate subtyping, we currently do not allow registering hidden types for opaque types. This PR also allows that.
This commit is contained in:
León Orell Valerian Liehr 2024-06-19 13:04:56 +02:00 committed by GitHub
commit 25d47fe388
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 37 additions and 87 deletions

View File

@ -878,9 +878,9 @@ pub fn subtype_predicate(
self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
if a_is_expected {
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b))
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
} else {
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a))
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
}
})
}

View File

@ -2,58 +2,23 @@
//! No hidden types are being constrained in the subtyping predicate, but type and
//! lifetime variables get subtyped in the generic parameter list of the opaque.
use std::iter;
//@ check-pass
mod either {
pub enum Either<L, R> {
Left(L),
Right(R),
}
impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for Either<L, R> {
type Item = L::Item;
fn next(&mut self) -> Option<Self::Item> {
todo!()
}
}
pub use self::Either::{Left, Right};
}
pub enum BabeConsensusLogRef<'a> {
NextEpochData(BabeNextEpochRef<'a>),
NextConfigData,
}
impl<'a> BabeConsensusLogRef<'a> {
pub fn scale_encoding(
&self,
) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
//~^ ERROR is not satisfied
//~| ERROR is not satisfied
//~| ERROR is not satisfied
match self {
BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left(
digest.scale_encoding().map(either::Left).map(either::Left),
)),
BabeConsensusLogRef::NextConfigData => either::Right(
// The Opaque type from ``scale_encoding` gets used opaquely here, while the `R`
// generic parameter of `Either` contains type variables that get subtyped and the
// opaque type contains lifetime variables that get subtyped.
iter::once(either::Right(either::Left([1])))
.chain(std::iter::once([1]).map(either::Right).map(either::Right)),
),
}
}
}
pub struct BabeNextEpochRef<'a>(&'a ());
impl<'a> BabeNextEpochRef<'a> {
pub fn scale_encoding(
&self,
) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
std::iter::once([1])
fn foo() -> impl Default + Copy {
if false {
let x = Default::default();
// add `Subtype(?x, ?y)` obligation
let y = x;
// Make a tuple `(?x, ?y)` and equate it with `(impl Default, u32)`.
// For us to try and prove a `Subtype(impl Default, u32)` obligation,
// we have to instantiate both `?x` and `?y` without any
// `select_where_possible` calls inbetween.
let mut tup = &mut (x, y);
let assign_tup = &mut (foo(), 1u32);
tup = assign_tup;
}
1u32
}
fn main() {}

View File

@ -1,21 +0,0 @@
error[E0277]: the trait bound `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>: Clone` is not satisfied
--> $DIR/lazy_subtyping_of_opaques.rs:30:10
|
LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<Map<Map<impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_, fn(impl AsRef<[u8]> + Clone + '_) -> Either<impl AsRef<[u8]> + Clone + '_, _> {Either::<impl AsRef<[u8]> + Clone + '_, _>::Left}>, fn(Either<impl AsRef<[u8]> + Clone + '_, _>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Left}>, _>, std::iter::Chain<std::iter::Once<Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>>, Map<Map<std::iter::Once<[{integer}; 1]>, fn([{integer}; 1]) -> Either<[{integer}; 1], [{integer}; 1]> {Either::<[{integer}; 1], [{integer}; 1]>::Right}>, fn(Either<[{integer}; 1], [{integer}; 1]>) -> Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>> {Either::<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>::Right}>>>`
error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: AsRef<[u8]>` is not satisfied
--> $DIR/lazy_subtyping_of_opaques.rs:30:31
|
LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `AsRef<[u8]>` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
error[E0277]: the trait bound `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>: Clone` is not satisfied
--> $DIR/lazy_subtyping_of_opaques.rs:30:31
|
LL | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `Either<Either<impl AsRef<[u8]> + Clone + '_, _>, Either<[{integer}; 1], [{integer}; 1]>>`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -7,9 +7,10 @@
type Tait = impl FnOnce() -> ();
fn reify_as_tait() -> Thunk<Tait> {
//~^ ERROR: expected a `FnOnce()` closure, found `()`
Thunk::new(|cont| cont)
//~^ ERROR: mismatched types
//~| ERROR: mismatched types
//~| ERROR: expected a `FnOnce()` closure, found `()`
}
struct Thunk<F>(F);

View File

@ -1,26 +1,31 @@
error[E0308]: mismatched types
--> $DIR/lazy_subtyping_of_opaques.rs:10:23
error[E0277]: expected a `FnOnce()` closure, found `()`
--> $DIR/lazy_subtyping_of_opaques.rs:11:23
|
LL | type Tait = impl FnOnce() -> ();
| ------------------- the found opaque type
...
LL | Thunk::new(|cont| cont)
| ^^^^ expected `()`, found opaque type
| ^^^^ expected an `FnOnce()` closure, found `()`
|
= note: expected unit type `()`
found opaque type `Tait`
= help: the trait `FnOnce()` is not implemented for `()`
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
error[E0308]: mismatched types
--> $DIR/lazy_subtyping_of_opaques.rs:10:5
error[E0277]: expected a `FnOnce()` closure, found `()`
--> $DIR/lazy_subtyping_of_opaques.rs:9:23
|
LL | fn reify_as_tait() -> Thunk<Tait> {
| ----------- expected `Thunk<_>` because of return type
| ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()`
|
= help: the trait `FnOnce()` is not implemented for `()`
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
error[E0308]: mismatched types
--> $DIR/lazy_subtyping_of_opaques.rs:11:5
|
LL | Thunk::new(|cont| cont)
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()`
|
= note: expected struct `Thunk<_>`
found unit type `()`
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.