Option::cloned disowns mut

I have the code:

#[derive(Clone)]
struct U;

fn main() {
    let u = Some(U);
    Option::cloned(u.as_mut());
}

Which fails with:

Option::cloned(u.as_mut());
               ^^^^^^^^^^ values differ in mutability

To clone I have to use .map(|t| t.clone()) directly.

Is there any way to use Option::cloned when external method strictly returns Option<&mut T>.

I feel .cloned() has unflexble implementation. Am I right or wrong?

1 Like

This looks like an oversight to me. Perhaps you could open an issue on github, or even just write up a quick pull request and see what the standard lib team thinks.

Perhaps it should take any Deref type?

impl<T: Clone, U: Deref<Target = T>> Option<U> {
    fn cloned(self) -> Option<T> {
        match self {
            Some(u) => Some(u.clone()),
            None => None,
        }
    }
}

playground

I think this wouldn't even be a breaking change. However, note that cloned(self) is taken by value, which is normally painless since any Option<&T> implements Copy. That's harder to deal with for other Deref types.

FWIW, I also tried AsRef<T>, but then T is not constrained in the impl. I think you could move the parameterization onto cloned itself, but this will lean more heavily on type inference at the caller, which could break existing cloned calls.

Thanks for useful ideas! :+1: I think I should to test an alternative implementation as change of standard library. Possible this improvement is worth to be a PR.