From 8a99ffc3442329d2fb2f07ce87852c3e12cc4d6a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 7 Mar 2023 23:37:52 +0000 Subject: [PATCH] Suppress copy impl error when post-normalized type references errors --- .../rustc_trait_selection/src/traits/misc.rs | 7 ++++++- .../ui/coherence/illegal-copy-bad-projection.rs | 16 ++++++++++++++++ .../coherence/illegal-copy-bad-projection.stderr | 9 +++++++++ .../const-generics/bad-generic-in-copy-impl.rs | 9 +++++++++ .../bad-generic-in-copy-impl.stderr | 9 +++++++++ 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 tests/ui/coherence/illegal-copy-bad-projection.rs create mode 100644 tests/ui/coherence/illegal-copy-bad-projection.stderr create mode 100644 tests/ui/const-generics/bad-generic-in-copy-impl.rs create mode 100644 tests/ui/const-generics/bad-generic-in-copy-impl.stderr diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index b94346b09560a..336db4fee6ced 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 0000000000000..797443a0abe5a --- /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 0000000000000..8fed9ba23b24b --- /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 0000000000000..b5663464cf422 --- /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 0000000000000..25701ce68ccc8 --- /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`.