Make hh_single_type_check --MRO output easier to read
[hiphop-php.git] / hphp / hack / src / typing / tast_check / foreach_collection_reactivity_check.ml
bloba0e728a282864b2db8f890bc0d93deb6abe06ceb
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 Hh_prelude
11 open Aast
12 open Typing_defs
13 module Env = Tast_env
14 module MakeType = Typing_make_type
15 module SN = Naming_special_names
17 let rxTraversableType =
18 MakeType.class_type
19 Reason.none
20 SN.Rx.cTraversable
21 [MakeType.mixed Reason.Rnone]
23 let rxAsyncIteratorType =
24 MakeType.class_type
25 Reason.none
26 SN.Rx.cAsyncIterator
27 [MakeType.mixed Reason.Rnone]
29 let check_foreach_collection env p ty =
30 (* do nothing if unsafe_rx is set *)
31 if TypecheckerOptions.unsafe_rx (Env.get_tcopt env) then
33 else
34 match Env.env_reactivity env with
35 | r when not (any_reactive r) -> ()
36 | _ ->
37 let rec check ty =
38 let (env, ty) = Env.expand_type env ty in
39 match get_node ty with
40 | Tunion l -> List.for_all l ~f:check
41 | Tdynamic ->
42 (* If it's a dynamic, we have no way of knowing whether or not it's
43 valid. Let it fail at runtime *)
44 true
45 | _ ->
46 (* collection type should be subtype or conditioned to Rx\Traversable *)
48 not
49 ( Env.can_subtype env ty rxTraversableType
50 || Env.can_subtype env ty rxAsyncIteratorType
51 || Env.condition_type_matches
52 ~is_self:false
53 env
55 rxTraversableType
56 || Env.condition_type_matches
57 ~is_self:false
58 env
60 rxAsyncIteratorType )
61 then (
62 Errors.invalid_traversable_in_rx p;
63 false
64 ) else
65 true
67 ignore (check ty)
69 let handler =
70 object
71 inherit Tast_visitor.handler_base
73 method! at_stmt env x =
74 match snd x with
75 | Foreach (((p, ty), _), _, _) -> check_foreach_collection env p ty
76 | _ -> ()
77 end