File: closure-signature-inference-hr-ambig-alias-naming-self.rs

package info (click to toggle)
rustc 1.86.0%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid
  • size: 913,560 kB
  • sloc: xml: 158,127; python: 35,921; javascript: 19,689; sh: 19,600; cpp: 18,906; ansic: 13,124; asm: 4,376; makefile: 708; perl: 29; lisp: 29; ruby: 19; sql: 11
file content (52 lines) | stat: -rw-r--r-- 1,843 bytes parent folder | download | duplicates (3)
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
46
47
48
49
50
51
52
//@ check-pass
//@ revisions: current next
//@[next] compile-flags: -Znext-solver

// When type checking a closure expr we look at the list of unsolved goals
// to determine if there are any bounds on the closure type to infer a signature from.
//
// We attempt to discard goals that name the closure type so as to avoid inferring the
// closure type to something like `?x = closure(sig=fn(?x))`. This test checks that when
// such a goal names the closure type inside of an ambiguous alias and there exists another
// potential goal to infer the closure signature from, we do that.

trait Trait<'a> {
    type Assoc;
}

impl<'a, F> Trait<'a> for F {
    type Assoc = u32;
}

fn closure_typer1<F>(_: F)
where
    F: Fn(u32) + for<'a> Fn(<F as Trait<'a>>::Assoc),
{
}

fn closure_typer2<F>(_: F)
where
    F: for<'a> Fn(<F as Trait<'a>>::Assoc) + Fn(u32),
{
}

fn main() {
    // Here we have some closure with a yet to be inferred type of `?c`. There are two goals
    // involving `?c` that can be used to determine the closure signature:
    // - `?c: for<'a> Fn<(<?c as Trait<'a>>::Assoc,), Output = ()>`
    // - `?c: Fn<(u32,), Output = ()>`
    //
    // If we were to infer the argument of the closure (`x` below) to `<?c as Trait<'a>>::Assoc`
    // then we would not be able to call `x.into()` as `x` is some unknown type. Instead we must
    // use the `?c: Fn(u32)` goal to infer a signature in order for this code to compile.
    //
    // As the algorithm for picking a goal to infer the signature from is dependent on the ordering
    // of pending goals in the type checker, we test both orderings of bounds to ensure we aren't
    // testing that we just *happen* to pick `?c: Fn(u32)`.
    closure_typer1(move |x| {
        let _: u32 = x.into();
    });
    closure_typer2(move |x| {
        let _: u32 = x.into();
    });
}