Skip to content

Commit

Permalink
Reject use of open tuples in is or as tests
Browse files Browse the repository at this point in the history
Summary: As the title says. We don't yet support this in HHVM, so should reject it for Hack.

Differential Revision: D68208091

fbshipit-source-id: 80d93a81052822055ad8b2e0d26aac59fcbdbfaa
  • Loading branch information
Andrew Kennedy authored and facebook-github-bot committed Jan 16, 2025
1 parent 9a1bf15 commit 591fe0a
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 5 deletions.
16 changes: 11 additions & 5 deletions hphp/hack/src/typing/typing_enforceable_hint.ml
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,19 @@ let validator =
( Typing_defs_core.get_reason ty,
"_ in a " ^ s ^ " (use `mixed` instead)" )))

method! on_ttuple acc _ { t_required; t_extra } =
method! on_ttuple acc r { t_required; t_extra } =
let acc = List.fold_left t_required ~f:this#on_type ~init:acc in
match t_extra with
| Textra { t_optional; t_variadic = _ } ->
let acc = List.fold_left t_optional ~f:this#on_type ~init:acc in
this#check_for_wildcards acc t_required "tuple"
| Tsplat t_splat -> this#on_type acc t_splat
| Textra { t_optional; t_variadic } ->
(* HHVM doesn't currently support is/as on open tuples, so let's reject it in Hack *)
if (not (is_nothing t_variadic)) || not (List.is_empty t_optional) then
this#invalid acc r
@@ "a tuple type with optional or variadic elements"
else
this#check_for_wildcards acc t_required "tuple"
| Tsplat _ ->
(* HHVM doesn't currently support is/as on type splats, so let's reject it in Hack *)
this#invalid acc r @@ "a tuple type with a splat element"

method! on_tshape acc _ { s_fields = fdm; _ } =
let tyl = TShapeMap.values fdm |> List.map ~f:(fun s -> s.sft_ty) in
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?hh
<<file: __EnableUnstableFeatures('open_tuples', 'type_splat')>>

function test2<<<__Enforceable>> reify T as (mixed...)>(mixed $m): void {
$m as (int, ...T);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ERROR: File "tuple_splat_is_as_test_bad.php", line 5, characters 9-19:
Invalid `as` expression hint (Typing[4195])
File "tuple_splat_is_as_test_bad.php", line 5, characters 9-19:
The `as` operator cannot be used with a tuple type with a splat element
14 changes: 14 additions & 0 deletions hphp/hack/test/typecheck/open_tuples/tuple_open_is_as_test_bad.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?hh
<<file: __EnableUnstableFeatures('open_tuples')>>

function test1(mixed $m): string {
$m as (nonnull...);
if ($m is (int, optional string)) {
return $m[1] ?? "default";
}
if ($m is (int, string...)) {
return $m[1] ?? "default";
}
$m as (optional bool, optional int);
return "fail";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
WARN: File "tuple_open_is_as_test_bad.php", line 6, characters 7-34:
This `is` check is always `false`. The expression on the left has type `(nonnull...)` which shares no values with `(int, optional string)`. (Warn[12010])
WARN: File "tuple_open_is_as_test_bad.php", line 9, characters 7-28:
This `is` check is always `false`. The expression on the left has type `(nonnull...)` which shares no values with `(int, string...)`. (Warn[12010])
ERROR: File "tuple_open_is_as_test_bad.php", line 5, characters 9-20:
Invalid `as` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 5, characters 9-20:
The `as` operator cannot be used with a tuple type with optional or variadic elements
ERROR: File "tuple_open_is_as_test_bad.php", line 6, characters 13-34:
Invalid `is` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 6, characters 13-34:
The `is` operator cannot be used with a tuple type with optional or variadic elements
ERROR: File "tuple_open_is_as_test_bad.php", line 9, characters 13-28:
Invalid `is` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 9, characters 13-28:
The `is` operator cannot be used with a tuple type with optional or variadic elements
ERROR: File "tuple_open_is_as_test_bad.php", line 12, characters 9-37:
Invalid `as` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 12, characters 9-37:
The `as` operator cannot be used with a tuple type with optional or variadic elements
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ERROR: File "tuple_open_is_as_test_bad.php", line 5, characters 9-20:
Invalid `as` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 5, characters 9-20:
The `as` operator cannot be used with a tuple type with optional or variadic elements
ERROR: File "tuple_open_is_as_test_bad.php", line 6, characters 13-34:
Invalid `is` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 6, characters 13-34:
The `is` operator cannot be used with a tuple type with optional or variadic elements
ERROR: File "tuple_open_is_as_test_bad.php", line 9, characters 13-28:
Invalid `is` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 9, characters 13-28:
The `is` operator cannot be used with a tuple type with optional or variadic elements
ERROR: File "tuple_open_is_as_test_bad.php", line 12, characters 9-37:
Invalid `as` expression hint (Typing[4195])
File "tuple_open_is_as_test_bad.php", line 12, characters 9-37:
The `as` operator cannot be used with a tuple type with optional or variadic elements

0 comments on commit 591fe0a

Please sign in to comment.