In general f1 could do stuff like *foo = Arc::new(SomeOtherTypeThatImplsFoo::new()), so you can no longer rely on the previous type of bar after f1 is called. An alternative would be for f1 to take &mut dyn Foo, then you would be able to call f1 with f1(bar.get_mut().unwrap())
Nah, that's not the problem. The problem is that unsized coercions can't be transitive, regardless of mutability. A pointer-to-pointer-to-X can't be treated as a pointer-to-pointer-to-Y even if &(mut) X can be coerced to &(mut) Y. (For example, pointer arithmetic doesn't work out. The equivalent is true in languages with classical object-oriented subtyping.)
@OP: if you are using unsafe for circumventing the type system or the borrow checker, then your code is probably unsound. Do this instead.
In general, there's usually no reason for taking &mut Arc directly, and even less reason for &Arc. If your function needs a copy of the Arc for ownership, then make it take an Arc by-value, preventing unnecessary copies. If you only need a reference, then accept a reference, not an Arc.
In general, there's usually no reason for taking &mut Arc directly, and even less reason for &Arc. If your function needs a copy of the Arc for ownership, then make it take an Arc by-value, preventing unnecessary copies. If you only need a reference, then accept a reference, not an Arc.
I slightly disagree with this, I can give examples, but this may a little off-topic here, I do want a solution in this certain case.
I mentioned this above, if I cloned, the Arc::get_mut(foo).unwrap(); in f1 will fail, since there are two instances holding it. That's why this question is tricky to me.
The reason f1 takes &mut Arc is that:
it wants to get mut from it,
then the arc will be cloned and passed to others.
It may look a little weird, but in the real case f1 is designed to be this for a reason.
This could be solved if you could change f1 to take a generic rather than a trait object. The problem is that once you go to a trait object, there's no going back. (Downcasting is only possible on dyn Any, but you can't coerce dyn Foo to dyn Any).
I don't think there is a direct solution. I strongly suggest redesigning your code.
That's practicable, though it needs a lot of code refactors. I assumed it would be a way in the language to manipulate dyn types safely, but it seems that it not as flexible as I thought.