@@ -702,6 +702,7 @@ impl<'db> HirDisplay<'db> for Const<'db> {
702702 & const_bytes. value . inner ( ) . memory ,
703703 & const_bytes. value . inner ( ) . memory_map ,
704704 const_bytes. ty ,
705+ CONST_SCALAR_RENDER_DEPTH_LIMIT ,
705706 ) ,
706707 ConstKind :: Unevaluated ( unev) => {
707708 let c = unev. def . 0 ;
@@ -715,16 +716,24 @@ impl<'db> HirDisplay<'db> for Const<'db> {
715716 }
716717}
717718
719+ /// Maximum recursion depth for rendering const scalars.
720+ /// This prevents stack overflow with self-referential data structures.
721+ const CONST_SCALAR_RENDER_DEPTH_LIMIT : usize = 20 ;
722+
718723fn render_const_scalar < ' db > (
719724 f : & mut HirFormatter < ' _ , ' db > ,
720725 b : & [ u8 ] ,
721726 memory_map : & MemoryMap < ' db > ,
722727 ty : Ty < ' db > ,
728+ depth : usize ,
723729) -> Result {
730+ if depth == 0 {
731+ return f. write_str ( "<recursion-limit>" ) ;
732+ }
724733 let param_env = ParamEnv :: empty ( ) ;
725734 let infcx = f. interner . infer_ctxt ( ) . build ( TypingMode :: PostAnalysis ) ;
726735 let ty = infcx. at ( & ObligationCause :: new ( ) , param_env) . deeply_normalize ( ty) . unwrap_or ( ty) ;
727- render_const_scalar_inner ( f, b, memory_map, ty, param_env)
736+ render_const_scalar_inner ( f, b, memory_map, ty, param_env, depth )
728737}
729738
730739fn render_const_scalar_inner < ' db > (
@@ -733,6 +742,7 @@ fn render_const_scalar_inner<'db>(
733742 memory_map : & MemoryMap < ' db > ,
734743 ty : Ty < ' db > ,
735744 param_env : ParamEnv < ' db > ,
745+ depth : usize ,
736746) -> Result {
737747 use TyKind ;
738748 let param_env = ParamEnvAndCrate { param_env, krate : f. krate ( ) } ;
@@ -822,7 +832,13 @@ fn render_const_scalar_inner<'db>(
822832 f. write_str ( ", " ) ?;
823833 }
824834 let offset = size_one * i;
825- render_const_scalar ( f, & bytes[ offset..offset + size_one] , memory_map, ty) ?;
835+ render_const_scalar (
836+ f,
837+ & bytes[ offset..offset + size_one] ,
838+ memory_map,
839+ ty,
840+ depth - 1 ,
841+ ) ?;
826842 }
827843 f. write_str ( "]" )
828844 }
@@ -840,7 +856,7 @@ fn render_const_scalar_inner<'db>(
840856 return f. write_str ( "<ref-data-not-available>" ) ;
841857 } ;
842858 f. write_str ( "&" ) ?;
843- render_const_scalar ( f, bytes, memory_map, t)
859+ render_const_scalar ( f, bytes, memory_map, t, depth - 1 )
844860 }
845861 TyKind :: Adt ( adt, _) if b. len ( ) == 2 * size_of :: < usize > ( ) => match adt. def_id ( ) . 0 {
846862 hir_def:: AdtId :: StructId ( s) => {
@@ -870,7 +886,7 @@ fn render_const_scalar_inner<'db>(
870886 return f. write_str ( "<ref-data-not-available>" ) ;
871887 } ;
872888 f. write_str ( "&" ) ?;
873- render_const_scalar ( f, bytes, memory_map, t)
889+ render_const_scalar ( f, bytes, memory_map, t, depth - 1 )
874890 }
875891 } ,
876892 TyKind :: Tuple ( tys) => {
@@ -891,7 +907,7 @@ fn render_const_scalar_inner<'db>(
891907 continue ;
892908 } ;
893909 let size = layout. size . bytes_usize ( ) ;
894- render_const_scalar ( f, & b[ offset..offset + size] , memory_map, ty) ?;
910+ render_const_scalar ( f, & b[ offset..offset + size] , memory_map, ty, depth - 1 ) ?;
895911 }
896912 f. write_str ( ")" )
897913 }
@@ -914,6 +930,7 @@ fn render_const_scalar_inner<'db>(
914930 args,
915931 b,
916932 memory_map,
933+ depth,
917934 )
918935 }
919936 hir_def:: AdtId :: UnionId ( u) => {
@@ -946,6 +963,7 @@ fn render_const_scalar_inner<'db>(
946963 args,
947964 b,
948965 memory_map,
966+ depth,
949967 )
950968 }
951969 }
@@ -973,7 +991,7 @@ fn render_const_scalar_inner<'db>(
973991 f. write_str ( ", " ) ?;
974992 }
975993 let offset = size_one * i;
976- render_const_scalar ( f, & b[ offset..offset + size_one] , memory_map, ty) ?;
994+ render_const_scalar ( f, & b[ offset..offset + size_one] , memory_map, ty, depth - 1 ) ?;
977995 }
978996 f. write_str ( "]" )
979997 }
@@ -1006,6 +1024,7 @@ fn render_variant_after_name<'db>(
10061024 args : GenericArgs < ' db > ,
10071025 b : & [ u8 ] ,
10081026 memory_map : & MemoryMap < ' db > ,
1027+ depth : usize ,
10091028) -> Result {
10101029 let param_env = ParamEnvAndCrate { param_env, krate : f. krate ( ) } ;
10111030 match data. shape {
@@ -1017,7 +1036,7 @@ fn render_variant_after_name<'db>(
10171036 return f. write_str ( "<layout-error>" ) ;
10181037 } ;
10191038 let size = layout. size . bytes_usize ( ) ;
1020- render_const_scalar ( f, & b[ offset..offset + size] , memory_map, ty)
1039+ render_const_scalar ( f, & b[ offset..offset + size] , memory_map, ty, depth - 1 )
10211040 } ;
10221041 let mut it = data. fields ( ) . iter ( ) ;
10231042 if matches ! ( data. shape, FieldsShape :: Record ) {
0 commit comments