Skip to content

Commit a70d03b

Browse files
committed
Extend BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE.
To temporarily allow a `str` field in a packed struct using `derive`, along with `[u8]`.
1 parent ef934d9 commit a70d03b

File tree

4 files changed

+81
-25
lines changed

4 files changed

+81
-25
lines changed

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs

+35-20
Original file line numberDiff line numberDiff line change
@@ -1557,31 +1557,46 @@ impl<'a> TraitDef<'a> {
15571557
}),
15581558
),
15591559
);
1560-
// In general, fields in packed structs are copied via a
1561-
// block, e.g. `&{self.0}`. The one exception is `[u8]`
1562-
// fields, which cannot be copied and also never cause
1563-
// unaligned references. This exception is allowed to
1564-
// handle the `FlexZeroSlice` type in the `zerovec` crate
1565-
// within `icu4x-0.9.0`.
1566-
//
1567-
// Once use of `icu4x-0.9.0` has dropped sufficiently, this
1568-
// exception should be removed.
1569-
let is_u8_slice = if let TyKind::Slice(ty) = &struct_field.ty.kind &&
1570-
let TyKind::Path(None, rustc_ast::Path { segments, .. }) = &ty.kind &&
1571-
let [seg] = segments.as_slice() &&
1572-
seg.ident.name == sym::u8 && seg.args.is_none()
1573-
{
1574-
true
1575-
} else {
1576-
false
1577-
};
15781560
if is_packed {
1579-
if is_u8_slice {
1561+
// In general, fields in packed structs are copied via a
1562+
// block, e.g. `&{self.0}`. The two exceptions are `[u8]`
1563+
// and `str` fields, which cannot be copied and also never
1564+
// cause unaligned references. These exceptions are allowed
1565+
// to handle the `FlexZeroSlice` type in the `zerovec`
1566+
// crate within `icu4x-0.9.0`.
1567+
//
1568+
// Once use of `icu4x-0.9.0` has dropped sufficiently, this
1569+
// exception should be removed.
1570+
let is_simple_path = |ty: &P<ast::Ty>, sym| {
1571+
if let TyKind::Path(None, ast::Path { segments, .. }) = &ty.kind &&
1572+
let [seg] = segments.as_slice() &&
1573+
seg.ident.name == sym && seg.args.is_none()
1574+
{
1575+
true
1576+
} else {
1577+
false
1578+
}
1579+
};
1580+
1581+
let exception = if let TyKind::Slice(ty) = &struct_field.ty.kind &&
1582+
is_simple_path(ty, sym::u8)
1583+
{
1584+
Some("byte")
1585+
} else if is_simple_path(&struct_field.ty, sym::str) {
1586+
Some("string")
1587+
} else {
1588+
None
1589+
};
1590+
1591+
if let Some(ty) = exception {
15801592
cx.sess.parse_sess.buffer_lint_with_diagnostic(
15811593
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
15821594
sp,
15831595
ast::CRATE_NODE_ID,
1584-
"byte slice in a packed struct that derives a built-in trait",
1596+
&format!(
1597+
"{} slice in a packed struct that derives a built-in trait",
1598+
ty
1599+
),
15851600
rustc_lint_defs::BuiltinLintDiagnostics::ByteSliceInPackedStructWithDerive
15861601
);
15871602
} else {

compiler/rustc_lint_defs/src/builtin.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -4073,7 +4073,8 @@ declare_lint! {
40734073

40744074
declare_lint! {
40754075
/// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field
4076-
/// (`[u8]`) is used in a `packed` struct that derives one or more built-in traits.
4076+
/// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or
4077+
/// more built-in traits.
40774078
///
40784079
/// ### Example
40794080
///
@@ -4091,11 +4092,11 @@ declare_lint! {
40914092
/// ### Explanation
40924093
///
40934094
/// This was previously accepted but is being phased out, because fields in packed structs are
4094-
/// now required to implement `Copy` for `derive` to work. Byte slices are a temporary
4095-
/// exception because certain crates depended on them.
4095+
/// now required to implement `Copy` for `derive` to work. Byte slices and string slices are a
4096+
/// temporary exception because certain crates depended on them.
40964097
pub BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
40974098
Warn,
4098-
"`[u8]` slice used in a packed struct with `derive`",
4099+
"`[u8]` or `str` used in a packed struct with `derive`",
40994100
@future_incompatible = FutureIncompatibleInfo {
41004101
reference: "issue #107457 <https://github.com/rust-lang/rust/issues/107457>",
41014102
reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,

tests/ui/derives/deriving-with-repr-packed.rs

+10
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,14 @@ struct FlexZeroSlice {
3333
//~^^ this was previously accepted
3434
}
3535

36+
// Again, currently allowed, but will be phased out.
37+
#[derive(Debug)]
38+
#[repr(packed)]
39+
struct WithStr {
40+
width: u8,
41+
data: str,
42+
//~^ WARNING string slice in a packed struct that derives a built-in trait
43+
//~^^ this was previously accepted
44+
}
45+
3646
fn main() {}

tests/ui/derives/deriving-with-repr-packed.stderr

+31-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@ LL | data: [u8],
1313
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
1414
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
1515

16+
warning: string slice in a packed struct that derives a built-in trait
17+
--> $DIR/deriving-with-repr-packed.rs:41:5
18+
|
19+
LL | #[derive(Debug)]
20+
| ----- in this derive macro expansion
21+
...
22+
LL | data: str,
23+
| ^^^^^^^^^
24+
|
25+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
26+
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
27+
= help: consider implementing the trait by hand, or remove the `packed` attribute
28+
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
29+
1630
error[E0507]: cannot move out of `self` which is behind a shared reference
1731
--> $DIR/deriving-with-repr-packed.rs:22:10
1832
|
@@ -24,7 +38,7 @@ LL | struct X(Y);
2438
|
2539
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
2640

27-
error: aborting due to previous error; 1 warning emitted
41+
error: aborting due to previous error; 2 warnings emitted
2842

2943
For more information about this error, try `rustc --explain E0507`.
3044
Future incompatibility report: Future breakage diagnostic:
@@ -43,3 +57,19 @@ LL | data: [u8],
4357
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
4458
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
4559

60+
Future breakage diagnostic:
61+
warning: string slice in a packed struct that derives a built-in trait
62+
--> $DIR/deriving-with-repr-packed.rs:41:5
63+
|
64+
LL | #[derive(Debug)]
65+
| ----- in this derive macro expansion
66+
...
67+
LL | data: str,
68+
| ^^^^^^^^^
69+
|
70+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
71+
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
72+
= help: consider implementing the trait by hand, or remove the `packed` attribute
73+
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
74+
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
75+

0 commit comments

Comments
 (0)