@@ -1012,11 +1012,11 @@ def _visit_tuple_display(builder: IRBuilder, expr: TupleExpr) -> Value:
10121012 return builder .primitive_op (list_tuple_op , [val_as_list ], expr .line )
10131013
10141014
1015- def dict_literal_values (builder : IRBuilder , items : Sequence [tuple [Expression | None , Expression ]], line : int ) -> "Value | None" :
1016- """Try to extract a constant dict from a dict literal.
1015+ def dict_literal_values (builder : IRBuilder , items : Sequence [tuple [Expression | None , Expression ]], line : int ) -> "dict | None" :
1016+ """Try to extract a constant dict from a dict literal, recursively staticizing nested dicts .
10171017
1018- If all keys and values are deeply immutable and constant, register it as a static
1019- and return a LoadLiteral for it . Otherwise, return None.
1018+ If all keys and values are deeply immutable and constant (including nested dicts as values),
1019+ return the Python dict value . Otherwise, return None.
10201020 """
10211021 result = {}
10221022 for key_expr , value_expr in items :
@@ -1027,12 +1027,21 @@ def dict_literal_values(builder: IRBuilder, items: Sequence[tuple[Expression | N
10271027 key = constant_fold_expr (builder , key_expr )
10281028 if key is None :
10291029 return None
1030+ # Recursively staticize dict values
10301031 value = constant_fold_expr (builder , value_expr )
10311032 if value is None :
1032- return None
1033+ # Try to staticize nested dicts
1034+ if isinstance (value_expr , DictExpr ):
1035+ nested = dict_literal_values (builder , value_expr .items , value_expr .line )
1036+ if nested is not None :
1037+ value = nested
1038+ else :
1039+ return None
1040+ else :
1041+ return None
10331042 result [key ] = value
10341043
1035- return builder . add ( LoadLiteral ( result , dict_rprimitive )) if result else None
1044+ return result or None
10361045
10371046def transform_dict_expr (builder : IRBuilder , expr : DictExpr ) -> Value :
10381047 """First accepts all keys and values, then makes a dict out of them.
@@ -1041,10 +1050,11 @@ def transform_dict_expr(builder: IRBuilder, expr: DictExpr) -> Value:
10411050 and at runtime use PyDict_Copy to return a fresh dict.
10421051 """
10431052 # Try to constant fold the dict and get a static Value
1044- template = dict_literal_values (builder , expr .items , expr .line )
1045- if template is not None :
1046- # At runtime, return PyDict_Copy(template)
1047- return builder .call_c (dict_template_copy_op , [template ], expr .line )
1053+ static_dict = dict_literal_values (builder , expr .items , expr .line )
1054+ if static_dict is not None :
1055+ # Register the static dict and return a copy at runtime
1056+ static_val = builder .add (LoadLiteral (static_dict , dict_rprimitive ))
1057+ return builder .call_c (dict_template_copy_op , [static_val ], expr .line )
10481058
10491059 # Fallback: build dict at runtime as before
10501060 key_value_pairs = []
0 commit comments