File: indirectly-constrained-term.rs

package info (click to toggle)
rustc 1.85.0%2Bdfsg2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 893,176 kB
  • sloc: xml: 158,127; python: 35,830; javascript: 19,497; cpp: 19,002; sh: 17,245; ansic: 13,127; asm: 4,376; makefile: 1,051; lisp: 29; perl: 29; ruby: 19; sql: 11
file content (45 lines) | stat: -rw-r--r-- 1,736 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
//@ 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() {}