Skip to content

Commit 1b08d1a

Browse files
Rollup merge of #121702 - compiler-errors:coerce-alias-relate, r=lcnr
Process alias-relate obligations in CoerceUnsized loop After #119106, we now emit `AliasRelate` goals when relating `?0` and `Alias<T, ..>` in the new solver. In the ad-hoc `CoerceUnsized` selection loop, we now may have `AliasRelate` goals which must be processed to constrain type variables which are mentioned in other goals. --- For example, in the included test, we try to coerce `&<ManuallyDrop<T> as Deref>::Target` to `&dyn Foo`. This requires proving: * 1 `&<ManuallyDrop<T> as Deref>::Target: CoerceUnsized<&dyn Foo>` * 2 `<ManuallyDrop<T> as Deref>::Target alias-relate ?0` * 3 `?0: Unsize<dyn Foo>` * 4 `?0: Foo` * 5 `?0: Sized` If we don't process goal (2.) before processing goal (3.), then we hit ambiguity since `?0` is never constrained, and therefore we bail out, refusing to coerce the types. After processing (2.), we know `?0 := T`, and the rest of the goals can be processed normally.
2 parents ca69a1f + cc584ba commit 1b08d1a

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+14
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,20 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
636636
{
637637
self.resolve_vars_if_possible(trait_pred)
638638
}
639+
// Eagerly process alias-relate obligations in new trait solver,
640+
// since these can be emitted in the process of solving trait goals,
641+
// but we need to constrain vars before processing goals mentioning
642+
// them.
643+
Some(ty::PredicateKind::AliasRelate(..)) => {
644+
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
645+
fulfill_cx.register_predicate_obligation(self, obligation);
646+
let errs = fulfill_cx.select_where_possible(self);
647+
if !errs.is_empty() {
648+
return Err(TypeError::Mismatch);
649+
}
650+
coercion.obligations.extend(fulfill_cx.pending_obligations());
651+
continue;
652+
}
639653
_ => {
640654
coercion.obligations.push(obligation);
641655
continue;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
use std::mem::ManuallyDrop;
5+
6+
trait Foo {}
7+
8+
struct Guard<T> {
9+
value: ManuallyDrop<T>,
10+
}
11+
12+
impl<T: Foo> Guard<T> {
13+
fn uwu(&self) {
14+
let x: &dyn Foo = &*self.value;
15+
}
16+
}
17+
18+
fn main() {}

0 commit comments

Comments
 (0)