@@ -57,6 +57,11 @@ use super::{
5757
5858pub 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>) ]
6166impl < ' 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 ( )
0 commit comments