Skip to content

Commit 9ed3483

Browse files
committed
require an ErrorGuaranteed to taint infcx with errors
1 parent 1c48039 commit 9ed3483

File tree

15 files changed

+94
-59
lines changed

15 files changed

+94
-59
lines changed

compiler/rustc_borrowck/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ fn do_mir_borrowck<'tcx>(
197197
// Gather the upvars of a closure, if any.
198198
let tables = tcx.typeck_opt_const_arg(def);
199199
if let Some(e) = tables.tainted_by_errors {
200-
infcx.set_tainted_by_errors();
200+
infcx.set_tainted_by_errors(e);
201201
errors.set_tainted_by_errors(e);
202202
}
203203
let upvars: Vec<_> = tables

compiler/rustc_borrowck/src/nll.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
303303

304304
if !nll_errors.is_empty() {
305305
// Suppress unhelpful extra errors in `infer_opaque_types`.
306-
infcx.set_tainted_by_errors();
306+
infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug(
307+
body.span,
308+
"`compute_regions` tainted `infcx` with errors but did not emit any errors",
309+
));
307310
}
308311

309312
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);

compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub trait AstConv<'tcx> {
115115
/// (e.g., resolve) that is translated into a ty-error. This is
116116
/// used to help suppress derived errors typeck might otherwise
117117
/// report.
118-
fn set_tainted_by_errors(&self);
118+
fn set_tainted_by_errors(&self, e: ErrorGuaranteed);
119119

120120
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
121121
}
@@ -2620,8 +2620,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
26202620
}
26212621
}
26222622
Res::Err => {
2623-
self.set_tainted_by_errors();
2624-
self.tcx().ty_error()
2623+
let e = self
2624+
.tcx()
2625+
.sess
2626+
.delay_span_bug(path.span, "path with `Res:Err` but no error emitted");
2627+
self.set_tainted_by_errors(e);
2628+
self.tcx().ty_error_with_guaranteed(e)
26252629
}
26262630
_ => span_bug!(span, "unexpected resolution: {:?}", path.res),
26272631
}

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
518518
ty
519519
}
520520

521-
fn set_tainted_by_errors(&self) {
521+
fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
522522
// There's no obvious place to track this, so just let it go.
523523
}
524524

compiler/rustc_hir_typeck/src/coercion.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1544,7 +1544,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
15441544
// Mark that we've failed to coerce the types here to suppress
15451545
// any superfluous errors we might encounter while trying to
15461546
// emit or provide suggestions on how to fix the initial error.
1547-
fcx.set_tainted_by_errors();
1547+
fcx.set_tainted_by_errors(
1548+
fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"),
1549+
);
15481550
let (expected, found) = if label_expression_as_expected {
15491551
// In the case where this is a "forced unit", like
15501552
// `break`, we want to call the `()` "expected"

compiler/rustc_hir_typeck/src/demand.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
154154
Err(e) => e,
155155
};
156156

157-
self.set_tainted_by_errors();
157+
self.set_tainted_by_errors(self.tcx.sess.delay_span_bug(
158+
expr.span,
159+
"`TypeError` when attempting coercion but no error emitted",
160+
));
158161
let expr = expr.peel_drop_temps();
159162
let cause = self.misc(expr.span);
160163
let expr_ty = self.resolve_vars_with_obligations(checked_ty);

compiler/rustc_hir_typeck/src/expr.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -527,12 +527,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
527527
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
528528
let ty = match res {
529529
Res::Err => {
530-
self.set_tainted_by_errors();
531-
tcx.ty_error()
530+
let e =
531+
self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
532+
self.set_tainted_by_errors(e);
533+
tcx.ty_error_with_guaranteed(e)
532534
}
533535
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
534-
report_unexpected_variant_res(tcx, res, qpath, expr.span);
535-
tcx.ty_error()
536+
let e = report_unexpected_variant_res(tcx, res, qpath, expr.span);
537+
tcx.ty_error_with_guaranteed(e)
536538
}
537539
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
538540
};
@@ -1962,7 +1964,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19621964
expr_span: Span,
19631965
) {
19641966
if variant.is_recovered() {
1965-
self.set_tainted_by_errors();
1967+
self.set_tainted_by_errors(
1968+
self.tcx
1969+
.sess
1970+
.delay_span_bug(expr_span, "parser recovered but no error was emitted"),
1971+
);
19661972
return;
19671973
}
19681974
let mut err = self.err_ctxt().type_error_struct_with_diag(

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
140140
debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
141141
self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
142142

143-
if ty.references_error() {
144-
self.set_tainted_by_errors();
143+
if let Err(e) = ty.error_reported() {
144+
self.set_tainted_by_errors(e);
145145
}
146146
}
147147

@@ -1148,9 +1148,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11481148
explicit_late_bound = ExplicitLateBound::Yes;
11491149
}
11501150

1151-
if let Err(GenericArgCountMismatch { reported: Some(_), .. }) = arg_count.correct {
1151+
if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct {
11521152
infer_args_for_err.insert(index);
1153-
self.set_tainted_by_errors(); // See issue #53251.
1153+
self.set_tainted_by_errors(e); // See issue #53251.
11541154
}
11551155
}
11561156

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
512512
tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
513513
}
514514

515-
self.set_tainted_by_errors();
516515
let tcx = self.tcx;
516+
// FIXME: taint after emitting errors and pass through an `ErrorGuaranteed`
517+
self.set_tainted_by_errors(
518+
tcx.sess.delay_span_bug(call_span, "no errors reported for args"),
519+
);
517520

518521
// Get the argument span in the context of the call span so that
519522
// suggestions and labels are (more) correct when an arg is a
@@ -1208,7 +1211,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12081211
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
12091212
let variant = match def {
12101213
Res::Err => {
1211-
self.set_tainted_by_errors();
1214+
self.set_tainted_by_errors(
1215+
self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"),
1216+
);
12121217
return None;
12131218
}
12141219
Res::Def(DefKind::Variant, _) => match ty.kind() {

compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod checks;
44
mod suggestions;
55

66
pub use _impl::*;
7+
use rustc_errors::ErrorGuaranteed;
78
pub use suggestions::*;
89

910
use crate::coercion::DynamicCoerceMany;
@@ -289,8 +290,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
289290
}
290291
}
291292

292-
fn set_tainted_by_errors(&self) {
293-
self.infcx.set_tainted_by_errors()
293+
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
294+
self.infcx.set_tainted_by_errors(e)
294295
}
295296

296297
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use crate::check::check_fn;
5353
use crate::coercion::DynamicCoerceMany;
5454
use crate::gather_locals::GatherLocalsVisitor;
5555
use rustc_data_structures::unord::UnordSet;
56-
use rustc_errors::{struct_span_err, MultiSpan};
56+
use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan};
5757
use rustc_hir as hir;
5858
use rustc_hir::def::Res;
5959
use rustc_hir::intravisit::Visitor;
@@ -428,7 +428,12 @@ impl<'tcx> EnclosingBreakables<'tcx> {
428428
}
429429
}
430430

431-
fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'_>, span: Span) {
431+
fn report_unexpected_variant_res(
432+
tcx: TyCtxt<'_>,
433+
res: Res,
434+
qpath: &hir::QPath<'_>,
435+
span: Span,
436+
) -> ErrorGuaranteed {
432437
struct_span_err!(
433438
tcx.sess,
434439
span,
@@ -437,7 +442,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'
437442
res.descr(),
438443
rustc_hir_pretty::qpath_to_string(qpath),
439444
)
440-
.emit();
445+
.emit()
441446
}
442447

443448
/// Controls whether the arguments are tupled. This is used for the call

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -839,12 +839,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
839839
let (res, opt_ty, segments) = path_resolution;
840840
match res {
841841
Res::Err => {
842-
self.set_tainted_by_errors();
843-
return tcx.ty_error();
842+
let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
843+
self.set_tainted_by_errors(e);
844+
return tcx.ty_error_with_guaranteed(e);
844845
}
845846
Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
846-
report_unexpected_variant_res(tcx, res, qpath, pat.span);
847-
return tcx.ty_error();
847+
let e = report_unexpected_variant_res(tcx, res, qpath, pat.span);
848+
return tcx.ty_error_with_guaranteed(e);
848849
}
849850
Res::SelfCtor(..)
850851
| Res::Def(
@@ -985,9 +986,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
985986
ti: TopInfo<'tcx>,
986987
) -> Ty<'tcx> {
987988
let tcx = self.tcx;
988-
let on_error = || {
989+
let on_error = |e| {
989990
for pat in subpats {
990-
self.check_pat(pat, tcx.ty_error(), def_bm, ti);
991+
self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti);
991992
}
992993
};
993994
let report_unexpected_res = |res: Res| {
@@ -1014,36 +1015,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10141015
err.span_label(pat.span, "not a tuple variant or struct");
10151016
}
10161017
}
1017-
err.emit();
1018-
on_error();
1018+
let e = err.emit();
1019+
on_error(e);
1020+
e
10191021
};
10201022

10211023
// Resolve the path and check the definition for errors.
10221024
let (res, opt_ty, segments) =
10231025
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
10241026
if res == Res::Err {
1025-
self.set_tainted_by_errors();
1026-
on_error();
1027-
return self.tcx.ty_error();
1027+
let e = tcx.sess.delay_span_bug(pat.span, "`Res:Err` but no error emitted");
1028+
self.set_tainted_by_errors(e);
1029+
on_error(e);
1030+
return tcx.ty_error_with_guaranteed(e);
10281031
}
10291032

10301033
// Type-check the path.
10311034
let (pat_ty, res) =
10321035
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
10331036
if !pat_ty.is_fn() {
1034-
report_unexpected_res(res);
1035-
return tcx.ty_error();
1037+
let e = report_unexpected_res(res);
1038+
return tcx.ty_error_with_guaranteed(e);
10361039
}
10371040

10381041
let variant = match res {
10391042
Res::Err => {
1040-
self.set_tainted_by_errors();
1041-
on_error();
1042-
return tcx.ty_error();
1043+
let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
1044+
self.set_tainted_by_errors(e);
1045+
on_error(e);
1046+
return tcx.ty_error_with_guaranteed(e);
10431047
}
10441048
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
1045-
report_unexpected_res(res);
1046-
return tcx.ty_error();
1049+
let e = report_unexpected_res(res);
1050+
return tcx.ty_error_with_guaranteed(e);
10471051
}
10481052
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
10491053
_ => bug!("unexpected pattern resolution: {:?}", res),
@@ -1082,9 +1086,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10821086
}
10831087
} else {
10841088
// Pattern has wrong number of fields.
1085-
self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
1086-
on_error();
1087-
return tcx.ty_error();
1089+
let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
1090+
on_error(e);
1091+
return tcx.ty_error_with_guaranteed(e);
10881092
}
10891093
pat_ty
10901094
}
@@ -1098,7 +1102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
10981102
fields: &'tcx [ty::FieldDef],
10991103
expected: Ty<'tcx>,
11001104
had_err: bool,
1101-
) {
1105+
) -> ErrorGuaranteed {
11021106
let subpats_ending = pluralize!(subpats.len());
11031107
let fields_ending = pluralize!(fields.len());
11041108

@@ -1245,7 +1249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12451249
}
12461250
}
12471251

1248-
err.emit();
1252+
err.emit()
12491253
}
12501254

12511255
fn check_pat_tuple(

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub use rustc_middle::ty::IntVarValue;
3434
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
3535
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
3636
use rustc_span::symbol::Symbol;
37-
use rustc_span::{Span, DUMMY_SP};
37+
use rustc_span::Span;
3838

3939
use std::cell::{Cell, RefCell};
4040
use std::fmt;
@@ -1224,20 +1224,19 @@ impl<'tcx> InferCtxt<'tcx> {
12241224

12251225
if self.tcx.sess.err_count() > self.err_count_on_creation {
12261226
// errors reported since this infcx was made
1227-
self.set_tainted_by_errors();
1228-
return self.tainted_by_errors.get();
1227+
let e = self.tcx.sess.has_errors().unwrap();
1228+
self.set_tainted_by_errors(e);
1229+
return Some(e);
12291230
}
12301231

12311232
None
12321233
}
12331234

12341235
/// Set the "tainted by errors" flag to true. We call this when we
12351236
/// observe an error from a prior pass.
1236-
pub fn set_tainted_by_errors(&self) {
1237-
debug!("set_tainted_by_errors()");
1238-
self.tainted_by_errors.set(Some(
1239-
self.tcx.sess.delay_span_bug(DUMMY_SP, "`InferCtxt` incorrectly tainted by errors"),
1240-
));
1237+
pub fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
1238+
debug!("set_tainted_by_errors(ErrorGuaranteed)");
1239+
self.tainted_by_errors.set(Some(e));
12411240
}
12421241

12431242
pub fn skip_region_resolution(&self) {

compiler/rustc_infer/src/infer/sub.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
116116
Ok(a)
117117
}
118118

119-
(&ty::Error(_), _) | (_, &ty::Error(_)) => {
120-
infcx.set_tainted_by_errors();
121-
Ok(self.tcx().ty_error())
119+
(&ty::Error(e), _) | (_, &ty::Error(e)) => {
120+
infcx.set_tainted_by_errors(e);
121+
Ok(self.tcx().ty_error_with_guaranteed(e))
122122
}
123123

124124
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
532532
root_obligation: &PredicateObligation<'tcx>,
533533
error: &SelectionError<'tcx>,
534534
) {
535-
self.set_tainted_by_errors();
536535
let tcx = self.tcx;
537536
let mut span = obligation.cause.span;
537+
// FIXME: statically guarantee this by tainting after the diagnostic is emitted
538+
self.set_tainted_by_errors(
539+
tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"),
540+
);
538541

539542
let mut err = match *error {
540543
SelectionError::Unimplemented => {

0 commit comments

Comments
 (0)