From 4158e58d79af7a538944c0acffbc0718551f221a Mon Sep 17 00:00:00 2001 From: oli Date: Wed, 30 Dec 2020 16:48:07 +0000 Subject: [PATCH] Enhance some comments --- .../src/transform/check_consts/validation.rs | 2 ++ src/test/ui/consts/std/cell.rs | 15 ++++++++++----- 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 c2c54c940612..c2b702f265b6 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 de75d868c7fc..f1ef541319a4 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> = Wrap(Cell::new(42)); const FOO3_CONST: Wrap> = 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 75cae00611aa..355c326f0b6f 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(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^