@@ -99,26 +99,36 @@ pub trait InferCtxtExt<'tcx> {
9999}
100100
101101pub 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+
102115 fn report_fulfillment_errors (
103116 & self ,
104117 errors : & [ FulfillmentError < ' tcx > ] ,
105118 body_id : Option < hir:: BodyId > ,
106119 ) -> ErrorGuaranteed ;
107120
108- fn report_overflow_error < T > (
121+ fn report_overflow_obligation < T > (
109122 & self ,
110123 obligation : & Obligation < ' tcx , T > ,
111124 suggest_increasing_limit : bool ,
112125 ) -> !
113126 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 ;
118128
119129 fn suggest_new_overflow_limit ( & self , err : & mut Diagnostic ) ;
120130
121- fn report_overflow_error_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> !;
131+ fn report_overflow_obligation_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> !;
122132
123133 /// The `root_obligation` parameter should be the `root_obligation` field
124134 /// from a `FulfillmentError`. If no `FulfillmentError` is available,
@@ -458,17 +468,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
458468 /// occurrences in any case.
459469 fn report_overflow_error < T > (
460470 & self ,
461- obligation : & Obligation < ' tcx , T > ,
471+ predicate : & T ,
472+ span : Span ,
462473 suggest_increasing_limit : bool ,
474+ mutate : impl FnOnce ( & mut Diagnostic ) ,
463475 ) -> !
464476 where
465477 T : fmt:: Display
466478 + TypeFoldable < ' tcx >
467479 + Print < ' tcx , FmtPrinter < ' tcx , ' tcx > , Output = FmtPrinter < ' tcx , ' tcx > > ,
468480 <T as Print < ' tcx , FmtPrinter < ' tcx , ' tcx > > >:: Error : std:: fmt:: Debug ,
469481 {
470- let predicate = self . resolve_vars_if_possible ( obligation . predicate . clone ( ) ) ;
482+ let predicate = self . resolve_vars_if_possible ( predicate. clone ( ) ) ;
471483 let mut pred_str = predicate. to_string ( ) ;
484+
472485 if pred_str. len ( ) > 50 {
473486 // We don't need to save the type to a file, we will be talking about this type already
474487 // 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> {
483496 }
484497 let mut err = struct_span_err ! (
485498 self . tcx. sess,
486- obligation . cause . span,
499+ span,
487500 E0275 ,
488501 "overflow evaluating the requirement `{}`" ,
489502 pred_str,
@@ -493,20 +506,46 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
493506 self . suggest_new_overflow_limit ( & mut err) ;
494507 }
495508
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) ;
504510
505511 err. emit ( ) ;
506512 self . tcx . sess . abort_if_errors ( ) ;
507513 bug ! ( ) ;
508514 }
509515
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+
510549 fn suggest_new_overflow_limit ( & self , err : & mut Diagnostic ) {
511550 let suggested_limit = match self . tcx . recursion_limit ( ) {
512551 Limit ( 0 ) => Limit ( 2 ) ,
@@ -521,19 +560,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
521560 }
522561
523562 /// 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
525564 /// that we can give a more helpful error message (and, in particular,
526565 /// we do not suggest increasing the overflow limit, which is not
527566 /// going to help).
528- fn report_overflow_error_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> ! {
567+ fn report_overflow_obligation_cycle ( & self , cycle : & [ PredicateObligation < ' tcx > ] ) -> ! {
529568 let cycle = self . resolve_vars_if_possible ( cycle. to_owned ( ) ) ;
530569 assert ! ( !cycle. is_empty( ) ) ;
531570
532571 debug ! ( ?cycle, "report_overflow_error_cycle" ) ;
533572
534573 // The 'deepest' obligation is most likely to have a useful
535574 // 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+ ) ;
537579 }
538580
539581 fn report_selection_error (
@@ -1554,7 +1596,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
15541596 diag. emit ( ) ;
15551597 }
15561598 FulfillmentErrorCode :: CodeCycle ( ref cycle) => {
1557- self . report_overflow_error_cycle ( cycle) ;
1599+ self . report_overflow_obligation_cycle ( cycle) ;
15581600 }
15591601 }
15601602 }
0 commit comments