@@ -2198,7 +2198,8 @@ simplify_let(#c_let{arg=Arg}=Let, Sub) ->
2198
2198
move_let_into_expr (Let , Arg , Sub ).
2199
2199
2200
2200
move_let_into_expr (# c_let {vars = InnerVs0 ,body = InnerBody0 }= Inner0 ,
2201
- # c_let {vars = OuterVs0 ,arg = Arg0 ,body = OuterBody0 }= Outer , Sub0 ) ->
2201
+ # c_let {vars = OuterVs0 ,arg = OuterArg0 ,body = OuterBody0 }= Outer0 ,
2202
+ Sub0 ) ->
2202
2203
% %
2203
2204
% % let <InnerVars> = let <OuterVars> = <Arg>
2204
2205
% % in <OuterBody>
@@ -2210,29 +2211,33 @@ move_let_into_expr(#c_let{vars=InnerVs0,body=InnerBody0}=Inner0,
2210
2211
% % in let <InnerVars> = <OuterBody>
2211
2212
% % in <InnerBody>
2212
2213
% %
2213
- Arg = body (Arg0 , Sub0 ),
2214
+ OuterArg = body (OuterArg0 , Sub0 ),
2214
2215
ScopeSub0 = sub_subst_scope (Sub0 # sub {t = #{}}),
2215
- {OuterVs ,ScopeSub } = var_list (OuterVs0 , ScopeSub0 ),
2216
2216
2217
+ {OuterVs ,ScopeSub } = var_list (OuterVs0 , ScopeSub0 ),
2217
2218
OuterBody = body (OuterBody0 , ScopeSub ),
2218
2219
2220
+ {InnerVs ,Sub } = var_list (InnerVs0 , Sub0 ),
2221
+ InnerBody = body (InnerBody0 , Sub ),
2222
+
2219
2223
case will_fail (OuterBody ) of
2220
2224
true ->
2225
+ % % If the outer body is known to fail, changing
2226
+ % % the structure may create unsafe code that
2227
+ % % requires another iteration of the outer
2228
+ % % fixpoint loop to clean it up, which is not
2229
+ % % guaranteed since it runs for a limited number
2230
+ % % of iterations.
2221
2231
% %
2222
- % % Avoid creating potentially unsafe code that
2223
- % % depends on another iteration of the outer
2224
- % % fixpoint loop to clean up. If <OuterBody>
2225
- % % consists of nested lets, we may run out of
2226
- % % iterations before the unsafe code is
2227
- % % eliminated.
2228
- % %
2229
- Inner0 ;
2232
+ % % Note that we still need to update the bodies
2233
+ % % as they might reference variables that no
2234
+ % % longer exist.
2235
+ Outer0 = Inner0 # c_let .arg , % Assertion.
2236
+ Outer = Outer0 # c_let {vars = OuterVs ,arg = OuterArg ,body = OuterBody },
2237
+ Inner0 # c_let {vars = InnerVs ,arg = Outer ,body = InnerBody };
2230
2238
false ->
2231
- {InnerVs ,Sub } = var_list (InnerVs0 , Sub0 ),
2232
- InnerBody = body (InnerBody0 , Sub ),
2233
-
2234
2239
Inner = Inner0 # c_let {vars = InnerVs ,arg = OuterBody ,body = InnerBody },
2235
- Outer # c_let {vars = OuterVs ,arg = Arg ,body = Inner }
2240
+ Outer0 # c_let {vars = OuterVs ,arg = OuterArg ,body = Inner }
2236
2241
end ;
2237
2242
move_let_into_expr (# c_let {vars = Lvs0 ,body = Lbody0 }= Let ,
2238
2243
# c_case {arg = Cexpr0 ,clauses = [Ca0 |Cs0 ]}= Case , Sub0 ) ->
0 commit comments