Skip to content

Commit

Permalink
Fix Uref in foreach loop
Browse files Browse the repository at this point in the history
Summary: When a Uref is in a foreach loop, the Uref node is collapsed into an Lvar. This diff preserves the Uref node.

Reviewed By: jamesjwu

Differential Revision: D5554699

fbshipit-source-id: 524cf07a52017e6244378d37110ab5b5bfdc92b7
  • Loading branch information
rameshvarun authored and hhvm-bot committed Aug 15, 2017
1 parent 58de2a6 commit 4cedc0e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
3 changes: 2 additions & 1 deletion hphp/hack/src/typing/typing.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2232,7 +2232,8 @@ let make_result env te1 ty1 = (env, T.make_typed_expr p ty1 te1, ty1) in
(* references can be "lvalues" in foreach bindings *)
if Env.is_strict env then
Errors.reference_expr pref;
assign p env e1' ty2
let env, texpr, ty = assign p env e1' ty2 in
make_result env (T.Unop (Ast.Uref, texpr)) ty
| _ ->
assign_simple p env e1 ty2

Expand Down
11 changes: 11 additions & 0 deletions hphp/hack/test/tast/foreach_ref.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?hh
function foo(): int {
$arr = array(1, 2, 3);
$y = 0;
foreach ($arr as &$val) {
$y += $val++;
}
var_dump($arr);
return $y;
}
foo();
67 changes: 67 additions & 0 deletions hphp/hack/test/tast/foreach_ref.php.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[(AnnotatedAST.Fun
{ AnnotatedAST.f_mode = <opaque>;
f_ret = (Some (<p>, (Hprim Tint)));
f_name = (<p>, "\\foo"); f_tparams = [];
f_where_constraints = []; f_variadic = AnnotatedAST.FVnonVariadic;
f_params = [];
f_body =
(AnnotatedAST.NamedBody
{ AnnotatedAST.fnb_nast =
[(AnnotatedAST.Expr
((Some array<int>),
(AnnotatedAST.Binop ((Eq None),
((Some array<int>),
(AnnotatedAST.Lvar (<p>, $arr))),
((Some array<int>),
(AnnotatedAST.Array
[(AnnotatedAST.AFvalue
((Some int),
(AnnotatedAST.Int (<p>, "1"))));
(AnnotatedAST.AFvalue
((Some int),
(AnnotatedAST.Int (<p>, "2"))));
(AnnotatedAST.AFvalue
((Some int),
(AnnotatedAST.Int (<p>, "3"))))
]))
))));
(AnnotatedAST.Expr
((Some int),
(AnnotatedAST.Binop ((Eq None),
((Some int), (AnnotatedAST.Lvar (<p>, $y))),
((Some int), (AnnotatedAST.Int (<p>, "0")))))));
(AnnotatedAST.Foreach (
((Some array<int>), (AnnotatedAST.Lvar (<p>, $arr))),
(AnnotatedAST.As_v
((Some int),
(AnnotatedAST.Unop (Uref,
((Some int), (AnnotatedAST.Lvar (<p>, $val)))
)))),
[(AnnotatedAST.Expr
((Some int),
(AnnotatedAST.Binop ((Eq (Some Plus)),
((Some int), (AnnotatedAST.Lvar (<p>, $y))),
((Some int),
(AnnotatedAST.Unop (Upincr,
((Some int),
(AnnotatedAST.Lvar (<p>, $val)))
)))
))))
]
));
(AnnotatedAST.Expr
((Some _),
(AnnotatedAST.Call (Cnormal,
((Some (function<...>($expression): _)),
(AnnotatedAST.Id (<p>, "\\var_dump"))),
[],
[((Some array<int>),
(AnnotatedAST.Lvar (<p>, $arr)))],
[]))));
(AnnotatedAST.Return (<p>,
(Some ((Some int), (AnnotatedAST.Lvar (<p>, $y))))
))
];
fnb_unsafe = false });
f_fun_kind = FSync; f_user_attributes = [] })
]

0 comments on commit 4cedc0e

Please sign in to comment.