Messages in this thread Patch in this message | | | Date | Wed, 2 Aug 2023 18:59:02 +0100 | From | Gary Guo <> | Subject | Re: [PATCH v3 06/13] rust: init: make initializer values inaccessible after initializing |
| |
On Sat, 29 Jul 2023 09:09:53 +0000 Benno Lossin <benno.lossin@proton.me> wrote:
> Previously the init macros would create a local variable with the name > and hygiene of the field that is being initialized to store the value of > the field. This would override any user defined variables. For example: > ``` > struct Foo { > a: usize, > b: usize, > } > let a = 10; > let foo = init!(Foo{ > a: a + 1, // This creates a local variable named `a`. > b: a, // This refers to that variable! > }); > let foo = Box::init!(foo)?; > assert_eq!(foo.a, 11); > assert_eq!(foo.b, 11); > ``` > > This patch changes this behavior, so the above code would panic at the > last assertion, since `b` would have value 10. > > Reviewed-by: Martin Rodriguez Reboredo <yakoyoku@gmail.com> > Reviewed-by: Alice Ryhl <aliceryhl@google.com> > Signed-off-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
> --- > v2 -> v3: > - added Reviewed-by's from Martin and Alice. > > rust/kernel/init/macros.rs | 20 +++++++++++--------- > 1 file changed, 11 insertions(+), 9 deletions(-) > > diff --git a/rust/kernel/init/macros.rs b/rust/kernel/init/macros.rs > index 2bad086cda0a..cfeacc4b3f7d 100644 > --- a/rust/kernel/init/macros.rs > +++ b/rust/kernel/init/macros.rs > @@ -1075,13 +1075,13 @@ macro_rules! __init_internal { > // In-place initialization syntax. > @munch_fields($field:ident <- $val:expr, $($rest:tt)*), > ) => { > - let $field = $val; > + let init = $val; > // Call the initializer. > // > // SAFETY: `slot` is valid, because we are inside of an initializer closure, we > // return when an error/panic occurs. > // We also use the `data` to require the correct trait (`Init` or `PinInit`) for `$field`. > - unsafe { $data.$field(::core::ptr::addr_of_mut!((*$slot).$field), $field)? }; > + unsafe { $data.$field(::core::ptr::addr_of_mut!((*$slot).$field), init)? }; > // Create the drop guard: > // > // We rely on macro hygiene to make it impossible for users to access this local variable. > @@ -1107,12 +1107,12 @@ macro_rules! __init_internal { > // In-place initialization syntax. > @munch_fields($field:ident <- $val:expr, $($rest:tt)*), > ) => { > - let $field = $val; > + let init = $val; > // Call the initializer. > // > // SAFETY: `slot` is valid, because we are inside of an initializer closure, we > // return when an error/panic occurs. > - unsafe { $crate::init::Init::__init($field, ::core::ptr::addr_of_mut!((*$slot).$field))? }; > + unsafe { $crate::init::Init::__init(init, ::core::ptr::addr_of_mut!((*$slot).$field))? }; > // Create the drop guard: > // > // We rely on macro hygiene to make it impossible for users to access this local variable. > @@ -1138,11 +1138,13 @@ macro_rules! __init_internal { > // Init by-value. > @munch_fields($field:ident $(: $val:expr)?, $($rest:tt)*), > ) => { > - $(let $field = $val;)? > - // Initialize the field. > - // > - // SAFETY: The memory at `slot` is uninitialized. > - unsafe { ::core::ptr::write(::core::ptr::addr_of_mut!((*$slot).$field), $field) }; > + { > + $(let $field = $val;)? > + // Initialize the field. > + // > + // SAFETY: The memory at `slot` is uninitialized. > + unsafe { ::core::ptr::write(::core::ptr::addr_of_mut!((*$slot).$field), $field) }; > + } > // Create the drop guard: > // > // We rely on macro hygiene to make it impossible for users to access this local variable.
| |