2019-02-15 19:43:56 -06:00
|
|
|
// A callee may not read the destination of our `&mut` without us noticing.
|
2018-11-07 10:33:41 -06:00
|
|
|
// Thise code got carefully checked to not introduce any reborrows
|
2019-02-15 19:43:56 -06:00
|
|
|
// that are not explicit in the source. Let's hope the compiler does not break this later!
|
|
|
|
|
2018-11-07 10:33:41 -06:00
|
|
|
use std::mem;
|
|
|
|
|
2022-06-06 10:44:36 -05:00
|
|
|
union HiddenRef {
|
2022-06-26 20:14:18 -05:00
|
|
|
// We avoid retagging at this type, and we only read, so shared vs mutable does not matter.
|
2022-06-06 10:44:36 -05:00
|
|
|
r: &'static i32,
|
|
|
|
}
|
|
|
|
|
2018-11-07 10:33:41 -06:00
|
|
|
fn main() {
|
|
|
|
let mut x: i32 = 15;
|
|
|
|
let xref1 = &mut x;
|
2022-06-06 10:44:36 -05:00
|
|
|
let xref1_sneaky: HiddenRef = unsafe { mem::transmute_copy(&xref1) };
|
2019-02-15 19:43:56 -06:00
|
|
|
// Derived from `xref1`, so using raw value is still ok, ...
|
|
|
|
let xref2 = &mut *xref1;
|
2018-11-07 10:33:41 -06:00
|
|
|
callee(xref1_sneaky);
|
2019-02-15 19:43:56 -06:00
|
|
|
// ... though any use of it will invalidate our ref.
|
|
|
|
let _val = *xref2;
|
2019-04-16 10:17:28 -05:00
|
|
|
//~^ ERROR: borrow stack
|
2018-11-07 10:33:41 -06:00
|
|
|
}
|
|
|
|
|
2022-06-06 10:44:36 -05:00
|
|
|
fn callee(xref1: HiddenRef) {
|
2018-11-07 10:33:41 -06:00
|
|
|
// Doing the deref and the transmute (through the union) in the same place expression
|
|
|
|
// should avoid retagging.
|
2022-06-06 10:44:36 -05:00
|
|
|
let _val = unsafe { *xref1.r };
|
2018-11-07 10:33:41 -06:00
|
|
|
}
|