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:
commit
d10f2b32f0
8 changed files with 41 additions and 232 deletions
|
@ -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)
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue