Provenance is a hard problem, so I'm probably missing something here
Provenance is a hard problem, so I'm probably missing something here
Posted Oct 8, 2025 21:33 UTC (Wed) by NYKevin (subscriber, #129325)In reply to: Provenance is a hard problem, so I'm probably missing something here by daroc
Parent article: Progress on defeating lifetime-end pointer zapping
Another way of thinking about it is that, if we ignore the Mutex (and const correctness) for the sake of simplicity, Arc<&dyn Foo> is morally equivalent to std::shared_ptr<Foo*> (where Foo has a vtable), not to be confused with the more usual std::shared_ptr<Foo>. The mutation you are describing is equivalent to replacing the Foo* with an entirely different Foo* that happens to point at an entirely different Foo instance. The mutex is needed to do this properly, of course, but it just adds another layer of indirection without really changing anything.
You might wonder what happens if we instead have Arc<Mutex<dyn Foo>>, which is of course an entirely legitimate type to construct. That allows you to get as far as obtaining &mut dyn Foo, but you can't get any further from there. You would need to call something like std::mem::swap() to replace it with a different Foo. But you can't do that, because dyn Foo is unsized and std::mem::swap() has an implied T: Sized bound, so the compiler will reject the call. All other (safe) functions or methods for doing this will either have a similar bound (usually implied), or will take T by value (which can't accept an unsized type), because there is no reasonable way to guarantee that the new Foo is small enough to fit into the old Foo's allocation.