diff options
| author | oli <github35764891676564198441@oli-obk.de> | 2020-12-30 16:48:07 +0000 |
|---|---|---|
| committer | oli <github35764891676564198441@oli-obk.de> | 2021-01-01 16:59:12 +0000 |
| commit | 4158e58d79af7a538944c0acffbc0718551f221a (patch) | |
| tree | f406daa8bc335f39c3fc1c3da533f8ce998b9725 | |
| parent | 354e510f7d9e9f19b5f3ff55da83658a260bca4f (diff) | |
| download | rust-4158e58d79af7a538944c0acffbc0718551f221a.tar.gz rust-4158e58d79af7a538944c0acffbc0718551f221a.zip | |
Enhance some comments
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/validation.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/consts/std/cell.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/consts/std/cell.stderr | 8 |
3 files changed, 16 insertions, 9 deletions
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index c2c54c94061..c2b702f265b 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -584,6 +584,8 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { if borrowed_place_has_mut_interior { // Locals without StorageDead follow the "enclosing scope" rule, meaning // they are essentially anonymous static items themselves. + // Note: This is only sound if every local that has a `StorageDead` has a + // `StorageDead` in every control flow path leading to a `return` terminator. if self.local_has_storage_dead(place.local) { self.check_op(ops::CellBorrowBehindRef); } else { diff --git a/src/test/ui/consts/std/cell.rs b/src/test/ui/consts/std/cell.rs index de75d868c7f..f1ef541319a 100644 --- a/src/test/ui/consts/std/cell.rs +++ b/src/test/ui/consts/std/cell.rs @@ -2,23 +2,28 @@ use std::cell::*; -// not ok, because this would create a silent constant with interior mutability. -// the rules could be relaxed in the future +// not ok, because this creates a dangling pointer, just like `let x = Cell::new(42).as_ptr()` would static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); //~^ ERROR encountered dangling pointer const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); //~^ ERROR encountered dangling pointer +// Ok, these are just base values and it is the `Wrap` author's job to uphold `Send` and `Sync` +// invariants, since they used `unsafe impl`. static FOO3: Wrap<Cell<u32>> = Wrap(Cell::new(42)); const FOO3_CONST: Wrap<Cell<u32>> = Wrap(Cell::new(42)); -// ok +// ok, we are referring to the memory of another static item. static FOO4: Wrap<*mut u32> = Wrap(FOO3.0.as_ptr()); + +// not ok, the use of a constant here is equivalent to an inline declaration of the value, so +// its memory will get freed before the constant is finished evaluating, thus creating a dangling +// pointer. This would happen exactly the same at runtime. const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr()); //~^ ERROR encountered dangling pointer -// not ok, because the `as_ptr` call takes a reference to a type with interior mutability -// which is not allowed in constants +// not ok, because the `as_ptr` call takes a reference to a temporary that will get freed +// before the constant is finished evaluating. const FOO2: *mut u32 = Cell::new(42).as_ptr(); //~^ ERROR encountered dangling pointer diff --git a/src/test/ui/consts/std/cell.stderr b/src/test/ui/consts/std/cell.stderr index 75cae00611a..355c326f0b6 100644 --- a/src/test/ui/consts/std/cell.stderr +++ b/src/test/ui/consts/std/cell.stderr @@ -1,23 +1,23 @@ error: encountered dangling pointer in final constant - --> $DIR/cell.rs:7:1 + --> $DIR/cell.rs:6:1 | LL | static FOO: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered dangling pointer in final constant - --> $DIR/cell.rs:9:1 + --> $DIR/cell.rs:8:1 | LL | const FOO_CONST: Wrap<*mut u32> = Wrap(Cell::new(42).as_ptr()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered dangling pointer in final constant - --> $DIR/cell.rs:17:1 + --> $DIR/cell.rs:22:1 | LL | const FOO4_CONST: Wrap<*mut u32> = Wrap(FOO3_CONST.0.as_ptr()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: encountered dangling pointer in final constant - --> $DIR/cell.rs:22:1 + --> $DIR/cell.rs:27:1 | LL | const FOO2: *mut u32 = Cell::new(42).as_ptr(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
