Skip to content

Commit f7cdff8

Browse files
committed
overflow errors: change source to a concrete enum
1 parent f392a87 commit f7cdff8

15 files changed

+126
-91
lines changed

Diff for: 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::{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
|_| {},
@@ -109,7 +113,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> {
109113
let recursion_limit = tcx.recursion_limit();
110114
if !recursion_limit.value_within_limit(self.depth) {
111115
self.at.infcx.err_ctxt().report_overflow_error(
112-
&ty::Const::new_unevaluated(tcx, uv, ty),
116+
OverflowCause::DeeplyNormalize(ty::AliasTy::new(tcx, uv.def, uv.args)),
113117
self.at.cause.span,
114118
true,
115119
|_| {},

Diff for: compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+57-32
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,49 +189,65 @@ 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 DiagnosticBuilder<'_>),
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
FatalError.raise();
201203
}
202204

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

231252
if suggest_increasing_limit {
232253
self.suggest_new_overflow_limit(&mut err);
@@ -252,7 +273,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
252273
let predicate = obligation.predicate.clone().to_predicate(self.tcx);
253274
let predicate = self.resolve_vars_if_possible(predicate);
254275
self.report_overflow_error(
255-
&predicate,
276+
OverflowCause::TraitSolver(predicate),
256277
obligation.cause.span,
257278
suggest_increasing_limit,
258279
|err| {
@@ -303,7 +324,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
303324

304325
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed {
305326
let obligation = self.resolve_vars_if_possible(obligation);
306-
let mut err = self.build_overflow_error(&obligation.predicate, obligation.cause.span, true);
327+
let mut err = self.build_overflow_error(
328+
OverflowCause::TraitSolver(obligation.predicate),
329+
obligation.cause.span,
330+
true,
331+
);
307332
self.note_obligation_cause(&mut err, &obligation);
308333
self.point_at_returns_when_relevant(&mut err, &obligation);
309334
err.emit()

Diff for: compiler/rustc_trait_selection/src/traits/fulfill.rs

+1-6
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)) => {

Diff for: compiler/rustc_trait_selection/src/traits/normalize.rs

+7-7
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`.
@@ -173,7 +173,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
173173
}
174174

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

@@ -210,7 +210,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
210210
let recursion_limit = self.interner().recursion_limit();
211211
if !recursion_limit.value_within_limit(self.depth) {
212212
self.selcx.infcx.err_ctxt().report_overflow_error(
213-
&ty,
213+
OverflowCause::DeeplyNormalize(data),
214214
self.cause.span,
215215
true,
216216
|_| {},
@@ -306,7 +306,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
306306
let recursion_limit = self.interner().recursion_limit();
307307
if !recursion_limit.value_within_limit(self.depth) {
308308
self.selcx.infcx.err_ctxt().report_overflow_error(
309-
&ty,
309+
OverflowCause::DeeplyNormalize(data),
310310
self.cause.span,
311311
false,
312312
|diag| {

Diff for: compiler/rustc_trait_selection/src/traits/query/normalize.rs

+6-1
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
}

Diff for: 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

Diff for: tests/ui/impl-trait/issues/issue-62742.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ fn _alias_check() {
44
WrongImpl::foo(0i32);
55
//~^ ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
66
//~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
7-
//~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
87
WrongImpl::<()>::foo(0i32);
98
//~^ ERROR the trait bound `RawImpl<()>: Raw<()>` is not satisfied
109
//~| ERROR trait bounds were not satisfied

Diff for: tests/ui/impl-trait/issues/issue-62742.stderr

+9-17
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
22
--> $DIR/issue-62742.rs:4:5
33
|
44
LL | WrongImpl::foo(0i32);
5-
| ^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
5+
| ^^^^^^^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
66
|
77
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
88
note: required by a bound in `SafeImpl::<T, A>::foo`
9-
--> $DIR/issue-62742.rs:30:20
9+
--> $DIR/issue-62742.rs:29:20
1010
|
1111
LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
1212
| ^^^^^^ required by this bound in `SafeImpl::<T, A>::foo`
@@ -21,21 +21,13 @@ LL | WrongImpl::foo(0i32);
2121
|
2222
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
2323
note: required by a bound in `SafeImpl`
24-
--> $DIR/issue-62742.rs:28:35
24+
--> $DIR/issue-62742.rs:27:35
2525
|
2626
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
2727
| ^^^^^^ required by this bound in `SafeImpl`
2828

29-
error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
30-
--> $DIR/issue-62742.rs:4:5
31-
|
32-
LL | WrongImpl::foo(0i32);
33-
| ^^^^^^^^^^^^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
34-
|
35-
= help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
36-
3729
error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied
38-
--> $DIR/issue-62742.rs:8:22
30+
--> $DIR/issue-62742.rs:7:22
3931
|
4032
LL | WrongImpl::<()>::foo(0i32);
4133
| ^^^ function or associated item cannot be called on `SafeImpl<(), RawImpl<()>>` due to unsatisfied trait bounds
@@ -47,33 +39,33 @@ LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
4739
| ----------------------------------------- function or associated item `foo` not found for this struct
4840
|
4941
note: trait bound `RawImpl<()>: Raw<()>` was not satisfied
50-
--> $DIR/issue-62742.rs:30:20
42+
--> $DIR/issue-62742.rs:29:20
5143
|
5244
LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
5345
| ^^^^^^ --------------
5446
| |
5547
| unsatisfied trait bound introduced here
5648
note: the trait `Raw` must be implemented
57-
--> $DIR/issue-62742.rs:14:1
49+
--> $DIR/issue-62742.rs:13:1
5850
|
5951
LL | pub trait Raw<T: ?Sized> {
6052
| ^^^^^^^^^^^^^^^^^^^^^^^^
6153

6254
error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied
63-
--> $DIR/issue-62742.rs:8:5
55+
--> $DIR/issue-62742.rs:7:5
6456
|
6557
LL | WrongImpl::<()>::foo(0i32);
6658
| ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>`
6759
|
6860
= help: the trait `Raw<[()]>` is implemented for `RawImpl<()>`
6961
= help: for that trait implementation, expected `[()]`, found `()`
7062
note: required by a bound in `SafeImpl`
71-
--> $DIR/issue-62742.rs:28:35
63+
--> $DIR/issue-62742.rs:27:35
7264
|
7365
LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
7466
| ^^^^^^ required by this bound in `SafeImpl`
7567

76-
error: aborting due to 5 previous errors
68+
error: aborting due to 4 previous errors
7769

7870
Some errors have detailed explanations: E0277, E0599.
7971
For more information about an error, try `rustc --explain E0277`.

Diff for: 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;

Diff for: 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() {}

Diff for: 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>;

Diff for: 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)