File: static-no-inner-mut.rs

package info (click to toggle)
rustc 1.89.0%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 906,624 kB
  • sloc: xml: 158,148; python: 34,888; javascript: 19,595; sh: 19,221; ansic: 13,046; cpp: 7,144; asm: 4,376; makefile: 692; lisp: 174; sql: 15
file content (42 lines) | stat: -rw-r--r-- 1,700 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//@ stderr-per-bitwidth
//@ compile-flags: -Zunleash-the-miri-inside-of-you

// All "inner" allocations that come with a `static` are interned immutably. This means it is
// crucial that we do not accept any form of (interior) mutability there.
use std::sync::atomic::*;

static REF: &AtomicI32 = &AtomicI32::new(42);
//~^ ERROR `UnsafeCell` in read-only memory

static REFMUT: &mut i32 = &mut 0;
//~^ ERROR mutable reference or box pointing to read-only memory

// Different way of writing this that avoids promotion.
static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
//~^ ERROR `UnsafeCell` in read-only memory
static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
//~^ ERROR mutable reference or box pointing to read-only memory

// This one is obvious, since it is non-Sync. (It also suppresses the other errors, so it is
// commented out.)
// static RAW: *const AtomicI32 = &AtomicI32::new(42);

struct SyncPtr<T> { x : *const T }
unsafe impl<T> Sync for SyncPtr<T> {}

// All of these pass the lifetime checks because of the "tail expression" / "outer scope" rule.
// (This relies on `SyncPtr` being a curly brace struct.)
// Then they get interned immutably, which is not great. See
// <https://github.com/rust-lang/rust/pull/128543> for why we accept such code.
static RAW_SYNC: SyncPtr<AtomicI32> = SyncPtr { x: &AtomicI32::new(42) };

// With mutable references at least, we can detect this and error.
static RAW_MUT_CAST: SyncPtr<i32> = SyncPtr { x : &mut 42 as *mut _ as *const _ };
//~^ ERROR mutable pointer in final value

static RAW_MUT_COERCE: SyncPtr<i32> = SyncPtr { x: &mut 0 };
//~^ ERROR mutable pointer in final value

fn main() {}

//~? WARN skipping const checks