about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-09-09 11:48:57 +0000
committerbors <bors@rust-lang.org>2017-09-09 11:48:57 +0000
commit18366f4e8aaec1d46282cf0a6e0fe1a0ab202530 (patch)
tree5ad930aa865a44f897f8e23de3d696a2adfdebee
parent929b878262622292b76b8a27f09d3ccc646f9a46 (diff)
parent1d5c0ba75f5ca999396466b455dc07e45546e9a8 (diff)
downloadrust-18366f4e8aaec1d46282cf0a6e0fe1a0ab202530.tar.gz
rust-18366f4e8aaec1d46282cf0a6e0fe1a0ab202530.zip
Auto merge of #44212 - eddyb:drop-const, r=nikomatsakis
Allow Drop types in const's too, with #![feature(drop_types_in_const)].

Implements the remaining amendment, see #33156. cc @SergioBenitez

r? @nikomatsakis
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs12
-rw-r--r--src/test/compile-fail/issue-17718-const-destructors.rs2
-rw-r--r--src/test/compile-fail/static-drop-scope.rs11
-rw-r--r--src/test/run-pass/issue-34053.rs22
-rw-r--r--src/test/ui/span/E0493.rs4
-rw-r--r--src/test/ui/span/E0493.stderr8
6 files changed, 44 insertions, 15 deletions
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index ded97275468..f891c991321 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -204,7 +204,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
 
     /// Check for NEEDS_DROP (from an ADT or const fn call) and
     /// error, unless we're in a function, or the feature-gate
-    /// for globals with destructors is enabled.
+    /// for constant with destructors is enabled.
     fn deny_drop(&self) {
         self.deny_drop_with_feature_gate_override(true);
     }
@@ -214,9 +214,9 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
             return;
         }
 
-        // Static and const fn's allow destructors, but they're feature-gated.
-        let msg = if allow_gate && self.mode != Mode::Const {
-            // Feature-gate for globals with destructors is enabled.
+        // Constants allow destructors, but they're feature-gated.
+        let msg = if allow_gate {
+            // Feature-gate for constant with destructors is enabled.
             if self.tcx.sess.features.borrow().drop_types_in_const {
                 return;
             }
@@ -236,11 +236,13 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
         let mut err =
             struct_span_err!(self.tcx.sess, self.span, E0493, "{}", msg);
 
-        if allow_gate && self.mode != Mode::Const {
+        if allow_gate {
             help!(&mut err,
                   "in Nightly builds, add `#![feature(drop_types_in_const)]` \
                    to the crate attributes to enable");
         } else {
+            // FIXME(eddyb) this looks up `self.mir.return_ty`.
+            // We probably want the actual return type here, if at all.
             self.find_drop_implementation_method_span()
                 .map(|span| err.span_label(span, "destructor defined here"));
 
diff --git a/src/test/compile-fail/issue-17718-const-destructors.rs b/src/test/compile-fail/issue-17718-const-destructors.rs
index e888f917741..6c2eafe040a 100644
--- a/src/test/compile-fail/issue-17718-const-destructors.rs
+++ b/src/test/compile-fail/issue-17718-const-destructors.rs
@@ -14,6 +14,6 @@ impl Drop for A {
 }
 
 const FOO: A = A;
-//~^ ERROR: constants are not allowed to have destructors
+//~^ ERROR: destructors in constants are an unstable feature
 
 fn main() {}
diff --git a/src/test/compile-fail/static-drop-scope.rs b/src/test/compile-fail/static-drop-scope.rs
index e5f10b65cee..f8fdf8c45cb 100644
--- a/src/test/compile-fail/static-drop-scope.rs
+++ b/src/test/compile-fail/static-drop-scope.rs
@@ -16,11 +16,18 @@ impl Drop for WithDtor {
     fn drop(&mut self) {}
 }
 
-static FOO: Option<&'static WithDtor> = Some(&WithDtor);
+static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
 //~^ ERROR statics are not allowed to have destructors
 //~| ERROR borrowed value does not live long enoug
 
-static BAR: i32 = (WithDtor, 0).1;
+const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
+//~^ ERROR constants are not allowed to have destructors
+//~| ERROR borrowed value does not live long enoug
+
+static EARLY_DROP_S: i32 = (WithDtor, 0).1;
 //~^ ERROR statics are not allowed to have destructors
 
+const EARLY_DROP_C: i32 = (WithDtor, 0).1;
+//~^ ERROR constants are not allowed to have destructors
+
 fn main () {}
diff --git a/src/test/run-pass/issue-34053.rs b/src/test/run-pass/issue-34053.rs
index 7f8a4941494..c085ee7d46a 100644
--- a/src/test/run-pass/issue-34053.rs
+++ b/src/test/run-pass/issue-34053.rs
@@ -10,14 +10,32 @@
 
 #![feature(drop_types_in_const)]
 
+use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
+
+static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
+
 struct A(i32);
 
 impl Drop for A {
-    fn drop(&mut self) {}
+    fn drop(&mut self) {
+        // update global drop count
+        DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
+    }
 }
 
 static FOO: A = A(123);
+const BAR: A = A(456);
+
+impl A {
+    const BAZ: A = A(789);
+}
 
 fn main() {
-    println!("{}", &FOO.0);
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
+    assert_eq!(&FOO.0, &123);
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
+    assert_eq!(BAR.0, 456);
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 1);
+    assert_eq!(A::BAZ.0, 789);
+    assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
 }
diff --git a/src/test/ui/span/E0493.rs b/src/test/ui/span/E0493.rs
index ea4526b70f6..eae871d2d4e 100644
--- a/src/test/ui/span/E0493.rs
+++ b/src/test/ui/span/E0493.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#![feature(drop_types_in_const)]
+
 struct Foo {
     a: u32
 }
@@ -24,7 +26,7 @@ impl Drop for Bar {
     fn drop(&mut self) {}
 }
 
-const F : Foo = Foo { a : 0 };
+const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
 
 fn main() {
 }
diff --git a/src/test/ui/span/E0493.stderr b/src/test/ui/span/E0493.stderr
index afcc9a240eb..8da11fefc17 100644
--- a/src/test/ui/span/E0493.stderr
+++ b/src/test/ui/span/E0493.stderr
@@ -1,11 +1,11 @@
 error[E0493]: constants are not allowed to have destructors
-  --> $DIR/E0493.rs:27:17
+  --> $DIR/E0493.rs:29:17
    |
-16 |     fn drop(&mut self) {}
+18 |     fn drop(&mut self) {}
    |     --------------------- destructor defined here
 ...
-27 | const F : Foo = Foo { a : 0 };
-   |                 ^^^^^^^^^^^^^ constants cannot have destructors
+29 | const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constants cannot have destructors
 
 error: aborting due to previous error