Skip to content

Commit 2e2b1fe

Browse files
committed
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
2 parents dead08c + 1d5c0ba commit 2e2b1fe

File tree

6 files changed

+44
-15
lines changed

6 files changed

+44
-15
lines changed

src/librustc_mir/transform/qualify_consts.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
204204

205205
/// Check for NEEDS_DROP (from an ADT or const fn call) and
206206
/// error, unless we're in a function, or the feature-gate
207-
/// for globals with destructors is enabled.
207+
/// for constant with destructors is enabled.
208208
fn deny_drop(&self) {
209209
self.deny_drop_with_feature_gate_override(true);
210210
}
@@ -214,9 +214,9 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
214214
return;
215215
}
216216

217-
// Static and const fn's allow destructors, but they're feature-gated.
218-
let msg = if allow_gate && self.mode != Mode::Const {
219-
// Feature-gate for globals with destructors is enabled.
217+
// Constants allow destructors, but they're feature-gated.
218+
let msg = if allow_gate {
219+
// Feature-gate for constant with destructors is enabled.
220220
if self.tcx.sess.features.borrow().drop_types_in_const {
221221
return;
222222
}
@@ -236,11 +236,13 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
236236
let mut err =
237237
struct_span_err!(self.tcx.sess, self.span, E0493, "{}", msg);
238238

239-
if allow_gate && self.mode != Mode::Const {
239+
if allow_gate {
240240
help!(&mut err,
241241
"in Nightly builds, add `#![feature(drop_types_in_const)]` \
242242
to the crate attributes to enable");
243243
} else {
244+
// FIXME(eddyb) this looks up `self.mir.return_ty`.
245+
// We probably want the actual return type here, if at all.
244246
self.find_drop_implementation_method_span()
245247
.map(|span| err.span_label(span, "destructor defined here"));
246248

src/test/compile-fail/issue-17718-const-destructors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ impl Drop for A {
1414
}
1515

1616
const FOO: A = A;
17-
//~^ ERROR: constants are not allowed to have destructors
17+
//~^ ERROR: destructors in constants are an unstable feature
1818

1919
fn main() {}

src/test/compile-fail/static-drop-scope.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@ impl Drop for WithDtor {
1616
fn drop(&mut self) {}
1717
}
1818

19-
static FOO: Option<&'static WithDtor> = Some(&WithDtor);
19+
static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
2020
//~^ ERROR statics are not allowed to have destructors
2121
//~| ERROR borrowed value does not live long enoug
2222

23-
static BAR: i32 = (WithDtor, 0).1;
23+
const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
24+
//~^ ERROR constants are not allowed to have destructors
25+
//~| ERROR borrowed value does not live long enoug
26+
27+
static EARLY_DROP_S: i32 = (WithDtor, 0).1;
2428
//~^ ERROR statics are not allowed to have destructors
2529

30+
const EARLY_DROP_C: i32 = (WithDtor, 0).1;
31+
//~^ ERROR constants are not allowed to have destructors
32+
2633
fn main () {}

src/test/run-pass/issue-34053.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,32 @@
1010

1111
#![feature(drop_types_in_const)]
1212

13+
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
14+
15+
static DROP_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
16+
1317
struct A(i32);
1418

1519
impl Drop for A {
16-
fn drop(&mut self) {}
20+
fn drop(&mut self) {
21+
// update global drop count
22+
DROP_COUNTER.fetch_add(1, Ordering::SeqCst);
23+
}
1724
}
1825

1926
static FOO: A = A(123);
27+
const BAR: A = A(456);
28+
29+
impl A {
30+
const BAZ: A = A(789);
31+
}
2032

2133
fn main() {
22-
println!("{}", &FOO.0);
34+
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
35+
assert_eq!(&FOO.0, &123);
36+
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 0);
37+
assert_eq!(BAR.0, 456);
38+
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 1);
39+
assert_eq!(A::BAZ.0, 789);
40+
assert_eq!(DROP_COUNTER.load(Ordering::SeqCst), 2);
2341
}

src/test/ui/span/E0493.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
#![feature(drop_types_in_const)]
12+
1113
struct Foo {
1214
a: u32
1315
}
@@ -24,7 +26,7 @@ impl Drop for Bar {
2426
fn drop(&mut self) {}
2527
}
2628

27-
const F : Foo = Foo { a : 0 };
29+
const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
2830

2931
fn main() {
3032
}

src/test/ui/span/E0493.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
error[E0493]: constants are not allowed to have destructors
2-
--> $DIR/E0493.rs:27:17
2+
--> $DIR/E0493.rs:29:17
33
|
4-
16 | fn drop(&mut self) {}
4+
18 | fn drop(&mut self) {}
55
| --------------------- destructor defined here
66
...
7-
27 | const F : Foo = Foo { a : 0 };
8-
| ^^^^^^^^^^^^^ constants cannot have destructors
7+
29 | const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constants cannot have destructors
99

1010
error: aborting due to previous error
1111

0 commit comments

Comments
 (0)