Skip to content

Commit

Permalink
mir/interpret: only use ErrorHandled::Reported for ErrorReported.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Apr 16, 2020
1 parent e22d479 commit d7c4081
Show file tree
Hide file tree
Showing 16 changed files with 87 additions and 74 deletions.
7 changes: 5 additions & 2 deletions src/librustc_codegen_ssa/mir/operand.rs
Expand Up @@ -6,6 +6,7 @@ use crate::glue;
use crate::traits::*;
use crate::MemFlags;

use rustc_errors::ErrorReported;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
use rustc_middle::ty::layout::TyAndLayout;
Expand Down Expand Up @@ -447,8 +448,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| {
match err {
// errored or at least linted
ErrorHandled::Reported => {}
ErrorHandled::TooGeneric => bug!("codgen encountered polymorphic constant"),
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
ErrorHandled::TooGeneric => {
bug!("codegen encountered polymorphic constant")
}
}
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
// the above error (or silence it under some conditions) will not cause UB.
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_infer/infer/error_reporting/mod.rs
Expand Up @@ -304,8 +304,8 @@ pub fn unexpected_hidden_region_diagnostic(
// down this path which gives a decent human readable
// explanation.
//
// (*) if not, the `tainted_by_errors` flag would be set to
// true in any case, so we wouldn't be here at all.
// (*) if not, the `tainted_by_errors` field would be set to
// `Some(ErrorReported)` in any case, so we wouldn't be here at all.
note_and_explain_free_region(
tcx,
&mut err,
Expand Down
57 changes: 25 additions & 32 deletions src/librustc_middle/mir/interpret/error.rs
Expand Up @@ -8,7 +8,7 @@ use crate::ty::{self, layout, Ty};

use backtrace::Backtrace;
use rustc_data_structures::sync::Lock;
use rustc_errors::{struct_span_err, DiagnosticBuilder};
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::definitions::DefPathData;
use rustc_macros::HashStable;
Expand All @@ -19,25 +19,16 @@ use std::{any::Any, fmt, mem};

#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
pub enum ErrorHandled {
/// Already reported a lint or an error for this evaluation.
Reported,
/// Already reported an error for this evaluation, and the compilation is
/// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`.
Reported(ErrorReported),
/// Already emitted a lint for this evaluation.
Linted,
/// Don't emit an error, the evaluation failed because the MIR was generic
/// and the substs didn't fully monomorphize it.
TooGeneric,
}

impl ErrorHandled {
pub fn assert_reported(self) {
match self {
ErrorHandled::Reported => {}
ErrorHandled::TooGeneric => bug!(
"MIR interpretation failed without reporting an error \
even though it was fully monomorphized"
),
}
}
}

CloneTypeFoldableImpls! {
ErrorHandled,
}
Expand Down Expand Up @@ -84,15 +75,12 @@ impl<'tcx> ConstEvalErr<'tcx> {
tcx: TyCtxtAt<'tcx>,
message: &str,
emit: impl FnOnce(DiagnosticBuilder<'_>),
) -> Result<(), ErrorHandled> {
) -> ErrorHandled {
self.struct_generic(tcx, message, emit, None)
}

pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled {
match self.struct_error(tcx, message, |mut e| e.emit()) {
Ok(_) => ErrorHandled::Reported,
Err(x) => x,
}
self.struct_error(tcx, message, |mut e| e.emit())
}

pub fn report_as_lint(
Expand All @@ -102,7 +90,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
lint_root: hir::HirId,
span: Option<Span>,
) -> ErrorHandled {
match self.struct_generic(
self.struct_generic(
tcx,
message,
|mut lint: DiagnosticBuilder<'_>| {
Expand All @@ -122,10 +110,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
lint.emit();
},
Some(lint_root),
) {
Ok(_) => ErrorHandled::Reported,
Err(err) => err,
}
)
}

/// Create a diagnostic for this const eval error.
Expand All @@ -143,12 +128,14 @@ impl<'tcx> ConstEvalErr<'tcx> {
message: &str,
emit: impl FnOnce(DiagnosticBuilder<'_>),
lint_root: Option<hir::HirId>,
) -> Result<(), ErrorHandled> {
) -> ErrorHandled {
let must_error = match self.error {
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
return Err(ErrorHandled::TooGeneric);
return ErrorHandled::TooGeneric;
}
err_inval!(TypeckError(error_reported)) => {
return ErrorHandled::Reported(error_reported);
}
err_inval!(TypeckError) => return Err(ErrorHandled::Reported),
// We must *always* hard error on these, even if the caller wants just a lint.
err_inval!(Layout(LayoutError::SizeOverflow(_))) => true,
_ => false,
Expand Down Expand Up @@ -183,6 +170,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
// caller thinks anyway.
// See <https://github.com/rust-lang/rust/pull/63152>.
finish(struct_error(tcx, &err_msg), None);
ErrorHandled::Reported(ErrorReported)
} else {
// Regular case.
if let Some(lint_root) = lint_root {
Expand All @@ -200,12 +188,13 @@ impl<'tcx> ConstEvalErr<'tcx> {
tcx.span,
|lint| finish(lint.build(message), Some(err_msg)),
);
ErrorHandled::Linted
} else {
// Report as hard error.
finish(struct_error(tcx, message), Some(err_msg));
ErrorHandled::Reported(ErrorReported)
}
}
Ok(())
}
}

Expand Down Expand Up @@ -246,7 +235,9 @@ fn print_backtrace(backtrace: &mut Backtrace) {
impl From<ErrorHandled> for InterpErrorInfo<'_> {
fn from(err: ErrorHandled) -> Self {
match err {
ErrorHandled::Reported => err_inval!(ReferencedConstant),
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {
err_inval!(ReferencedConstant)
}
ErrorHandled::TooGeneric => err_inval!(TooGeneric),
}
.into()
Expand Down Expand Up @@ -288,7 +279,7 @@ pub enum InvalidProgramInfo<'tcx> {
/// which already produced an error.
ReferencedConstant,
/// Abort in case type errors are reached.
TypeckError,
TypeckError(ErrorReported),
/// An error occurred during layout computation.
Layout(layout::LayoutError<'tcx>),
/// An invalid transmute happened.
Expand All @@ -301,7 +292,9 @@ impl fmt::Debug for InvalidProgramInfo<'_> {
match self {
TooGeneric => write!(f, "encountered overly generic constant"),
ReferencedConstant => write!(f, "referenced constant has errors"),
TypeckError => write!(f, "encountered constants with type errors, stopping evaluation"),
TypeckError(ErrorReported) => {
write!(f, "encountered constants with type errors, stopping evaluation")
}
Layout(ref err) => write!(f, "{}", err),
TransmuteSizeDiff(from_ty, to_ty) => write!(
f,
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_middle/ty/context.rs
Expand Up @@ -410,8 +410,8 @@ pub struct TypeckTables<'tcx> {
pub used_trait_imports: Lrc<DefIdSet>,

/// If any errors occurred while type-checking this body,
/// this field will be set to `true`.
pub tainted_by_errors: bool,
/// this field will be set to `Some(ErrorReported)`.
pub tainted_by_errors: Option<ErrorReported>,

/// All the opaque types that are restricted to concrete types
/// by this function.
Expand Down Expand Up @@ -447,7 +447,7 @@ impl<'tcx> TypeckTables<'tcx> {
fru_field_types: Default::default(),
coercion_casts: Default::default(),
used_trait_imports: Lrc::new(Default::default()),
tainted_by_errors: false,
tainted_by_errors: None,
concrete_opaque_types: Default::default(),
upvar_list: Default::default(),
generator_interior_types: Default::default(),
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_middle/ty/mod.rs
Expand Up @@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sorted_map::SortedIndexMultiMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::{self, par_iter, ParallelIterator};
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
Expand Down Expand Up @@ -2388,7 +2389,7 @@ impl<'tcx> AdtDef {
None
}
}
Err(ErrorHandled::Reported) => {
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {
if !expr_did.is_local() {
span_bug!(
tcx.def_span(expr_did),
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/borrow_check/mod.rs
Expand Up @@ -3,7 +3,7 @@
use rustc_ast::ast::Name;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
use rustc_hir as hir;
use rustc_hir::{def_id::DefId, HirId, Node};
use rustc_index::bit_set::BitSet;
Expand Down Expand Up @@ -135,7 +135,7 @@ fn do_mir_borrowck<'a, 'tcx>(

// Gather the upvars of a closure, if any.
let tables = tcx.typeck_tables_of(def_id);
if tables.tainted_by_errors {
if let Some(ErrorReported) = tables.tainted_by_errors {
infcx.set_tainted_by_errors();
}
let upvars: Vec<_> = tables
Expand Down
16 changes: 6 additions & 10 deletions src/librustc_mir/const_eval/eval_queries.rs
Expand Up @@ -213,13 +213,10 @@ fn validate_and_turn_into_const<'tcx>(

val.map_err(|error| {
let err = error_to_const_error(&ecx, error);
match err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| {
err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| {
diag.note(note_on_undefined_behavior_error());
diag.emit();
}) {
Ok(_) => ErrorHandled::Reported,
Err(err) => err,
}
})
})
}

Expand Down Expand Up @@ -292,11 +289,10 @@ pub fn const_eval_raw_provider<'tcx>(
let cid = key.value;
let def_id = cid.instance.def.def_id();

if def_id.is_local()
&& tcx.has_typeck_tables(def_id)
&& tcx.typeck_tables_of(def_id).tainted_by_errors
{
return Err(ErrorHandled::Reported);
if def_id.is_local() && tcx.has_typeck_tables(def_id) {
if let Some(error_reported) = tcx.typeck_tables_of(def_id).tainted_by_errors {
return Err(ErrorHandled::Reported(error_reported));
}
}

let is_static = tcx.is_static(def_id);
Expand Down
9 changes: 4 additions & 5 deletions src/librustc_mir/interpret/eval_context.rs
Expand Up @@ -400,11 +400,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> InterpResult<'tcx, mir::ReadOnlyBodyAndCache<'tcx, 'tcx>> {
// do not continue if typeck errors occurred (can only occur in local crate)
let did = instance.def_id();
if did.is_local()
&& self.tcx.has_typeck_tables(did)
&& self.tcx.typeck_tables_of(did).tainted_by_errors
{
throw_inval!(TypeckError)
if did.is_local() && self.tcx.has_typeck_tables(did) {
if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors {
throw_inval!(TypeckError(error_reported))
}
}
trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
if let Some(promoted) = promoted {
Expand Down
5 changes: 4 additions & 1 deletion src/librustc_mir/interpret/intern.rs
Expand Up @@ -5,6 +5,7 @@

use super::validity::RefTracking;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_middle::mir::interpret::{ErrorHandled, InterpResult};
use rustc_middle::ty::{self, Ty};
Expand Down Expand Up @@ -337,7 +338,9 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
diag.emit();
},
) {
Ok(()) | Err(ErrorHandled::TooGeneric) | Err(ErrorHandled::Reported) => {}
ErrorHandled::TooGeneric
| ErrorHandled::Reported(ErrorReported)
| ErrorHandled::Linted => {}
}
}
}
Expand Down
9 changes: 3 additions & 6 deletions src/librustc_mir/interpret/memory.rs
Expand Up @@ -18,8 +18,8 @@ use rustc_middle::ty::{self, query::TyCtxtAt, Instance, ParamEnv};
use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout};

use super::{
AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, ErrorHandled, GlobalAlloc,
GlobalId, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar,
AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, GlobalId,
InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar,
};
use crate::util::pretty;

Expand Down Expand Up @@ -462,10 +462,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// no need to report anything, the const_eval call takes care of that
// for statics
assert!(tcx.is_static(def_id));
match err {
ErrorHandled::Reported => err_inval!(ReferencedConstant),
ErrorHandled::TooGeneric => err_inval!(TooGeneric),
}
err
})?;
// Make sure we use the ID of the resolved memory, not the lazy one!
let id = raw_const.alloc_id;
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir/interpret/operand.rs
Expand Up @@ -4,6 +4,7 @@
use std::convert::TryFrom;
use std::fmt::Write;

use rustc_errors::ErrorReported;
use rustc_hir::def::Namespace;
use rustc_macros::HashStable;
use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
Expand Down Expand Up @@ -518,7 +519,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Early-return cases.
let val_val = match val.val {
ty::ConstKind::Param(_) => throw_inval!(TooGeneric),
ty::ConstKind::Error => throw_inval!(TypeckError),
ty::ConstKind::Error => throw_inval!(TypeckError(ErrorReported)),
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
let instance = self.resolve(def_id, substs)?;
// We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir/monomorphize/collector.rs
Expand Up @@ -178,6 +178,7 @@ use crate::monomorphize;

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
Expand Down Expand Up @@ -602,7 +603,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) {
Ok(val) => collect_const_value(self.tcx, val, self.output),
Err(ErrorHandled::Reported) => {}
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
Err(ErrorHandled::TooGeneric) => span_bug!(
self.tcx.def_span(def_id),
"collection encountered polymorphic constant",
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir_build/build/mod.rs
Expand Up @@ -3,6 +3,7 @@ use crate::build::scope::DropKind;
use crate::hair::cx::Cx;
use crate::hair::{BindingMode, LintLevel, PatKind};
use rustc_attr::{self as attr, UnwindAttr};
use rustc_errors::ErrorReported;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items;
Expand Down Expand Up @@ -59,7 +60,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {

tcx.infer_ctxt().enter(|infcx| {
let cx = Cx::new(&infcx, id);
let body = if cx.tables().tainted_by_errors {
let body = if let Some(ErrorReported) = cx.tables().tainted_by_errors {
build::construct_error(cx, body_id)
} else if cx.body_owner_kind.is_fn_or_closure() {
// fetch the fully liberated fn signature (that is, all bound
Expand Down

0 comments on commit d7c4081

Please sign in to comment.