Skip to content

Commit

Permalink
Auto merge of #54596 - mjbshaw:drop, r=RalfJung
Browse files Browse the repository at this point in the history
Make core::mem::needs_drop a const fn

This fixes #51929.
  • Loading branch information
bors committed Sep 30, 2018
2 parents a677e4c + 43cc32f commit 1886d5f
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 13 deletions.
10 changes: 10 additions & 0 deletions src/libcore/mem.rs
Expand Up @@ -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>() }
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/ty/context.rs
Expand Up @@ -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,
_ => {},
}
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_mir/interpret/intrinsics.rs
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/transform/qualify_consts.rs
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/intrinsic.rs
Expand Up @@ -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[..] {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/collect.rs
Expand Up @@ -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 {
Expand Down
39 changes: 39 additions & 0 deletions 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);
}
20 changes: 9 additions & 11 deletions src/test/run-pass/union/union-nodrop.rs
Expand Up @@ -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>>>());
}

0 comments on commit 1886d5f

Please sign in to comment.