//@ 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( as Unconstrained>::Assoc, ())`. This // normalizes ` as Unconstrained>::Assoc` to `?1` with nested goals // `[Projection(::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( as Unconstrained>::Assoc, ())`. This normalizes // ` as Unconstrained>::Assoc` to `?1` and eagerly computes the nested // goals `[Projection(::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); trait NoImpl {} trait Unconstrained { type Assoc; } impl, U: NoImpl> Unconstrained for W { type Assoc = U; } trait Overlap {} impl> Overlap for T {} impl Overlap for W {} fn main() {}