require an ErrorGuaranteed
to taint infcx with errors
This commit is contained in:
parent
1c48039a87
commit
9ed348376f
15 changed files with 94 additions and 59 deletions
|
@ -197,7 +197,7 @@ fn do_mir_borrowck<'tcx>(
|
||||||
// Gather the upvars of a closure, if any.
|
// Gather the upvars of a closure, if any.
|
||||||
let tables = tcx.typeck_opt_const_arg(def);
|
let tables = tcx.typeck_opt_const_arg(def);
|
||||||
if let Some(e) = tables.tainted_by_errors {
|
if let Some(e) = tables.tainted_by_errors {
|
||||||
infcx.set_tainted_by_errors();
|
infcx.set_tainted_by_errors(e);
|
||||||
errors.set_tainted_by_errors(e);
|
errors.set_tainted_by_errors(e);
|
||||||
}
|
}
|
||||||
let upvars: Vec<_> = tables
|
let upvars: Vec<_> = tables
|
||||||
|
|
|
@ -303,7 +303,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||||
|
|
||||||
if !nll_errors.is_empty() {
|
if !nll_errors.is_empty() {
|
||||||
// Suppress unhelpful extra errors in `infer_opaque_types`.
|
// Suppress unhelpful extra errors in `infer_opaque_types`.
|
||||||
infcx.set_tainted_by_errors();
|
infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug(
|
||||||
|
body.span,
|
||||||
|
"`compute_regions` tainted `infcx` with errors but did not emit any errors",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);
|
let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values);
|
||||||
|
|
|
@ -115,7 +115,7 @@ pub trait AstConv<'tcx> {
|
||||||
/// (e.g., resolve) that is translated into a ty-error. This is
|
/// (e.g., resolve) that is translated into a ty-error. This is
|
||||||
/// used to help suppress derived errors typeck might otherwise
|
/// used to help suppress derived errors typeck might otherwise
|
||||||
/// report.
|
/// report.
|
||||||
fn set_tainted_by_errors(&self);
|
fn set_tainted_by_errors(&self, e: ErrorGuaranteed);
|
||||||
|
|
||||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
|
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
|
||||||
}
|
}
|
||||||
|
@ -2620,8 +2620,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Res::Err => {
|
Res::Err => {
|
||||||
self.set_tainted_by_errors();
|
let e = self
|
||||||
self.tcx().ty_error()
|
.tcx()
|
||||||
|
.sess
|
||||||
|
.delay_span_bug(path.span, "path with `Res:Err` but no error emitted");
|
||||||
|
self.set_tainted_by_errors(e);
|
||||||
|
self.tcx().ty_error_with_guaranteed(e)
|
||||||
}
|
}
|
||||||
_ => span_bug!(span, "unexpected resolution: {:?}", path.res),
|
_ => span_bug!(span, "unexpected resolution: {:?}", path.res),
|
||||||
}
|
}
|
||||||
|
|
|
@ -518,7 +518,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> {
|
||||||
ty
|
ty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_tainted_by_errors(&self) {
|
fn set_tainted_by_errors(&self, _: ErrorGuaranteed) {
|
||||||
// There's no obvious place to track this, so just let it go.
|
// There's no obvious place to track this, so just let it go.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1544,7 +1544,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
// Mark that we've failed to coerce the types here to suppress
|
// Mark that we've failed to coerce the types here to suppress
|
||||||
// any superfluous errors we might encounter while trying to
|
// any superfluous errors we might encounter while trying to
|
||||||
// emit or provide suggestions on how to fix the initial error.
|
// emit or provide suggestions on how to fix the initial error.
|
||||||
fcx.set_tainted_by_errors();
|
fcx.set_tainted_by_errors(
|
||||||
|
fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"),
|
||||||
|
);
|
||||||
let (expected, found) = if label_expression_as_expected {
|
let (expected, found) = if label_expression_as_expected {
|
||||||
// In the case where this is a "forced unit", like
|
// In the case where this is a "forced unit", like
|
||||||
// `break`, we want to call the `()` "expected"
|
// `break`, we want to call the `()` "expected"
|
||||||
|
|
|
@ -154,7 +154,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
Err(e) => e,
|
Err(e) => e,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors(self.tcx.sess.delay_span_bug(
|
||||||
|
expr.span,
|
||||||
|
"`TypeError` when attempting coercion but no error emitted",
|
||||||
|
));
|
||||||
let expr = expr.peel_drop_temps();
|
let expr = expr.peel_drop_temps();
|
||||||
let cause = self.misc(expr.span);
|
let cause = self.misc(expr.span);
|
||||||
let expr_ty = self.resolve_vars_with_obligations(checked_ty);
|
let expr_ty = self.resolve_vars_with_obligations(checked_ty);
|
||||||
|
|
|
@ -527,12 +527,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
|
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
|
||||||
let ty = match res {
|
let ty = match res {
|
||||||
Res::Err => {
|
Res::Err => {
|
||||||
self.set_tainted_by_errors();
|
let e =
|
||||||
tcx.ty_error()
|
self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
|
||||||
|
self.set_tainted_by_errors(e);
|
||||||
|
tcx.ty_error_with_guaranteed(e)
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
|
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => {
|
||||||
report_unexpected_variant_res(tcx, res, qpath, expr.span);
|
let e = report_unexpected_variant_res(tcx, res, qpath, expr.span);
|
||||||
tcx.ty_error()
|
tcx.ty_error_with_guaranteed(e)
|
||||||
}
|
}
|
||||||
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
|
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
|
||||||
};
|
};
|
||||||
|
@ -1962,7 +1964,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
expr_span: Span,
|
expr_span: Span,
|
||||||
) {
|
) {
|
||||||
if variant.is_recovered() {
|
if variant.is_recovered() {
|
||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors(
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.delay_span_bug(expr_span, "parser recovered but no error was emitted"),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let mut err = self.err_ctxt().type_error_struct_with_diag(
|
let mut err = self.err_ctxt().type_error_struct_with_diag(
|
||||||
|
|
|
@ -140,8 +140,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
|
debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
|
||||||
self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
|
self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
|
||||||
|
|
||||||
if ty.references_error() {
|
if let Err(e) = ty.error_reported() {
|
||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1148,9 +1148,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
explicit_late_bound = ExplicitLateBound::Yes;
|
explicit_late_bound = ExplicitLateBound::Yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(GenericArgCountMismatch { reported: Some(_), .. }) = arg_count.correct {
|
if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct {
|
||||||
infer_args_for_err.insert(index);
|
infer_args_for_err.insert(index);
|
||||||
self.set_tainted_by_errors(); // See issue #53251.
|
self.set_tainted_by_errors(e); // See issue #53251.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -512,8 +512,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
|
tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var())
|
||||||
}
|
}
|
||||||
|
|
||||||
self.set_tainted_by_errors();
|
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
|
// FIXME: taint after emitting errors and pass through an `ErrorGuaranteed`
|
||||||
|
self.set_tainted_by_errors(
|
||||||
|
tcx.sess.delay_span_bug(call_span, "no errors reported for args"),
|
||||||
|
);
|
||||||
|
|
||||||
// Get the argument span in the context of the call span so that
|
// Get the argument span in the context of the call span so that
|
||||||
// suggestions and labels are (more) correct when an arg is a
|
// suggestions and labels are (more) correct when an arg is a
|
||||||
|
@ -1208,7 +1211,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
|
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
|
||||||
let variant = match def {
|
let variant = match def {
|
||||||
Res::Err => {
|
Res::Err => {
|
||||||
self.set_tainted_by_errors();
|
self.set_tainted_by_errors(
|
||||||
|
self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"),
|
||||||
|
);
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Variant, _) => match ty.kind() {
|
Res::Def(DefKind::Variant, _) => match ty.kind() {
|
||||||
|
|
|
@ -4,6 +4,7 @@ mod checks;
|
||||||
mod suggestions;
|
mod suggestions;
|
||||||
|
|
||||||
pub use _impl::*;
|
pub use _impl::*;
|
||||||
|
use rustc_errors::ErrorGuaranteed;
|
||||||
pub use suggestions::*;
|
pub use suggestions::*;
|
||||||
|
|
||||||
use crate::coercion::DynamicCoerceMany;
|
use crate::coercion::DynamicCoerceMany;
|
||||||
|
@ -289,8 +290,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_tainted_by_errors(&self) {
|
fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
|
||||||
self.infcx.set_tainted_by_errors()
|
self.infcx.set_tainted_by_errors(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
|
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ use crate::check::check_fn;
|
||||||
use crate::coercion::DynamicCoerceMany;
|
use crate::coercion::DynamicCoerceMany;
|
||||||
use crate::gather_locals::GatherLocalsVisitor;
|
use crate::gather_locals::GatherLocalsVisitor;
|
||||||
use rustc_data_structures::unord::UnordSet;
|
use rustc_data_structures::unord::UnordSet;
|
||||||
use rustc_errors::{struct_span_err, MultiSpan};
|
use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
|
@ -428,7 +428,12 @@ impl<'tcx> EnclosingBreakables<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'_>, span: Span) {
|
fn report_unexpected_variant_res(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
res: Res,
|
||||||
|
qpath: &hir::QPath<'_>,
|
||||||
|
span: Span,
|
||||||
|
) -> ErrorGuaranteed {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
span,
|
span,
|
||||||
|
@ -437,7 +442,7 @@ fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'
|
||||||
res.descr(),
|
res.descr(),
|
||||||
rustc_hir_pretty::qpath_to_string(qpath),
|
rustc_hir_pretty::qpath_to_string(qpath),
|
||||||
)
|
)
|
||||||
.emit();
|
.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Controls whether the arguments are tupled. This is used for the call
|
/// Controls whether the arguments are tupled. This is used for the call
|
||||||
|
|
|
@ -839,12 +839,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
let (res, opt_ty, segments) = path_resolution;
|
let (res, opt_ty, segments) = path_resolution;
|
||||||
match res {
|
match res {
|
||||||
Res::Err => {
|
Res::Err => {
|
||||||
self.set_tainted_by_errors();
|
let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted");
|
||||||
return tcx.ty_error();
|
self.set_tainted_by_errors(e);
|
||||||
|
return tcx.ty_error_with_guaranteed(e);
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
|
Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => {
|
||||||
report_unexpected_variant_res(tcx, res, qpath, pat.span);
|
let e = report_unexpected_variant_res(tcx, res, qpath, pat.span);
|
||||||
return tcx.ty_error();
|
return tcx.ty_error_with_guaranteed(e);
|
||||||
}
|
}
|
||||||
Res::SelfCtor(..)
|
Res::SelfCtor(..)
|
||||||
| Res::Def(
|
| Res::Def(
|
||||||
|
@ -985,9 +986,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
ti: TopInfo<'tcx>,
|
ti: TopInfo<'tcx>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let on_error = || {
|
let on_error = |e| {
|
||||||
for pat in subpats {
|
for pat in subpats {
|
||||||
self.check_pat(pat, tcx.ty_error(), def_bm, ti);
|
self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let report_unexpected_res = |res: Res| {
|
let report_unexpected_res = |res: Res| {
|
||||||
|
@ -1014,36 +1015,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
err.span_label(pat.span, "not a tuple variant or struct");
|
err.span_label(pat.span, "not a tuple variant or struct");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err.emit();
|
let e = err.emit();
|
||||||
on_error();
|
on_error(e);
|
||||||
|
e
|
||||||
};
|
};
|
||||||
|
|
||||||
// Resolve the path and check the definition for errors.
|
// Resolve the path and check the definition for errors.
|
||||||
let (res, opt_ty, segments) =
|
let (res, opt_ty, segments) =
|
||||||
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
|
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
|
||||||
if res == Res::Err {
|
if res == Res::Err {
|
||||||
self.set_tainted_by_errors();
|
let e = tcx.sess.delay_span_bug(pat.span, "`Res:Err` but no error emitted");
|
||||||
on_error();
|
self.set_tainted_by_errors(e);
|
||||||
return self.tcx.ty_error();
|
on_error(e);
|
||||||
|
return tcx.ty_error_with_guaranteed(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type-check the path.
|
// Type-check the path.
|
||||||
let (pat_ty, res) =
|
let (pat_ty, res) =
|
||||||
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
|
self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id);
|
||||||
if !pat_ty.is_fn() {
|
if !pat_ty.is_fn() {
|
||||||
report_unexpected_res(res);
|
let e = report_unexpected_res(res);
|
||||||
return tcx.ty_error();
|
return tcx.ty_error_with_guaranteed(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
let variant = match res {
|
let variant = match res {
|
||||||
Res::Err => {
|
Res::Err => {
|
||||||
self.set_tainted_by_errors();
|
let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted");
|
||||||
on_error();
|
self.set_tainted_by_errors(e);
|
||||||
return tcx.ty_error();
|
on_error(e);
|
||||||
|
return tcx.ty_error_with_guaranteed(e);
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
|
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => {
|
||||||
report_unexpected_res(res);
|
let e = report_unexpected_res(res);
|
||||||
return tcx.ty_error();
|
return tcx.ty_error_with_guaranteed(e);
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
|
Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res),
|
||||||
_ => bug!("unexpected pattern resolution: {:?}", res),
|
_ => bug!("unexpected pattern resolution: {:?}", res),
|
||||||
|
@ -1082,9 +1086,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Pattern has wrong number of fields.
|
// Pattern has wrong number of fields.
|
||||||
self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
|
let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err);
|
||||||
on_error();
|
on_error(e);
|
||||||
return tcx.ty_error();
|
return tcx.ty_error_with_guaranteed(e);
|
||||||
}
|
}
|
||||||
pat_ty
|
pat_ty
|
||||||
}
|
}
|
||||||
|
@ -1098,7 +1102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fields: &'tcx [ty::FieldDef],
|
fields: &'tcx [ty::FieldDef],
|
||||||
expected: Ty<'tcx>,
|
expected: Ty<'tcx>,
|
||||||
had_err: bool,
|
had_err: bool,
|
||||||
) {
|
) -> ErrorGuaranteed {
|
||||||
let subpats_ending = pluralize!(subpats.len());
|
let subpats_ending = pluralize!(subpats.len());
|
||||||
let fields_ending = pluralize!(fields.len());
|
let fields_ending = pluralize!(fields.len());
|
||||||
|
|
||||||
|
@ -1245,7 +1249,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err.emit();
|
err.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_pat_tuple(
|
fn check_pat_tuple(
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub use rustc_middle::ty::IntVarValue;
|
||||||
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
|
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
|
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::Span;
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -1224,8 +1224,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
|
||||||
if self.tcx.sess.err_count() > self.err_count_on_creation {
|
if self.tcx.sess.err_count() > self.err_count_on_creation {
|
||||||
// errors reported since this infcx was made
|
// errors reported since this infcx was made
|
||||||
self.set_tainted_by_errors();
|
let e = self.tcx.sess.has_errors().unwrap();
|
||||||
return self.tainted_by_errors.get();
|
self.set_tainted_by_errors(e);
|
||||||
|
return Some(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -1233,11 +1234,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
|
||||||
/// Set the "tainted by errors" flag to true. We call this when we
|
/// Set the "tainted by errors" flag to true. We call this when we
|
||||||
/// observe an error from a prior pass.
|
/// observe an error from a prior pass.
|
||||||
pub fn set_tainted_by_errors(&self) {
|
pub fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
|
||||||
debug!("set_tainted_by_errors()");
|
debug!("set_tainted_by_errors(ErrorGuaranteed)");
|
||||||
self.tainted_by_errors.set(Some(
|
self.tainted_by_errors.set(Some(e));
|
||||||
self.tcx.sess.delay_span_bug(DUMMY_SP, "`InferCtxt` incorrectly tainted by errors"),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn skip_region_resolution(&self) {
|
pub fn skip_region_resolution(&self) {
|
||||||
|
|
|
@ -116,9 +116,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
||||||
Ok(a)
|
Ok(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::Error(_), _) | (_, &ty::Error(_)) => {
|
(&ty::Error(e), _) | (_, &ty::Error(e)) => {
|
||||||
infcx.set_tainted_by_errors();
|
infcx.set_tainted_by_errors(e);
|
||||||
Ok(self.tcx().ty_error())
|
Ok(self.tcx().ty_error_with_guaranteed(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
|
(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
|
||||||
|
|
|
@ -532,9 +532,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
root_obligation: &PredicateObligation<'tcx>,
|
root_obligation: &PredicateObligation<'tcx>,
|
||||||
error: &SelectionError<'tcx>,
|
error: &SelectionError<'tcx>,
|
||||||
) {
|
) {
|
||||||
self.set_tainted_by_errors();
|
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let mut span = obligation.cause.span;
|
let mut span = obligation.cause.span;
|
||||||
|
// FIXME: statically guarantee this by tainting after the diagnostic is emitted
|
||||||
|
self.set_tainted_by_errors(
|
||||||
|
tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"),
|
||||||
|
);
|
||||||
|
|
||||||
let mut err = match *error {
|
let mut err = match *error {
|
||||||
SelectionError::Unimplemented => {
|
SelectionError::Unimplemented => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue