---
# System prepended metadata

title: Meeting 2025-07-23
tags: [meeting notes]

---

# Meeting 2025-07-23
<!-- Leave your topic starting with ### in the relevant sections below -->

## Critical
<!-- bugs, soundness issues, urgent patches/reviews etc. -->

## Status Reports
<!-- You want to report on something you are working on/request reviews.
Or you want to know the status of something someone else is doing -->

* Xiang is still working on the abitrary self type.
* Boqun: I'm not able to follow the blocking issue of pin-initializer, please add more details @dingxf.
  * xiang: Recently we were talking about allowing `T: Init<[T; N]>` to also implicate `T: Init<[T]>`. The technical details of allowing such type judgement are to finalize, especially I need to find a safe way to select a correct `T: Init<[T; N]>`, if any, and rejects ambiguity, if we are in a situation to prove that `T: Init<[T]>`.

## Discussion Questions
<!-- Anything that requires lengthy discussion/more general questions also fit here -->

### Kangrejos 2025

* Joel asked for the status about calling functions between Rust modules, and Miguel planned to give a topic about that on Kangrejos.
* Daniel suggested to talk about Tyr at Kangrejos.
* Boqun suggested to talk about SpinLockIrq at Kangrejos.

### Pinned Data in `Lock<T>`

Boqun: I think we should also separate `Mutex` and `Spinlock`, ie get rid of the generic `Lock`.

But this is orthogonal

Changes needed for data in `Mutex<T>` are:
* in the `new` use `impl PinInit<T>` instead `T`
* the guard needs to only implement `DerefMut` if `T: Unpin`
* the guard needs to have `fn as_mut(&mut self) -> Pin<&mut T>`

Alice: We need pin/field projections for this to be useful in practice.

```rust
#[pin_data]
struct Data {
    #[pin]
    a: Devres<A>,
    #[pin]
    b: Devres<B>,
}

fn handle_data(mutex: &Mutex<Data>) {
    let mut data: MutexGuard<'_, Data> = mutex.lock();
    let mut data: Pin<&mut Data> = data.as_mut();
    let a = &mut data.a; // <- won't compile
    // instead can do this now:
    let a: Pin<&mut Devres<A>> = unsafe { Pin::map_mut_unchecked(data, |data| &mut data.a) };
    
    // what we could also do with macros would be:
    let a: Pin<&mut Devres<A>> = Data::project_a(data);
    let a: Pin<&mut Devres<A>> = data.project().a;
    
    
    // field projection prototype
    let a = proj!(data => a); // <- Boqun: can we just expand this line with the above unsafe code?
    let a = proj!(unsafe data => a);
    
    let a = p!(@mut data->a);
    
    
    // Either reference a generated name
    let PinProjectedData { a, b } = data.project();
    
    // or
    let proj = data.project();
    let a = proj.a;
    let a = proj.b;
    
    // this would be with field projections: (faar in the future)
    let a: Pin<&mut Devres<A>> = @mut data.a;
}
```

Conclusion: if we want to invest more to make it help field projection proposal, let's try to see if we can get `syn` in as a dependency and have the safe `p!()` macro (i.e. a macro implemenation of field projection).

<https://github.com/Rust-for-Linux/field-projection/blob/new/examples/fair_race_future.rs>


```patch
diff --git a/rust/pin-init/src/macros.rs b/rust/pin-init/src/macros.rs
index 9ced630737b8..94092bd11cda 100644
--- a/rust/pin-init/src/macros.rs
+++ b/rust/pin-init/src/macros.rs
@@ -988,6 +988,31 @@ fn drop(&mut self) {
         @pinned($($(#[$($p_attr:tt)*])* $pvis:vis $p_field:ident : $p_type:ty),* $(,)?),
         @not_pinned($($(#[$($attr:tt)*])* $fvis:vis $field:ident : $type:ty),* $(,)?),
     ) => {
+        $crate::macros::paste! {
+            impl<$($impl_generics)*> $name<$($ty_generics)*>
+            where $($whr)*
+            {
+                $(
+                    $(#[$($p_attr)*])*
+                    $pvis unsafe fn [< project_ $p_field >](
+                        self: ::core::pin::Pin<&mut Self>,
+                    ) -> ::core::pin::Pin<&mut $p_type> {
+                        // SAFETY: `$p_field` is structurally pinned.
+                        unsafe { ::core::pin::Pin::map_unchecked_mut(self, |inner| &mut inner.$p_field) }
+                    }
+                )*
+                $(
+                    $(#[$($attr)*])*
+                    $fvis unsafe fn [< project_ $field >](
+                        self: ::core::pin::Pin<&mut Self>,
+                    ) -> &mut $type {
+                        // SAFETY: `$field` is not structurally pinned.
+                        unsafe { &mut ::core::pin::Pin::get_unchecked_mut(self).$field }
+                    }
+                )*
+            }
+        }
+
         // For every field, we create a projection function according to its projection type. If a
         // field is structurally pinned, then it must be initialized via `PinInit`, if it is not
         // structurally pinned, then it can be initialized via `Init`.
```

## Miscellaneous
<!-- stuff that does not fit into other categories -->
