Skip to content

Commit 921cfbe

Browse files
authored
Rollup merge of rust-lang#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`
2 parents 65d2392 + 168c5b1 commit 921cfbe

File tree

3 files changed

+68
-51
lines changed

3 files changed

+68
-51
lines changed

compiler/rustc_mir_transform/src/check_packed_ref.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,16 @@ fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) {
3636
tcx.struct_span_lint_hir(UNALIGNED_REFERENCES, lint_hir_id, tcx.def_span(def_id), |lint| {
3737
// FIXME: when we make this a hard error, this should have its
3838
// own error code.
39-
let message = if tcx.generics_of(def_id).own_requires_monomorphization() {
40-
"`#[derive]` can't be used on a `#[repr(packed)]` struct with \
41-
type or const parameters (error E0133)"
39+
let extra = if tcx.generics_of(def_id).own_requires_monomorphization() {
40+
"with type or const parameters"
4241
} else {
43-
"`#[derive]` can't be used on a `#[repr(packed)]` struct that \
44-
does not derive Copy (error E0133)"
42+
"that does not derive `Copy`"
4543
};
44+
let message = format!(
45+
"`{}` can't be derived on this `#[repr(packed)]` struct {} (error E0133)",
46+
tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")),
47+
extra
48+
);
4649
lint.build(message).emit();
4750
});
4851
}

src/test/ui/derives/deriving-with-repr-packed.rs

+26-12
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,43 @@
11
#![deny(unaligned_references)]
22

3-
// check that derive on a packed struct with non-Copy fields
4-
// correctly. This can't be made to work perfectly because
5-
// we can't just use the field from the struct as it might
6-
// not be aligned.
3+
// Check that deriving certain builtin traits on certain packed structs cause
4+
// errors. This happens when the derived trait would need to use a potentially
5+
// misaligned reference. But there are two cases that are allowed:
6+
// - If all the fields within the struct meet the required alignment: 1 for
7+
// `repr(packed)`, or `N` for `repr(packed(N))`.
8+
// - If `Default` is the only trait derived, because it doesn't involve any
9+
// references.
710

8-
#[derive(Copy, Clone, PartialEq, Eq)]
9-
//~^ ERROR `#[derive]` can't be used
11+
#[derive(Copy, Clone, Default, PartialEq, Eq)]
12+
//~^ ERROR `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters
1013
//~| hard error
11-
//~^^^ ERROR `#[derive]` can't be used
14+
//~^^^ ERROR `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters
1215
//~| hard error
1316
#[repr(packed)]
1417
pub struct Foo<T>(T, T, T);
1518

16-
#[derive(PartialEq, Eq)]
17-
//~^ ERROR `#[derive]` can't be used
19+
#[derive(Default, Hash)]
20+
//~^ ERROR `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy`
1821
//~| hard error
1922
#[repr(packed)]
2023
pub struct Bar(u32, u32, u32);
2124

22-
#[derive(PartialEq)]
25+
// This one is fine because the field alignment is 1.
26+
#[derive(Default, Hash)]
27+
#[repr(packed)]
28+
pub struct Bar2(u8, i8, bool);
29+
30+
// This one is fine because the field alignment is 2, matching `packed(2)`.
31+
#[derive(Default, Hash)]
32+
#[repr(packed(2))]
33+
pub struct Bar3(u16, i16, bool);
34+
35+
// This one is fine because it's not packed.
36+
#[derive(Debug, Default)]
2337
struct Y(usize);
2438

25-
#[derive(PartialEq)]
26-
//~^ ERROR `#[derive]` can't be used
39+
#[derive(Debug, Default)]
40+
//~^ ERROR `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy`
2741
//~| hard error
2842
#[repr(packed)]
2943
struct X(Y);
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
2-
--> $DIR/deriving-with-repr-packed.rs:8:16
1+
error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
2+
--> $DIR/deriving-with-repr-packed.rs:11:16
33
|
4-
LL | #[derive(Copy, Clone, PartialEq, Eq)]
4+
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
55
| ^^^^^
66
|
77
note: the lint level is defined here
@@ -13,43 +13,43 @@ LL | #![deny(unaligned_references)]
1313
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
1414
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
1515

16-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
17-
--> $DIR/deriving-with-repr-packed.rs:8:23
16+
error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
17+
--> $DIR/deriving-with-repr-packed.rs:11:32
1818
|
19-
LL | #[derive(Copy, Clone, PartialEq, Eq)]
20-
| ^^^^^^^^^
19+
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
20+
| ^^^^^^^^^
2121
|
2222
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2323
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
2424
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
2525

26-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
27-
--> $DIR/deriving-with-repr-packed.rs:16:10
26+
error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
27+
--> $DIR/deriving-with-repr-packed.rs:19:19
2828
|
29-
LL | #[derive(PartialEq, Eq)]
30-
| ^^^^^^^^^
29+
LL | #[derive(Default, Hash)]
30+
| ^^^^
3131
|
3232
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3333
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
34-
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
34+
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
3535

36-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
37-
--> $DIR/deriving-with-repr-packed.rs:25:10
36+
error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
37+
--> $DIR/deriving-with-repr-packed.rs:39:10
3838
|
39-
LL | #[derive(PartialEq)]
40-
| ^^^^^^^^^
39+
LL | #[derive(Debug, Default)]
40+
| ^^^^^
4141
|
4242
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4343
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
44-
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
44+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
4545

4646
error: aborting due to 4 previous errors
4747

4848
Future incompatibility report: Future breakage diagnostic:
49-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
50-
--> $DIR/deriving-with-repr-packed.rs:8:16
49+
error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
50+
--> $DIR/deriving-with-repr-packed.rs:11:16
5151
|
52-
LL | #[derive(Copy, Clone, PartialEq, Eq)]
52+
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
5353
| ^^^^^
5454
|
5555
note: the lint level is defined here
@@ -62,11 +62,11 @@ LL | #![deny(unaligned_references)]
6262
= note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info)
6363

6464
Future breakage diagnostic:
65-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct with type or const parameters (error E0133)
66-
--> $DIR/deriving-with-repr-packed.rs:8:23
65+
error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters (error E0133)
66+
--> $DIR/deriving-with-repr-packed.rs:11:32
6767
|
68-
LL | #[derive(Copy, Clone, PartialEq, Eq)]
69-
| ^^^^^^^^^
68+
LL | #[derive(Copy, Clone, Default, PartialEq, Eq)]
69+
| ^^^^^^^^^
7070
|
7171
note: the lint level is defined here
7272
--> $DIR/deriving-with-repr-packed.rs:1:9
@@ -78,11 +78,11 @@ LL | #![deny(unaligned_references)]
7878
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
7979

8080
Future breakage diagnostic:
81-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
82-
--> $DIR/deriving-with-repr-packed.rs:16:10
81+
error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
82+
--> $DIR/deriving-with-repr-packed.rs:19:19
8383
|
84-
LL | #[derive(PartialEq, Eq)]
85-
| ^^^^^^^^^
84+
LL | #[derive(Default, Hash)]
85+
| ^^^^
8686
|
8787
note: the lint level is defined here
8888
--> $DIR/deriving-with-repr-packed.rs:1:9
@@ -91,14 +91,14 @@ LL | #![deny(unaligned_references)]
9191
| ^^^^^^^^^^^^^^^^^^^^
9292
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
9393
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
94-
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
94+
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
9595

9696
Future breakage diagnostic:
97-
error: `#[derive]` can't be used on a `#[repr(packed)]` struct that does not derive Copy (error E0133)
98-
--> $DIR/deriving-with-repr-packed.rs:25:10
97+
error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not derive `Copy` (error E0133)
98+
--> $DIR/deriving-with-repr-packed.rs:39:10
9999
|
100-
LL | #[derive(PartialEq)]
101-
| ^^^^^^^^^
100+
LL | #[derive(Debug, Default)]
101+
| ^^^^^
102102
|
103103
note: the lint level is defined here
104104
--> $DIR/deriving-with-repr-packed.rs:1:9
@@ -107,5 +107,5 @@ LL | #![deny(unaligned_references)]
107107
| ^^^^^^^^^^^^^^^^^^^^
108108
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
109109
= note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523>
110-
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
110+
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
111111

0 commit comments

Comments
 (0)