about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/diagnostics.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs37
-rw-r--r--src/libsyntax/feature_gate.rs5
-rw-r--r--src/test/compile-fail/check-static-values-constraints.rs26
-rw-r--r--src/test/compile-fail/issue-9243.rs5
-rw-r--r--src/test/compile-fail/static-mut-not-constant.rs2
6 files changed, 54 insertions, 23 deletions
diff --git a/src/librustc_mir/diagnostics.rs b/src/librustc_mir/diagnostics.rs
index 30d3a39e473..65d51d20528 100644
--- a/src/librustc_mir/diagnostics.rs
+++ b/src/librustc_mir/diagnostics.rs
@@ -345,7 +345,7 @@ impl Drop for Foo {
 const F : Foo = Foo { a : 0 };
 // error: constants are not allowed to have destructors
 static S : Foo = Foo { a : 0 };
-// error: statics are not allowed to have destructors
+// error: destructors in statics are an unstable feature
 ```
 
 To solve this issue, please use a type which does allow the usage of type with
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
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index e269475d1e2..7f01821b004 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -266,7 +266,10 @@ declare_features! (
     (active, specialization, "1.7.0", Some(31844)),
 
     // pub(restricted) visibilities (RFC 1422)
-    (active, pub_restricted, "1.9.0", Some(32409))
+    (active, pub_restricted, "1.9.0", Some(32409)),
+
+     // Allow Drop types in statics/const functions (RFC 1440)
+    (active, drop_types_in_const, "1.9.0", Some(33156))
 );
 
 declare_features! (
diff --git a/src/test/compile-fail/check-static-values-constraints.rs b/src/test/compile-fail/check-static-values-constraints.rs
index ded0d07d737..df22e2ea4de 100644
--- a/src/test/compile-fail/check-static-values-constraints.rs
+++ b/src/test/compile-fail/check-static-values-constraints.rs
@@ -37,7 +37,7 @@ static STATIC2: SafeEnum = SafeEnum::Variant2(0);
 
 // This one should fail
 static STATIC3: SafeEnum = SafeEnum::Variant3(WithDtor);
-//~^ ERROR statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
 
 
 // This enum will be used to test that variants
@@ -54,9 +54,9 @@ impl Drop for UnsafeEnum {
 
 
 static STATIC4: UnsafeEnum = UnsafeEnum::Variant5;
-//~^ ERROR statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
 static STATIC5: UnsafeEnum = UnsafeEnum::Variant6(0);
-//~^ ERROR statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
 
 
 struct SafeStruct {
@@ -71,7 +71,7 @@ static STATIC6: SafeStruct = SafeStruct{field1: SafeEnum::Variant1, field2: Safe
 // field2 has an unsafe value, hence this should fail
 static STATIC7: SafeStruct = SafeStruct{field1: SafeEnum::Variant1,
                                         field2: SafeEnum::Variant3(WithDtor)};
-//~^ ERROR statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
 
 // Test variadic constructor for structs. The base struct should be examined
 // as well as every field present in the constructor.
@@ -84,7 +84,7 @@ static STATIC8: SafeStruct = SafeStruct{field1: SafeEnum::Variant1,
 static STATIC9: SafeStruct = SafeStruct{field1: SafeEnum::Variant1,
                                         ..SafeStruct{field1: SafeEnum::Variant3(WithDtor),
                                                      field2: SafeEnum::Variant1}};
-//~^^ ERROR statics are not allowed to have destructors
+//~^^ ERROR destructors in statics are an unstable feature
 
 struct UnsafeStruct;
 
@@ -94,7 +94,7 @@ impl Drop for UnsafeStruct {
 
 // Types with destructors are not allowed for statics
 static STATIC10: UnsafeStruct = UnsafeStruct;
-//~^ ERROR statics are not allowed to have destructor
+//~^ ERROR destructors in statics are an unstable feature
 
 struct MyOwned;
 
@@ -105,19 +105,19 @@ static STATIC11: Box<MyOwned> = box MyOwned;
 // to have types with destructors
 // These should fail
 static mut STATIC12: UnsafeStruct = UnsafeStruct;
-//~^ ERROR mutable statics are not allowed to have destructors
-//~^^ ERROR statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
+//~^^ ERROR destructors in statics are an unstable feature
 
 static mut STATIC13: SafeStruct = SafeStruct{field1: SafeEnum::Variant1,
-//~^ ERROR mutable statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
                                              field2: SafeEnum::Variant3(WithDtor)};
-//~^ ERROR: statics are not allowed to have destructors
+//~^ ERROR: destructors in statics are an unstable feature
 
 static mut STATIC14: SafeStruct = SafeStruct {
-//~^ ERROR mutable statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
     field1: SafeEnum::Variant1,
     field2: SafeEnum::Variant4("str".to_string())
-//~^ ERROR method calls in statics are limited to constant inherent methods
+//~^ ERROR calls in statics are limited to constant functions
 };
 
 static STATIC15: &'static [Box<MyOwned>] = &[
@@ -131,7 +131,7 @@ static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) = (
 );
 
 static mut STATIC17: SafeEnum = SafeEnum::Variant1;
-//~^ ERROR mutable statics are not allowed to have destructors
+//~^ ERROR destructors in statics are an unstable feature
 
 static STATIC19: Box<isize> =
     box 3;
diff --git a/src/test/compile-fail/issue-9243.rs b/src/test/compile-fail/issue-9243.rs
index 7424a45d044..58bdff6c041 100644
--- a/src/test/compile-fail/issue-9243.rs
+++ b/src/test/compile-fail/issue-9243.rs
@@ -10,11 +10,12 @@
 
 // Regression test for issue 9243
 
-struct Test {
+pub struct Test {
     mem: isize,
 }
 
-pub static g_test: Test = Test {mem: 0}; //~ ERROR statics are not allowed to have destructors
+pub static g_test: Test = Test {mem: 0};
+//~^ ERROR destructors in statics are an unstable feature
 
 impl Drop for Test {
     fn drop(&mut self) {}
diff --git a/src/test/compile-fail/static-mut-not-constant.rs b/src/test/compile-fail/static-mut-not-constant.rs
index e3bb01e6970..9b83c42609a 100644
--- a/src/test/compile-fail/static-mut-not-constant.rs
+++ b/src/test/compile-fail/static-mut-not-constant.rs
@@ -12,6 +12,6 @@
 
 static mut a: Box<isize> = box 3;
 //~^ ERROR allocations are not allowed in statics
-//~^^ ERROR mutable statics are not allowed to have boxes
+//~^^ ERROR destructors in statics are an unstable feature
 
 fn main() {}