Skip to content

Commit ba4510e

Browse files
committed
Allow constraining opaque types during subtyping in the trait system
1 parent 9889a6f commit ba4510e

File tree

5 files changed

+38
-88
lines changed

5 files changed

+38
-88
lines changed

compiler/rustc_infer/src/infer/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -878,9 +878,9 @@ impl<'tcx> InferCtxt<'tcx> {
878878

879879
self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
880880
if a_is_expected {
881-
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b))
881+
Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b))
882882
} else {
883-
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a))
883+
Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a))
884884
}
885885
})
886886
}

tests/ui/impl-trait/lazy_subtyping_of_opaques.rs

+16-51
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,23 @@
22
//! No hidden types are being constrained in the subtyping predicate, but type and
33
//! lifetime variables get subtyped in the generic parameter list of the opaque.
44
5-
use std::iter;
6-
7-
mod either {
8-
pub enum Either<L, R> {
9-
Left(L),
10-
Right(R),
11-
}
12-
13-
impl<L: Iterator, R: Iterator<Item = L::Item>> Iterator for Either<L, R> {
14-
type Item = L::Item;
15-
fn next(&mut self) -> Option<Self::Item> {
16-
todo!()
17-
}
18-
}
19-
pub use self::Either::{Left, Right};
20-
}
21-
22-
pub enum BabeConsensusLogRef<'a> {
23-
NextEpochData(BabeNextEpochRef<'a>),
24-
NextConfigData,
25-
}
26-
27-
impl<'a> BabeConsensusLogRef<'a> {
28-
pub fn scale_encoding(
29-
&self,
30-
) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
31-
//~^ ERROR is not satisfied
32-
//~| ERROR is not satisfied
33-
//~| ERROR is not satisfied
34-
match self {
35-
BabeConsensusLogRef::NextEpochData(digest) => either::Left(either::Left(
36-
digest.scale_encoding().map(either::Left).map(either::Left),
37-
)),
38-
BabeConsensusLogRef::NextConfigData => either::Right(
39-
// The Opaque type from ``scale_encoding` gets used opaquely here, while the `R`
40-
// generic parameter of `Either` contains type variables that get subtyped and the
41-
// opaque type contains lifetime variables that get subtyped.
42-
iter::once(either::Right(either::Left([1])))
43-
.chain(std::iter::once([1]).map(either::Right).map(either::Right)),
44-
),
45-
}
46-
}
47-
}
48-
49-
pub struct BabeNextEpochRef<'a>(&'a ());
50-
51-
impl<'a> BabeNextEpochRef<'a> {
52-
pub fn scale_encoding(
53-
&self,
54-
) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
55-
std::iter::once([1])
5+
//@ check-pass
6+
7+
fn foo() -> impl Default + Copy {
8+
if false {
9+
let x = Default::default();
10+
// add `Subtype(?x, ?y)` obligation
11+
let y = x;
12+
13+
// Make a tuple `(?x, ?y)` and equate it with `(impl Default, u32)`.
14+
// For us to try and prove a `Subtype(impl Default, u32)` obligation,
15+
// we have to instantiate both `?x` and `?y` without any
16+
// `select_where_possible` calls inbetween.
17+
let mut tup = &mut (x, y);
18+
let assign_tup = &mut (foo(), 1u32);
19+
tup = assign_tup;
5620
}
21+
1u32
5722
}
5823

5924
fn main() {}

tests/ui/impl-trait/lazy_subtyping_of_opaques.stderr

-21
This file was deleted.

tests/ui/type-alias-impl-trait/lazy_subtyping_of_opaques.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
type Tait = impl FnOnce() -> ();
88

99
fn reify_as_tait() -> Thunk<Tait> {
10+
//~^ ERROR: expected a `FnOnce()` closure, found `()`
1011
Thunk::new(|cont| cont)
1112
//~^ ERROR: mismatched types
12-
//~| ERROR: mismatched types
13+
//~| ERROR: expected a `FnOnce()` closure, found `()`
1314
}
1415

1516
struct Thunk<F>(F);
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/lazy_subtyping_of_opaques.rs:10:23
1+
error[E0277]: expected a `FnOnce()` closure, found `()`
2+
--> $DIR/lazy_subtyping_of_opaques.rs:11:23
33
|
4-
LL | type Tait = impl FnOnce() -> ();
5-
| ------------------- the found opaque type
6-
...
74
LL | Thunk::new(|cont| cont)
8-
| ^^^^ expected `()`, found opaque type
5+
| ^^^^ expected an `FnOnce()` closure, found `()`
96
|
10-
= note: expected unit type `()`
11-
found opaque type `Tait`
7+
= help: the trait `FnOnce()` is not implemented for `()`
8+
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
129

13-
error[E0308]: mismatched types
14-
--> $DIR/lazy_subtyping_of_opaques.rs:10:5
10+
error[E0277]: expected a `FnOnce()` closure, found `()`
11+
--> $DIR/lazy_subtyping_of_opaques.rs:9:23
1512
|
1613
LL | fn reify_as_tait() -> Thunk<Tait> {
17-
| ----------- expected `Thunk<_>` because of return type
14+
| ^^^^^^^^^^^ expected an `FnOnce()` closure, found `()`
15+
|
16+
= help: the trait `FnOnce()` is not implemented for `()`
17+
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
18+
19+
error[E0308]: mismatched types
20+
--> $DIR/lazy_subtyping_of_opaques.rs:11:5
21+
|
1822
LL | Thunk::new(|cont| cont)
1923
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `Thunk<_>`, found `()`
2024
|
2125
= note: expected struct `Thunk<_>`
2226
found unit type `()`
2327

24-
error: aborting due to 2 previous errors
28+
error: aborting due to 3 previous errors
2529

26-
For more information about this error, try `rustc --explain E0308`.
30+
Some errors have detailed explanations: E0277, E0308.
31+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)