about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-03-08 21:24:51 +0100
committerGitHub <noreply@github.com>2023-03-08 21:24:51 +0100
commitf6b8a9f6dbfad6dc0e7651cbb5372ac8f5b593c6 (patch)
treee94262c0badd9a0f44da84a96123d437c26eadf4
parent1a9376dc47860ca4bbd21e2b5bb8fb64bba81af0 (diff)
parent8a99ffc3442329d2fb2f07ce87852c3e12cc4d6a (diff)
downloadrust-f6b8a9f6dbfad6dc0e7651cbb5372ac8f5b593c6.tar.gz
rust-f6b8a9f6dbfad6dc0e7651cbb5372ac8f5b593c6.zip
Rollup merge of #108883 - compiler-errors:post-norm-copy-err, r=BoxyUwU
Suppress copy impl error when post-normalized type references errors

Suppress spurious errors from the `Copy` impl validity check when fields have bad types *post*-normalization, instead of just pre-normalization.

----

The const-generics test regressed recently due to #107965, cc `````@BoxyUwU.`````
 * I think it's because `[_; 0u32]: Copy` now fails to hold because a nested obligation `ConstArgHasType(0u32, usize)` fails.
 * It's interesting that `[const_error]` shows up in the type only after normalization, though, but I'm pretty sure that it's due to the evaluate call that happens when normalizing unevaluated consts.
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs7
-rw-r--r--tests/ui/coherence/illegal-copy-bad-projection.rs16
-rw-r--r--tests/ui/coherence/illegal-copy-bad-projection.stderr9
-rw-r--r--tests/ui/const-generics/bad-generic-in-copy-impl.rs9
-rw-r--r--tests/ui/const-generics/bad-generic-in-copy-impl.stderr9
5 files changed, 49 insertions, 1 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index b94346b0956..336db4fee6c 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -87,7 +87,12 @@ pub fn type_allowed_to_implement_copy<'tcx>(
             };
             let ty = ocx.normalize(&normalization_cause, param_env, unnormalized_ty);
             let normalization_errors = ocx.select_where_possible();
-            if !normalization_errors.is_empty() {
+
+            // NOTE: The post-normalization type may also reference errors,
+            // such as when we project to a missing type or we have a mismatch
+            // between expected and found const-generic types. Don't report an
+            // additional copy error here, since it's not typically useful.
+            if !normalization_errors.is_empty() || ty.references_error() {
                 tcx.sess.delay_span_bug(field_span, format!("couldn't normalize struct field `{unnormalized_ty}` when checking Copy implementation"));
                 continue;
             }
diff --git a/tests/ui/coherence/illegal-copy-bad-projection.rs b/tests/ui/coherence/illegal-copy-bad-projection.rs
new file mode 100644
index 00000000000..797443a0abe
--- /dev/null
+++ b/tests/ui/coherence/illegal-copy-bad-projection.rs
@@ -0,0 +1,16 @@
+trait AsPtr {
+    type Ptr;
+}
+
+impl AsPtr for () {
+    type Ptr = *const void;
+    //~^ ERROR cannot find type `void` in this scope
+}
+
+#[derive(Copy, Clone)]
+struct Foo {
+    p: <() as AsPtr>::Ptr,
+    // Do not report a "`Copy` cannot be implemented" here.
+}
+
+fn main() {}
diff --git a/tests/ui/coherence/illegal-copy-bad-projection.stderr b/tests/ui/coherence/illegal-copy-bad-projection.stderr
new file mode 100644
index 00000000000..8fed9ba23b2
--- /dev/null
+++ b/tests/ui/coherence/illegal-copy-bad-projection.stderr
@@ -0,0 +1,9 @@
+error[E0412]: cannot find type `void` in this scope
+  --> $DIR/illegal-copy-bad-projection.rs:6:23
+   |
+LL |     type Ptr = *const void;
+   |                       ^^^^ not found in this scope
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/const-generics/bad-generic-in-copy-impl.rs b/tests/ui/const-generics/bad-generic-in-copy-impl.rs
new file mode 100644
index 00000000000..b5663464cf4
--- /dev/null
+++ b/tests/ui/const-generics/bad-generic-in-copy-impl.rs
@@ -0,0 +1,9 @@
+#[derive(Copy, Clone)]
+pub struct Foo {
+    x: [u8; SIZE],
+    //~^ ERROR mismatched types
+}
+
+const SIZE: u32 = 1;
+
+fn main() {}
diff --git a/tests/ui/const-generics/bad-generic-in-copy-impl.stderr b/tests/ui/const-generics/bad-generic-in-copy-impl.stderr
new file mode 100644
index 00000000000..25701ce68cc
--- /dev/null
+++ b/tests/ui/const-generics/bad-generic-in-copy-impl.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/bad-generic-in-copy-impl.rs:3:13
+   |
+LL |     x: [u8; SIZE],
+   |             ^^^^ expected `usize`, found `u32`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.