@@ -156,6 +156,9 @@ pub struct LocalCrateContext<'tcx> {
156
156
/// contexts around the same size.
157
157
n_llvm_insns : Cell < usize > ,
158
158
159
+ /// Depth of the current type-of computation - used to bail out
160
+ type_of_depth : Cell < usize > ,
161
+
159
162
trait_cache : RefCell < FnvHashMap < ty:: PolyTraitRef < ' tcx > ,
160
163
traits:: Vtable < ' tcx , ( ) > > > ,
161
164
}
@@ -470,6 +473,7 @@ impl<'tcx> LocalCrateContext<'tcx> {
470
473
unwind_resume_hooked : Cell :: new ( false ) ,
471
474
intrinsics : RefCell :: new ( FnvHashMap ( ) ) ,
472
475
n_llvm_insns : Cell :: new ( 0 ) ,
476
+ type_of_depth : Cell :: new ( 0 ) ,
473
477
trait_cache : RefCell :: new ( FnvHashMap ( ) ) ,
474
478
} ;
475
479
@@ -774,6 +778,17 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
774
778
obj) )
775
779
}
776
780
781
+ pub fn enter_type_of ( & self , ty : Ty < ' tcx > ) -> TypeOfDepthLock < ' b , ' tcx > {
782
+ let current_depth = self . local . type_of_depth . get ( ) ;
783
+ debug ! ( "enter_type_of({:?}) at depth {:?}" , ty, current_depth) ;
784
+ if current_depth > self . sess ( ) . recursion_limit . get ( ) {
785
+ self . sess ( ) . fatal (
786
+ & format ! ( "overflow representing the type `{}`" , ty) )
787
+ }
788
+ self . local . type_of_depth . set ( current_depth + 1 ) ;
789
+ TypeOfDepthLock ( self . local )
790
+ }
791
+
777
792
pub fn check_overflow ( & self ) -> bool {
778
793
self . shared . check_overflow
779
794
}
@@ -790,6 +805,14 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
790
805
}
791
806
}
792
807
808
+ pub struct TypeOfDepthLock < ' a , ' tcx : ' a > ( & ' a LocalCrateContext < ' tcx > ) ;
809
+
810
+ impl < ' a , ' tcx > Drop for TypeOfDepthLock < ' a , ' tcx > {
811
+ fn drop ( & mut self ) {
812
+ self . 0 . type_of_depth . set ( self . 0 . type_of_depth . get ( ) - 1 ) ;
813
+ }
814
+ }
815
+
793
816
/// Declare any llvm intrinsics that you might need
794
817
fn declare_intrinsic ( ccx : & CrateContext , key : & str ) -> Option < ValueRef > {
795
818
macro_rules! ifn {
0 commit comments