1
Fork 0

Extend BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE.

To temporarily allow a `str` field in a packed struct using `derive`,
along with `[u8]`.
This commit is contained in:
Nicholas Nethercote 2023-02-06 12:58:39 +11:00
parent ef934d9b63
commit a70d03b624
4 changed files with 81 additions and 25 deletions

View file

@ -1557,31 +1557,46 @@ impl<'a> TraitDef<'a> {
}), }),
), ),
); );
// In general, fields in packed structs are copied via a
// block, e.g. `&{self.0}`. The one exception is `[u8]`
// fields, which cannot be copied and also never cause
// unaligned references. This exception is allowed to
// handle the `FlexZeroSlice` type in the `zerovec` crate
// within `icu4x-0.9.0`.
//
// Once use of `icu4x-0.9.0` has dropped sufficiently, this
// exception should be removed.
let is_u8_slice = if let TyKind::Slice(ty) = &struct_field.ty.kind &&
let TyKind::Path(None, rustc_ast::Path { segments, .. }) = &ty.kind &&
let [seg] = segments.as_slice() &&
seg.ident.name == sym::u8 && seg.args.is_none()
{
true
} else {
false
};
if is_packed { if is_packed {
if is_u8_slice { // In general, fields in packed structs are copied via a
// block, e.g. `&{self.0}`. The two exceptions are `[u8]`
// and `str` fields, which cannot be copied and also never
// cause unaligned references. These exceptions are allowed
// to handle the `FlexZeroSlice` type in the `zerovec`
// crate within `icu4x-0.9.0`.
//
// Once use of `icu4x-0.9.0` has dropped sufficiently, this
// exception should be removed.
let is_simple_path = |ty: &P<ast::Ty>, sym| {
if let TyKind::Path(None, ast::Path { segments, .. }) = &ty.kind &&
let [seg] = segments.as_slice() &&
seg.ident.name == sym && seg.args.is_none()
{
true
} else {
false
}
};
let exception = if let TyKind::Slice(ty) = &struct_field.ty.kind &&
is_simple_path(ty, sym::u8)
{
Some("byte")
} else if is_simple_path(&struct_field.ty, sym::str) {
Some("string")
} else {
None
};
if let Some(ty) = exception {
cx.sess.parse_sess.buffer_lint_with_diagnostic( cx.sess.parse_sess.buffer_lint_with_diagnostic(
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE, BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
sp, sp,
ast::CRATE_NODE_ID, ast::CRATE_NODE_ID,
"byte slice in a packed struct that derives a built-in trait", &format!(
"{} slice in a packed struct that derives a built-in trait",
ty
),
rustc_lint_defs::BuiltinLintDiagnostics::ByteSliceInPackedStructWithDerive rustc_lint_defs::BuiltinLintDiagnostics::ByteSliceInPackedStructWithDerive
); );
} else { } else {

View file

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

View file

@ -33,4 +33,14 @@ struct FlexZeroSlice {
//~^^ this was previously accepted //~^^ this was previously accepted
} }
// Again, currently allowed, but will be phased out.
#[derive(Debug)]
#[repr(packed)]
struct WithStr {
width: u8,
data: str,
//~^ WARNING string slice in a packed struct that derives a built-in trait
//~^^ this was previously accepted
}
fn main() {} fn main() {}

View file

@ -13,6 +13,20 @@ LL | data: [u8],
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default = note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
warning: string slice in a packed struct that derives a built-in trait
--> $DIR/deriving-with-repr-packed.rs:41:5
|
LL | #[derive(Debug)]
| ----- in this derive macro expansion
...
LL | data: str,
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
= help: consider implementing the trait by hand, or remove the `packed` attribute
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0507]: cannot move out of `self` which is behind a shared reference error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed.rs:22:10 --> $DIR/deriving-with-repr-packed.rs:22:10
| |
@ -24,7 +38,7 @@ LL | struct X(Y);
| |
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error; 1 warning emitted error: aborting due to previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0507`. For more information about this error, try `rustc --explain E0507`.
Future incompatibility report: Future breakage diagnostic: Future incompatibility report: Future breakage diagnostic:
@ -43,3 +57,19 @@ LL | data: [u8],
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default = note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) = note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
warning: string slice in a packed struct that derives a built-in trait
--> $DIR/deriving-with-repr-packed.rs:41:5
|
LL | #[derive(Debug)]
| ----- in this derive macro expansion
...
LL | data: str,
| ^^^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #107457 <https://github.com/rust-lang/rust/issues/107457>
= help: consider implementing the trait by hand, or remove the `packed` attribute
= note: `#[warn(byte_slice_in_packed_struct_with_derive)]` on by default
= note: this warning originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)