This repository was archived by the owner on Apr 5, 2024. It is now read-only.
This repository was archived by the owner on Apr 5, 2024. It is now read-only.
Unsafe Mutability Polymorphism #31
Open
Description
One popular example of code where we are not certain about its UB status is mutability polymorphism:
struct BTree<K, V> { /* .. */ }
impl<K: Ord, V> BTree<K, V> {
fn get<'a>(&'a self, key: &K) -> Option<&'a V> { /* ... */ }
fn get_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
self.get(key).map(|v| unsafe { &mut *v })
}
// <or vice-versa>
}
Of course, the usage pattern is calling get_mut
and then mutating the value. However, with both the ACA and CA models, a reference derived from an &
-reference has no write permissions, and writing through it causes self-aliasing-violation and UB.
OTOH, having get
call get_mut
rather than vice-versa does not seem to create UB under both rules (because the reference is asserted only for reading), but without write-asserts to arguments we have the write-not-in-program issue.
Still, having one of these cases UB and the other well-defined is ugly, and hard to tell to users.