| // 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() {} |