mir/interpret: only use ErrorHandled::Reported
for ErrorReported
.
This commit is contained in:
parent
e22d4795d8
commit
d7c4081b18
16 changed files with 87 additions and 74 deletions
|
@ -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;
|
||||
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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<'_>| {
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
@ -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(),
|
||||
|
|
|
@ -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};
|
||||
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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};
|
||||
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
@ -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
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCod
|
|||
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use crate::infer::{self, InferCtxt, TyCtxtInferExt};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
|
||||
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorReported};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_hir::{Node, QPath, TyKind, WhereBoundPredicate, WherePredicate};
|
||||
|
@ -653,8 +653,17 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Already reported in the query.
|
||||
ConstEvalFailure(ErrorHandled::Reported) => {
|
||||
self.tcx.sess.delay_span_bug(span, "constant in type had an ignored error");
|
||||
ConstEvalFailure(ErrorHandled::Reported(ErrorReported)) => {
|
||||
// FIXME(eddyb) remove this once `ErrorReported` becomes a proof token.
|
||||
self.tcx.sess.delay_span_bug(span, "`ErrorReported` without an error");
|
||||
return;
|
||||
}
|
||||
|
||||
// Already reported in the query, but only as a lint.
|
||||
// This shouldn't actually happen for constants used in types, modulo
|
||||
// bugs. The `delay_span_bug` here ensures it won't be ignored.
|
||||
ConstEvalFailure(ErrorHandled::Linted) => {
|
||||
self.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
use crate::check::FnCtxt;
|
||||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefIdSet;
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
|
@ -75,7 +76,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
wbcx.tables.upvar_list =
|
||||
mem::replace(&mut self.tables.borrow_mut().upvar_list, Default::default());
|
||||
|
||||
wbcx.tables.tainted_by_errors |= self.is_tainted_by_errors();
|
||||
if self.is_tainted_by_errors() {
|
||||
// FIXME(eddyb) keep track of `ErrorReported` from where the error was emitted.
|
||||
wbcx.tables.tainted_by_errors = Some(ErrorReported);
|
||||
}
|
||||
|
||||
debug!("writeback: tables for {:?} are {:#?}", item_def_id, wbcx.tables);
|
||||
|
||||
|
@ -591,7 +595,10 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
// We may have introduced e.g. `ty::Error`, if inference failed, make sure
|
||||
// to mark the `TypeckTables` as tainted in that case, so that downstream
|
||||
// users of the tables don't produce extra errors, or worse, ICEs.
|
||||
self.tables.tainted_by_errors |= resolver.replaced_with_error;
|
||||
if resolver.replaced_with_error {
|
||||
// FIXME(eddyb) keep track of `ErrorReported` from where the error was emitted.
|
||||
self.tables.tainted_by_errors = Some(ErrorReported);
|
||||
}
|
||||
|
||||
x
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{struct_span_err, Applicability, StashKey};
|
||||
use rustc_errors::{struct_span_err, Applicability, ErrorReported, StashKey};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::DefId;
|
||||
|
@ -125,7 +125,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
|||
owner, def_id,
|
||||
),
|
||||
);
|
||||
if tcx.typeck_tables_of(owner).tainted_by_errors {
|
||||
if let Some(ErrorReported) =
|
||||
tcx.typeck_tables_of(owner).tainted_by_errors
|
||||
{
|
||||
// Some error in the
|
||||
// owner fn prevented us from populating
|
||||
// the `concrete_opaque_types` table.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue