refcell_ref.md: RefCell::RefMut is fine
See original GitHub issuerefcell_ref.md
says:
What is interesting about these types are the value fields. They use a normal Rust type, but in fact the guarantees for this are slightly weaker than normal: the reference is valid until either (a) the end of 'b OR (b) the field borrow is dropped, whichever happens first.
However, I think that applies only to RefCell::Ref
, not to RefCell::RefMut
. (The mistake is probably mine in the original mail to Niko.) The reason for this is that &mut T
is non-Copy
, so this actually is a reference that’s valid for as long as the lifetime says. If the destructor of RefCell::RefMut
is executed, ownership is moved from RefMut
back to the RefCell
. In some sense, having a variable of type &'a mut T
does not actually guarantee that the borrow lives for lifetime 'a
, all it really says is that if we keep hold of this variable, then the borrow lasts. But if we give up the variable, pass it to someone else, that someone may well kill the borrow earlier.
In contrast to that, &T
is Copy
, so there’s no “giving up” of ownership here.
(I was unsure whether an issue or the internals is the right place for this discussion. Feel free to move.)
Issue Analytics
- State:
- Created 7 years ago
- Comments:24 (12 by maintainers)
(Beware of the zombies!)
Now that we have done the proof, I am thinking maybe even
Ref
is just fine… The reasoning for that would be essentially as follows: If we take aRef<'a, T>
andmem::forget
it, then it is actually sound to use itsvalue
field at lifetime'a
. That is, we can “disassemble” the ownership captured inRef
to justify the type&'a T
given in the struct, but this “disassembling” is irreversible – along the way, we permanently lose our right to decrement the borrow count by1
.Maybe we don’t want to permit this kind of “irreversibility” when checking whether the private invariants are strong enough to justify the written type, I don’t know. If we do not, then I would agree with you that
RefMut
is just as bad; it also requires irreversible ownership transfer to obtain a&'a mut T
.Also see https://github.com/rust-lang/unsafe-code-guidelines/issues/125