22//@ normalize-stderr-test: "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)" 
33//@ normalize-stderr-test: "([0-9a-f][0-9a-f] |╾─*ALLOC[0-9]+(\+[a-z0-9]+)?(<imm>)?─*╼ )+ *│.*" -> "HEX_DUMP" 
44
5+ #![ allow( static_mut_refs) ]  
56#![ deny( const_eval_mutable_ptr_in_final_value) ]  
67use  std:: cell:: UnsafeCell ; 
8+ use  std:: sync:: atomic:: * ; 
9+ 
10+ // # Plain `&mut` in the final value 
711
812// This requires walking nested statics. 
913static  FOO :  & & mut  u32  = & & mut  42 ; 
1014//~^ ERROR it is undefined behavior to use this value 
11- 
15+ //~| pointing to read-only memory 
16+ static  OH_YES :  & mut  i32  = & mut  42 ; 
17+ //~^ ERROR it is undefined behavior to use this value 
18+ //~| pointing to read-only memory 
1219static  BAR :  & mut  ( )  = & mut  ( ) ; 
1320//~^ ERROR encountered mutable pointer in final value of static 
1421//~| WARNING this was previously accepted by the compiler 
@@ -19,15 +26,92 @@ static BOO: &mut Foo<()> = &mut Foo(());
1926//~^ ERROR encountered mutable pointer in final value of static 
2027//~| WARNING this was previously accepted by the compiler 
2128
29+ const  BLUNT :  & mut  i32  = & mut  42 ; 
30+ //~^ ERROR: it is undefined behavior to use this value 
31+ //~| pointing to read-only memory 
32+ 
33+ const  SUBTLE :  & mut  i32  = unsafe  {  static  mut  STATIC :  i32  = 0 ;  & mut  STATIC  } ; 
34+ //~^ ERROR: it is undefined behavior to use this value 
35+ //~| static 
36+ 
37+ // # Interior mutability 
38+ 
2239struct  Meh  { 
2340    x :  & ' static  UnsafeCell < i32 > , 
2441} 
2542unsafe  impl  Sync  for  Meh  { } 
2643static  MEH :  Meh  = Meh  {  x :  & UnsafeCell :: new ( 42 )  } ; 
2744//~^ ERROR it is undefined behavior to use this value 
45+ //~| `UnsafeCell` in read-only memory 
46+ // Same with a const: 
47+ // the following will never be ok! no interior mut behind consts, because 
48+ // all allocs interned here will be marked immutable. 
49+ const  MUH :  Meh  = Meh  { 
50+     //~^ ERROR it is undefined behavior to use this value 
51+     //~| `UnsafeCell` in read-only memory 
52+     x :  & UnsafeCell :: new ( 42 ) , 
53+ } ; 
54+ 
55+ struct  Synced  { 
56+     x :  UnsafeCell < i32 > , 
57+ } 
58+ unsafe  impl  Sync  for  Synced  { } 
59+ 
60+ // Make sure we also catch this behind a type-erased `dyn Trait` reference. 
61+ const  SNEAKY :  & dyn  Sync  = & Synced  {  x :  UnsafeCell :: new ( 42 )  } ; 
62+ //~^ ERROR: it is undefined behavior to use this value 
63+ //~| `UnsafeCell` in read-only memory 
64+ 
65+ // # Check for mutable references to read-only memory 
66+ 
67+ static  READONLY :  i32  = 0 ; 
68+ static  mut  MUT_TO_READONLY :  & mut  i32  = unsafe  {  & mut  * ( & READONLY  as  * const  _  as  * mut  _ )  } ; 
69+ //~^ ERROR: it is undefined behavior to use this value 
70+ //~| pointing to read-only memory 
71+ 
72+ // # Check for consts pointing to mutable memory 
73+ 
74+ static  mut  MUTABLE :  i32  = 42 ; 
75+ const  POINTS_TO_MUTABLE :  & i32  = unsafe  {  & MUTABLE  } ;  //~ERROR: undefined behavior 
76+ //~| encountered reference to mutable memory 
77+ static  mut  MUTABLE_REF :  & mut  i32  = & mut  42 ; 
78+ const  POINTS_TO_MUTABLE2 :  & i32  = unsafe  {  & * MUTABLE_REF  } ; 
79+ //~^ ERROR: evaluation of constant value failed 
80+ //~| accesses mutable global memory 
81+ 
82+ const  POINTS_TO_MUTABLE_INNER :  * const  i32  = & mut  42  as  * mut  _  as  * const  _ ; 
83+ //~^ ERROR: mutable pointer in final value 
84+ //~| WARNING this was previously accepted by the compiler 
85+ 
86+ const  POINTS_TO_MUTABLE_INNER2 :  * const  i32  = & mut  42  as  * const  _ ; 
87+ //~^ ERROR: mutable pointer in final value 
88+ //~| WARNING this was previously accepted by the compiler 
89+ 
90+ const  INTERIOR_MUTABLE_BEHIND_RAW :  * mut  i32  = & UnsafeCell :: new ( 42 )  as  * const  _  as  * mut  _ ; 
91+ //~^ ERROR: mutable pointer in final value 
92+ //~| WARNING this was previously accepted by the compiler 
93+ 
94+ struct  SyncPtr < T >  { 
95+     x :  * const  T , 
96+ } 
97+ unsafe  impl < T >  Sync  for  SyncPtr < T >  { } 
98+ 
99+ // These pass the lifetime checks because of the "tail expression" / "outer scope" rule. 
100+ // (This relies on `SyncPtr` being a curly brace struct.) 
101+ // However, we intern the inner memory as read-only, so this must be rejected. 
102+ // (Also see `static-no-inner-mut` for similar tests on `static`.) 
103+ const  RAW_SYNC :  SyncPtr < AtomicI32 >  = SyncPtr  {  x :  & AtomicI32 :: new ( 42 )  } ; 
104+ //~^ ERROR mutable pointer in final value 
105+ //~| WARNING this was previously accepted by the compiler 
106+ 
107+ const  RAW_MUT_CAST :  SyncPtr < i32 >  = SyncPtr  {  x :  & mut  42  as  * mut  _  as  * const  _  } ; 
108+ //~^ ERROR mutable pointer in final value 
109+ //~| WARNING this was previously accepted by the compiler 
110+ 
111+ const  RAW_MUT_COERCE :  SyncPtr < i32 >  = SyncPtr  {  x :  & mut  0  } ; 
112+ //~^ ERROR mutable pointer in final value 
113+ //~| WARNING this was previously accepted by the compiler 
28114
29- static  OH_YES :  & mut  i32  = & mut  42 ; 
30- //~^ ERROR it is undefined behavior to use this value 
31115
32116fn  main ( )  { 
33117    unsafe  { 
0 commit comments