overflow errors: change source to a concrete enum
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use crate::traits::error_reporting::TypeErrCtxtExt;
|
||||
use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt};
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
@@ -60,8 +60,12 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
|
||||
let tcx = infcx.tcx;
|
||||
let recursion_limit = tcx.recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
let ty::Alias(_, data) = *alias_ty.kind() else {
|
||||
unreachable!();
|
||||
};
|
||||
|
||||
self.at.infcx.err_ctxt().report_overflow_error(
|
||||
&alias_ty,
|
||||
OverflowCause::DeeplyNormalize(data),
|
||||
self.at.cause.span,
|
||||
true,
|
||||
|_| {},
|
||||
@@ -109,7 +113,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
|
||||
let recursion_limit = tcx.recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
self.at.infcx.err_ctxt().report_overflow_error(
|
||||
&ty::Const::new_unevaluated(tcx, uv, ty),
|
||||
OverflowCause::DeeplyNormalize(ty::AliasTy::new(tcx, uv.def, uv.args)),
|
||||
self.at.cause.span,
|
||||
true,
|
||||
|_| {},
|
||||
|
||||
@@ -57,6 +57,11 @@ use super::{
|
||||
|
||||
pub use rustc_infer::traits::error_reporting::*;
|
||||
|
||||
pub enum OverflowCause<'tcx> {
|
||||
DeeplyNormalize(ty::AliasTy<'tcx>),
|
||||
TraitSolver(ty::Predicate<'tcx>),
|
||||
}
|
||||
|
||||
#[extension(pub trait TypeErrCtxtExt<'tcx>)]
|
||||
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
fn report_fulfillment_errors(
|
||||
@@ -184,49 +189,65 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
/// whose result could not be truly determined and thus we can't say
|
||||
/// if the program type checks or not -- and they are unusual
|
||||
/// occurrences in any case.
|
||||
fn report_overflow_error<T>(
|
||||
fn report_overflow_error(
|
||||
&self,
|
||||
predicate: &T,
|
||||
cause: OverflowCause<'tcx>,
|
||||
span: Span,
|
||||
suggest_increasing_limit: bool,
|
||||
mutate: impl FnOnce(&mut DiagnosticBuilder<'_>),
|
||||
) -> !
|
||||
where
|
||||
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
|
||||
{
|
||||
let mut err = self.build_overflow_error(predicate, span, suggest_increasing_limit);
|
||||
) -> ! {
|
||||
let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit);
|
||||
mutate(&mut err);
|
||||
err.emit();
|
||||
FatalError.raise();
|
||||
}
|
||||
|
||||
fn build_overflow_error<T>(
|
||||
fn build_overflow_error(
|
||||
&self,
|
||||
predicate: &T,
|
||||
cause: OverflowCause<'tcx>,
|
||||
span: Span,
|
||||
suggest_increasing_limit: bool,
|
||||
) -> DiagnosticBuilder<'tcx>
|
||||
where
|
||||
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
|
||||
{
|
||||
let predicate = self.resolve_vars_if_possible(predicate.clone());
|
||||
let mut pred_str = predicate.to_string();
|
||||
|
||||
if pred_str.len() > 50 {
|
||||
// We don't need to save the type to a file, we will be talking about this type already
|
||||
// in a separate note when we explain the obligation, so it will be available that way.
|
||||
let mut cx: FmtPrinter<'_, '_> =
|
||||
FmtPrinter::new_with_limit(self.tcx, Namespace::TypeNS, rustc_session::Limit(6));
|
||||
predicate.print(&mut cx).unwrap();
|
||||
pred_str = cx.into_buffer();
|
||||
) -> DiagnosticBuilder<'tcx> {
|
||||
fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String
|
||||
where
|
||||
T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
|
||||
{
|
||||
let s = value.to_string();
|
||||
if s.len() > 50 {
|
||||
// We don't need to save the type to a file, we will be talking about this type already
|
||||
// in a separate note when we explain the obligation, so it will be available that way.
|
||||
let mut cx: FmtPrinter<'_, '_> =
|
||||
FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6));
|
||||
value.print(&mut cx).unwrap();
|
||||
cx.into_buffer()
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
let mut err = struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
E0275,
|
||||
"overflow evaluating the requirement `{}`",
|
||||
pred_str,
|
||||
);
|
||||
|
||||
let mut err = match cause {
|
||||
OverflowCause::DeeplyNormalize(alias_ty) => {
|
||||
let alias_ty = self.resolve_vars_if_possible(alias_ty);
|
||||
let kind = alias_ty.opt_kind(self.tcx).map_or("alias", |k| k.descr());
|
||||
let alias_str = with_short_path(self.tcx, alias_ty);
|
||||
struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
E0275,
|
||||
"overflow normalizing the {kind} `{alias_str}`",
|
||||
)
|
||||
}
|
||||
OverflowCause::TraitSolver(predicate) => {
|
||||
let predicate = self.resolve_vars_if_possible(predicate);
|
||||
let pred_str = with_short_path(self.tcx, predicate);
|
||||
struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
E0275,
|
||||
"overflow evaluating the requirement `{pred_str}`",
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
if suggest_increasing_limit {
|
||||
self.suggest_new_overflow_limit(&mut err);
|
||||
@@ -252,7 +273,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
let predicate = obligation.predicate.clone().to_predicate(self.tcx);
|
||||
let predicate = self.resolve_vars_if_possible(predicate);
|
||||
self.report_overflow_error(
|
||||
&predicate,
|
||||
OverflowCause::TraitSolver(predicate),
|
||||
obligation.cause.span,
|
||||
suggest_increasing_limit,
|
||||
|err| {
|
||||
@@ -303,7 +324,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed {
|
||||
let obligation = self.resolve_vars_if_possible(obligation);
|
||||
let mut err = self.build_overflow_error(&obligation.predicate, obligation.cause.span, true);
|
||||
let mut err = self.build_overflow_error(
|
||||
OverflowCause::TraitSolver(obligation.predicate),
|
||||
obligation.cause.span,
|
||||
true,
|
||||
);
|
||||
self.note_obligation_cause(&mut err, &obligation);
|
||||
self.point_at_returns_when_relevant(&mut err, &obligation);
|
||||
err.emit()
|
||||
|
||||
@@ -450,12 +450,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
.recursion_limit()
|
||||
.value_within_limit(obligation.recursion_depth) =>
|
||||
{
|
||||
self.selcx.infcx.err_ctxt().report_overflow_error(
|
||||
&obligation.predicate,
|
||||
obligation.cause.span,
|
||||
false,
|
||||
|_| {},
|
||||
);
|
||||
self.selcx.infcx.err_ctxt().report_overflow_obligation(&obligation, false);
|
||||
}
|
||||
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
//! Deeply normalize types using the old trait solver.
|
||||
use super::error_reporting::OverflowCause;
|
||||
use super::error_reporting::TypeErrCtxtExt;
|
||||
use super::SelectionContext;
|
||||
use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_infer::infer::at::At;
|
||||
use rustc_infer::infer::InferOk;
|
||||
@@ -8,10 +12,6 @@ use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFolder};
|
||||
use rustc_middle::ty::{TypeFoldable, TypeSuperFoldable, TypeVisitable, TypeVisitableExt};
|
||||
|
||||
use super::error_reporting::TypeErrCtxtExt;
|
||||
use super::SelectionContext;
|
||||
use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
|
||||
|
||||
#[extension(pub trait NormalizeExt<'tcx>)]
|
||||
impl<'tcx> At<'_, 'tcx> {
|
||||
/// Normalize a value using the `AssocTypeNormalizer`.
|
||||
@@ -173,7 +173,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
||||
}
|
||||
|
||||
let (kind, data) = match *ty.kind() {
|
||||
ty::Alias(kind, alias_ty) => (kind, alias_ty),
|
||||
ty::Alias(kind, data) => (kind, data),
|
||||
_ => return ty.super_fold_with(self),
|
||||
};
|
||||
|
||||
@@ -210,7 +210,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
||||
let recursion_limit = self.interner().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
self.selcx.infcx.err_ctxt().report_overflow_error(
|
||||
&ty,
|
||||
OverflowCause::DeeplyNormalize(data),
|
||||
self.cause.span,
|
||||
true,
|
||||
|_| {},
|
||||
@@ -306,7 +306,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
|
||||
let recursion_limit = self.interner().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
self.selcx.infcx.err_ctxt().report_overflow_error(
|
||||
&ty,
|
||||
OverflowCause::DeeplyNormalize(data),
|
||||
self.cause.span,
|
||||
false,
|
||||
|diag| {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
use crate::infer::at::At;
|
||||
use crate::infer::canonical::OriginalQueryValues;
|
||||
use crate::infer::{InferCtxt, InferOk};
|
||||
use crate::traits::error_reporting::OverflowCause;
|
||||
use crate::traits::error_reporting::TypeErrCtxtExt;
|
||||
use crate::traits::normalize::needs_normalization;
|
||||
use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
|
||||
@@ -228,7 +229,11 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
|
||||
let guar = self
|
||||
.infcx
|
||||
.err_ctxt()
|
||||
.build_overflow_error(&ty, self.cause.span, true)
|
||||
.build_overflow_error(
|
||||
OverflowCause::DeeplyNormalize(data),
|
||||
self.cause.span,
|
||||
true,
|
||||
)
|
||||
.delay_as_bug();
|
||||
return Ok(Ty::new_error(self.interner(), guar));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user