@@ -2257,7 +2257,28 @@ pub fn fnc_typetrees<'tcx>(tcx: TyCtxt<'tcx>, fn_ty: Ty<'tcx>) -> FncTree {
2257
2257
2258
2258
/// Generate TypeTree for a specific type.
2259
2259
/// 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
+
2260
2277
pub 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 {
2261
2282
if ty. is_scalar ( ) {
2262
2283
let ( kind, size) = if ty. is_integral ( ) || ty. is_char ( ) || ty. is_bool ( ) {
2263
2284
( 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 {
2299
2320
return TypeTree :: new ( ) ;
2300
2321
}
2301
2322
2302
- let element_tree = typetree_from_ty ( tcx, * element_ty) ;
2323
+ let element_tree = typetree_from_ty_impl ( tcx, * element_ty, depth + 1 ) ;
2303
2324
2304
2325
let element_layout = tcx
2305
2326
. 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 {
2335
2356
2336
2357
if ty. is_slice ( ) {
2337
2358
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 ) ;
2339
2360
return element_tree;
2340
2361
}
2341
2362
}
@@ -2349,7 +2370,7 @@ pub fn typetree_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> TypeTree {
2349
2370
let mut current_offset = 0 ;
2350
2371
2351
2372
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 ) ;
2353
2374
2354
2375
let element_layout = tcx
2355
2376
. 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 {
2385
2406
2386
2407
for ( field_idx, field_def) in adt_def. all_fields ( ) . enumerate ( ) {
2387
2408
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 ) ;
2389
2410
2390
2411
let field_offset = layout. fields . offset ( field_idx) . bytes_usize ( ) ;
2391
2412
0 commit comments