46 lines
974 B
Rust
46 lines
974 B
Rust
//@ check-pass
|
|
|
|
use std::sync::Mutex;
|
|
|
|
struct Foo {
|
|
x: usize
|
|
}
|
|
|
|
const fn foo() -> Foo {
|
|
Foo { x: 0 }
|
|
}
|
|
|
|
impl Foo {
|
|
const fn bar(&mut self) -> usize {
|
|
self.x = 1;
|
|
self.x
|
|
}
|
|
|
|
}
|
|
|
|
const fn baz(foo: &mut Foo) -> usize {
|
|
let x = &mut foo.x;
|
|
*x = 2;
|
|
*x
|
|
}
|
|
|
|
const fn bazz(foo: &mut Foo) -> usize {
|
|
foo.x = 3;
|
|
foo.x
|
|
}
|
|
|
|
// Empty slices get promoted so this passes the static checks.
|
|
// Make sure it also passes the dynamic checks.
|
|
static MUTABLE_REFERENCE_HOLDER: Mutex<&mut [u8]> = Mutex::new(&mut []);
|
|
// This variant with a non-empty slice also seems entirely reasonable.
|
|
static MUTABLE_REFERENCE_HOLDER2: Mutex<&mut [u8]> = unsafe {
|
|
static mut FOO: [u8; 1] = [42]; // a private static that we are sure nobody else will reference
|
|
Mutex::new(&mut *std::ptr::addr_of_mut!(FOO))
|
|
};
|
|
|
|
fn main() {
|
|
let _: [(); foo().bar()] = [(); 1];
|
|
let _: [(); baz(&mut foo())] = [(); 2];
|
|
let _: [(); bazz(&mut foo())] = [(); 3];
|
|
}
|