about summary refs log tree commit diff
diff options
context:
space:
mode:
authoroli <github35764891676564198441@oli-obk.de>2020-12-30 17:44:11 +0000
committeroli <github35764891676564198441@oli-obk.de>2021-01-01 16:59:12 +0000
commitaaee3f27eec3e14e28436cdcc6ffe469d400c789 (patch)
treebc04631ea569577adbbe0bd9d62b0d2efe038a38
parent3ed14033f7c087492a73c70bb11c1f7bae1b06c9 (diff)
downloadrust-aaee3f27eec3e14e28436cdcc6ffe469d400c789.tar.gz
rust-aaee3f27eec3e14e28436cdcc6ffe469d400c789.zip
Don't mix feature gates and hard errors, decide on one per op and stick with it
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/ops.rs7
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs26
2 files changed, 18 insertions, 15 deletions
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs
index 764031c0dae..cb6d16bc207 100644
--- a/compiler/rustc_mir/src/transform/check_consts/ops.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs
@@ -237,13 +237,6 @@ impl NonConstOp for TransientCellBorrow {
 /// it in the future for static items.
 pub struct CellBorrow;
 impl NonConstOp for CellBorrow {
-    fn status_in_item(&self, ccx: &ConstCx<'_, '_>) -> Status {
-        match ccx.const_kind() {
-            // The borrow checker does a much better job at handling these than we do.
-            hir::ConstContext::ConstFn => Status::Unstable(sym::const_refs_to_cell),
-            _ => Status::Forbidden,
-        }
-    }
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
         struct_span_err!(
             ccx.tcx.sess,
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index f0ab3ff0100..4770d659032 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -582,14 +582,24 @@ 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::TransientCellBorrow);
-                    } else {
-                        self.check_op(ops::CellBorrow);
+                    match self.const_kind() {
+                        // In a const fn all borrows are transient or point to the places given via
+                        // references in the arguments. The borrow checker guarantees that.
+                        // NOTE: Once we have heap allocations during CTFE we need to figure out
+                        // how to prevent `const fn` to create long-lived allocations that point
+                        // to (interior) mutable memory.
+                        hir::ConstContext::ConstFn => self.check_op(ops::TransientCellBorrow),
+                        _ => {
+                            // 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::TransientCellBorrow);
+                            } else {
+                                self.check_op(ops::CellBorrow);
+                            }
+                        }
                     }
                 }
             }