rust/tests/ui/repeat-expr/copy-check-const-element-un...

73 lines
2.2 KiB
Rust

#![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() {}