mirror of
https://github.com/torvalds/linux.git
synced 2026-05-12 16:18:45 +02:00
When a field has been initialized, `init!`/`pin_init!` create a reference
or pinned reference to the field so it can be accessed later during the
initialization of other fields. However, the reference it created is
incorrectly `&'static` rather than just the scope of the initializer.
This means that you can do
init!(Foo {
a: 1,
_: {
let b: &'static u32 = a;
}
})
which is unsound.
This is caused by `&mut (*#slot).#ident`, which actually allows arbitrary
lifetime, so this is effectively `'static`. Somewhat ironically, the safety
justification of creating the accessor is.. "SAFETY: TODO".
Fix it by adding `let_binding` method on `DropGuard` to shorten lifetime.
This results in exactly what we want for these accessors. The safety and
invariant comments of `DropGuard` have been reworked; instead of reasoning
about what caller can do with the guard, express it in a way that the
ownership is transferred to the guard and `forget` takes it back, so the
unsafe operations within the `DropGuard` can be more easily justified.
Fixes:
|
||
|---|---|---|
| .. | ||
| diagnostics.rs | ||
| init.rs | ||
| lib.rs | ||
| pin_data.rs | ||
| pinned_drop.rs | ||
| zeroable.rs | ||