Allow constraining opaque types during subtyping in the trait system
This commit is contained in:
parent
9889a6f5d3
commit
ba4510ece8
@ -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))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
fn foo() -> impl Default + Copy {
|
||||
if false {
|
||||
let x = Default::default();
|
||||
// add `Subtype(?x, ?y)` obligation
|
||||
let y = x;
|
||||
|
||||
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])
|
||||
// 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() {}
|
||||
|
@ -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`.
|
@ -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);
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user