@@ -2257,7 +2257,28 @@ pub fn fnc_typetrees<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>) -> FncTree {
22572257
22582258/// Generate TypeTree for a specific type.
22592259/// This function analyzes a Rust type and creates appropriate TypeTree metadata.
2260+
2261+ /// Maximum recursion depth for TypeTree generation to prevent infinite loops
2262+ /// Set to 32 levels which should be sufficient for most practical type hierarchies
2263+ /// while preventing stack overflow from pathological recursive types.
2264+ const MAX_TYPETREE_DEPTH : usize = 32 ;
2265+
2266+ /// Helper function to track recursion depth during TypeTree generation.
2267+ /// This prevents infinite recursion when processing recursive types like:
2268+ /// struct Node { value: T, next: Option<Box<Node>> }
2269+ fn typetree_from_ty_with_depth < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , depth : usize ) -> TypeTree {
2270+ if depth > MAX_TYPETREE_DEPTH {
2271+ return TypeTree :: new ( ) ;
2272+ }
2273+
2274+ typetree_from_ty_impl ( tcx, ty, depth)
2275+ }
2276+
22602277pub fn typetree_from_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> TypeTree {
2278+ typetree_from_ty_with_depth ( tcx, ty, 0 )
2279+ }
2280+
2281+ fn typetree_from_ty_impl < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > , depth : usize ) -> TypeTree {
22612282 if ty. is_scalar ( ) {
22622283 let ( kind, size) = if ty. is_integral ( ) || ty. is_char ( ) || ty. is_bool ( ) {
22632284 ( Kind :: Integer , ty. primitive_size ( tcx) . bytes_usize ( ) )
@@ -2299,7 +2320,7 @@ pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree {
22992320 return TypeTree :: new ( ) ;
23002321 }
23012322
2302- let element_tree = typetree_from_ty ( tcx, * element_ty) ;
2323+ let element_tree = typetree_from_ty_impl ( tcx, * element_ty, depth + 1 ) ;
23032324
23042325 let element_layout = tcx
23052326 . layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( * element_ty) )
@@ -2335,7 +2356,7 @@ pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree {
23352356
23362357 if ty. is_slice ( ) {
23372358 if let ty:: Slice ( element_ty) = ty. kind ( ) {
2338- let element_tree = typetree_from_ty ( tcx, * element_ty) ;
2359+ let element_tree = typetree_from_ty_impl ( tcx, * element_ty, depth + 1 ) ;
23392360 return element_tree;
23402361 }
23412362 }
@@ -2349,7 +2370,7 @@ pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree {
23492370 let mut current_offset = 0 ;
23502371
23512372 for tuple_ty in tuple_types. iter ( ) {
2352- let element_tree = typetree_from_ty ( tcx, tuple_ty) ;
2373+ let element_tree = typetree_from_ty_impl ( tcx, tuple_ty, depth + 1 ) ;
23532374
23542375 let element_layout = tcx
23552376 . layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( tuple_ty) )
@@ -2385,7 +2406,7 @@ pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree {
23852406
23862407 for ( field_idx, field_def) in adt_def. all_fields ( ) . enumerate ( ) {
23872408 let field_ty = field_def. ty ( tcx, args) ;
2388- let field_tree = typetree_from_ty ( tcx, field_ty) ;
2409+ let field_tree = typetree_from_ty_impl ( tcx, field_ty, depth + 1 ) ;
23892410
23902411 let field_offset = layout. fields . offset ( field_idx) . bytes_usize ( ) ;
23912412
0 commit comments