Skip to content

Commit

Permalink
Rollup merge of rust-lang#107713 - nnethercote:extend-BYTE_SLICE_IN_P…
Browse files Browse the repository at this point in the history
…ACKED_STRUCT_WITH_DERIVE, r=RalfJung

Extend `BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE`.

To temporarily allow a `str` field in a packed struct using `derive`, along with `[u8]`.

r? `@RalfJung`
  • Loading branch information
compiler-errors authored Feb 9, 2023
2 parents cda1583 + a70d03b commit 3e81dec
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 25 deletions.
55 changes: 35 additions & 20 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_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(
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
sp,
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
);
} else {
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4073,7 +4073,8 @@ declare_lint! {

declare_lint! {
/// 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
///
Expand All @@ -4091,11 +4092,11 @@ declare_lint! {
/// ### Explanation
///
/// 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
/// exception because certain crates depended on them.
/// now required to implement `Copy` for `derive` to work. Byte slices and string slices are a
/// temporary exception because certain crates depended on them.
pub BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
Warn,
"`[u8]` slice used in a packed struct with `derive`",
"`[u8]` or `str` used in a packed struct with `derive`",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #107457 <https://github.com/rust-lang/rust/issues/107457>",
reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/derives/deriving-with-repr-packed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,14 @@ struct FlexZeroSlice {
//~^^ 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() {}
32 changes: 31 additions & 1 deletion tests/ui/derives/deriving-with-repr-packed.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ LL | data: [u8],
= 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)

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
--> $DIR/deriving-with-repr-packed.rs:22:10
|
Expand All @@ -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)

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`.
Future incompatibility report: Future breakage diagnostic:
Expand All @@ -43,3 +57,19 @@ LL | data: [u8],
= 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)

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)

0 comments on commit 3e81dec

Please sign in to comment.