summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Bauereiss2018-05-17 16:00:31 +0100
committerThomas Bauereiss2018-05-18 20:11:24 +0100
commit5e363d23bc54b3970a9e1f6fbea77bbb8459df6f (patch)
treeac6bd6ea9d6eaa4db3057788225b541cf34af8a6 /src
parent96efc58a8c8a6f61988d42a552dceb167d4f603d (diff)
Fix bug in rewriting variable updates
Diffstat (limited to 'src')
-rw-r--r--src/rewrites.ml9
1 files changed, 6 insertions, 3 deletions
diff --git a/src/rewrites.ml b/src/rewrites.ml
index b59a248e..dff8e3e5 100644
--- a/src/rewrites.ml
+++ b/src/rewrites.ml
@@ -2911,7 +2911,8 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) =
| E_for(id,exp1,exp2,exp3,order,exp4) ->
(* Translate for loops into calls to one of the foreach combinators.
The loop body becomes a function of the loop variable and any
- mutable local variables that are updated inside the loop.
+ mutable local variables that are updated inside the loop and
+ are used after or within the loop.
Since the foreach* combinators are higher-order functions,
they cannot be represented faithfully in the AST. The following
code abuses the parameters of an E_app node, embedding the loop body
@@ -2920,7 +2921,7 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) =
function and passed to foreach*. *)
let vars, varpats =
find_updated_vars exp4
- |> IdSet.inter used_vars
+ |> IdSet.inter (IdSet.union used_vars (find_used_vars full_exp))
|> mk_var_exps_pats pl env
in
let exp4 = rewrite_var_updates (add_vars overwrite exp4 vars) in
@@ -2976,9 +2977,11 @@ let rec rewrite_var_updates ((E_aux (expaux,((l,_) as annot))) as exp) =
let v = fix_eff_exp (annot_exp (E_app (mk_id "foreach", [exp1; exp2; exp3; ord_exp; tuple_exp vars; guarded_body])) el env (typ_of body)) in
Added_vars (v, tuple_pat (if overwrite then varpats else pat :: varpats))
| E_loop(loop,cond,body) ->
+ (* Find variables that might be updated in the loop body and are used
+ either after or within the loop. *)
let vars, varpats =
find_updated_vars body
- |> IdSet.inter used_vars
+ |> IdSet.inter (IdSet.union used_vars (find_used_vars full_exp))
|> mk_var_exps_pats pl env
in
let body = rewrite_var_updates (add_vars overwrite body vars) in