1
Fork 0
This commit is contained in:
Boxy 2025-02-15 02:01:41 +00:00
parent dc6db192c4
commit 6c3243f008
11 changed files with 181 additions and 5 deletions

View file

@ -1,11 +1,16 @@
static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5]; static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
//~^ ERROR the trait bound `String: Copy` is not satisfied //~^ ERROR the trait bound `String: Copy` is not satisfied
fn main() { // should hint to create an inline `const` block
// should hint to create an inline `const` block // or to create a new `const` item
// or to create a new `const` item fn foo() {
let _strings: [String; 5] = [String::new(); 5]; let _strings: [String; 5] = [String::new(); 5];
//~^ ERROR the trait bound `String: Copy` is not satisfied //~^ ERROR the trait bound `String: Copy` is not satisfied
}
fn bar() {
let _maybe_strings: [Option<String>; 5] = [None; 5]; let _maybe_strings: [Option<String>; 5] = [None; 5];
//~^ ERROR the trait bound `String: Copy` is not satisfied //~^ ERROR the trait bound `String: Copy` is not satisfied
} }
fn main() {}

View file

@ -22,7 +22,7 @@ LL | let _strings: [String; 5] = [String::new(); 5];
= note: the `Copy` trait is required because this value will be copied for each element of the array = note: the `Copy` trait is required because this value will be copied for each element of the array
error[E0277]: the trait bound `String: Copy` is not satisfied error[E0277]: the trait bound `String: Copy` is not satisfied
--> $DIR/const-fn-in-vec.rs:9:48 --> $DIR/const-fn-in-vec.rs:12:48
| |
LL | let _maybe_strings: [Option<String>; 5] = [None; 5]; LL | let _maybe_strings: [Option<String>; 5] = [None; 5];
| ^^^^ | ^^^^

View file

@ -0,0 +1,37 @@
#![feature(generic_arg_infer)]
// Test that would start passing if we defer repeat expr copy checks to end of
// typechecking and they're checked after integer fallback occurs. We accomplish
// this by contriving a situation where integer fallback allows progress to be
// made on a trait goal that infers the length of a repeat expr.
use std::marker::PhantomData;
struct NotCopy;
trait Trait<const N: usize> {}
impl Trait<2> for u32 {}
impl Trait<1> for i32 {}
fn make_goal<T: Trait<N>, const N: usize>(_: &T, _: [NotCopy; N]) {}
fn main() {
let a = 1;
let b = [NotCopy; _];
//~^ ERROR: type annotations needed
// a is of type `?y`
// b is of type `[NotCopy; ?x]`
// there is a goal ?y: Trait<?x>` with two candidates:
// - `i32: Trait<1>`, ?y=i32 ?x=1 which doesnt require `NotCopy: Copy`
// - `u32: Trait<2>` ?y=u32 ?x=2 which requires `NotCopy: Copy`
make_goal(&a, b);
// final repeat expr checks:
//
// `NotCopy; ?x`
// - succeeds if fallback happens before repeat exprs as `i32: Trait<?x>` infers `?x=1`
// - fails if repeat expr checks happen first as `?x` is unconstrained so cannot be
// structurally resolved
}

View file

@ -0,0 +1,14 @@
error[E0282]: type annotations needed for `[NotCopy; _]`
--> $DIR/copy-check-deferred-after-fallback.rs:21:9
|
LL | let b = [NotCopy; _];
| ^ ------- type must be known at this point
|
help: consider giving `b` an explicit type, where the value of const parameter `N` is specified
|
LL | let b: [_; N] = [NotCopy; _];
| ++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0282`.

View file

@ -0,0 +1,59 @@
//@ check-pass
#![feature(generic_arg_infer)]
// Test that if we defer repeat expr copy checks to end of typechecking they're
// checked before integer fallback occurs. We accomplish this by contriving a
// situation where we have a goal that can be proven either via another repeat expr
// check or by integer fallback. In the integer fallback case an array length would
// be inferred to `2` requiring `NotCopy: Copy`, and in the repeat expr case it would
// be inferred to `1`.
use std::marker::PhantomData;
struct NotCopy;
struct Foo<T>(PhantomData<T>);
impl Clone for Foo<u32> {
fn clone(&self) -> Self {
Foo(PhantomData)
}
}
impl Copy for Foo<u32> {}
fn tie<T>(_: &T, _: [Foo<T>; 2]) {}
trait Trait<const N: usize> {}
impl Trait<2> for i32 {}
impl Trait<1> for u32 {}
fn make_goal<T: Trait<N>, const N: usize>(_: &T, _: [NotCopy; N]) {}
fn main() {
let a = 1;
let b: [Foo<_>; 2] = [Foo(PhantomData); _];
tie(&a, b);
let c = [NotCopy; _];
// a is of type `?y`
// b is of type `[Foo<?y>; 2]`
// c is of type `[NotCopy; ?x]`
// there is a goal ?y: Trait<?x>` with two candidates:
// - `i32: Trait<2>`, ?y=i32 ?x=2 which requires `NotCopy: Copy` when expr checks happen
// - `u32: Trait<1>` ?y=u32 ?x=1 which doesnt require `NotCopy: Copy`
make_goal(&a, c);
// final repeat expr checks:
//
// `Foo<?y>; 2`
// - Foo<?y>: Copy
// - requires ?y=u32
//
// `NotCopy; ?x`
// - fails if fallback happens before repeat exprs as `i32: Trait<?x>` infers `?x=2`
// - succeeds if repeat expr checks happen first as `?y=u32` means `u32: Trait<?x>`
// infers `?x=1`
}

View file

@ -0,0 +1,17 @@
error[E0282]: type annotations needed for `[Foo<_>; 2]`
--> $DIR/copy-inference-side-effects-are-lazy.rs:22:9
|
LL | let x = [Foo(PhantomData); 2];
| ^
LL |
LL | _ = extract(x).max(2);
| ---------- type must be known at this point
|
help: consider giving `x` an explicit type, where the type for type parameter `T` is specified
|
LL | let x: [Foo<T>; 2] = [Foo(PhantomData); 2];
| +++++++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0282`.

View file

@ -1,4 +1,7 @@
//@ check-pass //@revisions: current gai
//@[current] check-pass
#![cfg_attr(gai, feature(generic_arg_infer))]
use std::marker::PhantomData; use std::marker::PhantomData;
@ -17,5 +20,6 @@ fn extract<T, const N: usize>(_: [Foo<T>; N]) -> T {
fn main() { fn main() {
let x = [Foo(PhantomData); 2]; let x = [Foo(PhantomData); 2];
//[gai]~^ ERROR: type annotations needed
_ = extract(x).max(2); _ = extract(x).max(2);
} }

View file

@ -0,0 +1,6 @@
//@ check-pass
#![feature(generic_arg_infer)]
fn main() {
let a: [_; 1] = [String::new(); _];
}

View file

@ -0,0 +1,20 @@
#![feature(generic_arg_infer)]
struct Foo<const N: usize>;
impl Clone for Foo<1> {
fn clone(&self) -> Self {
Foo
}
}
impl Copy for Foo<1> {}
fn unify<const N: usize>(_: &[Foo<N>; N]) {
loop {}
}
fn main() {
let x = &[Foo::<_>; _];
//~^ ERROR: type annotations needed for `&[Foo<_>; _]`
_ = unify(x);
}

View file

@ -0,0 +1,14 @@
error[E0282]: type annotations needed for `&[Foo<_>; _]`
--> $DIR/no-conservative-copy-impl-requirement.rs:17:9
|
LL | let x = &[Foo::<_>; _];
| ^ -------- type must be known at this point
|
help: consider giving `x` an explicit type, where the value of const parameter `N` is specified
|
LL | let x: &[Foo<N>; N] = &[Foo::<_>; _];
| ++++++++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0282`.