rename Tunresolved to Tunion
[hiphop-php.git] / hphp / hack / src / typing / tast_check / foreach_collection_reactivity_check.ml
blobe769d2a3b865cdc0fdf8d3cfbfc9e31ebdbb5260
1 (**
2 * Copyright (c) 2018, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
8 *)
10 open Core_kernel
11 open Tast
12 open Typing_defs
14 module Env = Tast_env
15 module MakeType = Typing_make_type
17 let rxTraversableType =
18 MakeType.class_type Reason.none Naming_special_names.Rx.cTraversable [(Reason.Rnone, Tany)]
20 let rxAsyncIteratorType =
21 MakeType.class_type Reason.none Naming_special_names.Rx.cAsyncIterator [(Reason.Rnone, Tany)]
23 let check_foreach_collection env p ty =
24 (* do nothing if unsafe_rx is set *)
25 if TypecheckerOptions.unsafe_rx (Env.get_tcopt env) then () else
26 match Env.env_reactivity env with | Nonreactive | Local _ -> () | _ ->
27 let rec check ty =
28 let env, ty = Env.expand_type env ty in
29 match ty with
30 | _, Tunion l -> List.for_all l ~f:check
31 | _ ->
32 (* collection type should be subtype or conditioned to Rx\Traversable *)
33 if not (Env.can_subtype env ty rxTraversableType ||
34 Env.can_subtype env ty rxAsyncIteratorType ||
35 Env.condition_type_matches ~is_self:false env ty rxTraversableType ||
36 Env.condition_type_matches ~is_self:false env ty rxAsyncIteratorType)
37 then begin
38 Errors.invalid_traversable_in_rx p;
39 false
40 end
41 else true in
42 ignore (check ty)
44 let handler = object
45 inherit Tast_visitor.handler_base
47 method! at_stmt env x =
48 match snd x with
49 | Foreach (((p, ty), _), _, _) -> check_foreach_collection env p ty
50 | _ -> ()
51 end