# 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 -->