]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Extend `BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE`.
[rust.git] / compiler / rustc_builtin_macros / src / deriving / generic / mod.rs
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 {