Safe API for converting `&mut Box` to `&mut Pin>`?

⚓ Rust    📅 2025-07-23    👤 surdeus    👁️ 2      

surdeus

Hi everyone,

I'm working with futures::Sink and make a study about Pin<Box<dyn Sink>> between Box<dyn Sink>. I'm into a situation where I need to convert a &mut Box<dyn Sink> to &mut Pin<Box<dyn Sink>>. I believe this conversion should be safe, but I can't find a safe API to do it.

My reasoning

Here's why I think this conversion should be safe:

  1. Unique mutable reference: I have the only &mut Box<T> reference to the boxed value
  2. Consuming conversion: The conversion would consume my original &mut Box<T> reference, so I can't use it to move the contents afterward
  3. Pin guarantees: Through &mut Pin<Box<T>>, I cannot safely obtain &mut T (unless T: Unpin) to move the contents

The key insight is that while Box<T> puts T on the heap, I could theoretically still move T's contents through operations like std::mem::replace(&mut **box_ref, new_value). However, once I convert to &mut Pin<Box<T>> and lose access to the original reference, there's no way to perform such operations anymore.

I'm wondering why there isn't a API just like Option::as_pin_mut() for Box<T>.

Questions

  1. Is my reasoning correct about this conversion being safe?
  2. If it is safe, why doesn't the standard library provide this API?
  3. Are there any edge cases or subtle issues I'm missing?
  4. Would this be worth proposing as an addition to the standard library?

The conversion seems logically sound to me - the borrowing rules ensure I can't access the original Box after conversion, and Pin prevents unsafe access to the contents. But I'm curious if there are deeper reasons why this isn't available as a safe API.

Any insights would be greatly appreciated!

2 posts - 2 participants

Read full topic

🏷️ Rust_feed