@@ -57,6 +57,11 @@ use super::{
57
57
58
58
pub use rustc_infer:: traits:: error_reporting:: * ;
59
59
60
+ pub enum OverflowCause < ' tcx > {
61
+ DeeplyNormalize ( ty:: AliasTy < ' tcx > ) ,
62
+ TraitSolver ( ty:: Predicate < ' tcx > ) ,
63
+ }
64
+
60
65
#[ extension( pub trait TypeErrCtxtExt <' tcx>) ]
61
66
impl < ' tcx > TypeErrCtxt < ' _ , ' tcx > {
62
67
fn report_fulfillment_errors (
@@ -184,49 +189,65 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
184
189
/// whose result could not be truly determined and thus we can't say
185
190
/// if the program type checks or not -- and they are unusual
186
191
/// occurrences in any case.
187
- fn report_overflow_error < T > (
192
+ fn report_overflow_error (
188
193
& self ,
189
- predicate : & T ,
194
+ cause : OverflowCause < ' tcx > ,
190
195
span : Span ,
191
196
suggest_increasing_limit : bool ,
192
197
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) ;
198
200
mutate ( & mut err) ;
199
201
err. emit ( ) ;
200
202
FatalError . raise ( ) ;
201
203
}
202
204
203
- fn build_overflow_error < T > (
205
+ fn build_overflow_error (
204
206
& self ,
205
- predicate : & T ,
207
+ cause : OverflowCause < ' tcx > ,
206
208
span : Span ,
207
209
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
+ }
222
226
}
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
+ } ;
230
251
231
252
if suggest_increasing_limit {
232
253
self . suggest_new_overflow_limit ( & mut err) ;
@@ -252,7 +273,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
252
273
let predicate = obligation. predicate . clone ( ) . to_predicate ( self . tcx ) ;
253
274
let predicate = self . resolve_vars_if_possible ( predicate) ;
254
275
self . report_overflow_error (
255
- & predicate,
276
+ OverflowCause :: TraitSolver ( predicate) ,
256
277
obligation. cause . span ,
257
278
suggest_increasing_limit,
258
279
|err| {
@@ -303,7 +324,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
303
324
304
325
fn report_overflow_no_abort ( & self , obligation : PredicateObligation < ' tcx > ) -> ErrorGuaranteed {
305
326
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
+ ) ;
307
332
self . note_obligation_cause ( & mut err, & obligation) ;
308
333
self . point_at_returns_when_relevant ( & mut err, & obligation) ;
309
334
err. emit ( )
0 commit comments