Skip to content

Commit

Permalink
Rollup merge of rust-lang#108883 - compiler-errors:post-norm-copy-err…
Browse files Browse the repository at this point in the history
…, 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 rust-lang#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.
  • Loading branch information
JohnTitor authored Mar 8, 2023
2 parents 3c9b079 + 8a99ffc commit dfdcf52
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 1 deletion.
7 changes: 6 additions & 1 deletion compiler/rustc_trait_selection/src/traits/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/coherence/illegal-copy-bad-projection.rs
Original file line number Diff line number Diff line change
@@ -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() {}
9 changes: 9 additions & 0 deletions tests/ui/coherence/illegal-copy-bad-projection.stderr
Original file line number Diff line number Diff line change
@@ -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`.
9 changes: 9 additions & 0 deletions tests/ui/const-generics/bad-generic-in-copy-impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#[derive(Copy, Clone)]
pub struct Foo {
x: [u8; SIZE],
//~^ ERROR mismatched types
}

const SIZE: u32 = 1;

fn main() {}
9 changes: 9 additions & 0 deletions tests/ui/const-generics/bad-generic-in-copy-impl.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit dfdcf52

Please sign in to comment.