about summary refs log tree commit diff
path: root/src/librustc_mir/transform
diff options
context:
space:
mode:
authorEduard Burtescu <edy.burt@gmail.com>2016-05-05 08:11:28 +0300
committerEduard Burtescu <edy.burt@gmail.com>2016-05-07 19:14:33 +0300
commited66fe48e94df2cd0dee5af4afa44d7fb50cb0cf (patch)
tree0a875e37191033361b5c3a04aa8494551157922a /src/librustc_mir/transform
parent4f5900aefac42cec488a68c041ecd538c04b84fd (diff)
downloadrust-ed66fe48e94df2cd0dee5af4afa44d7fb50cb0cf.tar.gz
rust-ed66fe48e94df2cd0dee5af4afa44d7fb50cb0cf.zip
Implement RFC 1440 "Allow Drop types in statics/const functions".
Diffstat (limited to 'src/librustc_mir/transform')
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 7728d43774f..90823528973 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -222,13 +222,40 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx> {
     }
 
     /// Check for NEEDS_DROP (from an ADT or const fn call) and
-    /// error, unless we're in a function.
+    /// error, unless we're in a function, or the feature-gate
+    /// for globals with destructors is enabled.
     fn deny_drop(&self) {
-        if self.mode != Mode::Fn && self.qualif.intersects(Qualif::NEEDS_DROP) {
-            span_err!(self.tcx.sess, self.span, E0493,
-                      "{}s are not allowed to have destructors",
-                      self.mode);
+        if self.mode == Mode::Fn || !self.qualif.intersects(Qualif::NEEDS_DROP) {
+            return;
+        }
+
+        // Static and const fn's allow destructors, but they're feature-gated.
+        let msg = if self.mode != Mode::Const {
+            // Feature-gate for globals with destructors is enabled.
+            if self.tcx.sess.features.borrow().drop_types_in_const {
+                return;
+            }
+
+            // This comes from a macro that has #[allow_internal_unstable].
+            if self.tcx.sess.codemap().span_allows_unstable(self.span) {
+                return;
+            }
+
+            format!("destructors in {}s are an unstable feature",
+                    self.mode)
+        } else {
+            format!("{}s are not allowed to have destructors",
+                    self.mode)
+        };
+
+        let mut err =
+            struct_span_err!(self.tcx.sess, self.span, E0493, "{}", msg);
+        if self.mode != Mode::Const {
+            help!(&mut err,
+                  "in Nightly builds, add `#![feature(drop_types_in_const)]` \
+                   to the crate attributes to enable");
         }
+        err.emit();
     }
 
     /// Check if an Lvalue with the current qualifications could