about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBoxy <rust@boxyuwu.dev>2025-02-15 02:01:41 +0000
committerBoxy <rust@boxyuwu.dev>2025-02-27 20:02:25 +0000
commit6c3243f0086c0f6a77b4a66fdfcf7f55c36f94a1 (patch)
treeec2a387553f77d1a1c9edbd0f8c1a3e44145b762
parentdc6db192c4bc8906b42c68f5ed586cf1b41477a2 (diff)
Bless
-rw-r--r--tests/ui/consts/const-fn-in-vec.rs11
-rw-r--r--tests/ui/consts/const-fn-in-vec.stderr2
-rw-r--r--tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs37
-rw-r--r--tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr14
-rw-r--r--tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs59
-rw-r--r--tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr17
-rw-r--r--tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs (renamed from tests/ui/repeat-expr/infer-eager.rs)6
-rw-r--r--tests/ui/repeat-expr/copy-inference-side-effects.rs (renamed from tests/ui/repeat-expr/infer.rs)0
-rw-r--r--tests/ui/repeat-expr/dont-require-copy-on-infer.rs6
-rw-r--r--tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs20
-rw-r--r--tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr14
11 files changed, 181 insertions, 5 deletions
diff --git a/tests/ui/consts/const-fn-in-vec.rs b/tests/ui/consts/const-fn-in-vec.rs
index 0483800efef..d1430bc8e00 100644
--- a/tests/ui/consts/const-fn-in-vec.rs
+++ b/tests/ui/consts/const-fn-in-vec.rs
@@ -1,11 +1,16 @@
 static _MAYBE_STRINGS: [Option<String>; 5] = [None; 5];
 //~^ ERROR the trait bound `String: Copy` is not satisfied
 
-fn main() {
-    // should hint to create an inline `const` block
-    // or to create a new `const` item
+// should hint to create an inline `const` block
+// or to create a new `const` item
+fn foo() {
     let _strings: [String; 5] = [String::new(); 5];
     //~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn bar() {
     let _maybe_strings: [Option<String>; 5] = [None; 5];
     //~^ ERROR the trait bound `String: Copy` is not satisfied
 }
+
+fn main() {}
diff --git a/tests/ui/consts/const-fn-in-vec.stderr b/tests/ui/consts/const-fn-in-vec.stderr
index b31e180fea2..5be26d7c121 100644
--- a/tests/ui/consts/const-fn-in-vec.stderr
+++ b/tests/ui/consts/const-fn-in-vec.stderr
@@ -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
 
 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];
    |                                                ^^^^
diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs
new file mode 100644
index 00000000000..d9ad93541ec
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.rs
@@ -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
+}
diff --git a/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr
new file mode 100644
index 00000000000..2a0cb3fb7a3
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-check-deferred-after-fallback.stderr
@@ -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`.
diff --git a/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs
new file mode 100644
index 00000000000..4654d7483a6
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-check-deferred-before-fallback.rs
@@ -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`
+}
diff --git a/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr
new file mode 100644
index 00000000000..de38476c82b
--- /dev/null
+++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.gai.stderr
@@ -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`.
diff --git a/tests/ui/repeat-expr/infer-eager.rs b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs
index afac4aaa3fd..0b0672d9c2b 100644
--- a/tests/ui/repeat-expr/infer-eager.rs
+++ b/tests/ui/repeat-expr/copy-inference-side-effects-are-lazy.rs
@@ -1,4 +1,7 @@
-//@ check-pass
+//@revisions: current gai
+//@[current] check-pass
+
+#![cfg_attr(gai, feature(generic_arg_infer))]
 
 use std::marker::PhantomData;
 
@@ -17,5 +20,6 @@ fn extract<T, const N: usize>(_: [Foo<T>; N]) -> T {
 
 fn main() {
     let x = [Foo(PhantomData); 2];
+    //[gai]~^ ERROR: type annotations needed
     _ = extract(x).max(2);
 }
diff --git a/tests/ui/repeat-expr/infer.rs b/tests/ui/repeat-expr/copy-inference-side-effects.rs
index eb47b5f462f..eb47b5f462f 100644
--- a/tests/ui/repeat-expr/infer.rs
+++ b/tests/ui/repeat-expr/copy-inference-side-effects.rs
diff --git a/tests/ui/repeat-expr/dont-require-copy-on-infer.rs b/tests/ui/repeat-expr/dont-require-copy-on-infer.rs
new file mode 100644
index 00000000000..e81bf1595be
--- /dev/null
+++ b/tests/ui/repeat-expr/dont-require-copy-on-infer.rs
@@ -0,0 +1,6 @@
+//@ check-pass
+#![feature(generic_arg_infer)]
+
+fn main() {
+    let a: [_; 1] = [String::new(); _];
+}
diff --git a/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs
new file mode 100644
index 00000000000..eb70df62996
--- /dev/null
+++ b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.rs
@@ -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);
+}
diff --git a/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr
new file mode 100644
index 00000000000..04f8ff33fda
--- /dev/null
+++ b/tests/ui/repeat-expr/no-conservative-copy-impl-requirement.stderr
@@ -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`.