about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-30 12:00:45 +0000
committerbors <bors@rust-lang.org>2018-09-30 12:00:45 +0000
commit1886d5fe1cdd1a016ecea9fc93d68b3052c528c8 (patch)
tree4a35a5e72fac81649886bf524b7ed3948671c463
parenta677e4c347630b855f2889557c2d37180a1a41be (diff)
parent43cc32fbb2506eff0090e894c1e8a46b62a8eb0b (diff)
downloadrust-1886d5fe1cdd1a016ecea9fc93d68b3052c528c8.tar.gz
rust-1886d5fe1cdd1a016ecea9fc93d68b3052c528c8.zip
Auto merge of #54596 - mjbshaw:drop, r=RalfJung
Make core::mem::needs_drop a const fn

This fixes #51929.
-rw-r--r--src/libcore/mem.rs10
-rw-r--r--src/librustc/ty/context.rs1
-rw-r--r--src/librustc_mir/interpret/intrinsics.rs7
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs1
-rw-r--r--src/librustc_typeck/check/intrinsic.rs2
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/test/run-pass/const-needs_drop.rs39
-rw-r--r--src/test/run-pass/union/union-nodrop.rs20
8 files changed, 69 insertions, 13 deletions
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 9871f496678..f537add999a 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -455,6 +455,16 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
 /// ```
 #[inline]
 #[stable(feature = "needs_drop", since = "1.21.0")]
+#[rustc_const_unstable(feature = "const_needs_drop")]
+#[cfg(not(stage0))]
+pub const fn needs_drop<T>() -> bool {
+    intrinsics::needs_drop::<T>()
+}
+
+#[inline]
+#[stable(feature = "needs_drop", since = "1.21.0")]
+#[cfg(stage0)]
+/// Ceci n'est pas la documentation
 pub fn needs_drop<T>() -> bool {
     unsafe { intrinsics::needs_drop::<T>() }
 }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index c288285f2bb..63408d809ec 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1144,6 +1144,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 match &self.item_name(def_id).as_str()[..] {
                     | "size_of"
                     | "min_align_of"
+                    | "needs_drop"
                     => return true,
                     _ => {},
                 }
diff --git a/src/librustc_mir/interpret/intrinsics.rs b/src/librustc_mir/interpret/intrinsics.rs
index d2f274231c1..5fee49ba2fc 100644
--- a/src/librustc_mir/interpret/intrinsics.rs
+++ b/src/librustc_mir/interpret/intrinsics.rs
@@ -65,6 +65,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                 self.write_scalar(align_val, dest)?;
             }
 
+            "needs_drop" => {
+                let ty = substs.type_at(0);
+                let ty_needs_drop = ty.needs_drop(self.tcx.tcx, self.param_env);
+                let val = Scalar::from_bool(ty_needs_drop);
+                self.write_scalar(val, dest)?;
+            }
+
             "size_of" => {
                 let ty = substs.type_at(0);
                 let size = self.layout_of(ty)?.size.bytes() as u128;
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index cf45b541f80..a6e2cad5094 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -823,6 +823,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                         match &self.tcx.item_name(def_id).as_str()[..] {
                             | "size_of"
                             | "min_align_of"
+                            | "needs_drop"
                             | "type_id"
                             | "bswap"
                             | "bitreverse"
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index 24db9505cb8..d630c5b3040 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -117,7 +117,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         (0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe)
     } else {
         let unsafety = match &name[..] {
-            "size_of" | "min_align_of" => hir::Unsafety::Normal,
+            "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
             _ => hir::Unsafety::Unsafe,
         };
         let (n_tps, inputs, output) = match &name[..] {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index bffdf777240..17e0b0431da 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -2015,7 +2015,7 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
         match &*tcx.item_name(def_id).as_str() {
-            "size_of" | "min_align_of" => hir::Unsafety::Normal,
+            "size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
             _ => hir::Unsafety::Unsafe,
         }
     } else {
diff --git a/src/test/run-pass/const-needs_drop.rs b/src/test/run-pass/const-needs_drop.rs
new file mode 100644
index 00000000000..edf3a6b3dcd
--- /dev/null
+++ b/src/test/run-pass/const-needs_drop.rs
@@ -0,0 +1,39 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(const_needs_drop)]
+
+use std::mem;
+
+struct Trivial(u8, f32);
+
+struct NonTrivial(u8, String);
+
+const CONST_U8: bool = mem::needs_drop::<u8>();
+const CONST_STRING: bool = mem::needs_drop::<String>();
+const CONST_TRIVIAL: bool = mem::needs_drop::<Trivial>();
+const CONST_NON_TRIVIAL: bool = mem::needs_drop::<NonTrivial>();
+
+static STATIC_U8: bool = mem::needs_drop::<u8>();
+static STATIC_STRING: bool = mem::needs_drop::<String>();
+static STATIC_TRIVIAL: bool = mem::needs_drop::<Trivial>();
+static STATIC_NON_TRIVIAL: bool = mem::needs_drop::<NonTrivial>();
+
+fn main() {
+    assert!(!CONST_U8);
+    assert!(CONST_STRING);
+    assert!(!CONST_TRIVIAL);
+    assert!(CONST_NON_TRIVIAL);
+
+    assert!(!STATIC_U8);
+    assert!(STATIC_STRING);
+    assert!(!STATIC_TRIVIAL);
+    assert!(STATIC_NON_TRIVIAL);
+}
diff --git a/src/test/run-pass/union/union-nodrop.rs b/src/test/run-pass/union/union-nodrop.rs
index 4f2456e43ba..d024aca0cd7 100644
--- a/src/test/run-pass/union/union-nodrop.rs
+++ b/src/test/run-pass/union/union-nodrop.rs
@@ -57,15 +57,13 @@ impl<T> Drop for ActuallyDrop<T> {
 }
 
 fn main() {
-    unsafe {
-        // NoDrop should not make needs_drop true
-        assert!(!needs_drop::<Foo>());
-        assert!(!needs_drop::<NoDrop<u8>>());
-        assert!(!needs_drop::<NoDrop<Box<u8>>>());
-        // presence of other drop types should still work
-        assert!(needs_drop::<Baz>());
-        // drop impl on union itself should work
-        assert!(needs_drop::<ActuallyDrop<u8>>());
-        assert!(needs_drop::<ActuallyDrop<Box<u8>>>());
-    }
+    // NoDrop should not make needs_drop true
+    assert!(!needs_drop::<Foo>());
+    assert!(!needs_drop::<NoDrop<u8>>());
+    assert!(!needs_drop::<NoDrop<Box<u8>>>());
+    // presence of other drop types should still work
+    assert!(needs_drop::<Baz>());
+    // drop impl on union itself should work
+    assert!(needs_drop::<ActuallyDrop<u8>>());
+    assert!(needs_drop::<ActuallyDrop<Box<u8>>>());
 }