Skip to content

Commit

Permalink
rust: init: wrap type checking struct initializers in a closure
Browse files Browse the repository at this point in the history
In the implementation of the init macros there is a `if false` statement
that type checks the initializer to ensure every field is initialized.
Since the next patch has a stack variable to store the struct, the
function might allocate too much memory on debug builds. Putting the
struct into a closure that is never executed ensures that even in debug
builds no stack overflow error is caused. In release builds this was not
a problem since the code was optimized away due to the `if false`.

Reviewed-by: Martin Rodriguez Reboredo <[email protected]>
Reviewed-by: Alice Ryhl <[email protected]>
Reviewed-by: Gary Guo <[email protected]>
Signed-off-by: Benno Lossin <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Miguel Ojeda <[email protected]>
  • Loading branch information
Benno Lossin authored and ojeda committed Aug 21, 2023
1 parent 97de919 commit b9b88be
Showing 1 changed file with 4 additions and 4 deletions.
8 changes: 4 additions & 4 deletions rust/kernel/init/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,14 +1040,14 @@ macro_rules! __init_internal {
// once, this struct initializer will still be type-checked and complain with a
// very natural error message if a field is forgotten/mentioned more than once.
#[allow(unreachable_code, clippy::diverging_sub_expression)]
if false {
let _ = || {
$crate::__init_internal!(make_initializer:
@slot(slot),
@type_name($t),
@munch_fields($($fields)*,),
@acc(),
);
}
};
}
Ok(__InitOk)
}
Expand Down Expand Up @@ -1168,8 +1168,8 @@ macro_rules! __init_internal {
@acc($($acc:tt)*),
) => {
// Endpoint, nothing more to munch, create the initializer.
// Since we are in the `if false` branch, this will never get executed. We abuse `slot` to
// get the correct type inference here:
// Since we are in the closure that is never called, this will never get executed.
// We abuse `slot` to get the correct type inference here:
unsafe {
::core::ptr::write($slot, $t {
$($acc)*
Expand Down

0 comments on commit b9b88be

Please sign in to comment.