about summary refs log tree commit diff
path: root/tests/ui/repeat-expr/copy-check-const-element-uninferred-count.rs
blob: 6115146539c19524718bf3fc3aad842acd0289eb (plain)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#![feature(generic_arg_infer)]

// Test when deferring repeat expr copy checks to end of typechecking whether elements
// that are const items allow for repeat counts to go uninferred without an error being
// emitted if they would later wind up inferred by integer fallback.
//
// This test should be updated if we wind up deferring repeat expr checks until *after*
// integer fallback as the point of the test is not *specifically* about integer fallback
// but rather about the behaviour of `const` element exprs.

trait Trait<const N: usize> {}

// We impl `Trait` for both `i32` and `u32` to avoid being able
// to prove `?int: Trait<?n>` from there only being one impl.
impl Trait<2> for i32 {}
impl Trait<2> for u32 {}

fn tie_and_make_goal<const N: usize, T: Trait<N>>(_: &T, _: &[String; N]) {}

fn const_block() {
    // Deferred repeat expr `String; ?n`
    let a = [const { String::new() }; _];

    // `?int: Trait<?n>` goal
    tie_and_make_goal(&1, &a);

    // If repeat expr checks structurally resolve the `?n`s before checking if the
    // element is a `const` then we would error here. Otherwise we avoid doing so,
    // integer fallback occurs, allowing `?int: Trait<?n>` goals to make progress,
    // inferring the repeat counts (to `2` but that doesn't matter as the element is `const`).
}

fn const_item() {
    const MY_CONST: String = String::new();

    // Deferred repeat expr `String; ?n`
    let a = [MY_CONST; _];

    // `?int: Trait<?n>` goal
    tie_and_make_goal(&1, &a);

    // ... same as `const_block`
}

fn assoc_const() {
    trait Dummy {
        const ASSOC: String;
    }
    impl Dummy for () {
        const ASSOC: String = String::new();
    }

    // Deferred repeat expr `String; ?n`
    let a = [<() as Dummy>::ASSOC; _];

    // `?int: Trait<?n>` goal
    tie_and_make_goal(&1, &a);

    // ... same as `const_block`
}

fn const_block_but_uninferred() {
    // Deferred repeat expr `String; ?n`
    let a = [const { String::new() }; _];
    //~^ ERROR: type annotations needed for `[String; _]`

    // Even if we don't structurally resolve the repeat count as part of repeat expr
    // checks, we still error on the repeat count being uninferred as we require all
    // types/consts to be inferred by the end of type checking.
}

fn main() {}