diff options
| author | bors <bors@rust-lang.org> | 2018-09-30 12:00:45 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-09-30 12:00:45 +0000 |
| commit | 1886d5fe1cdd1a016ecea9fc93d68b3052c528c8 (patch) | |
| tree | 4a35a5e72fac81649886bf524b7ed3948671c463 | |
| parent | a677e4c347630b855f2889557c2d37180a1a41be (diff) | |
| parent | 43cc32fbb2506eff0090e894c1e8a46b62a8eb0b (diff) | |
| download | rust-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.rs | 10 | ||||
| -rw-r--r-- | src/librustc/ty/context.rs | 1 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/intrinsics.rs | 7 | ||||
| -rw-r--r-- | src/librustc_mir/transform/qualify_consts.rs | 1 | ||||
| -rw-r--r-- | src/librustc_typeck/check/intrinsic.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 2 | ||||
| -rw-r--r-- | src/test/run-pass/const-needs_drop.rs | 39 | ||||
| -rw-r--r-- | src/test/run-pass/union/union-nodrop.rs | 20 |
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>>>()); } |
