Skip to content

Commit c0048a4

Browse files
Andrew Kennedymeta-codesync[bot]
authored andcommitted
Hard-ban unset on non-array-access expressions
Summary: Add unfixmeable `Typing[4521]` for `unset(e)` when `e` is not an array access. Keep the existing container-type diagnostic for indexed accesses and cover local and property targets. Reviewed By: fangyi-zhou Differential Revision: D116917392 fbshipit-source-id: e3c2ad999de256d65fc4092b3d872f16070a05ee
1 parent 05e2011 commit c0048a4

18 files changed

Lines changed: 51 additions & 32 deletions

hphp/hack/src/diagnostics/error_codes.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,7 @@ module Typing = struct
816816
| StrictIsolationExcludedPathAccess [@value 4518]
817817
| EnumDuplicateValue [@value 4519]
818818
| EnumUncheckableValue [@value 4520]
819+
| InvalidUnsetTarget [@value 4521]
819820
(* Add new Typing codes here! Comment out when deprecating. *)
820821
[@@deriving enum, show { with_path = false }]
821822

hphp/hack/src/hackc/test/infer/member_op.hack

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -229,20 +229,6 @@ function mop_basel_unset_ei(dict<int, int> $a): void {
229229
unset($a[5]);
230230
}
231231

232-
// TEST-CHECK-BAL: define $root.mop_basel_unset_pt
233-
// CHECK: define $root.mop_basel_unset_pt($this: *void, $a: *C) : *void {
234-
// CHECK: #b0:
235-
// CHECK: // .column 1
236-
// CHECK: n0: *HackMixed = load &$a
237-
// CHECK: store n0.?.foo <- null: *HackMixed
238-
// CHECK: // .column 2
239-
// CHECK: ret null
240-
// CHECK: }
241-
function mop_basel_unset_pt(C $a): void {
242-
/* HH_FIXME[4135] Allow unset */
243-
unset($a->foo);
244-
}
245-
246232
// TEST-CHECK-BAL: define $root.mop_basec_querym_cget(
247233
// CHECK: define $root.mop_basec_querym_cget($this: *void, $d: .notnull *HackDict) : .notnull *HackInt {
248234
// CHECK: #b0:

hphp/hack/src/oxidized/gen/error_codes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// This source code is licensed under the MIT license found in the
44
// LICENSE file in the "hack" directory of this source tree.
55
//
6-
// @generated SignedSource<<7ef8934272d5c4675b44238825a34e3f>>
6+
// @generated SignedSource<<23a844de2b22a4423d0dc60ebaff4a51>>
77
//
88
// To regenerate this file, run:
99
// buck run @fbcode//mode/dev-nosan-lg fbcode//hphp/hack/src:oxidized_regen
@@ -587,6 +587,7 @@ pub enum Typing {
587587
StrictIsolationExcludedPathAccess = 4518,
588588
EnumDuplicateValue = 4519,
589589
EnumUncheckableValue = 4520,
590+
InvalidUnsetTarget = 4521,
590591
}
591592
impl TrivialDrop for Typing {}
592593
arena_deserializer::impl_deserialize_in_arena!(Typing);

hphp/hack/src/typing/typing.ml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6168,6 +6168,18 @@ end = struct
61686168
@@ Some
61696169
Typing_error.(
61706170
primary @@ Primary.Unset_nonidx_in_strict { pos = p; reason })
6171+
| ([Aast_defs.Anormal (_, _, Array_get (_, None))], None) ->
6172+
let ty_err =
6173+
Typing_error.(
6174+
primary
6175+
@@ Primary.Unset_nonidx_in_strict { pos = p; reason = lazy [] })
6176+
in
6177+
(env, Some ty_err)
6178+
| ([Aast_defs.Anormal _], None) ->
6179+
let ty_err =
6180+
Typing_error.(primary @@ Primary.Invalid_unset_target p)
6181+
in
6182+
(env, Some ty_err)
61716183
| _ ->
61726184
let ty_err =
61736185
Typing_error.(

hphp/hack/src/typing/typing_error.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ module Primary = struct
683683
pos: Pos.t;
684684
reason: Pos_or_decl.t Message.t list Lazy.t;
685685
}
686+
| Invalid_unset_target of Pos.t
686687
| Nullable_cast of {
687688
pos: Pos.t;
688689
ty_pos: Pos_or_decl.t;

hphp/hack/src/typing/typing_error.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ module Primary : sig
642642
pos: Pos.t;
643643
reason: Pos_or_decl.t Message.t list Lazy.t;
644644
}
645+
| Invalid_unset_target of Pos.t
645646
| Nullable_cast of {
646647
pos: Pos.t;
647648
ty_pos: Pos_or_decl.t;

hphp/hack/src/typing/typing_error_utils.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4288,6 +4288,12 @@ end = struct
42884288
~reasons
42894289
()
42904290

4291+
let invalid_unset_target pos =
4292+
create
4293+
~code:Error_code.InvalidUnsetTarget
4294+
~claim:(lazy (pos, "The argument to `unset` must be an array access."))
4295+
()
4296+
42914297
let unpacking_disallowed_builtin_function pos name =
42924298
create
42934299
~code:Error_code.UnpackingDisallowed
@@ -5099,6 +5105,7 @@ end = struct
50995105
| Invalid_substring { pos; ty_name } -> invalid_substring pos ty_name
51005106
| Unset_nonidx_in_strict { pos; reason } ->
51015107
unset_nonidx_in_strict pos reason
5108+
| Invalid_unset_target pos -> invalid_unset_target pos
51025109
| Nullable_cast { pos; ty_pos; ty_name } -> nullable_cast pos ty_pos ty_name
51035110
| Hh_expect { pos; equivalent } -> hh_expect pos equivalent
51045111
| Null_member { pos; obj_pos_opt; ctxt; kind; member_name; reason } ->

hphp/hack/test/tast/pseudofunctions.php.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Errors:
22
[16:3-12] `isset` tends to hide errors due to variable typos and so is limited to dynamic checks in `strict` mode
3-
[17:3-13] In `strict` mode, `unset` is banned except on dynamic, darray, keyset, or dict indexing
3+
[17:3-13] The argument to `unset` must be an array access.
44
[(Class
55
{ c_span = [3:1-6:2]; c_annotation = (); c_mode = Mstrict; c_final = false;
66
c_is_xhp = false; c_has_xhp_keyword = false; c_kind = (Cclass Concrete);

hphp/hack/test/typecheck/argument_unpacking/unpack_call10_unset.php.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ An expression is expected here. (Parsing[1002])
55
ERROR: File "unpack_call10_unset.php", line 6, characters 9-11:
66
Unbound name: `...` (a global constant) (Naming[2049])
77
ERROR: File "unpack_call10_unset.php", line 6, characters 3-18:
8-
In `strict` mode, `unset` is banned except on dynamic, darray, keyset, or dict indexing (Typing[4135])
8+
The argument to `unset` must be an array access. (Typing[4521])
99
ERROR: File "unpack_call10_unset.php", line 6, characters 9-11:
1010
Unbound global constant (Typing) (Typing[4106])
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
ERROR: File "unset_const_on_instance.php", line 10, characters 9-13:
22
You cannot use this syntax in an `unset()` expression. (Parsing[1002])
33
ERROR: File "unset_const_on_instance.php", line 10, characters 3-15:
4-
In `strict` mode, `unset` is banned except on dynamic, darray, keyset, or dict indexing (Typing[4135])
4+
The argument to `unset` must be an array access. (Typing[4521])

0 commit comments

Comments
 (0)