Skip to content

Commit b4c9632

Browse files
authored
Merge pull request #111 from Rust-for-Linux/dev/unsound-fix-packed
remove `#[disable_initialized_field_access]`
2 parents bbf992b + ef5a2da commit b4c9632

6 files changed

Lines changed: 16 additions & 133 deletions

File tree

CHANGELOG.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
- `[pin_]init!` now supports attributes on fields (such as `#[cfg(...)]`).
2929
- Add a `#[default_error(<type>)]` attribute to `[pin_]init!` to override the
3030
default error (when no `? Error` is specified).
31-
- Support packed struct in `[pin_]init!` with `#[disable_initialized_field_access]`.
3231

3332
### Removed
3433

internal/src/init.rs

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ impl InitializerKind {
6262

6363
enum InitializerAttribute {
6464
DefaultError(DefaultErrorAttribute),
65-
DisableInitializedFieldAccess,
6665
}
6766

6867
struct DefaultErrorAttribute {
@@ -86,6 +85,7 @@ pub(crate) fn expand(
8685
let error = error.map_or_else(
8786
|| {
8887
if let Some(default_error) = attrs.iter().fold(None, |acc, attr| {
88+
#[expect(irrefutable_let_patterns)]
8989
if let InitializerAttribute::DefaultError(DefaultErrorAttribute { ty }) = attr {
9090
Some(ty.clone())
9191
} else {
@@ -145,15 +145,7 @@ pub(crate) fn expand(
145145
};
146146
// `mixed_site` ensures that the data is not accessible to the user-controlled code.
147147
let data = Ident::new("__data", Span::mixed_site());
148-
let init_fields = init_fields(
149-
&fields,
150-
pinned,
151-
!attrs
152-
.iter()
153-
.any(|attr| matches!(attr, InitializerAttribute::DisableInitializedFieldAccess)),
154-
&data,
155-
&slot,
156-
);
148+
let init_fields = init_fields(&fields, pinned, &data, &slot);
157149
let field_check = make_field_check(&fields, init_kind, &path);
158150
Ok(quote! {{
159151
// We do not want to allow arbitrary returns, so we declare this type as the `Ok` return
@@ -242,7 +234,6 @@ fn get_init_kind(rest: Option<(Token![..], Expr)>, dcx: &mut DiagCtxt) -> InitKi
242234
fn init_fields(
243235
fields: &Punctuated<InitializerField, Token![,]>,
244236
pinned: bool,
245-
generate_initialized_accessors: bool,
246237
data: &Ident,
247238
slot: &Ident,
248239
) -> TokenStream {
@@ -266,6 +257,10 @@ fn init_fields(
266257
});
267258
// Again span for better diagnostics
268259
let write = quote_spanned!(ident.span()=> ::core::ptr::write);
260+
// NOTE: the field accessor ensures that the initialized field is properly aligned.
261+
// Unaligned fields will cause the compiler to emit E0793. We do not support
262+
// unaligned fields since `Init::__init` requires an aligned pointer; the call to
263+
// `ptr::write` below has the same requirement.
269264
let accessor = if pinned {
270265
let project_ident = format_ident!("__project_{ident}");
271266
quote! {
@@ -278,26 +273,25 @@ fn init_fields(
278273
unsafe { &mut (*#slot).#ident }
279274
}
280275
};
281-
let accessor = generate_initialized_accessors.then(|| {
282-
quote! {
283-
#(#cfgs)*
284-
#[allow(unused_variables)]
285-
let #ident = #accessor;
286-
}
287-
});
288276
quote! {
289277
#(#attrs)*
290278
{
291279
#value_prep
292280
// SAFETY: TODO
293281
unsafe { #write(&raw mut (*#slot).#ident, #value_ident) };
294282
}
295-
#accessor
283+
#(#cfgs)*
284+
#[allow(unused_variables)]
285+
let #ident = #accessor;
296286
}
297287
}
298288
InitializerKind::Init { ident, value, .. } => {
299289
// Again span for better diagnostics
300290
let init = format_ident!("init", span = value.span());
291+
// NOTE: the field accessor ensures that the initialized field is properly aligned.
292+
// Unaligned fields will cause the compiler to emit E0793. We do not support
293+
// unaligned fields since `Init::__init` requires an aligned pointer; the call to
294+
// `ptr::write` below has the same requirement.
301295
let (value_init, accessor) = if pinned {
302296
let project_ident = format_ident!("__project_{ident}");
303297
(
@@ -332,20 +326,15 @@ fn init_fields(
332326
},
333327
)
334328
};
335-
let accessor = generate_initialized_accessors.then(|| {
336-
quote! {
337-
#(#cfgs)*
338-
#[allow(unused_variables)]
339-
let #ident = #accessor;
340-
}
341-
});
342329
quote! {
343330
#(#attrs)*
344331
{
345332
let #init = #value;
346333
#value_init
347334
}
348-
#accessor
335+
#(#cfgs)*
336+
#[allow(unused_variables)]
337+
let #ident = #accessor;
349338
}
350339
}
351340
InitializerKind::Code { block: value, .. } => quote! {
@@ -472,10 +461,6 @@ impl Parse for Initializer {
472461
if a.path().is_ident("default_error") {
473462
a.parse_args::<DefaultErrorAttribute>()
474463
.map(InitializerAttribute::DefaultError)
475-
} else if a.path().is_ident("disable_initialized_field_access") {
476-
a.meta
477-
.require_path_only()
478-
.map(|_| InitializerAttribute::DisableInitializedFieldAccess)
479464
} else {
480465
Err(syn::Error::new_spanned(a, "unknown initializer attribute"))
481466
}

tests/ui/compile-fail/init/no_field_access.rs

Lines changed: 0 additions & 19 deletions
This file was deleted.

tests/ui/compile-fail/init/no_field_access.stderr

Lines changed: 0 additions & 5 deletions
This file was deleted.

tests/ui/expand/no_field_access.expanded.rs

Lines changed: 0 additions & 76 deletions
This file was deleted.

tests/ui/expand/no_field_access.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)