1 #![feature(const_mut_refs)]
2 #![feature(raw_ref_op)]
3 #![feature(const_raw_ptr_deref)]
5 const NULL: *mut i32 = std::ptr::null_mut();
6 const A: *const i32 = &4;
8 // It could be made sound to allow it to compile,
9 // but we do not want to allow this to compile,
10 // as that would be an enormous footgun in oli-obk's opinion.
11 const B: *mut i32 = &mut 4; //~ ERROR mutable references are not allowed
13 // Ok, no actual mutable allocation exists
14 const B2: Option<&mut i32> = None;
16 // Not ok, can't prove that no mutable allocation ends up in final value
17 const B3: Option<&mut i32> = Some(&mut 42); //~ ERROR temporary value dropped while borrowed
19 const fn helper(x: &mut i32) -> Option<&mut i32> { Some(x) }
20 const B4: Option<&mut i32> = helper(&mut 42); //~ ERROR temporary value dropped while borrowed
22 // Ok, because no references to mutable data exist here, since the `{}` moves
23 // its value and then takes a reference to that.
24 const C: *const i32 = &{
30 use std::cell::UnsafeCell;
31 struct NotAMutex<T>(UnsafeCell<T>);
33 unsafe impl<T> Sync for NotAMutex<T> {}
35 const FOO: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
36 //~^ ERROR temporary value dropped while borrowed
38 static FOO2: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
39 //~^ ERROR temporary value dropped while borrowed
41 static mut FOO3: NotAMutex<&mut i32> = NotAMutex(UnsafeCell::new(&mut 42));
42 //~^ ERROR temporary value dropped while borrowed
44 // `BAR` works, because `&42` promotes immediately instead of relying on
45 // the enclosing scope rule.
46 const BAR: NotAMutex<&i32> = NotAMutex(UnsafeCell::new(&42));
49 println!("{}", unsafe { *A });
50 unsafe { *B = 4 } // Bad news
54 assert_eq!(**FOO.0.get(), 99);