Stream: t-lang/wg-unsafe-code-guidelines

Topic: stacked borrows: Overlapping &RefCell and &mut T

RalfJ (Nov 09 2018 at 10:05, on Zulip):

@nikomatsakis I did some more refactoring after we talked yesterday, and now I have something that I am pretty happy with. It might be even nicer if we had type information on actual memory accesses, but alas, this is good enough I think. The key idea was to accept that we have two different "stack traversals":

This means we have three core per-location borrow operations: deref, access, create.
A reborrow is then generally described as doing all of those operations (deref original ptr, then access with it [write access if we are creating a mutable borrow], then create new borrow), except that if we create a raw borrow, we might skip the last two steps.

RalfJ (Nov 09 2018 at 10:07, on Zulip):

I had to disable reborrowing in UnsafeCell::get because that one needs to immediately take a raw ptr, or else the deref done as part of the reborrow chokes: It sees a shared reference and expects it to be frozen.

nikomatsakis (Nov 13 2018 at 14:01, on Zulip):

@RalfJ nice! This is not, I suppose, specific to UnsafeCell::get, right? That is, this is basically one of those cases where the "special semantics" of &x as *const u32 is important?

RalfJ (Nov 13 2018 at 14:03, on Zulip):

@nikomatsakis Yes, exactly.

RalfJ (Nov 13 2018 at 14:04, on Zulip):

Also after talking with a friend in the bus yesterday, I was able to make the special exception for raw borrows slightly less special

RalfJ (Nov 13 2018 at 14:04, on Zulip):

It is now a general "redundant reborrow" rule: For all reborrows, we check if they are redundant, and if they are we do not do them.

RalfJ (Nov 13 2018 at 14:04, on Zulip):

A reborrow is redundant if the new reference is already dereferencable, and if moreover its item in the stack lives above the item of the old reference in the stack.

nikomatsakis (Nov 13 2018 at 14:23, on Zulip):

Is there a case where this applies other than raw pointers? I guess &T

RalfJ (Nov 13 2018 at 14:25, on Zulip):

It certainly never applies for mutable references

RalfJ (Nov 13 2018 at 14:25, on Zulip):

I am still pondering whether this changes behavior for &T with T frozen

RalfJ (Nov 13 2018 at 14:25, on Zulip):

the test suite did not see any change, that much I can say^^

nikomatsakis (Nov 13 2018 at 14:28, on Zulip):


RalfJ (Nov 13 2018 at 16:01, on Zulip):

No it does not change behavior. The redundancy case can only occur if the location is already frozen, in which case both a read access and pushing a new Shr onto the stack do nothing.

RalfJ (Nov 13 2018 at 16:06, on Zulip):

The nice thing about this is that I can now assert that we will never push to a frozen stack, instead of having to handle that case. This will just not happen any more, it is caught by the redundancy check.

Last update: Jul 02 2020 at 12:40UTC