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:
parent
ef934d9b63
commit
a70d03b624
4 changed files with 81 additions and 25 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue