1
Fork 0

Introduce TypeErrCtxt

TypeErrCtxt optionally has a TypeckResults so that InferCtxt doesn't
need to.
This commit is contained in:
Cameron Steffen 2022-09-09 15:08:06 -05:00
parent 5854680388
commit 4a68373217
42 changed files with 655 additions and 589 deletions

View file

@ -29,7 +29,7 @@ use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVE
use rustc_span::symbol::sym;
use rustc_span::{self, Span};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCtxt};
use rustc_ty_utils::representability::{self, Representability};
@ -760,7 +760,7 @@ fn check_opaque_meets_bounds<'tcx>(
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
}
match origin {
// Checked when type checking the function containing them.

View file

@ -61,7 +61,7 @@ use rustc_span::symbol::sym;
use rustc_span::{self, BytePos, DesugaringKind, Span};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
use smallvec::{smallvec, SmallVec};
@ -702,7 +702,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// Object safety violations or miscellaneous.
Err(err) => {
self.report_selection_error(obligation.clone(), &obligation, &err, false);
self.err_ctxt().report_selection_error(
obligation.clone(),
&obligation,
&err,
false,
);
// Treat this like an obligation and follow through
// with the unsizing - the lack of a coercion should
// be silent, as it causes a type mismatch later.
@ -1549,7 +1554,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}
}
_ => {
err = fcx.report_mismatched_types(
err = fcx.err_ctxt().report_mismatched_types(
cause,
expected,
found,
@ -1629,7 +1634,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
expression: Option<&'tcx hir::Expr<'tcx>>,
blk_id: Option<hir::HirId>,
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err);
let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
let mut pointing_at_return_type = false;
let mut fn_output = None;

View file

@ -19,7 +19,7 @@ use rustc_middle::ty::{
};
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, ObligationCtxt, Reveal,
@ -395,7 +395,7 @@ fn compare_predicate_entailment<'tcx>(
_ => {}
}
infcx.note_type_err(
infcx.err_ctxt().note_type_err(
&mut diag,
&cause,
trait_err_span.map(|sp| (sp, "type in trait".to_owned())),
@ -415,7 +415,7 @@ fn compare_predicate_entailment<'tcx>(
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
let reported = infcx.report_fulfillment_errors(&errors, None, false);
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
return Err(reported);
}
@ -508,7 +508,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
trait_m.name
);
let hir = tcx.hir();
infcx.note_type_err(
infcx.err_ctxt().note_type_err(
&mut diag,
&cause,
hir.get_if_local(impl_m.def_id)
@ -530,7 +530,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
// RPITs.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
let reported = infcx.report_fulfillment_errors(&errors, None, false);
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
return Err(reported);
}
@ -1382,7 +1382,7 @@ pub(crate) fn raw_compare_const_impl<'tcx>(
}
});
infcx.note_type_err(
infcx.err_ctxt().note_type_err(
&mut diag,
&cause,
trait_c_span.map(|span| (span, "type in trait".to_owned())),
@ -1401,7 +1401,7 @@ pub(crate) fn raw_compare_const_impl<'tcx>(
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
return Err(infcx.report_fulfillment_errors(&errors, None, false));
return Err(infcx.err_ctxt().report_fulfillment_errors(&errors, None, false));
}
// FIXME return `ErrorReported` if region obligations error?
@ -1522,7 +1522,7 @@ fn compare_type_predicate_entailment<'tcx>(
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
let reported = infcx.report_fulfillment_errors(&errors, None, false);
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
return Err(reported);
}
@ -1751,7 +1751,7 @@ pub fn check_type_bounds<'tcx>(
// version.
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
let reported = infcx.report_fulfillment_errors(&errors, None, false);
let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
return Err(reported);
}
@ -1769,6 +1769,7 @@ pub fn check_type_bounds<'tcx>(
let constraints = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
for (key, value) in constraints {
infcx
.err_ctxt()
.report_mismatched_types(
&ObligationCause::misc(
value.hidden_type.span,

View file

@ -79,7 +79,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.register_predicates(obligations);
None
}
Err(e) => Some(self.report_mismatched_types(&cause, expected, actual, e)),
Err(e) => Some(self.err_ctxt().report_mismatched_types(&cause, expected, actual, e)),
}
}
@ -109,7 +109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.register_predicates(obligations);
None
}
Err(e) => Some(self.report_mismatched_types(cause, expected, actual, e)),
Err(e) => Some(self.err_ctxt().report_mismatched_types(cause, expected, actual, e)),
}
}
@ -153,7 +153,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let expr = expr.peel_drop_temps();
let cause = self.misc(expr.span);
let expr_ty = self.resolve_vars_with_obligations(checked_ty);
let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e.clone());
let mut err = self.err_ctxt().report_mismatched_types(&cause, expected, expr_ty, e.clone());
let is_insufficiently_polymorphic =
matches!(e, TypeError::RegionsInsufficientlyPolymorphic(..));

View file

@ -1649,13 +1649,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Err(_) => {
// This should never happen, since we're just subtyping the
// remaining_fields, but it's fine to emit this, I guess.
self.report_mismatched_types(
&cause,
target_ty,
fru_ty,
FieldMisMatch(variant.name, ident.name),
)
.emit();
self.err_ctxt()
.report_mismatched_types(
&cause,
target_ty,
fru_ty,
FieldMisMatch(variant.name, ident.name),
)
.emit();
}
}
}
@ -1942,7 +1943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.set_tainted_by_errors();
return;
}
let mut err = self.type_error_struct_with_diag(
let mut err = self.err_ctxt().type_error_struct_with_diag(
field.ident.span,
|actual| match ty.kind() {
ty::Adt(adt, ..) if adt.is_enum() => struct_span_err!(

View file

@ -32,7 +32,7 @@ use rustc_span::hygiene::DesugaringKind;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
};
@ -615,7 +615,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !errors.is_empty() {
self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
self.report_fulfillment_errors(&errors, self.inh.body_id, false);
self.err_ctxt().report_fulfillment_errors(&errors, self.inh.body_id, false);
}
}
@ -629,7 +629,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if !result.is_empty() {
mutate_fulfillment_errors(&mut result);
self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
self.report_fulfillment_errors(&result, self.inh.body_id, fallback_has_occurred);
self.err_ctxt().report_fulfillment_errors(
&result,
self.inh.body_id,
fallback_has_occurred,
);
}
}
@ -1466,7 +1470,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty
} else {
if !self.is_tainted_by_errors() {
self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
self.err_ctxt()
.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
.emit();
}
let err = self.tcx.ty_error();

View file

@ -650,7 +650,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if tys.len() == 1 {
// A tuple wrap suggestion actually occurs within,
// so don't do anything special here.
err = self.report_and_explain_type_error(
err = self.err_ctxt().report_and_explain_type_error(
TypeTrace::types(
&self.misc(*lo),
true,
@ -742,7 +742,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
if !matches!(trace.cause.as_failure_code(*e), FailureCode::Error0308(_)) {
self.report_and_explain_type_error(trace, *e).emit();
self.err_ctxt().report_and_explain_type_error(trace, *e).emit();
return true;
}
false
@ -766,7 +766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
let cause = &self.misc(provided_arg_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
let mut err = self.report_and_explain_type_error(trace, *err);
let mut err = self.err_ctxt().report_and_explain_type_error(trace, *err);
self.emit_coerce_suggestions(
&mut err,
&provided_args[*provided_idx],
@ -840,7 +840,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let cause = &self.misc(provided_span);
let trace = TypeTrace::types(cause, true, expected_ty, provided_ty);
if let Some(e) = error {
self.note_type_err(
self.err_ctxt().note_type_err(
&mut err,
&trace.cause,
None,
@ -1474,7 +1474,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut |err| {
if let Some(expected_ty) = expected.only_has_type(self) {
if !self.consider_removing_semicolon(blk, expected_ty, err) {
self.consider_returning_binding(blk, expected_ty, err);
self.err_ctxt().consider_returning_binding(
blk,
expected_ty,
err,
);
}
if expected_ty == self.tcx.types.bool {
// If this is caused by a missing `let` in a `while let`,

View file

@ -13,6 +13,7 @@ use crate::check::{Diverges, EnclosingBreakables, Inherited, UnsafetyState};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::subst::GenericArgKind;
@ -168,6 +169,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self.tcx.sess
}
/// Creates an `TypeErrCtxt` with a reference to the in-progress
/// `TypeckResults` which is used for diagnostics.
/// Use [`InferCtxt::err_ctxt`] to start one without a `TypeckResults`.
///
/// [`InferCtxt::err_ctxt`]: infer::InferCtxt::err_ctxt
pub fn err_ctxt(&'a self) -> TypeErrCtxt<'a, 'tcx> {
TypeErrCtxt { infcx: &self.infcx, typeck_results: Some(self.typeck_results.borrow()) }
}
pub fn errors_reported_since_creation(&self) -> bool {
self.tcx.sess.err_count() > self.err_count_on_creation
}

View file

@ -1037,7 +1037,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We'll later suggest `.as_ref` when noting the type error,
// so skip if we will suggest that instead.
if self.should_suggest_as_ref(expected_ty, expr_ty).is_some() {
if self.err_ctxt().should_suggest_as_ref(expected_ty, expr_ty).is_some() {
return false;
}
@ -1187,7 +1187,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expected_ty: Ty<'tcx>,
err: &mut Diagnostic,
) -> bool {
if let Some((span_semi, boxed)) = self.could_remove_semicolon(blk, expected_ty) {
if let Some((span_semi, boxed)) = self.err_ctxt().could_remove_semicolon(blk, expected_ty) {
if let StatementAsExpression::NeedsBoxing = boxed {
err.span_suggestion_verbose(
span_semi,

View file

@ -78,7 +78,7 @@ impl<'a, 'tcx> Deref for Inherited<'a, 'tcx> {
}
/// A temporary returned by `Inherited::build(...)`. This is necessary
/// for multiple `InferCtxt` to share the same `in_progress_typeck_results`
/// for multiple `InferCtxt` to share the same `typeck_results`
/// without using `Rc` or something similar.
pub struct InheritedBuilder<'tcx> {
infcx: infer::InferCtxtBuilder<'tcx>,

View file

@ -22,7 +22,7 @@ use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Symbol;
use rustc_span::{lev_distance, source_map, ExpnKind, FileName, MacroKind, Span};
use rustc_trait_selection::traits::error_reporting::on_unimplemented::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{
FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, OnUnimplementedNote,
@ -855,8 +855,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Avoid crashing.
return (None, None);
}
let OnUnimplementedNote { message, label, .. } =
self.on_unimplemented_note(trait_ref, &obligation);
let OnUnimplementedNote { message, label, .. } = self
.err_ctxt()
.on_unimplemented_note(trait_ref, &obligation);
(message, label)
})
.unwrap_or((None, None))

View file

@ -18,7 +18,7 @@ use rustc_span::source_map::Spanned;
use rustc_span::symbol::{sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt};
use rustc_type_ir::sty::TyKind::*;
@ -512,7 +512,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => None,
};
self.suggest_restricting_param_bound(
self.err_ctxt().suggest_restricting_param_bound(
&mut err,
trait_pred,
output_associated_item,
@ -662,7 +662,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
error.obligation.predicate.to_opt_poly_trait_pred()
});
for pred in predicates {
self.suggest_restricting_param_bound(
self.err_ctxt().suggest_restricting_param_bound(
&mut err,
pred,
None,

View file

@ -22,7 +22,7 @@ use rustc_session::parse::feature_err;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::autoderef::Autoderef;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_trait_selection::traits::{
@ -104,7 +104,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
f(&mut wfcx);
let errors = wfcx.select_all_or_error();
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
return;
}
@ -1677,7 +1677,7 @@ fn receiver_is_valid<'tcx>(
// `self: Self` is always valid.
if can_eq_self(receiver_ty) {
if let Err(err) = wfcx.equate_types(&cause, wfcx.param_env, self_ty, receiver_ty) {
infcx.report_mismatched_types(&cause, self_ty, receiver_ty, err).emit();
infcx.err_ctxt().report_mismatched_types(&cause, self_ty, receiver_ty, err).emit();
}
return true;
}
@ -1709,7 +1709,10 @@ fn receiver_is_valid<'tcx>(
if let Err(err) =
wfcx.equate_types(&cause, wfcx.param_env, self_ty, potential_self_ty)
{
infcx.report_mismatched_types(&cause, self_ty, potential_self_ty, err).emit();
infcx
.err_ctxt()
.report_mismatched_types(&cause, self_ty, potential_self_ty, err)
.emit();
}
break;

View file

@ -720,6 +720,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) {
if !self.tcx.sess.has_errors().is_some() {
self.infcx
.err_ctxt()
.emit_inference_failure_err(
Some(self.body.id()),
self.span.to_span(self.tcx),

View file

@ -12,7 +12,7 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::TyCtxtInferExt;
use rustc_middle::ty::adjustment::CoerceUnsizedInfo;
use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitable};
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::misc::{can_type_implement_copy, CopyImplementationError};
use rustc_trait_selection::traits::predicate_for_trait_def;
use rustc_trait_selection::traits::{self, ObligationCause};
@ -324,7 +324,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
}),
);
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
}
// Finally, resolve all regions.
@ -377,6 +377,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
mk_ptr: &dyn Fn(Ty<'tcx>) -> Ty<'tcx>| {
if (mt_a.mutbl, mt_b.mutbl) == (hir::Mutability::Not, hir::Mutability::Mut) {
infcx
.err_ctxt()
.report_mismatched_types(
&cause,
mk_ptr(mt_b.ty),
@ -576,7 +577,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
);
let errors = traits::fully_solve_obligation(&infcx, predicate);
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
}
// Finally, resolve all regions.

View file

@ -77,7 +77,7 @@ use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
use rustc_span::Span;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_trait_selection::traits::{self, translate_substs, wf, ObligationCtxt};
@ -153,7 +153,7 @@ fn get_impl_substs<'tcx>(
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
ocx.infcx.report_fulfillment_errors(&errors, None, false);
ocx.infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
return None;
}

View file

@ -110,7 +110,7 @@ use rustc_middle::util;
use rustc_session::config::EntryFnType;
use rustc_span::{symbol::sym, Span, DUMMY_SP};
use rustc_target::spec::abi::Abi;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode};
use std::iter;
@ -146,7 +146,7 @@ fn require_same_types<'tcx>(
let errors = match infcx.at(cause, param_env).eq(expected, actual) {
Ok(InferOk { obligations, .. }) => traits::fully_solve_obligations(infcx, obligations),
Err(err) => {
infcx.report_mismatched_types(cause, expected, actual, err).emit();
infcx.err_ctxt().report_mismatched_types(cause, expected, actual, err).emit();
return false;
}
};
@ -154,7 +154,7 @@ fn require_same_types<'tcx>(
match &errors[..] {
[] => true,
errors => {
infcx.report_fulfillment_errors(errors, None, false);
infcx.err_ctxt().report_fulfillment_errors(errors, None, false);
false
}
}
@ -318,7 +318,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.report_fulfillment_errors(&errors, None, false);
infcx.err_ctxt().report_fulfillment_errors(&errors, None, false);
error = true;
}
});