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

Topic: VecDeque vs Stacked Borrows

RalfJ (Apr 18 2019 at 11:35, on Zulip):

And another Stacked Borrows violation in VecDeque::drain:

RalfJ (Apr 19 2019 at 14:04, on Zulip):

This is interesting because it is the first time I found a conflict between existing code and the notion of "barriers". I think without barriers there would be no issue.

RalfJ (Apr 19 2019 at 14:06, on Zulip):

This is a bit like

struct<T> NoCopy(T);
fn foo(mut x: NoCopy<&i32>) {
  let ptr = &x.0 as *const i32;
  drop(x); // "consume" the shared reference
  *(ptr as *mut U) = ...;

The NoCopy wrapper here changes nothing, and without that this is clearly UB.

RalfJ (Apr 19 2019 at 14:06, on Zulip):

Cc @nikomatsakis this relates to the question of whether to traverse below private fields or not

RalfJ (Apr 19 2019 at 20:34, on Zulip):

uh, actually RefCell has the same problem...

use std::cell::{RefCell, Ref};

fn break_it(rc: &RefCell<i32>, r: Ref<'_, i32>) {
    // `r` has a shared reference, it is passed in as argument and hence
    // a barrier is added that marks this memory as read-only for the entire
    // duration of this function.
    // *oops* here we can mutate that memory.
    *rc.borrow_mut() = 2;

fn main() {
    let rc = RefCell::new(0);
    break_it(&rc, rc.borrow())
RalfJ (Apr 19 2019 at 20:36, on Zulip):

actually @comex predicted this long ago but it seems I kind of forgot about it oops

Last update: Jul 03 2020 at 17:20UTC