From 3318657eaf0b8403317883a8cd68689d8a5c7d9a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 2 Aug 2019 08:15:52 +0200 Subject: [PATCH] test Ref/RefMut protector interactions --- tests/run-pass/refcell.rs | 33 ----------- tests/run-pass/stacked-borrows/refcell.rs | 68 +++++++++++++++++++++++ 2 files changed, 68 insertions(+), 33 deletions(-) delete mode 100644 tests/run-pass/refcell.rs create mode 100644 tests/run-pass/stacked-borrows/refcell.rs diff --git a/tests/run-pass/refcell.rs b/tests/run-pass/refcell.rs deleted file mode 100644 index 93cef1572a..0000000000 --- a/tests/run-pass/refcell.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::cell::RefCell; - -fn main() { - 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; - } -} diff --git a/tests/run-pass/stacked-borrows/refcell.rs b/tests/run-pass/stacked-borrows/refcell.rs new file mode 100644 index 0000000000..0939a66619 --- /dev/null +++ b/tests/run-pass/stacked-borrows/refcell.rs @@ -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, 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, 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()) +}