Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix evaluating trivial drop glue in constants #57734

Merged
merged 3 commits into from
Jan 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2946,16 +2946,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) {
Expand Down
29 changes: 16 additions & 13 deletions src/librustc_mir/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,19 +391,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) {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,11 +265,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)),
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/consts/drop_none.rs
Original file line number Diff line number Diff line change
@@ -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() {}
14 changes: 13 additions & 1 deletion src/test/ui/static/static-drop-scope.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
8 changes: 8 additions & 0 deletions src/test/ui/static/static-drop-scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 () {}
14 changes: 13 additions & 1 deletion src/test/ui/static/static-drop-scope.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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`.