Skip to content

Commit d5e2221

Browse files
committed
overflow errors: change source to a concrete enum
1 parent e6d20c3 commit d5e2221

10 files changed

+100
-67
lines changed

compiler/rustc_trait_selection/src/solve/normalize.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::traits::error_reporting::TypeErrCtxtExt;
1+
use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt};
22
use crate::traits::query::evaluate_obligation::InferCtxtExt;
33
use crate::traits::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
44
use rustc_data_structures::stack::ensure_sufficient_stack;
@@ -60,8 +60,12 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
6060
let tcx = infcx.tcx;
6161
let recursion_limit = tcx.recursion_limit();
6262
if !recursion_limit.value_within_limit(self.depth) {
63+
let ty::Alias(_, data) = *alias_ty.kind() else {
64+
unreachable!();
65+
};
66+
6367
self.at.infcx.err_ctxt().report_overflow_error(
64-
&alias_ty,
68+
OverflowCause::DeeplyNormalize(data),
6569
self.at.cause.span,
6670
true,
6771
|_| {},
@@ -118,7 +122,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
118122
let recursion_limit = tcx.recursion_limit();
119123
if !recursion_limit.value_within_limit(self.depth) {
120124
self.at.infcx.err_ctxt().report_overflow_error(
121-
&ty::Const::new_unevaluated(tcx, uv, ty),
125+
OverflowCause::DeeplyNormalize(ty::AliasTy::new(tcx, uv.def, uv.args)),
122126
self.at.cause.span,
123127
true,
124128
|_| {},

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

+63-42
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,26 @@ use super::{
5555

5656
pub use rustc_infer::traits::error_reporting::*;
5757

58+
pub enum OverflowCause<'tcx> {
59+
DeeplyNormalize(ty::AliasTy<'tcx>),
60+
TraitSolver(ty::Predicate<'tcx>),
61+
}
62+
5863
pub trait TypeErrCtxtExt<'tcx> {
59-
fn build_overflow_error<T>(
64+
fn build_overflow_error(
6065
&self,
61-
predicate: &T,
66+
cause: OverflowCause<'tcx>,
6267
span: Span,
6368
suggest_increasing_limit: bool,
64-
) -> DiagnosticBuilder<'tcx>
65-
where
66-
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
69+
) -> DiagnosticBuilder<'tcx>;
6770

68-
fn report_overflow_error<T>(
71+
fn report_overflow_error(
6972
&self,
70-
predicate: &T,
73+
cause: OverflowCause<'tcx>,
7174
span: Span,
7275
suggest_increasing_limit: bool,
7376
mutate: impl FnOnce(&mut Diagnostic),
74-
) -> !
75-
where
76-
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>;
77+
) -> !;
7778

7879
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed;
7980

@@ -241,17 +242,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
241242
/// whose result could not be truly determined and thus we can't say
242243
/// if the program type checks or not -- and they are unusual
243244
/// occurrences in any case.
244-
fn report_overflow_error<T>(
245+
fn report_overflow_error(
245246
&self,
246-
predicate: &T,
247+
cause: OverflowCause<'tcx>,
247248
span: Span,
248249
suggest_increasing_limit: bool,
249250
mutate: impl FnOnce(&mut Diagnostic),
250-
) -> !
251-
where
252-
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
253-
{
254-
let mut err = self.build_overflow_error(predicate, span, suggest_increasing_limit);
251+
) -> ! {
252+
let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit);
255253
mutate(&mut err);
256254
err.emit();
257255

@@ -264,33 +262,52 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
264262
);
265263
}
266264

267-
fn build_overflow_error<T>(
265+
fn build_overflow_error(
268266
&self,
269-
predicate: &T,
267+
cause: OverflowCause<'tcx>,
270268
span: Span,
271269
suggest_increasing_limit: bool,
272-
) -> DiagnosticBuilder<'tcx>
273-
where
274-
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
275-
{
276-
let predicate = self.resolve_vars_if_possible(predicate.clone());
277-
let mut pred_str = predicate.to_string();
278-
279-
if pred_str.len() > 50 {
280-
// We don't need to save the type to a file, we will be talking about this type already
281-
// in a separate note when we explain the obligation, so it will be available that way.
282-
let mut cx: FmtPrinter<'_, '_> =
283-
FmtPrinter::new_with_limit(self.tcx, Namespace::TypeNS, rustc_session::Limit(6));
284-
predicate.print(&mut cx).unwrap();
285-
pred_str = cx.into_buffer();
270+
) -> DiagnosticBuilder<'tcx> {
271+
fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String
272+
where
273+
T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
274+
{
275+
let s = value.to_string();
276+
if s.len() > 50 {
277+
// We don't need to save the type to a file, we will be talking about this type already
278+
// in a separate note when we explain the obligation, so it will be available that way.
279+
let mut cx: FmtPrinter<'_, '_> =
280+
FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6));
281+
value.print(&mut cx).unwrap();
282+
cx.into_buffer()
283+
} else {
284+
s
285+
}
286286
}
287-
let mut err = struct_span_code_err!(
288-
self.dcx(),
289-
span,
290-
E0275,
291-
"overflow evaluating the requirement `{}`",
292-
pred_str,
293-
);
287+
288+
let mut err = match cause {
289+
OverflowCause::DeeplyNormalize(alias_ty) => {
290+
let alias_ty = self.resolve_vars_if_possible(alias_ty);
291+
let kind = alias_ty.opt_kind(self.tcx).map_or("alias", |k| k.descr());
292+
let alias_str = with_short_path(self.tcx, alias_ty);
293+
struct_span_code_err!(
294+
self.dcx(),
295+
span,
296+
E0275,
297+
"overflow normalizing the {kind} `{alias_str}`",
298+
)
299+
}
300+
OverflowCause::TraitSolver(predicate) => {
301+
let predicate = self.resolve_vars_if_possible(predicate);
302+
let pred_str = with_short_path(self.tcx, predicate);
303+
struct_span_code_err!(
304+
self.dcx(),
305+
span,
306+
E0275,
307+
"overflow evaluating the requirement `{pred_str}`",
308+
)
309+
}
310+
};
294311

295312
if suggest_increasing_limit {
296313
self.suggest_new_overflow_limit(&mut err);
@@ -316,7 +333,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
316333
let predicate = obligation.predicate.clone().to_predicate(self.tcx);
317334
let predicate = self.resolve_vars_if_possible(predicate);
318335
self.report_overflow_error(
319-
&predicate,
336+
OverflowCause::TraitSolver(predicate),
320337
obligation.cause.span,
321338
suggest_increasing_limit,
322339
|err| {
@@ -367,7 +384,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
367384

368385
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed {
369386
let obligation = self.resolve_vars_if_possible(obligation);
370-
let mut err = self.build_overflow_error(&obligation.predicate, obligation.cause.span, true);
387+
let mut err = self.build_overflow_error(
388+
OverflowCause::TraitSolver(obligation.predicate),
389+
obligation.cause.span,
390+
true,
391+
);
371392
self.note_obligation_cause(&mut err, &obligation);
372393
self.point_at_returns_when_relevant(&mut err, &obligation);
373394
err.emit()

compiler/rustc_trait_selection/src/traits/fulfill.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
435435
.recursion_limit()
436436
.value_within_limit(obligation.recursion_depth) =>
437437
{
438-
self.selcx.infcx.err_ctxt().report_overflow_error(
439-
&obligation.predicate,
440-
obligation.cause.span,
441-
false,
442-
|_| {},
443-
);
438+
self.selcx.infcx.err_ctxt().report_overflow_obligation(&obligation, false);
444439
}
445440

446441
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {

compiler/rustc_trait_selection/src/traits/project.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Code for projecting associated types out of trait references.
22
33
use super::check_args_compatible;
4+
use super::error_reporting::OverflowCause;
45
use super::specialization_graph;
56
use super::translate_args;
67
use super::util;
@@ -516,10 +517,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
516517
return ty;
517518
}
518519

519-
let (kind, data) = match *ty.kind() {
520-
ty::Alias(kind, alias_ty) => (kind, alias_ty),
521-
_ => return ty.super_fold_with(self),
522-
};
520+
let ty::Alias(kind, data) = *ty.kind() else { return ty.super_fold_with(self) };
523521

524522
// We try to be a little clever here as a performance optimization in
525523
// cases where there are nested projections under binders.
@@ -554,7 +552,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
554552
let recursion_limit = self.interner().recursion_limit();
555553
if !recursion_limit.value_within_limit(self.depth) {
556554
self.selcx.infcx.err_ctxt().report_overflow_error(
557-
&ty,
555+
OverflowCause::DeeplyNormalize(data),
558556
self.cause.span,
559557
true,
560558
|_| {},
@@ -664,7 +662,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
664662
let recursion_limit = self.interner().recursion_limit();
665663
if !recursion_limit.value_within_limit(self.depth) {
666664
self.selcx.infcx.err_ctxt().report_overflow_error(
667-
&ty,
665+
OverflowCause::DeeplyNormalize(data),
668666
self.cause.span,
669667
false,
670668
|diag| {

compiler/rustc_trait_selection/src/traits/query/normalize.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use crate::infer::at::At;
66
use crate::infer::canonical::OriginalQueryValues;
77
use crate::infer::{InferCtxt, InferOk};
8-
use crate::traits::error_reporting::TypeErrCtxtExt;
8+
use crate::traits::error_reporting::{OverflowCause, TypeErrCtxtExt};
99
use crate::traits::project::{needs_normalization, BoundVarReplacer, PlaceholderReplacer};
1010
use crate::traits::{ObligationCause, PredicateObligation, Reveal};
1111
use rustc_data_structures::sso::SsoHashMap;
@@ -233,7 +233,11 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
233233
let guar = self
234234
.infcx
235235
.err_ctxt()
236-
.build_overflow_error(&ty, self.cause.span, true)
236+
.build_overflow_error(
237+
OverflowCause::DeeplyNormalize(data),
238+
self.cause.span,
239+
true,
240+
)
237241
.delay_as_bug();
238242
return Ok(Ty::new_error(self.interner(), guar));
239243
}

compiler/rustc_type_ir/src/ty_kind.rs

+11
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,17 @@ pub enum AliasKind {
105105
Weak,
106106
}
107107

108+
impl AliasKind {
109+
pub fn descr(self) -> &'static str {
110+
match self {
111+
AliasKind::Projection => "associated type",
112+
AliasKind::Inherent => "inherent associated type",
113+
AliasKind::Opaque => "opaque type",
114+
AliasKind::Weak => "type alias",
115+
}
116+
}
117+
}
118+
108119
/// Defines the kinds of types used by the type system.
109120
///
110121
/// Types written by the user start out as `hir::TyKind` and get

tests/ui/infinite/infinite-type-alias-mutual-recursion.feature.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
error[E0275]: overflow evaluating the requirement `X2`
1+
error[E0275]: overflow normalizing the type alias `X2`
22
--> $DIR/infinite-type-alias-mutual-recursion.rs:6:11
33
|
44
LL | type X1 = X2;
55
| ^^
66
|
77
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
88

9-
error[E0275]: overflow evaluating the requirement `X3`
9+
error[E0275]: overflow normalizing the type alias `X3`
1010
--> $DIR/infinite-type-alias-mutual-recursion.rs:9:11
1111
|
1212
LL | type X2 = X3;
1313
| ^^
1414
|
1515
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
1616

17-
error[E0275]: overflow evaluating the requirement `X1`
17+
error[E0275]: overflow normalizing the type alias `X1`
1818
--> $DIR/infinite-type-alias-mutual-recursion.rs:11:11
1919
|
2020
LL | type X3 = X1;

tests/ui/infinite/infinite-type-alias-mutual-recursion.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
type X1 = X2;
77
//[gated]~^ ERROR cycle detected when expanding type alias `X1`
8-
//[feature]~^^ ERROR: overflow evaluating the requirement `X2`
8+
//[feature]~^^ ERROR: overflow normalizing the type alias `X2`
99
type X2 = X3;
10-
//[feature]~^ ERROR: overflow evaluating the requirement `X3`
10+
//[feature]~^ ERROR: overflow normalizing the type alias `X3`
1111
type X3 = X1;
12-
//[feature]~^ ERROR: overflow evaluating the requirement `X1`
12+
//[feature]~^ ERROR: overflow normalizing the type alias `X1`
1313

1414
fn main() {}

tests/ui/infinite/infinite-vec-type-recursion.feature.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0275]: overflow evaluating the requirement `X`
1+
error[E0275]: overflow normalizing the type alias `X`
22
--> $DIR/infinite-vec-type-recursion.rs:6:10
33
|
44
LL | type X = Vec<X>;

tests/ui/infinite/infinite-vec-type-recursion.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
type X = Vec<X>;
77
//[gated]~^ ERROR cycle detected
8-
//[feature]~^^ ERROR: overflow evaluating the requirement `X`
8+
//[feature]~^^ ERROR: overflow normalizing the type alias `X`
99

1010
#[rustfmt::skip]
1111
fn main() { let b: X = Vec::new(); }

0 commit comments

Comments
 (0)