Rollup merge of #99581 - nnethercote:improve-derive-packed-errors, r=estebank

Improve error messages involving `derive` and `packed`.

There are two errors involving `derive` and `packed`.

```
`#[derive]` can't be derived on a `#[repr(packed)]` struct with type or const parameters
`#[derive]` can't be derived on a `#[repr(packed)]` struct that does not derive Copy
```
The second one overstates things. It is possible to use derive on a
repr(packed) struct that doesn't derive Copy in two cases.
- If all the fields within the struct meet the required alignment: 1 for
  `repr(packed)`, or `N` for `repr(packed(N))`.
- If `Default` is the only trait derived.

This commit improves things in a few ways.
- Changes the errors to say `this trait can't be derived on this ...`.
  This is more accurate, because it's just *this* trait and *this*
  packed struct that are a problem, not *all* derived traits on *all*
  packed structs.
- Adds more details to the "ERROR" lines in the test case, enough to
  distinguish between the two error messages.
- Adds more cases to the test case that don't cause errors, e.g. `Default`
  derives.
- Uses a wider variety of builtin traits in the test case, for better coverage.

r? `@estebank`
This commit is contained in:
Yuki Okushi 2022-07-25 18:46:51 +09:00 committed by GitHub
commit 921cfbe56f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 51 deletions

View file

@ -36,13 +36,16 @@ fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
tcx.struct_span_lint_hir(UNALIGNED_REFERENCES, lint_hir_id, tcx.def_span(def_id), |lint| {
// FIXME: when we make this a hard error, this should have its
// own error code.
let message = if tcx.generics_of(def_id).own_requires_monomorphization() {
"`#[derive]` can't be used on a `#[repr(packed)]` struct with \
type or const parameters (error E0133)"
let extra = if tcx.generics_of(def_id).own_requires_monomorphization() {
"with type or const parameters"
} else {
"`#[derive]` can't be used on a `#[repr(packed)]` struct that \
does not derive Copy (error E0133)"
"that does not derive `Copy`"
};
let message = format!(
"`{}` can't be derived on this `#[repr(packed)]` struct {} (error E0133)",
tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")),
extra
);
lint.build(message).emit();
});
}