Trait `DerefMut` is required but how do I satisfy it through a generic

I am using nightly rust for the Coroutine features

I am trying to write a Coroutine writer that accept AsRef<[u8]> and write it to a file

here is the problematic snippet

struct WriteLinesCoroutine<W: Write>
{
    writer: W
}

impl<W, R> Coroutine<R> for WriteLinesCoroutine<W>
where
    W: Write,
    R: AsRef<[u8]>
{
    type Yield = ();
    type Return = ();

    fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> {
        self.writer.write(arg.as_ref());
        CoroutineState::Yielded(())
    }
}

error[E0596]: cannot borrow data in dereference of `Pin<&mut WriteLinesCoroutine<W>>` as mutable
  --> src/main.rs:55:9
   |
55 |         self.writer.write(arg.as_ref());
   |         ^^^^^^^^^^^ cannot borrow as mutable
   |
   = help: trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Pin<&mut WriteLinesCoroutine<W>>`

it says that Pin<&mut WriteLinesCoroutine<W>> doesn't implement DerefMut, I took a look at Pin blanked implementation

looks like &mut WriteLinesCoroutine<W> should implement DerefMut for it to work, but I am not sure why or how to implemented in my case

if I change my generic W for some concrete type, it works fine

impl<R> Coroutine<R> for WriteLinesCoroutine<File>
where
    R: AsRef<[u8]>
{
    ...
}

I am not sure why the compiler accepts File, &mut WriteLinesCoroutine<File> still doesn't implement DerefMut(?), I looked at what traits File implements

doesn't look like File also implements DerefMut so why the compiler accepts it

so I tried to put more constraints on my generic like W: Write + DerefMut but doesn't seem to work either

the compiler's diagnostic message is not very helpful in this case.

the easist workaround is to add a Unpin bound, e.g. on the impl block:

impl<W, R> Coroutine<R> for WriteLinesCoroutine<W>
where
    W: Write,
    R: AsRef<[u8]>,
+   Self: Unpin,
{
    ...
}

if you find Unpin too restrictive for your use case, then you'll have to use proper pin porjection and explicitly make self.writer as non structural pinned, in order to get a &mut W from the Pin<&mut Self>.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.