@@ -99,26 +99,36 @@ pub trait InferCtxtExt<'tcx> {
99
99
}
100
100
101
101
pub trait TypeErrCtxtExt < ' tcx > {
102
+ fn report_overflow_error < T > (
103
+ & self ,
104
+ predicate : & T ,
105
+ span : Span ,
106
+ suggest_increasing_limit : bool ,
107
+ mutate : impl FnOnce ( & mut Diagnostic ) ,
108
+ ) -> !
109
+ where
110
+ T : fmt:: Display
111
+ + TypeFoldable < ' tcx >
112
+ + Print < ' tcx , FmtPrinter < ' tcx , ' tcx > , Output = FmtPrinter < ' tcx , ' tcx > > ,
113
+ <T as Print < ' tcx , FmtPrinter < ' tcx , ' tcx > > >:: Error : std:: fmt:: Debug ;
114
+
102
115
fn report_fulfillment_errors (
103
116
& self ,
104
117
errors : & [ FulfillmentError < ' tcx > ] ,
105
118
body_id : Option < hir:: BodyId > ,
106
119
) -> ErrorGuaranteed ;
107
120
108
- fn report_overflow_error < T > (
121
+ fn report_overflow_obligation < T > (
109
122
& self ,
110
123
obligation : & Obligation < ' tcx , T > ,
111
124
suggest_increasing_limit : bool ,
112
125
) -> !
113
126
where
114
- T : fmt:: Display
115
- + TypeFoldable < ' tcx >
116
- + Print < ' tcx , FmtPrinter < ' tcx , ' tcx > , Output = FmtPrinter < ' tcx , ' tcx > > ,
117
- <T as Print < ' tcx , FmtPrinter < ' tcx , ' tcx > > >:: Error : std:: fmt:: Debug ;
127
+ T : ToPredicate < ' tcx > + Clone ;
118
128
119
129
fn suggest_new_overflow_limit ( & self , err : & mut Diagnostic ) ;
120
130
121
- fn report_overflow_error_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> !;
131
+ fn report_overflow_obligation_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> !;
122
132
123
133
/// The `root_obligation` parameter should be the `root_obligation` field
124
134
/// from a `FulfillmentError`. If no `FulfillmentError` is available,
@@ -458,17 +468,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
458
468
/// occurrences in any case.
459
469
fn report_overflow_error < T > (
460
470
& self ,
461
- obligation : & Obligation < ' tcx , T > ,
471
+ predicate : & T ,
472
+ span : Span ,
462
473
suggest_increasing_limit : bool ,
474
+ mutate : impl FnOnce ( & mut Diagnostic ) ,
463
475
) -> !
464
476
where
465
477
T : fmt:: Display
466
478
+ TypeFoldable < ' tcx >
467
479
+ Print < ' tcx , FmtPrinter < ' tcx , ' tcx > , Output = FmtPrinter < ' tcx , ' tcx > > ,
468
480
<T as Print < ' tcx , FmtPrinter < ' tcx , ' tcx > > >:: Error : std:: fmt:: Debug ,
469
481
{
470
- let predicate = self . resolve_vars_if_possible ( obligation . predicate . clone ( ) ) ;
482
+ let predicate = self . resolve_vars_if_possible ( predicate. clone ( ) ) ;
471
483
let mut pred_str = predicate. to_string ( ) ;
484
+
472
485
if pred_str. len ( ) > 50 {
473
486
// We don't need to save the type to a file, we will be talking about this type already
474
487
// in a separate note when we explain the obligation, so it will be available that way.
@@ -483,7 +496,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
483
496
}
484
497
let mut err = struct_span_err ! (
485
498
self . tcx. sess,
486
- obligation . cause . span,
499
+ span,
487
500
E0275 ,
488
501
"overflow evaluating the requirement `{}`" ,
489
502
pred_str,
@@ -493,20 +506,46 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
493
506
self . suggest_new_overflow_limit ( & mut err) ;
494
507
}
495
508
496
- self . note_obligation_cause_code (
497
- & mut err,
498
- & obligation. predicate ,
499
- obligation. param_env ,
500
- obligation. cause . code ( ) ,
501
- & mut vec ! [ ] ,
502
- & mut Default :: default ( ) ,
503
- ) ;
509
+ mutate ( & mut err) ;
504
510
505
511
err. emit ( ) ;
506
512
self . tcx . sess . abort_if_errors ( ) ;
507
513
bug ! ( ) ;
508
514
}
509
515
516
+ /// Reports that an overflow has occurred and halts compilation. We
517
+ /// halt compilation unconditionally because it is important that
518
+ /// overflows never be masked -- they basically represent computations
519
+ /// whose result could not be truly determined and thus we can't say
520
+ /// if the program type checks or not -- and they are unusual
521
+ /// occurrences in any case.
522
+ fn report_overflow_obligation < T > (
523
+ & self ,
524
+ obligation : & Obligation < ' tcx , T > ,
525
+ suggest_increasing_limit : bool ,
526
+ ) -> !
527
+ where
528
+ T : ToPredicate < ' tcx > + Clone ,
529
+ {
530
+ let predicate = obligation. predicate . clone ( ) . to_predicate ( self . tcx ) ;
531
+ let predicate = self . resolve_vars_if_possible ( predicate) ;
532
+ self . report_overflow_error (
533
+ & predicate,
534
+ obligation. cause . span ,
535
+ suggest_increasing_limit,
536
+ |err| {
537
+ self . note_obligation_cause_code (
538
+ err,
539
+ & predicate,
540
+ obligation. param_env ,
541
+ obligation. cause . code ( ) ,
542
+ & mut vec ! [ ] ,
543
+ & mut Default :: default ( ) ,
544
+ ) ;
545
+ } ,
546
+ ) ;
547
+ }
548
+
510
549
fn suggest_new_overflow_limit ( & self , err : & mut Diagnostic ) {
511
550
let suggested_limit = match self . tcx . recursion_limit ( ) {
512
551
Limit ( 0 ) => Limit ( 2 ) ,
@@ -521,19 +560,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
521
560
}
522
561
523
562
/// Reports that a cycle was detected which led to overflow and halts
524
- /// compilation. This is equivalent to `report_overflow_error ` except
563
+ /// compilation. This is equivalent to `report_overflow_obligation ` except
525
564
/// that we can give a more helpful error message (and, in particular,
526
565
/// we do not suggest increasing the overflow limit, which is not
527
566
/// going to help).
528
- fn report_overflow_error_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> ! {
567
+ fn report_overflow_obligation_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> ! {
529
568
let cycle = self . resolve_vars_if_possible ( cycle. to_owned ( ) ) ;
530
569
assert ! ( !cycle. is_empty( ) ) ;
531
570
532
571
debug ! ( ?cycle, "report_overflow_error_cycle" ) ;
533
572
534
573
// The 'deepest' obligation is most likely to have a useful
535
574
// cause 'backtrace'
536
- self . report_overflow_error ( cycle. iter ( ) . max_by_key ( |p| p. recursion_depth ) . unwrap ( ) , false ) ;
575
+ self . report_overflow_obligation (
576
+ cycle. iter ( ) . max_by_key ( |p| p. recursion_depth ) . unwrap ( ) ,
577
+ false ,
578
+ ) ;
537
579
}
538
580
539
581
fn report_selection_error (
@@ -1554,7 +1596,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
1554
1596
diag. emit ( ) ;
1555
1597
}
1556
1598
FulfillmentErrorCode :: CodeCycle ( ref cycle) => {
1557
- self . report_overflow_error_cycle ( cycle) ;
1599
+ self . report_overflow_obligation_cycle ( cycle) ;
1558
1600
}
1559
1601
}
1560
1602
}
0 commit comments