Skip to content

Commit d7c4081

Browse files
committed
mir/interpret: only use ErrorHandled::Reported for ErrorReported.
1 parent e22d479 commit d7c4081

File tree

16 files changed

+87
-74
lines changed

16 files changed

+87
-74
lines changed

src/librustc_codegen_ssa/mir/operand.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::glue;
66
use crate::traits::*;
77
use crate::MemFlags;
88

9+
use rustc_errors::ErrorReported;
910
use rustc_middle::mir;
1011
use rustc_middle::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar};
1112
use rustc_middle::ty::layout::TyAndLayout;
@@ -447,8 +448,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
447448
self.eval_mir_constant_to_operand(bx, constant).unwrap_or_else(|err| {
448449
match err {
449450
// errored or at least linted
450-
ErrorHandled::Reported => {}
451-
ErrorHandled::TooGeneric => bug!("codgen encountered polymorphic constant"),
451+
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {}
452+
ErrorHandled::TooGeneric => {
453+
bug!("codegen encountered polymorphic constant")
454+
}
452455
}
453456
// Allow RalfJ to sleep soundly knowing that even refactorings that remove
454457
// the above error (or silence it under some conditions) will not cause UB.

src/librustc_infer/infer/error_reporting/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,8 @@ pub fn unexpected_hidden_region_diagnostic(
304304
// down this path which gives a decent human readable
305305
// explanation.
306306
//
307-
// (*) if not, the `tainted_by_errors` flag would be set to
308-
// true in any case, so we wouldn't be here at all.
307+
// (*) if not, the `tainted_by_errors` field would be set to
308+
// `Some(ErrorReported)` in any case, so we wouldn't be here at all.
309309
note_and_explain_free_region(
310310
tcx,
311311
&mut err,

src/librustc_middle/mir/interpret/error.rs

+25-32
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::ty::{self, layout, Ty};
88

99
use backtrace::Backtrace;
1010
use rustc_data_structures::sync::Lock;
11-
use rustc_errors::{struct_span_err, DiagnosticBuilder};
11+
use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorReported};
1212
use rustc_hir as hir;
1313
use rustc_hir::definitions::DefPathData;
1414
use rustc_macros::HashStable;
@@ -19,25 +19,16 @@ use std::{any::Any, fmt, mem};
1919

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

29-
impl ErrorHandled {
30-
pub fn assert_reported(self) {
31-
match self {
32-
ErrorHandled::Reported => {}
33-
ErrorHandled::TooGeneric => bug!(
34-
"MIR interpretation failed without reporting an error \
35-
even though it was fully monomorphized"
36-
),
37-
}
38-
}
39-
}
40-
4132
CloneTypeFoldableImpls! {
4233
ErrorHandled,
4334
}
@@ -84,15 +75,12 @@ impl<'tcx> ConstEvalErr<'tcx> {
8475
tcx: TyCtxtAt<'tcx>,
8576
message: &str,
8677
emit: impl FnOnce(DiagnosticBuilder<'_>),
87-
) -> Result<(), ErrorHandled> {
78+
) -> ErrorHandled {
8879
self.struct_generic(tcx, message, emit, None)
8980
}
9081

9182
pub fn report_as_error(&self, tcx: TyCtxtAt<'tcx>, message: &str) -> ErrorHandled {
92-
match self.struct_error(tcx, message, |mut e| e.emit()) {
93-
Ok(_) => ErrorHandled::Reported,
94-
Err(x) => x,
95-
}
83+
self.struct_error(tcx, message, |mut e| e.emit())
9684
}
9785

9886
pub fn report_as_lint(
@@ -102,7 +90,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
10290
lint_root: hir::HirId,
10391
span: Option<Span>,
10492
) -> ErrorHandled {
105-
match self.struct_generic(
93+
self.struct_generic(
10694
tcx,
10795
message,
10896
|mut lint: DiagnosticBuilder<'_>| {
@@ -122,10 +110,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
122110
lint.emit();
123111
},
124112
Some(lint_root),
125-
) {
126-
Ok(_) => ErrorHandled::Reported,
127-
Err(err) => err,
128-
}
113+
)
129114
}
130115

131116
/// Create a diagnostic for this const eval error.
@@ -143,12 +128,14 @@ impl<'tcx> ConstEvalErr<'tcx> {
143128
message: &str,
144129
emit: impl FnOnce(DiagnosticBuilder<'_>),
145130
lint_root: Option<hir::HirId>,
146-
) -> Result<(), ErrorHandled> {
131+
) -> ErrorHandled {
147132
let must_error = match self.error {
148133
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
149-
return Err(ErrorHandled::TooGeneric);
134+
return ErrorHandled::TooGeneric;
135+
}
136+
err_inval!(TypeckError(error_reported)) => {
137+
return ErrorHandled::Reported(error_reported);
150138
}
151-
err_inval!(TypeckError) => return Err(ErrorHandled::Reported),
152139
// We must *always* hard error on these, even if the caller wants just a lint.
153140
err_inval!(Layout(LayoutError::SizeOverflow(_))) => true,
154141
_ => false,
@@ -183,6 +170,7 @@ impl<'tcx> ConstEvalErr<'tcx> {
183170
// caller thinks anyway.
184171
// See <https://github.com/rust-lang/rust/pull/63152>.
185172
finish(struct_error(tcx, &err_msg), None);
173+
ErrorHandled::Reported(ErrorReported)
186174
} else {
187175
// Regular case.
188176
if let Some(lint_root) = lint_root {
@@ -200,12 +188,13 @@ impl<'tcx> ConstEvalErr<'tcx> {
200188
tcx.span,
201189
|lint| finish(lint.build(message), Some(err_msg)),
202190
);
191+
ErrorHandled::Linted
203192
} else {
204193
// Report as hard error.
205194
finish(struct_error(tcx, message), Some(err_msg));
195+
ErrorHandled::Reported(ErrorReported)
206196
}
207197
}
208-
Ok(())
209198
}
210199
}
211200

@@ -246,7 +235,9 @@ fn print_backtrace(backtrace: &mut Backtrace) {
246235
impl From<ErrorHandled> for InterpErrorInfo<'_> {
247236
fn from(err: ErrorHandled) -> Self {
248237
match err {
249-
ErrorHandled::Reported => err_inval!(ReferencedConstant),
238+
ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => {
239+
err_inval!(ReferencedConstant)
240+
}
250241
ErrorHandled::TooGeneric => err_inval!(TooGeneric),
251242
}
252243
.into()
@@ -288,7 +279,7 @@ pub enum InvalidProgramInfo<'tcx> {
288279
/// which already produced an error.
289280
ReferencedConstant,
290281
/// Abort in case type errors are reached.
291-
TypeckError,
282+
TypeckError(ErrorReported),
292283
/// An error occurred during layout computation.
293284
Layout(layout::LayoutError<'tcx>),
294285
/// An invalid transmute happened.
@@ -301,7 +292,9 @@ impl fmt::Debug for InvalidProgramInfo<'_> {
301292
match self {
302293
TooGeneric => write!(f, "encountered overly generic constant"),
303294
ReferencedConstant => write!(f, "referenced constant has errors"),
304-
TypeckError => write!(f, "encountered constants with type errors, stopping evaluation"),
295+
TypeckError(ErrorReported) => {
296+
write!(f, "encountered constants with type errors, stopping evaluation")
297+
}
305298
Layout(ref err) => write!(f, "{}", err),
306299
TransmuteSizeDiff(from_ty, to_ty) => write!(
307300
f,

src/librustc_middle/ty/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,8 @@ pub struct TypeckTables<'tcx> {
410410
pub used_trait_imports: Lrc<DefIdSet>,
411411

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

416416
/// All the opaque types that are restricted to concrete types
417417
/// by this function.
@@ -447,7 +447,7 @@ impl<'tcx> TypeckTables<'tcx> {
447447
fru_field_types: Default::default(),
448448
coercion_casts: Default::default(),
449449
used_trait_imports: Lrc::new(Default::default()),
450-
tainted_by_errors: false,
450+
tainted_by_errors: None,
451451
concrete_opaque_types: Default::default(),
452452
upvar_list: Default::default(),
453453
generator_interior_types: Default::default(),

src/librustc_middle/ty/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use rustc_data_structures::fx::FxIndexMap;
2727
use rustc_data_structures::sorted_map::SortedIndexMultiMap;
2828
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
2929
use rustc_data_structures::sync::{self, par_iter, ParallelIterator};
30+
use rustc_errors::ErrorReported;
3031
use rustc_hir as hir;
3132
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Namespace, Res};
3233
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX};
@@ -2388,7 +2389,7 @@ impl<'tcx> AdtDef {
23882389
None
23892390
}
23902391
}
2391-
Err(ErrorHandled::Reported) => {
2392+
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {
23922393
if !expr_did.is_local() {
23932394
span_bug!(
23942395
tcx.def_span(expr_did),

src/librustc_mir/borrow_check/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use rustc_ast::ast::Name;
44
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55
use rustc_data_structures::graph::dominators::Dominators;
6-
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
6+
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorReported};
77
use rustc_hir as hir;
88
use rustc_hir::{def_id::DefId, HirId, Node};
99
use rustc_index::bit_set::BitSet;
@@ -135,7 +135,7 @@ fn do_mir_borrowck<'a, 'tcx>(
135135

136136
// Gather the upvars of a closure, if any.
137137
let tables = tcx.typeck_tables_of(def_id);
138-
if tables.tainted_by_errors {
138+
if let Some(ErrorReported) = tables.tainted_by_errors {
139139
infcx.set_tainted_by_errors();
140140
}
141141
let upvars: Vec<_> = tables

src/librustc_mir/const_eval/eval_queries.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,10 @@ fn validate_and_turn_into_const<'tcx>(
213213

214214
val.map_err(|error| {
215215
let err = error_to_const_error(&ecx, error);
216-
match err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| {
216+
err.struct_error(ecx.tcx, "it is undefined behavior to use this value", |mut diag| {
217217
diag.note(note_on_undefined_behavior_error());
218218
diag.emit();
219-
}) {
220-
Ok(_) => ErrorHandled::Reported,
221-
Err(err) => err,
222-
}
219+
})
223220
})
224221
}
225222

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

295-
if def_id.is_local()
296-
&& tcx.has_typeck_tables(def_id)
297-
&& tcx.typeck_tables_of(def_id).tainted_by_errors
298-
{
299-
return Err(ErrorHandled::Reported);
292+
if def_id.is_local() && tcx.has_typeck_tables(def_id) {
293+
if let Some(error_reported) = tcx.typeck_tables_of(def_id).tainted_by_errors {
294+
return Err(ErrorHandled::Reported(error_reported));
295+
}
300296
}
301297

302298
let is_static = tcx.is_static(def_id);

src/librustc_mir/interpret/eval_context.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -400,11 +400,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
400400
) -> InterpResult<'tcx, mir::ReadOnlyBodyAndCache<'tcx, 'tcx>> {
401401
// do not continue if typeck errors occurred (can only occur in local crate)
402402
let did = instance.def_id();
403-
if did.is_local()
404-
&& self.tcx.has_typeck_tables(did)
405-
&& self.tcx.typeck_tables_of(did).tainted_by_errors
406-
{
407-
throw_inval!(TypeckError)
403+
if did.is_local() && self.tcx.has_typeck_tables(did) {
404+
if let Some(error_reported) = self.tcx.typeck_tables_of(did).tainted_by_errors {
405+
throw_inval!(TypeckError(error_reported))
406+
}
408407
}
409408
trace!("load mir(instance={:?}, promoted={:?})", instance, promoted);
410409
if let Some(promoted) = promoted {

src/librustc_mir/interpret/intern.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
use super::validity::RefTracking;
77
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
8+
use rustc_errors::ErrorReported;
89
use rustc_hir as hir;
910
use rustc_middle::mir::interpret::{ErrorHandled, InterpResult};
1011
use rustc_middle::ty::{self, Ty};
@@ -337,7 +338,9 @@ pub fn intern_const_alloc_recursive<M: CompileTimeMachine<'mir, 'tcx>>(
337338
diag.emit();
338339
},
339340
) {
340-
Ok(()) | Err(ErrorHandled::TooGeneric) | Err(ErrorHandled::Reported) => {}
341+
ErrorHandled::TooGeneric
342+
| ErrorHandled::Reported(ErrorReported)
343+
| ErrorHandled::Linted => {}
341344
}
342345
}
343346
}

src/librustc_mir/interpret/memory.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use rustc_middle::ty::{self, query::TyCtxtAt, Instance, ParamEnv};
1818
use rustc_target::abi::{Align, HasDataLayout, Size, TargetDataLayout};
1919

2020
use super::{
21-
AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, ErrorHandled, GlobalAlloc,
22-
GlobalId, InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar,
21+
AllocId, AllocMap, Allocation, AllocationExtra, CheckInAllocMsg, GlobalAlloc, GlobalId,
22+
InterpResult, Machine, MayLeak, Pointer, PointerArithmetic, Scalar,
2323
};
2424
use crate::util::pretty;
2525

@@ -462,10 +462,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
462462
// no need to report anything, the const_eval call takes care of that
463463
// for statics
464464
assert!(tcx.is_static(def_id));
465-
match err {
466-
ErrorHandled::Reported => err_inval!(ReferencedConstant),
467-
ErrorHandled::TooGeneric => err_inval!(TooGeneric),
468-
}
465+
err
469466
})?;
470467
// Make sure we use the ID of the resolved memory, not the lazy one!
471468
let id = raw_const.alloc_id;

src/librustc_mir/interpret/operand.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::convert::TryFrom;
55
use std::fmt::Write;
66

7+
use rustc_errors::ErrorReported;
78
use rustc_hir::def::Namespace;
89
use rustc_macros::HashStable;
910
use rustc_middle::ty::layout::{IntegerExt, PrimitiveExt, TyAndLayout};
@@ -518,7 +519,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
518519
// Early-return cases.
519520
let val_val = match val.val {
520521
ty::ConstKind::Param(_) => throw_inval!(TooGeneric),
521-
ty::ConstKind::Error => throw_inval!(TypeckError),
522+
ty::ConstKind::Error => throw_inval!(TypeckError(ErrorReported)),
522523
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
523524
let instance = self.resolve(def_id, substs)?;
524525
// We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.

src/librustc_mir/monomorphize/collector.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ use crate::monomorphize;
178178

179179
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
180180
use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator};
181+
use rustc_errors::ErrorReported;
181182
use rustc_hir as hir;
182183
use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE};
183184
use rustc_hir::itemlikevisit::ItemLikeVisitor;
@@ -602,7 +603,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
602603
ty::ConstKind::Unevaluated(def_id, substs, promoted) => {
603604
match self.tcx.const_eval_resolve(param_env, def_id, substs, promoted, None) {
604605
Ok(val) => collect_const_value(self.tcx, val, self.output),
605-
Err(ErrorHandled::Reported) => {}
606+
Err(ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted) => {}
606607
Err(ErrorHandled::TooGeneric) => span_bug!(
607608
self.tcx.def_span(def_id),
608609
"collection encountered polymorphic constant",

src/librustc_mir_build/build/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::build::scope::DropKind;
33
use crate::hair::cx::Cx;
44
use crate::hair::{BindingMode, LintLevel, PatKind};
55
use rustc_attr::{self as attr, UnwindAttr};
6+
use rustc_errors::ErrorReported;
67
use rustc_hir as hir;
78
use rustc_hir::def_id::DefId;
89
use rustc_hir::lang_items;
@@ -59,7 +60,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
5960

6061
tcx.infer_ctxt().enter(|infcx| {
6162
let cx = Cx::new(&infcx, id);
62-
let body = if cx.tables().tainted_by_errors {
63+
let body = if let Some(ErrorReported) = cx.tables().tainted_by_errors {
6364
build::construct_error(cx, body_id)
6465
} else if cx.body_owner_kind.is_fn_or_closure() {
6566
// fetch the fully liberated fn signature (that is, all bound

0 commit comments

Comments
 (0)