about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-03-23 22:13:22 +0100
committerGitHub <noreply@github.com>2022-03-23 22:13:22 +0100
commitaf19a50a2697392e89cdda2b94ab271459e1c729 (patch)
tree73deb8a87a4d78b97e4880e146fd7399bd658a49 /src
parent547369d3d881a9eb1de0d3e368f9a59aa7c648b0 (diff)
parentc8cbd3d03c92ec903a964b67dd90aa2cc6d78f2c (diff)
downloadrust-af19a50a2697392e89cdda2b94ab271459e1c729.tar.gz
rust-af19a50a2697392e89cdda2b94ab271459e1c729.zip
Rollup merge of #94249 - compiler-errors:better-copy-errors, r=davidtwco
Better errors when a Copy impl on a Struct is not self-consistent

As discovered in a Zulip thread with `@nnethercote` and `@Mark-Simulacrum,` it's not immediately obvious why a field on an ADT doesn't implement `Copy`.  This PR attempts to give slightly more detailed information by spinning up a fulfillment context to try to dig down and discover transitive fulfillment errors that cause `is_copy_modulo_regions` to fail on a ADT field.

The error message still kinda sucks, but should only show up in the case that an existing error message was totally missing... so I think it's a good compromise for now?
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/coherence/deep-bad-copy-reason.rs40
-rw-r--r--src/test/ui/coherence/deep-bad-copy-reason.stderr18
-rw-r--r--src/test/ui/union/union-copy.stderr6
3 files changed, 64 insertions, 0 deletions
diff --git a/src/test/ui/coherence/deep-bad-copy-reason.rs b/src/test/ui/coherence/deep-bad-copy-reason.rs
new file mode 100644
index 00000000000..80bbe387ac7
--- /dev/null
+++ b/src/test/ui/coherence/deep-bad-copy-reason.rs
@@ -0,0 +1,40 @@
+#![feature(extern_types)]
+
+extern "Rust" {
+    type OpaqueListContents;
+}
+
+pub struct ListS<T> {
+    len: usize,
+    data: [T; 0],
+    opaque: OpaqueListContents,
+}
+
+pub struct Interned<'a, T>(&'a T);
+
+impl<'a, T> Clone for Interned<'a, T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<'a, T> Copy for Interned<'a, T> {}
+
+pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
+//~^ NOTE this field does not implement `Copy`
+//~| NOTE the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
+
+impl<'tcx, T> Clone for List<'tcx, T> {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
+
+impl<'tcx, T> Copy for List<'tcx, T> {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn assert_is_copy<T: Copy>() {}
+
+fn main() {
+    assert_is_copy::<List<'static, ()>>();
+}
diff --git a/src/test/ui/coherence/deep-bad-copy-reason.stderr b/src/test/ui/coherence/deep-bad-copy-reason.stderr
new file mode 100644
index 00000000000..295538cee60
--- /dev/null
+++ b/src/test/ui/coherence/deep-bad-copy-reason.stderr
@@ -0,0 +1,18 @@
+error[E0204]: the trait `Copy` may not be implemented for this type
+  --> $DIR/deep-bad-copy-reason.rs:33:15
+   |
+LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
+   |                          ------------------------ this field does not implement `Copy`
+...
+LL | impl<'tcx, T> Copy for List<'tcx, T> {}
+   |               ^^^^
+   |
+note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
+  --> $DIR/deep-bad-copy-reason.rs:23:26
+   |
+LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0204`.
diff --git a/src/test/ui/union/union-copy.stderr b/src/test/ui/union/union-copy.stderr
index 0f47bae7f0f..279808dd55b 100644
--- a/src/test/ui/union/union-copy.stderr
+++ b/src/test/ui/union/union-copy.stderr
@@ -6,6 +6,12 @@ LL |     a: std::mem::ManuallyDrop<String>
 ...
 LL | impl Copy for W {}
    |      ^^^^
+   |
+note: the `Copy` impl for `ManuallyDrop<String>` requires that `String: Copy`
+  --> $DIR/union-copy.rs:8:5
+   |
+LL |     a: std::mem::ManuallyDrop<String>
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error