Rollup merge of #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
This commit is contained in:
commit
141fa859b8
7 changed files with 68 additions and 30 deletions
|
|
@ -2937,16 +2937,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Given the DefId of an item, returns its MIR, borrowed immutably.
|
||||
/// Returns None if there is no MIR for the DefId
|
||||
pub fn maybe_optimized_mir(self, did: DefId) -> Option<&'gcx Mir<'gcx>> {
|
||||
if self.is_mir_available(did) {
|
||||
Some(self.optimized_mir(did))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the attributes of a definition.
|
||||
pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
|
||||
if let Some(id) = self.hir().as_local_node_id(did) {
|
||||
|
|
|
|||
|
|
@ -340,19 +340,22 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
|
|||
ret: Option<mir::BasicBlock>,
|
||||
) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> {
|
||||
debug!("eval_fn_call: {:?}", instance);
|
||||
// Execution might have wandered off into other crates, so we cannot to a stability-
|
||||
// sensitive check here. But we can at least rule out functions that are not const
|
||||
// at all.
|
||||
if !ecx.tcx.is_const_fn_raw(instance.def_id()) {
|
||||
// Some functions we support even if they are non-const -- but avoid testing
|
||||
// that for const fn! We certainly do *not* want to actually call the fn
|
||||
// though, so be sure we return here.
|
||||
return if ecx.hook_fn(instance, args, dest)? {
|
||||
ecx.goto_block(ret)?; // fully evaluated and done
|
||||
Ok(None)
|
||||
} else {
|
||||
err!(MachineError(format!("calling non-const function `{}`", instance)))
|
||||
};
|
||||
// Only check non-glue functions
|
||||
if let ty::InstanceDef::Item(def_id) = instance.def {
|
||||
// Execution might have wandered off into other crates, so we cannot to a stability-
|
||||
// sensitive check here. But we can at least rule out functions that are not const
|
||||
// at all.
|
||||
if !ecx.tcx.is_const_fn_raw(def_id) {
|
||||
// Some functions we support even if they are non-const -- but avoid testing
|
||||
// that for const fn! We certainly do *not* want to actually call the fn
|
||||
// though, so be sure we return here.
|
||||
return if ecx.hook_fn(instance, args, dest)? {
|
||||
ecx.goto_block(ret)?; // fully evaluated and done
|
||||
Ok(None)
|
||||
} else {
|
||||
err!(MachineError(format!("calling non-const function `{}`", instance)))
|
||||
};
|
||||
}
|
||||
}
|
||||
// This is a const fn. Call it.
|
||||
Ok(Some(match ecx.load_mir(instance.def) {
|
||||
|
|
|
|||
|
|
@ -273,11 +273,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
|||
}
|
||||
trace!("load mir {:?}", instance);
|
||||
match instance {
|
||||
ty::InstanceDef::Item(def_id) => {
|
||||
self.tcx.maybe_optimized_mir(def_id).ok_or_else(||
|
||||
EvalErrorKind::NoMirFor(self.tcx.item_path_str(def_id)).into()
|
||||
)
|
||||
}
|
||||
ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
|
||||
Ok(self.tcx.optimized_mir(did))
|
||||
} else {
|
||||
err!(NoMirFor(self.tcx.item_path_str(def_id)))
|
||||
},
|
||||
_ => Ok(self.tcx.instance_mir(instance)),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
src/test/ui/consts/drop_none.rs
Normal file
13
src/test/ui/consts/drop_none.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// compile-pass
|
||||
#![allow(dead_code)]
|
||||
struct A;
|
||||
impl Drop for A {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
const FOO: Option<A> = None;
|
||||
|
||||
const BAR: () = (FOO, ()).1;
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -54,7 +54,19 @@ error[E0493]: destructors cannot be evaluated at compile-time
|
|||
LL | (x, ()).1
|
||||
| ^^^^^^^ constant functions cannot evaluate destructors
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/static-drop-scope.rs:31:34
|
||||
|
|
||||
LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
|
||||
| ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/static-drop-scope.rs:36:43
|
||||
|
|
||||
LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
|
||||
| ^^^^^^^^^^^ constants cannot evaluate destructors
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors occurred: E0493, E0716.
|
||||
For more information about an error, try `rustc --explain E0493`.
|
||||
|
|
|
|||
|
|
@ -28,4 +28,12 @@ const fn const_drop2<T>(x: T) {
|
|||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
}
|
||||
|
||||
const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
|
||||
const HELPER: Option<WithDtor> = Some(WithDtor);
|
||||
|
||||
const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
|
||||
//~^ ERROR destructors cannot be evaluated at compile-time
|
||||
|
||||
fn main () {}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,19 @@ error[E0493]: destructors cannot be evaluated at compile-time
|
|||
LL | (x, ()).1
|
||||
| ^^^^^^^ constant functions cannot evaluate destructors
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/static-drop-scope.rs:31:34
|
||||
|
|
||||
LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
|
||||
| ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors
|
||||
|
||||
error[E0493]: destructors cannot be evaluated at compile-time
|
||||
--> $DIR/static-drop-scope.rs:36:43
|
||||
|
|
||||
LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
|
||||
| ^^^^^^^^^^^ constants cannot evaluate destructors
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
Some errors occurred: E0493, E0597.
|
||||
For more information about an error, try `rustc --explain E0493`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue