208
208
mod autodiff;
209
209
210
210
use std:: cell:: OnceCell ;
211
+ use std:: ops:: ControlFlow ;
211
212
212
213
use rustc_data_structures:: fx:: FxIndexMap ;
213
214
use rustc_data_structures:: sync:: { MTLock , par_for_each_in} ;
@@ -228,7 +229,7 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCoercion};
228
229
use rustc_middle:: ty:: layout:: ValidityRequirement ;
229
230
use rustc_middle:: ty:: {
230
231
self , GenericArgs , GenericParamDefKind , Instance , InstanceKind , Ty , TyCtxt , TypeFoldable ,
231
- TypeVisitableExt , VtblEntry ,
232
+ TypeVisitable , TypeVisitableExt , TypeVisitor , VtblEntry ,
232
233
} ;
233
234
use rustc_middle:: util:: Providers ;
234
235
use rustc_middle:: { bug, span_bug} ;
@@ -473,6 +474,23 @@ fn collect_items_rec<'tcx>(
473
474
recursion_limit,
474
475
) ) ;
475
476
477
+ // Plenty of code paths later assume that everything can be normalized.
478
+ // Check normalization here to provide better diagnostics.
479
+ // Normalization errors here are usually due to trait solving overflow.
480
+ // FIXME: I assume that there are few type errors at post-analysis stage, but not
481
+ // entirely sure.
482
+ if tcx. has_normalization_error_in_mono ( instance) {
483
+ let def_id = instance. def_id ( ) ;
484
+ let def_span = tcx. def_span ( def_id) ;
485
+ let def_path_str = tcx. def_path_str ( def_id) ;
486
+ tcx. dcx ( ) . emit_fatal ( RecursionLimit {
487
+ span : starting_item. span ,
488
+ instance,
489
+ def_span,
490
+ def_path_str,
491
+ } ) ;
492
+ }
493
+
476
494
rustc_data_structures:: stack:: ensure_sufficient_stack ( || {
477
495
let ( used, mentioned) = tcx. items_of_instance ( ( instance, mode) ) ;
478
496
used_items. extend ( used. into_iter ( ) . copied ( ) ) ;
@@ -603,6 +621,33 @@ fn collect_items_rec<'tcx>(
603
621
}
604
622
}
605
623
624
+ // Check whether we can normalize the MIR body. Make it a query since decoding MIR from disk cache
625
+ // may be expensive.
626
+ fn has_normalization_error_in_mono < ' tcx > ( tcx : TyCtxt < ' tcx > , instance : Instance < ' tcx > ) -> bool {
627
+ struct NormalizationChecker < ' tcx > {
628
+ tcx : TyCtxt < ' tcx > ,
629
+ instance : Instance < ' tcx > ,
630
+ }
631
+ impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for NormalizationChecker < ' tcx > {
632
+ type Result = ControlFlow < ( ) > ;
633
+
634
+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> Self :: Result {
635
+ match self . instance . try_instantiate_mir_and_normalize_erasing_regions (
636
+ self . tcx ,
637
+ ty:: TypingEnv :: fully_monomorphized ( ) ,
638
+ ty:: EarlyBinder :: bind ( t) ,
639
+ ) {
640
+ Ok ( _) => ControlFlow :: Continue ( ( ) ) ,
641
+ Err ( _) => ControlFlow :: Break ( ( ) ) ,
642
+ }
643
+ }
644
+ }
645
+
646
+ let body = tcx. instance_mir ( instance. def ) ;
647
+ let mut checker = NormalizationChecker { tcx, instance } ;
648
+ body. visit_with ( & mut checker) . is_break ( )
649
+ }
650
+
606
651
fn check_recursion_limit < ' tcx > (
607
652
tcx : TyCtxt < ' tcx > ,
608
653
instance : Instance < ' tcx > ,
@@ -1770,4 +1815,5 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
1770
1815
pub ( crate ) fn provide ( providers : & mut Providers ) {
1771
1816
providers. hooks . should_codegen_locally = should_codegen_locally;
1772
1817
providers. items_of_instance = items_of_instance;
1818
+ providers. has_normalization_error_in_mono = has_normalization_error_in_mono;
1773
1819
}
0 commit comments