Skip to content

Commit 7fbecb6

Browse files
authored
Rollup merge of rust-lang#57734 - oli-obk:fixes_and_cleanups, r=pnkfelix
Fix evaluating trivial drop glue in constants ```rust struct A; impl Drop for A { fn drop(&mut self) {} } const FOO: Option<A> = None; const BAR: () = (FOO, ()).1; ``` was erroring with ``` error: any use of this value will cause an error --> src/lib.rs:9:1 | 9 | const BAR: () = (FOO, ()).1; | ^^^^^^^^^^^^^^^^^^^^^^^^^^-^ | | | calling non-const function `std::ptr::real_drop_in_place::<(std::option::Option<A>, ())> - shim(Some((std::option::Option<A>, ())))` | = note: #[deny(const_err)] on by default error: aborting due to previous error ``` before this PR. According to godbolt this last compiled successfully in 1.27
2 parents 25f6171 + 39aa89b commit 7fbecb6

File tree

6 files changed

+55
-29
lines changed

6 files changed

+55
-29
lines changed

src/librustc/ty/mod.rs

-10
Original file line numberDiff line numberDiff line change
@@ -2937,16 +2937,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
29372937
}
29382938
}
29392939

2940-
/// Given the DefId of an item, returns its MIR, borrowed immutably.
2941-
/// Returns None if there is no MIR for the DefId
2942-
pub fn maybe_optimized_mir(self, did: DefId) -> Option<&'gcx Mir<'gcx>> {
2943-
if self.is_mir_available(did) {
2944-
Some(self.optimized_mir(did))
2945-
} else {
2946-
None
2947-
}
2948-
}
2949-
29502940
/// Get the attributes of a definition.
29512941
pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
29522942
if let Some(id) = self.hir().as_local_node_id(did) {

src/librustc_mir/const_eval.rs

+16-13
Original file line numberDiff line numberDiff line change
@@ -340,19 +340,22 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
340340
ret: Option<mir::BasicBlock>,
341341
) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> {
342342
debug!("eval_fn_call: {:?}", instance);
343-
// Execution might have wandered off into other crates, so we cannot to a stability-
344-
// sensitive check here. But we can at least rule out functions that are not const
345-
// at all.
346-
if !ecx.tcx.is_const_fn_raw(instance.def_id()) {
347-
// Some functions we support even if they are non-const -- but avoid testing
348-
// that for const fn! We certainly do *not* want to actually call the fn
349-
// though, so be sure we return here.
350-
return if ecx.hook_fn(instance, args, dest)? {
351-
ecx.goto_block(ret)?; // fully evaluated and done
352-
Ok(None)
353-
} else {
354-
err!(MachineError(format!("calling non-const function `{}`", instance)))
355-
};
343+
// Only check non-glue functions
344+
if let ty::InstanceDef::Item(def_id) = instance.def {
345+
// Execution might have wandered off into other crates, so we cannot to a stability-
346+
// sensitive check here. But we can at least rule out functions that are not const
347+
// at all.
348+
if !ecx.tcx.is_const_fn_raw(def_id) {
349+
// Some functions we support even if they are non-const -- but avoid testing
350+
// that for const fn! We certainly do *not* want to actually call the fn
351+
// though, so be sure we return here.
352+
return if ecx.hook_fn(instance, args, dest)? {
353+
ecx.goto_block(ret)?; // fully evaluated and done
354+
Ok(None)
355+
} else {
356+
err!(MachineError(format!("calling non-const function `{}`", instance)))
357+
};
358+
}
356359
}
357360
// This is a const fn. Call it.
358361
Ok(Some(match ecx.load_mir(instance.def) {

src/librustc_mir/interpret/eval_context.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
273273
}
274274
trace!("load mir {:?}", instance);
275275
match instance {
276-
ty::InstanceDef::Item(def_id) => {
277-
self.tcx.maybe_optimized_mir(def_id).ok_or_else(||
278-
EvalErrorKind::NoMirFor(self.tcx.item_path_str(def_id)).into()
279-
)
280-
}
276+
ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
277+
Ok(self.tcx.optimized_mir(did))
278+
} else {
279+
err!(NoMirFor(self.tcx.item_path_str(def_id)))
280+
},
281281
_ => Ok(self.tcx.instance_mir(instance)),
282282
}
283283
}

src/test/ui/consts/drop_none.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// compile-pass
2+
#![allow(dead_code)]
3+
struct A;
4+
impl Drop for A {
5+
fn drop(&mut self) {}
6+
}
7+
8+
const FOO: Option<A> = None;
9+
10+
const BAR: () = (FOO, ()).1;
11+
12+
13+
fn main() {}

src/test/ui/static/static-drop-scope.rs

+8
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,12 @@ const fn const_drop2<T>(x: T) {
2828
//~^ ERROR destructors cannot be evaluated at compile-time
2929
}
3030

31+
const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
32+
//~^ ERROR destructors cannot be evaluated at compile-time
33+
34+
const HELPER: Option<WithDtor> = Some(WithDtor);
35+
36+
const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
37+
//~^ ERROR destructors cannot be evaluated at compile-time
38+
3139
fn main () {}

src/test/ui/static/static-drop-scope.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,19 @@ error[E0493]: destructors cannot be evaluated at compile-time
5454
LL | (x, ()).1
5555
| ^^^^^^^ constant functions cannot evaluate destructors
5656

57-
error: aborting due to 8 previous errors
57+
error[E0493]: destructors cannot be evaluated at compile-time
58+
--> $DIR/static-drop-scope.rs:31:34
59+
|
60+
LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
61+
| ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors
62+
63+
error[E0493]: destructors cannot be evaluated at compile-time
64+
--> $DIR/static-drop-scope.rs:36:43
65+
|
66+
LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
67+
| ^^^^^^^^^^^ constants cannot evaluate destructors
68+
69+
error: aborting due to 10 previous errors
5870

5971
Some errors occurred: E0493, E0597.
6072
For more information about an error, try `rustc --explain E0493`.

0 commit comments

Comments
 (0)