|
2 | 2 |
|
3 | 3 | use std::cell::*; |
4 | 4 |
|
5 | | -// not ok, because this would create a silent constant with interior mutability. |
6 | | -// the rules could be relaxed in the future |
| 5 | +// not ok, because this creates a dangling pointer, just like `let x = Cell::new(42).as_ptr()` would |
7 | 6 | static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); |
8 | 7 | //~^ ERROR encountered dangling pointer |
9 | 8 | const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); |
10 | 9 | //~^ ERROR encountered dangling pointer |
11 | 10 |
|
| 11 | +// Ok, these are just base values and it is the `Wrap` author's job to uphold `Send` and `Sync` |
| 12 | +// invariants, since they used `unsafe impl`. |
12 | 13 | static FOO3: Wrap<Cell<u32>> = Wrap(Cell::new(42)); |
13 | 14 | const FOO3_CONST: Wrap<Cell<u32>> = Wrap(Cell::new(42)); |
14 | 15 |
|
15 | | -// ok |
| 16 | +// ok, we are referring to the memory of another static item. |
16 | 17 | static FOO4: Wrap<*mut u32> = Wrap(FOO3.0.as_ptr()); |
| 18 | + |
| 19 | +// not ok, the use of a constant here is equivalent to an inline declaration of the value, so |
| 20 | +// its memory will get freed before the constant is finished evaluating, thus creating a dangling |
| 21 | +// pointer. This would happen exactly the same at runtime. |
17 | 22 | const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr()); |
18 | 23 | //~^ ERROR encountered dangling pointer |
19 | 24 |
|
20 | | -// not ok, because the `as_ptr` call takes a reference to a type with interior mutability |
21 | | -// which is not allowed in constants |
| 25 | +// not ok, because the `as_ptr` call takes a reference to a temporary that will get freed |
| 26 | +// before the constant is finished evaluating. |
22 | 27 | const FOO2: *mut u32 = Cell::new(42).as_ptr(); |
23 | 28 | //~^ ERROR encountered dangling pointer |
24 | 29 |
|
|
0 commit comments