1
Fork 0

Rollup merge of #127907 - RalfJung:byte_slice_in_packed_struct_with_derive, r=nnethercote

built-in derive: remove BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE hack and lint

Fixes https://github.com/rust-lang/rust/issues/107457 by turning the lint into a hard error. The lint has been shown in future breakage reports since Rust 1.69 (released in April 2023).

Let's see (via crater) if enough time has passed since https://github.com/rust-lang/rust/pull/104429, and https://github.com/unicode-org/icu4x/pull/2834 has propagated far enough to let us make this a hard error.

Cc ``@nnethercote`` ``@Manishearth``
This commit is contained in:
Matthias Krüger 2024-08-05 05:40:19 +02:00 committed by GitHub
commit d10f2b32f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 41 additions and 232 deletions

View file

@ -181,11 +181,10 @@ use std::{iter, vec};
use rustc_ast::ptr::P;
use rustc_ast::{
self as ast, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind, Generics,
Mutability, PatKind, TyKind, VariantData,
Mutability, PatKind, VariantData,
};
use rustc_attr as attr;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_session::lint::builtin::BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use thin_vec::{thin_vec, ThinVec};
@ -1599,52 +1598,11 @@ impl<'a> TraitDef<'a> {
),
);
if is_packed {
// 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.psess.buffer_lint(
BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE,
sp,
ast::CRATE_NODE_ID,
rustc_lint_defs::BuiltinLintDiag::ByteSliceInPackedStructWithDerive {
ty: ty.to_string(),
},
);
} else {
// Wrap the expression in `{...}`, causing a copy.
field_expr = cx.expr_block(
cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]),
);
}
// Fields in packed structs are wrapped in a block, e.g. `&{self.0}`,
// causing a copy instead of a (potentially misaligned) reference.
field_expr = cx.expr_block(
cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]),
);
}
cx.expr_addr_of(sp, field_expr)
})