From 2ac4c4d9ce4d371ceb53039e66474b7e23e3606d Mon Sep 17 00:00:00 2001 From: Andrew Kennedy Date: Sat, 13 Apr 2019 23:17:19 -0700 Subject: [PATCH] Treat array as subtype of Traversable Summary: Currently, the untyped array type `array` is a subtype of `Traversable` and `KeyedTraversable` for *any* `t` and `u`. This diff makes a small change: it is now treated as a subtype of `Traversable<_>` and `KeyedTraversable<_,_>` where `_` is the "any" type. This leads to better propagation of `_`, rather than instantiation with `[unresolved]` (under legacy checking) or `nothing` (in new inference), or unresolved type variables that later produce errors (new inference). See the new test for an example of this latter behaviour. Reviewed By: dlreeves Differential Revision: D14916991 fbshipit-source-id: 66d044a0bcf5462b60c3de5ba2b1bc2f056c9862 --- hphp/hack/src/typing/typing_subtype.ml | 10 +++++++--- hphp/hack/test/tast/array_filter.php.exp | 4 ++-- hphp/hack/test/typecheck/new_inference/untyped_array.php | 8 ++++++++ hphp/hack/test/typecheck/new_inference/untyped_array.php.exp | 1 + 4 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 hphp/hack/test/typecheck/new_inference/untyped_array.php create mode 100644 hphp/hack/test/typecheck/new_inference/untyped_array.php.exp diff --git a/hphp/hack/src/typing/typing_subtype.ml b/hphp/hack/src/typing/typing_subtype.ml index f81bc73d223..90156b1c3d2 100644 --- a/hphp/hack/src/typing/typing_subtype.ml +++ b/hphp/hack/src/typing/typing_subtype.ml @@ -802,8 +802,9 @@ and simplify_subtype coll = SN.Rx.cTraversable || coll = SN.Collections.cContainer) -> (match akind with - (* array <: Traversable and emptyarray <: Traversable for any t *) - | AKany -> valid () + (* array <: Traversable<_> and emptyarray <: Traversable for any t *) + | AKany -> + simplify_subtype ~seen_generic_params ~deep ~this_ty (fst ety_sub, Tany) tv_super env | AKempty -> valid () (* vec <: Traversable * iff tv <: tv_super @@ -823,7 +824,10 @@ and simplify_subtype || coll = SN.Collections.cKeyedContainer) -> let r = fst ety_sub in (match akind with - | AKany -> valid () + | AKany -> + env |> + simplify_subtype ~seen_generic_params ~deep ~this_ty (fst ety_sub, Tany) tk_super &&& + simplify_subtype ~seen_generic_params ~deep ~this_ty (fst ety_sub, Tany) tv_super | AKempty -> valid () | AKvarray tv | AKvec tv -> diff --git a/hphp/hack/test/tast/array_filter.php.exp b/hphp/hack/test/tast/array_filter.php.exp index 0a4baf3119c..b6226570f39 100644 --- a/hphp/hack/test/tast/array_filter.php.exp +++ b/hphp/hack/test/tast/array_filter.php.exp @@ -70,7 +70,7 @@ (Expr (([13:3-31], array), (Call (Cnormal, - (([13:3-15], (function(Container $input, ?(function(nothing): bool) $callback): array)), + (([13:3-15], (function(Container<_> $input, ?(function(_): bool) $callback): array)), (Id ([13:3-15], "\\array_filter"))), [], [(([13:16-30], array), (Lvar ([13:16-30], $untyped_array))) @@ -163,7 +163,7 @@ (Expr (([22:3-35], array), (Call (Cnormal, - (([22:3-15], (function(Container $input, ?(function(nothing): bool) $callback): array)), + (([22:3-15], (function(Container<_> $input, ?(function(_): bool) $callback): array)), (Id ([22:3-15], "\\array_filter"))), [], [(([22:16-30], array), (Lvar ([22:16-30], $untyped_array))); diff --git a/hphp/hack/test/typecheck/new_inference/untyped_array.php b/hphp/hack/test/typecheck/new_inference/untyped_array.php new file mode 100644 index 00000000000..6aebd050475 --- /dev/null +++ b/hphp/hack/test/typecheck/new_inference/untyped_array.php @@ -0,0 +1,8 @@ +foo(); + $y = new Map($m); + $y['a']->foo(); +} diff --git a/hphp/hack/test/typecheck/new_inference/untyped_array.php.exp b/hphp/hack/test/typecheck/new_inference/untyped_array.php.exp new file mode 100644 index 00000000000..4269126fceb --- /dev/null +++ b/hphp/hack/test/typecheck/new_inference/untyped_array.php.exp @@ -0,0 +1 @@ +No errors -- 2.11.4.GIT