mirror of https://github.com/rust-lang/rust
46 lines
1.7 KiB
Rust
46 lines
1.7 KiB
Rust
//@ revisions: current next
|
|
//@[next] compile-flags: -Znext-solver=coherence
|
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
|
//@ check-pass
|
|
|
|
// A regression test for `paperclip-core`. This previously failed to compile
|
|
// in the new solver.
|
|
//
|
|
// Behavior in old solver:
|
|
// We prove `Projection(<W<?0> as Unconstrained>::Assoc, ())`. This
|
|
// normalizes `<W<?0> as Unconstrained>::Assoc` to `?1` with nested goals
|
|
// `[Projection(<?0 as Unconstrained>::Assoc, ?1), Trait(?1: NoImpl)]`.
|
|
// We then unify `?1` with `()`. At this point `?1: NoImpl` does not hold,
|
|
// and we get an error.
|
|
//
|
|
// Previous behavior of the new solver:
|
|
// We prove `Projection(<W<?0> as Unconstrained>::Assoc, ())`. This normalizes
|
|
// `<W<?0> as Unconstrained>::Assoc` to `?1` and eagerly computes the nested
|
|
// goals `[Projection(<?0 as Unconstrained>::Assoc, ?1), Trait(?1: NoImpl)]`.
|
|
// These goals are both ambiguous. `NormalizesTo`` then returns `?1` as the
|
|
// normalized-to type. It discards the nested goals, forcing the certainty of
|
|
// the normalization to `Maybe`. Unifying `?1` with `()` succeeds¹. However,
|
|
// this is never propagated to the `?1: NoImpl` goal, as it only exists inside
|
|
// of the `NormalizesTo` goal. The normalized-to term always starts out as
|
|
// unconstrained.
|
|
//
|
|
// We fix this regression by returning the nested goals of `NormalizesTo` goals
|
|
// to the `AliasRelate`. This results in us checking `(): NoImpl`, same as the
|
|
// old solver.
|
|
|
|
struct W<T: ?Sized>(T);
|
|
trait NoImpl {}
|
|
trait Unconstrained {
|
|
type Assoc;
|
|
}
|
|
impl<T: Unconstrained<Assoc = U>, U: NoImpl> Unconstrained for W<T> {
|
|
type Assoc = U;
|
|
}
|
|
|
|
|
|
trait Overlap {}
|
|
impl<T: Unconstrained<Assoc = ()>> Overlap for T {}
|
|
impl<U> Overlap for W<U> {}
|
|
|
|
fn main() {}
|