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.
This commit is contained in:
commit
1b08d1a92c
2 changed files with 32 additions and 0 deletions
|
@ -636,6 +636,20 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||||
{
|
{
|
||||||
self.resolve_vars_if_possible(trait_pred)
|
self.resolve_vars_if_possible(trait_pred)
|
||||||
}
|
}
|
||||||
|
// Eagerly process alias-relate obligations in new trait solver,
|
||||||
|
// since these can be emitted in the process of solving trait goals,
|
||||||
|
// but we need to constrain vars before processing goals mentioning
|
||||||
|
// them.
|
||||||
|
Some(ty::PredicateKind::AliasRelate(..)) => {
|
||||||
|
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
|
||||||
|
fulfill_cx.register_predicate_obligation(self, obligation);
|
||||||
|
let errs = fulfill_cx.select_where_possible(self);
|
||||||
|
if !errs.is_empty() {
|
||||||
|
return Err(TypeError::Mismatch);
|
||||||
|
}
|
||||||
|
coercion.obligations.extend(fulfill_cx.pending_obligations());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
coercion.obligations.push(obligation);
|
coercion.obligations.push(obligation);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
|
trait Foo {}
|
||||||
|
|
||||||
|
struct Guard<T> {
|
||||||
|
value: ManuallyDrop<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Foo> Guard<T> {
|
||||||
|
fn uwu(&self) {
|
||||||
|
let x: &dyn Foo = &*self.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue