@@ -1063,21 +1063,31 @@ def let_32(a_33, b_34, c_35):
1063
1063
arg_deps .append (expr_deps )
1064
1064
arg_exprs .append (_unwrap_node (expr_node ))
1065
1065
1066
+ # Generate an outer function to hold the entire let expression (including bindings).
1067
+ # We need to do this to guarantee that no binding expressions are executed as part of
1068
+ # an assignment as a dependency node. This eager evaluation could leak out as part of
1069
+ # (at least) if statements dependency nodes.
1070
+ outer_letname = genname ('let' )
1071
+ let_fn_body : List [ast .AST ] = []
1072
+
1066
1073
# Generate a function to hold the body of the let expression
1067
1074
letname = genname ('let' )
1068
1075
with ctx .new_symbol_table (letname ):
1069
1076
args , body , vargs = _fn_args_body (ctx , vec .vector (arg_syms .keys ()), runtime .nthrest (form , 2 ))
1070
- yield _dependency (_expressionize (body , letname , args = args , vargs = vargs ))
1077
+ let_fn_body . append (_expressionize (body , letname , args = args , vargs = vargs ))
1071
1078
1072
1079
# Generate local variable assignments for processing let bindings
1073
1080
var_names = seq (var_names ).map (lambda n : ast .Name (id = n , ctx = ast .Store ()))
1074
1081
for name , deps , expr in zip (var_names , arg_deps , arg_exprs ):
1075
- yield from deps
1076
- yield _dependency (ast .Assign (targets = [name ], value = expr ))
1082
+ let_fn_body .extend (_unwrap_nodes (deps ))
1083
+ let_fn_body .append (ast .Assign (targets = [name ], value = expr ))
1084
+
1085
+ let_fn_body .append (ast .Call (func = _load_attr (letname ),
1086
+ args = seq (arg_syms .values ()).map (lambda n : ast .Name (id = n , ctx = ast .Load ())).to_list (),
1087
+ keywords = []))
1077
1088
1078
- yield _node (ast .Call (func = _load_attr (letname ),
1079
- args = seq (arg_syms .values ()).map (lambda n : ast .Name (id = n , ctx = ast .Load ())).to_list (),
1080
- keywords = []))
1089
+ yield _dependency (_expressionize (let_fn_body , outer_letname ))
1090
+ yield _node (ast .Call (func = _load_attr (outer_letname ), args = [], keywords = []))
1081
1091
1082
1092
1083
1093
def _quote_ast (ctx : CompilerContext , form : llist .List ) -> ASTStream :
0 commit comments