Re: [PATCH v2] rust: check type of `$ptr` in `container_of!`
From: Tamir Duberstein
Date: Mon Apr 14 2025 - 10:43:25 EST
On Mon, Apr 14, 2025 at 10:04 AM Alice Ryhl <aliceryhl@xxxxxxxxxx> wrote:
>
> On Sat, Apr 12, 2025 at 02:16:08PM -0400, Tamir Duberstein wrote:
> > + ($field_ptr:expr, $Container:ty, $($fields:tt)*) => {{
> > + let offset: usize = ::core::mem::offset_of!($Container, $($fields)*);
> > + let container_ptr = $field_ptr.byte_sub(offset).cast::<$Container>();
> > + if false {
> > + let field_ptr = ::core::ptr::addr_of!((*container_ptr).$($fields)*).cast_mut();
> > + [$field_ptr, field_ptr]; // typeof(`$ptr_to_field`) == typeof(`$Container.$($fields)*`)
>
> This evaluates $field_ptr twice. The `if false` avoids bad stuff if the
> expression has side-effects, but still seems sub-optimal.
I don't disagree but I intentionally made this choice so that the
compiler error was clear about the LHS element being one of the
arguments to the macro. But maybe the comment provides enough clarity.
The alternative error is
> error[E0308]: mismatched types
> --> rust/kernel/lib.rs:207:25
> |
> 207 | [field_ptr, container_field_ptr]; // typeof(`$field_ptr`) == typeof(`$Container.$($fields)*`)
> | ^^^^^^^^^^^^^^^^^^^ expected `*mut rb_node`, found `*mut K`
> |
> ::: rust/kernel/rbtree.rs:270:6
> |
> 270 | impl<K, V> RBTree<K, V>
> | - found this type parameter
> ...
> 332 | let node = unsafe { container_of!(curr, Node<K, V>, key) };
> | ------------------------------------ in this macro invocation
> |
> = note: expected raw pointer `*mut bindings::rb_node`
> found raw pointer `*mut K`
> = note: this error originates in the macro `container_of` (in Nightly builds, run with -Z macro-backtrace for more info)
>
> error: aborting due to 1 previous error
Seems OK to me, so I'll do this in v3.