Skip to content

Commit

Permalink
use body.tainted_by_error to skip loading MIR
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Feb 11, 2022
1 parent a431174 commit 67ad0ff
Showing 6 changed files with 21 additions and 58 deletions.
23 changes: 0 additions & 23 deletions compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@ use crate::interpret::{
ScalarMaybeUninit, StackPopCleanup,
};

use rustc_errors::ErrorReported;
use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::mir::interpret::ErrorHandled;
@@ -281,28 +280,6 @@ pub fn eval_to_allocation_raw_provider<'tcx>(

let cid = key.value;
let def = cid.instance.def.with_opt_param();

if let Some(def) = def.as_local() {
if tcx.has_typeck_results(def.did) {
if let Some(error_reported) = tcx.typeck_opt_const_arg(def).tainted_by_errors {
return Err(ErrorHandled::Reported(error_reported));
}
if let Some(error_reported) = tcx.mir_borrowck_opt_const_arg(def).tainted_by_errors {
return Err(ErrorHandled::Reported(error_reported));
}
}
if !tcx.is_mir_available(def.did) {
tcx.sess.delay_span_bug(
tcx.def_span(def.did),
&format!("no MIR body is available for {:?}", def.did),
);
return Err(ErrorHandled::Reported(ErrorReported {}));
}
if let Some(error_reported) = tcx.mir_const_qualif_opt_const_arg(def).error_occured {
return Err(ErrorHandled::Reported(error_reported));
}
}

let is_static = tcx.is_static(def.did);

let mut ecx = InterpCx::new(
8 changes: 8 additions & 0 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use rustc_errors::ErrorReported;
use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::ty::{self, Ty};
use std::borrow::Borrow;
@@ -243,6 +245,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
ty::InstanceDef::Item(def) => {
if ecx.tcx.is_ctfe_mir_available(def.did) {
Ok(ecx.tcx.mir_for_ctfe_opt_const_arg(def))
} else if ecx.tcx.def_kind(def.did) == DefKind::AssocConst {
ecx.tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
"This is likely a const item that is missing from its impl",
);
throw_inval!(AlreadyReported(ErrorReported {}));
} else {
let path = ecx.tcx.def_path_str(def.did);
Err(ConstEvalErrKind::NeedsRfc(format!("calling extern function `{}`", path))
26 changes: 9 additions & 17 deletions compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
@@ -509,26 +509,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
instance: ty::InstanceDef<'tcx>,
promoted: Option<mir::Promoted>,
) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> {
// do not continue if typeck errors occurred (can only occur in local crate)
let def = instance.with_opt_param();
if let Some(def) = def.as_local() {
if self.tcx.has_typeck_results(def.did) {
if let Some(error_reported) = self.tcx.typeck_opt_const_arg(def).tainted_by_errors {
throw_inval!(AlreadyReported(error_reported));
}
if let Some(error_reported) =
self.tcx.mir_borrowck_opt_const_arg(def).tainted_by_errors
{
throw_inval!(AlreadyReported(error_reported));
}
}
}

trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
if let Some(promoted) = promoted {
return Ok(&self.tcx.promoted_mir_opt_const_arg(def)[promoted]);
let body = if let Some(promoted) = promoted {
&self.tcx.promoted_mir_opt_const_arg(def)[promoted]
} else {
M::load_mir(self, instance)?
};
// do not continue if typeck errors occurred (can only occur in local crate)
if let Some(err) = body.tainted_by_errors {
throw_inval!(AlreadyReported(err));
}
M::load_mir(self, instance)
Ok(body)
}

/// Call this on things you got out of the MIR (so it is as generic as the current
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -836,14 +836,13 @@ rustc_queries! {
/// additional requirements that the closure's creator must verify.
query mir_borrowck(key: LocalDefId) -> &'tcx mir::BorrowCheckResult<'tcx> {
desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) }
cache_on_disk_if { true }
cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) }
}
query mir_borrowck_const_arg(key: (LocalDefId, DefId)) -> &'tcx mir::BorrowCheckResult<'tcx> {
desc {
|tcx| "borrow-checking the const argument`{}`",
tcx.def_path_str(key.0.to_def_id())
}
cache_on_disk_if { true }
}

/// Gets a complete map from all types to their inherent impls.
1 change: 0 additions & 1 deletion src/test/ui/consts/const-fn-error.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,6 @@ const fn f(x: usize) -> usize {
//~^ ERROR mutable references
//~| ERROR calls in constant functions
//~| ERROR calls in constant functions
//~| ERROR E0080
//~| ERROR `for` is not allowed in a `const fn`
sum += i;
}
18 changes: 3 additions & 15 deletions src/test/ui/consts/const-fn-error.stderr
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ LL | / for i in 0..x {
LL | |
LL | |
LL | |
... |
LL | |
LL | | sum += i;
LL | | }
| |_____^
@@ -34,19 +34,7 @@ error[E0015]: calls in constant functions are limited to constant functions, tup
LL | for i in 0..x {
| ^^^^

error[E0080]: evaluation of constant value failed
--> $DIR/const-fn-error.rs:5:14
|
LL | for i in 0..x {
| ^^^^
| |
| calling non-const function `<std::ops::Range<usize> as IntoIterator>::into_iter`
| inside `f` at $DIR/const-fn-error.rs:5:14
...
LL | let a : [i32; f(X)];
| ---- inside `main::{constant#0}` at $DIR/const-fn-error.rs:18:19

error: aborting due to 5 previous errors
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0015, E0080, E0658.
Some errors have detailed explanations: E0015, E0658.
For more information about an error, try `rustc --explain E0015`.

0 comments on commit 67ad0ff

Please sign in to comment.