You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I was hoping to use Immutable trait in my own crate, but I discovered strange behavior that seems to contradict the definition of Immutable given by the documentation:
T: Immutable indicates that T does not permit interior mutation, except
by ownership or an exclusive (&mut) borrow.
Namely, there are blanket implementations of Immutable for &T and &mut T. This means that the unassuming usage of Immutable can lead to loopholes where the value can be unexpectedly mutated. For example, take this function:
fnperform_work<T:Immutable + Debug,F:FnOnce(&T)>(value:T,do_something:F){println!("{:#?}", value);do_something(&value);println!("{:#?}", value);// <-- because T: Immutable, we are not expecting the value to be different here}
Because of the promise given by the definition of Immutable and because T: Immutable, we expect the second print statement to always return exactly the same value as the first, and our code can come to rely on that. However, because of the blanket implementation of Immutable for &T and &mut T, we can easily write code that violates this promise:
#[derive(Debug,Immutable)]structData<T>{field:Rc<RefCell<T>>,}fnmain(){let value = Data{field:Rc::new(RefCell::new(100)),};perform_work(&value, |val| {*val.field.borrow_mut() = 200;});}
In this example the first print statement prints 100 while the second prints 200. This behavior seems to neither be explained in the definition of Immutable, nor under the impl blocks for &T and &mut T.
I would appreciate some additional clarity regarding Immutable, specifically, why is &Rc<RefCell<T>> (or similar) still considered a type that "does not permit interior mutation"? If it is crucial that this remains the case for the zerocopy crate, I would suggest additional explanation of this behavior in the documentation.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Hello!
I was hoping to use
Immutabletrait in my own crate, but I discovered strange behavior that seems to contradict the definition ofImmutablegiven by the documentation:Namely, there are blanket implementations of
Immutablefor&Tand&mut T. This means that the unassuming usage ofImmutablecan lead to loopholes where the value can be unexpectedly mutated. For example, take this function:Because of the promise given by the definition of
Immutableand becauseT: Immutable, we expect the second print statement to always return exactly the same value as the first, and our code can come to rely on that. However, because of the blanket implementation ofImmutablefor&Tand&mut T, we can easily write code that violates this promise:In this example the first print statement prints
100while the second prints200. This behavior seems to neither be explained in the definition ofImmutable, nor under the impl blocks for&Tand&mut T.I would appreciate some additional clarity regarding
Immutable, specifically, why is&Rc<RefCell<T>>(or similar) still considered a type that "does not permit interior mutation"? If it is crucial that this remains the case for thezerocopycrate, I would suggest additional explanation of this behavior in the documentation.Thanks!
All reactions