Skip to content

Commit 6fe47bd

Browse files
committed
overflow errors: change source to a concrete enum
1 parent f5adda2 commit 6fe47bd

File tree

10 files changed

+97
-57
lines changed

10 files changed

+97
-57
lines changed

compiler/rustc_trait_selection/src/solve/normalize.rs

Lines changed: 7 additions & 3 deletions
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::{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

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ use super::{
5757

5858
pub use rustc_infer::traits::error_reporting::*;
5959

60+
pub enum OverflowCause<'tcx> {
61+
DeeplyNormalize(ty::AliasTy<'tcx>),
62+
TraitSolver(ty::Predicate<'tcx>),
63+
}
64+
6065
#[extension(pub trait TypeErrCtxtExt<'tcx>)]
6166
impl<'tcx> TypeErrCtxt<'_, 'tcx> {
6267
fn report_fulfillment_errors(
@@ -184,17 +189,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
184189
/// whose result could not be truly determined and thus we can't say
185190
/// if the program type checks or not -- and they are unusual
186191
/// occurrences in any case.
187-
fn report_overflow_error<T>(
192+
fn report_overflow_error(
188193
&self,
189-
predicate: &T,
194+
cause: OverflowCause<'tcx>,
190195
span: Span,
191196
suggest_increasing_limit: bool,
192197
mutate: impl FnOnce(&mut Diagnostic),
193-
) -> !
194-
where
195-
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
196-
{
197-
let mut err = self.build_overflow_error(predicate, span, suggest_increasing_limit);
198+
) -> ! {
199+
let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit);
198200
mutate(&mut err);
199201
err.emit();
200202

@@ -207,33 +209,52 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
207209
);
208210
}
209211

210-
fn build_overflow_error<T>(
212+
fn build_overflow_error(
211213
&self,
212-
predicate: &T,
214+
cause: OverflowCause<'tcx>,
213215
span: Span,
214216
suggest_increasing_limit: bool,
215-
) -> DiagnosticBuilder<'tcx>
216-
where
217-
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
218-
{
219-
let predicate = self.resolve_vars_if_possible(predicate.clone());
220-
let mut pred_str = predicate.to_string();
221-
222-
if pred_str.len() > 50 {
223-
// We don't need to save the type to a file, we will be talking about this type already
224-
// in a separate note when we explain the obligation, so it will be available that way.
225-
let mut cx: FmtPrinter<'_, '_> =
226-
FmtPrinter::new_with_limit(self.tcx, Namespace::TypeNS, rustc_session::Limit(6));
227-
predicate.print(&mut cx).unwrap();
228-
pred_str = cx.into_buffer();
217+
) -> DiagnosticBuilder<'tcx> {
218+
fn with_short_path<'tcx, T>(tcx: TyCtxt<'tcx>, value: T) -> String
219+
where
220+
T: fmt::Display + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
221+
{
222+
let s = value.to_string();
223+
if s.len() > 50 {
224+
// We don't need to save the type to a file, we will be talking about this type already
225+
// in a separate note when we explain the obligation, so it will be available that way.
226+
let mut cx: FmtPrinter<'_, '_> =
227+
FmtPrinter::new_with_limit(tcx, Namespace::TypeNS, rustc_session::Limit(6));
228+
value.print(&mut cx).unwrap();
229+
cx.into_buffer()
230+
} else {
231+
s
232+
}
229233
}
230-
let mut err = struct_span_code_err!(
231-
self.dcx(),
232-
span,
233-
E0275,
234-
"overflow evaluating the requirement `{}`",
235-
pred_str,
236-
);
234+
235+
let mut err = match cause {
236+
OverflowCause::DeeplyNormalize(alias_ty) => {
237+
let alias_ty = self.resolve_vars_if_possible(alias_ty);
238+
let kind = alias_ty.opt_kind(self.tcx).map_or("alias", |k| k.descr());
239+
let alias_str = with_short_path(self.tcx, alias_ty);
240+
struct_span_code_err!(
241+
self.dcx(),
242+
span,
243+
E0275,
244+
"overflow normalizing the {kind} `{alias_str}`",
245+
)
246+
}
247+
OverflowCause::TraitSolver(predicate) => {
248+
let predicate = self.resolve_vars_if_possible(predicate);
249+
let pred_str = with_short_path(self.tcx, predicate);
250+
struct_span_code_err!(
251+
self.dcx(),
252+
span,
253+
E0275,
254+
"overflow evaluating the requirement `{pred_str}`",
255+
)
256+
}
257+
};
237258

238259
if suggest_increasing_limit {
239260
self.suggest_new_overflow_limit(&mut err);
@@ -259,7 +280,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
259280
let predicate = obligation.predicate.clone().to_predicate(self.tcx);
260281
let predicate = self.resolve_vars_if_possible(predicate);
261282
self.report_overflow_error(
262-
&predicate,
283+
OverflowCause::TraitSolver(predicate),
263284
obligation.cause.span,
264285
suggest_increasing_limit,
265286
|err| {
@@ -310,7 +331,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
310331

311332
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed {
312333
let obligation = self.resolve_vars_if_possible(obligation);
313-
let mut err = self.build_overflow_error(&obligation.predicate, obligation.cause.span, true);
334+
let mut err = self.build_overflow_error(
335+
OverflowCause::TraitSolver(obligation.predicate),
336+
obligation.cause.span,
337+
true,
338+
);
314339
self.note_obligation_cause(&mut err, &obligation);
315340
self.point_at_returns_when_relevant(&mut err, &obligation);
316341
err.emit()

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -450,12 +450,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
450450
.recursion_limit()
451451
.value_within_limit(obligation.recursion_depth) =>
452452
{
453-
self.selcx.infcx.err_ctxt().report_overflow_error(
454-
&obligation.predicate,
455-
obligation.cause.span,
456-
false,
457-
|_| {},
458-
);
453+
self.selcx.infcx.err_ctxt().report_overflow_obligation(&obligation, false);
459454
}
460455

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

compiler/rustc_trait_selection/src/traits/normalize.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
//! Deeply normalize types using the old trait solver.
2+
use super::error_reporting::OverflowCause;
3+
use super::error_reporting::TypeErrCtxtExt;
4+
use super::SelectionContext;
5+
use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
26
use rustc_data_structures::stack::ensure_sufficient_stack;
37
use rustc_infer::infer::at::At;
48
use rustc_infer::infer::InferOk;
@@ -8,10 +12,6 @@ use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal};
812
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFolder};
913
use rustc_middle::ty::{TypeFoldable, TypeSuperFoldable, TypeVisitable, TypeVisitableExt};
1014

11-
use super::error_reporting::TypeErrCtxtExt;
12-
use super::SelectionContext;
13-
use super::{project, with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
14-
1515
#[extension(pub trait NormalizeExt<'tcx>)]
1616
impl<'tcx> At<'_, 'tcx> {
1717
/// Normalize a value using the `AssocTypeNormalizer`.
@@ -175,7 +175,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
175175
}
176176

177177
let (kind, data) = match *ty.kind() {
178-
ty::Alias(kind, alias_ty) => (kind, alias_ty),
178+
ty::Alias(kind, data) => (kind, data),
179179
_ => return ty.super_fold_with(self),
180180
};
181181

@@ -212,7 +212,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
212212
let recursion_limit = self.interner().recursion_limit();
213213
if !recursion_limit.value_within_limit(self.depth) {
214214
self.selcx.infcx.err_ctxt().report_overflow_error(
215-
&ty,
215+
OverflowCause::DeeplyNormalize(data),
216216
self.cause.span,
217217
true,
218218
|_| {},
@@ -308,7 +308,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
308308
let recursion_limit = self.interner().recursion_limit();
309309
if !recursion_limit.value_within_limit(self.depth) {
310310
self.selcx.infcx.err_ctxt().report_overflow_error(
311-
&ty,
311+
OverflowCause::DeeplyNormalize(data),
312312
self.cause.span,
313313
false,
314314
|diag| {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +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::OverflowCause;
89
use crate::traits::error_reporting::TypeErrCtxtExt;
910
use crate::traits::normalize::needs_normalization;
1011
use crate::traits::{BoundVarReplacer, PlaceholderReplacer};
@@ -228,7 +229,11 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx>
228229
let guar = self
229230
.infcx
230231
.err_ctxt()
231-
.build_overflow_error(&ty, self.cause.span, true)
232+
.build_overflow_error(
233+
OverflowCause::DeeplyNormalize(data),
234+
self.cause.span,
235+
true,
236+
)
232237
.delay_as_bug();
233238
return Ok(Ty::new_error(self.interner(), guar));
234239
}

compiler/rustc_type_ir/src/ty_kind.rs

Lines changed: 11 additions & 0 deletions
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

Lines changed: 3 additions & 3 deletions
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

Lines changed: 3 additions & 3 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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)