Skip to content

Commit 6c3243f

Browse files
committed
Bless
1 parent dc6db19 commit 6c3243f

11 files changed

+181
-5
lines changed

tests/ui/consts/const-fn-in-vec.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
22
//~^ ERROR the trait bound `String: Copy` is not satisfied
33

4-
fn main() {
5-
// should hint to create an inline `const` block
6-
// or to create a new `const` item
4+
// should hint to create an inline `const` block
5+
// or to create a new `const` item
6+
fn foo() {
77
let _strings: [String; 5] = [String::new(); 5];
88
//~^ ERROR the trait bound `String: Copy` is not satisfied
9+
}
10+
11+
fn bar() {
912
let _maybe_strings: [Option<String>; 5] = [None; 5];
1013
//~^ ERROR the trait bound `String: Copy` is not satisfied
1114
}
15+
16+
fn main() {}

tests/ui/consts/const-fn-in-vec.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ LL | let _strings: [String; 5] = [String::new(); 5];
2222
= note: the `Copy` trait is required because this value will be copied for each element of the array
2323

2424
error[E0277]: the trait bound `String: Copy` is not satisfied
25-
--> $DIR/const-fn-in-vec.rs:9:48
25+
--> $DIR/const-fn-in-vec.rs:12:48
2626
|
2727
LL | let _maybe_strings: [Option<String>; 5] = [None; 5];
2828
| ^^^^
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#![feature(generic_arg_infer)]
2+
3+
// Test that would start passing if we defer repeat expr copy checks to end of
4+
// typechecking and they're checked after integer fallback occurs. We accomplish
5+
// this by contriving a situation where integer fallback allows progress to be
6+
// made on a trait goal that infers the length of a repeat expr.
7+
8+
use std::marker::PhantomData;
9+
10+
struct NotCopy;
11+
12+
trait Trait<const N: usize> {}
13+
14+
impl Trait<2> for u32 {}
15+
impl Trait<1> for i32 {}
16+
17+
fn make_goal<T: Trait<N>, const N: usize>(_: &T, _: [NotCopy; N]) {}
18+
19+
fn main() {
20+
let a = 1;
21+
let b = [NotCopy; _];
22+
//~^ ERROR: type annotations needed
23+
24+
// a is of type `?y`
25+
// b is of type `[NotCopy; ?x]`
26+
// there is a goal ?y: Trait<?x>` with two candidates:
27+
// - `i32: Trait<1>`, ?y=i32 ?x=1 which doesnt require `NotCopy: Copy`
28+
// - `u32: Trait<2>` ?y=u32 ?x=2 which requires `NotCopy: Copy`
29+
make_goal(&a, b);
30+
31+
// final repeat expr checks:
32+
//
33+
// `NotCopy; ?x`
34+
// - succeeds if fallback happens before repeat exprs as `i32: Trait<?x>` infers `?x=1`
35+
// - fails if repeat expr checks happen first as `?x` is unconstrained so cannot be
36+
// structurally resolved
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0282]: type annotations needed for `[NotCopy; _]`
2+
--> $DIR/copy-check-deferred-after-fallback.rs:21:9
3+
|
4+
LL | let b = [NotCopy; _];
5+
| ^ ------- type must be known at this point
6+
|
7+
help: consider giving `b` an explicit type, where the value of const parameter `N` is specified
8+
|
9+
LL | let b: [_; N] = [NotCopy; _];
10+
| ++++++++
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
//@ check-pass
2+
3+
#![feature(generic_arg_infer)]
4+
5+
// Test that if we defer repeat expr copy checks to end of typechecking they're
6+
// checked before integer fallback occurs. We accomplish this by contriving a
7+
// situation where we have a goal that can be proven either via another repeat expr
8+
// check or by integer fallback. In the integer fallback case an array length would
9+
// be inferred to `2` requiring `NotCopy: Copy`, and in the repeat expr case it would
10+
// be inferred to `1`.
11+
12+
use std::marker::PhantomData;
13+
14+
struct NotCopy;
15+
16+
struct Foo<T>(PhantomData<T>);
17+
18+
impl Clone for Foo<u32> {
19+
fn clone(&self) -> Self {
20+
Foo(PhantomData)
21+
}
22+
}
23+
24+
impl Copy for Foo<u32> {}
25+
26+
fn tie<T>(_: &T, _: [Foo<T>; 2]) {}
27+
28+
trait Trait<const N: usize> {}
29+
30+
impl Trait<2> for i32 {}
31+
impl Trait<1> for u32 {}
32+
33+
fn make_goal<T: Trait<N>, const N: usize>(_: &T, _: [NotCopy; N]) {}
34+
35+
fn main() {
36+
let a = 1;
37+
let b: [Foo<_>; 2] = [Foo(PhantomData); _];
38+
tie(&a, b);
39+
let c = [NotCopy; _];
40+
41+
// a is of type `?y`
42+
// b is of type `[Foo<?y>; 2]`
43+
// c is of type `[NotCopy; ?x]`
44+
// there is a goal ?y: Trait<?x>` with two candidates:
45+
// - `i32: Trait<2>`, ?y=i32 ?x=2 which requires `NotCopy: Copy` when expr checks happen
46+
// - `u32: Trait<1>` ?y=u32 ?x=1 which doesnt require `NotCopy: Copy`
47+
make_goal(&a, c);
48+
49+
// final repeat expr checks:
50+
//
51+
// `Foo<?y>; 2`
52+
// - Foo<?y>: Copy
53+
// - requires ?y=u32
54+
//
55+
// `NotCopy; ?x`
56+
// - fails if fallback happens before repeat exprs as `i32: Trait<?x>` infers `?x=2`
57+
// - succeeds if repeat expr checks happen first as `?y=u32` means `u32: Trait<?x>`
58+
// infers `?x=1`
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0282]: type annotations needed for `[Foo<_>; 2]`
2+
--> $DIR/copy-inference-side-effects-are-lazy.rs:22:9
3+
|
4+
LL | let x = [Foo(PhantomData); 2];
5+
| ^
6+
LL |
7+
LL | _ = extract(x).max(2);
8+
| ---------- type must be known at this point
9+
|
10+
help: consider giving `x` an explicit type, where the type for type parameter `T` is specified
11+
|
12+
LL | let x: [Foo<T>; 2] = [Foo(PhantomData); 2];
13+
| +++++++++++++
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0282`.

tests/ui/repeat-expr/infer-eager.rs renamed to tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
//@ check-pass
1+
//@revisions: current gai
2+
//@[current] check-pass
3+
4+
#![cfg_attr(gai, feature(generic_arg_infer))]
25

36
use std::marker::PhantomData;
47

@@ -17,5 +20,6 @@ fn extract<T, const N: usize>(_: [Foo<T>; N]) -> T {
1720

1821
fn main() {
1922
let x = [Foo(PhantomData); 2];
23+
//[gai]~^ ERROR: type annotations needed
2024
_ = extract(x).max(2);
2125
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@ check-pass
2+
#![feature(generic_arg_infer)]
3+
4+
fn main() {
5+
let a: [_; 1] = [String::new(); _];
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#![feature(generic_arg_infer)]
2+
3+
struct Foo<const N: usize>;
4+
5+
impl Clone for Foo<1> {
6+
fn clone(&self) -> Self {
7+
Foo
8+
}
9+
}
10+
impl Copy for Foo<1> {}
11+
12+
fn unify<const N: usize>(_: &[Foo<N>; N]) {
13+
loop {}
14+
}
15+
16+
fn main() {
17+
let x = &[Foo::<_>; _];
18+
//~^ ERROR: type annotations needed for `&[Foo<_>; _]`
19+
_ = unify(x);
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0282]: type annotations needed for `&[Foo<_>; _]`
2+
--> $DIR/no-conservative-copy-impl-requirement.rs:17:9
3+
|
4+
LL | let x = &[Foo::<_>; _];
5+
| ^ -------- type must be known at this point
6+
|
7+
help: consider giving `x` an explicit type, where the value of const parameter `N` is specified
8+
|
9+
LL | let x: &[Foo<N>; N] = &[Foo::<_>; _];
10+
| ++++++++++++++
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)