]> git.lizzy.rs Git - rust.git/commitdiff
Extend `BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE`.
authorNicholas Nethercote <n.nethercote@gmail.com>
Mon, 6 Feb 2023 01:58:39 +0000 (12:58 +1100)
committerNicholas Nethercote <n.nethercote@gmail.com>
Thu, 9 Feb 2023 00:47:12 +0000 (11:47 +1100)
To temporarily allow a `str` field in a packed struct using `derive`,
along with `[u8]`.

compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
compiler/rustc_lint_defs/src/builtin.rs
tests/ui/derives/deriving-with-repr-packed.rs
tests/ui/derives/deriving-with-repr-packed.stderr

index a8c0aeb787078140ba2cab22b851002e2bbdf3f6..970b9115d8d79639aa232db382c0936dbad366e9 100644 (file)
@@ -1557,31 +1557,46 @@ fn create_struct_field_access_fields(
                             }),
                         ),
                     );
-                    // 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 {
index 7e9ba4cd22b8d8132f62ad6158678df3b74ad2a8..9d8ad9d9ed9f6f5c7d2fa66b7e0d656ba2393581 100644 (file)
 
 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
     ///
     /// ### 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,
index afa91da133dc0f0b862211777c837d3bb4564741..58be4519720178b8fab1f5504fc43607bc8e05a9 100644 (file)
@@ -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() {}
index 7ed84af91bdc354d4a3eb14e6633c4f9e8040d1b..0cfe03869af1bd6846e3e836dca9d12ee5f37fd0 100644 (file)
@@ -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
    |
@@ -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:
@@ -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)
+