//@ 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]; }