Skip to content

Commit 1886d5f

Browse files
committed
Auto merge of #54596 - mjbshaw:drop, r=RalfJung
Make core::mem::needs_drop a const fn This fixes #51929.
2 parents a677e4c + 43cc32f commit 1886d5f

File tree

8 files changed

+69
-13
lines changed

8 files changed

+69
-13
lines changed

Diff for: src/libcore/mem.rs

+10
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,16 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
455455
/// ```
456456
#[inline]
457457
#[stable(feature = "needs_drop", since = "1.21.0")]
458+
#[rustc_const_unstable(feature = "const_needs_drop")]
459+
#[cfg(not(stage0))]
460+
pub const fn needs_drop<T>() -> bool {
461+
intrinsics::needs_drop::<T>()
462+
}
463+
464+
#[inline]
465+
#[stable(feature = "needs_drop", since = "1.21.0")]
466+
#[cfg(stage0)]
467+
/// Ceci n'est pas la documentation
458468
pub fn needs_drop<T>() -> bool {
459469
unsafe { intrinsics::needs_drop::<T>() }
460470
}

Diff for: src/librustc/ty/context.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
11441144
match &self.item_name(def_id).as_str()[..] {
11451145
| "size_of"
11461146
| "min_align_of"
1147+
| "needs_drop"
11471148
=> return true,
11481149
_ => {},
11491150
}

Diff for: src/librustc_mir/interpret/intrinsics.rs

+7
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
6565
self.write_scalar(align_val, dest)?;
6666
}
6767

68+
"needs_drop" => {
69+
let ty = substs.type_at(0);
70+
let ty_needs_drop = ty.needs_drop(self.tcx.tcx, self.param_env);
71+
let val = Scalar::from_bool(ty_needs_drop);
72+
self.write_scalar(val, dest)?;
73+
}
74+
6875
"size_of" => {
6976
let ty = substs.type_at(0);
7077
let size = self.layout_of(ty)?.size.bytes() as u128;

Diff for: src/librustc_mir/transform/qualify_consts.rs

+1
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
823823
match &self.tcx.item_name(def_id).as_str()[..] {
824824
| "size_of"
825825
| "min_align_of"
826+
| "needs_drop"
826827
| "type_id"
827828
| "bswap"
828829
| "bitreverse"

Diff for: src/librustc_typeck/check/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
117117
(0, Vec::new(), tcx.types.never, hir::Unsafety::Unsafe)
118118
} else {
119119
let unsafety = match &name[..] {
120-
"size_of" | "min_align_of" => hir::Unsafety::Normal,
120+
"size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
121121
_ => hir::Unsafety::Unsafe,
122122
};
123123
let (n_tps, inputs, output) = match &name[..] {

Diff for: src/librustc_typeck/collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2015,7 +2015,7 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>(
20152015
) -> ty::PolyFnSig<'tcx> {
20162016
let unsafety = if abi == abi::Abi::RustIntrinsic {
20172017
match &*tcx.item_name(def_id).as_str() {
2018-
"size_of" | "min_align_of" => hir::Unsafety::Normal,
2018+
"size_of" | "min_align_of" | "needs_drop" => hir::Unsafety::Normal,
20192019
_ => hir::Unsafety::Unsafe,
20202020
}
20212021
} else {

Diff for: src/test/run-pass/const-needs_drop.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(const_needs_drop)]
12+
13+
use std::mem;
14+
15+
struct Trivial(u8, f32);
16+
17+
struct NonTrivial(u8, String);
18+
19+
const CONST_U8: bool = mem::needs_drop::<u8>();
20+
const CONST_STRING: bool = mem::needs_drop::<String>();
21+
const CONST_TRIVIAL: bool = mem::needs_drop::<Trivial>();
22+
const CONST_NON_TRIVIAL: bool = mem::needs_drop::<NonTrivial>();
23+
24+
static STATIC_U8: bool = mem::needs_drop::<u8>();
25+
static STATIC_STRING: bool = mem::needs_drop::<String>();
26+
static STATIC_TRIVIAL: bool = mem::needs_drop::<Trivial>();
27+
static STATIC_NON_TRIVIAL: bool = mem::needs_drop::<NonTrivial>();
28+
29+
fn main() {
30+
assert!(!CONST_U8);
31+
assert!(CONST_STRING);
32+
assert!(!CONST_TRIVIAL);
33+
assert!(CONST_NON_TRIVIAL);
34+
35+
assert!(!STATIC_U8);
36+
assert!(STATIC_STRING);
37+
assert!(!STATIC_TRIVIAL);
38+
assert!(STATIC_NON_TRIVIAL);
39+
}

Diff for: src/test/run-pass/union/union-nodrop.rs

+9-11
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,13 @@ impl<T> Drop for ActuallyDrop<T> {
5757
}
5858

5959
fn main() {
60-
unsafe {
61-
// NoDrop should not make needs_drop true
62-
assert!(!needs_drop::<Foo>());
63-
assert!(!needs_drop::<NoDrop<u8>>());
64-
assert!(!needs_drop::<NoDrop<Box<u8>>>());
65-
// presence of other drop types should still work
66-
assert!(needs_drop::<Baz>());
67-
// drop impl on union itself should work
68-
assert!(needs_drop::<ActuallyDrop<u8>>());
69-
assert!(needs_drop::<ActuallyDrop<Box<u8>>>());
70-
}
60+
// NoDrop should not make needs_drop true
61+
assert!(!needs_drop::<Foo>());
62+
assert!(!needs_drop::<NoDrop<u8>>());
63+
assert!(!needs_drop::<NoDrop<Box<u8>>>());
64+
// presence of other drop types should still work
65+
assert!(needs_drop::<Baz>());
66+
// drop impl on union itself should work
67+
assert!(needs_drop::<ActuallyDrop<u8>>());
68+
assert!(needs_drop::<ActuallyDrop<Box<u8>>>());
7169
}

0 commit comments

Comments
 (0)