Skip to content

Commit

Permalink
test Ref/RefMut protector interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Aug 2, 2019
1 parent c4c2716 commit 3318657
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 33 deletions.
33 changes: 0 additions & 33 deletions tests/run-pass/refcell.rs

This file was deleted.

68 changes: 68 additions & 0 deletions tests/run-pass/stacked-borrows/refcell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::cell::{RefCell, Ref, RefMut};

fn main() {
basic();
ref_protector();
ref_mut_protector();
}

fn basic() {
let c = RefCell::new(42);
{
let s1 = c.borrow();
let _x: i32 = *s1;
let s2 = c.borrow();
let _x: i32 = *s1;
let _y: i32 = *s2;
let _x: i32 = *s1;
let _y: i32 = *s2;
}
{
let mut m = c.borrow_mut();
let _z: i32 = *m;
{
let s: &i32 = &*m;
let _x = *s;
}
*m = 23;
let _z: i32 = *m;
}
{
let s1 = c.borrow();
let _x: i32 = *s1;
let s2 = c.borrow();
let _x: i32 = *s1;
let _y: i32 = *s2;
let _x: i32 = *s1;
let _y: i32 = *s2;
}
}

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

let rc = RefCell::new(0);
break_it(&rc, rc.borrow())
}

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

let rc = RefCell::new(0);
break_it(&rc, rc.borrow_mut())
}

0 comments on commit 3318657

Please sign in to comment.