New inference: use lists not sets for tyvars
[hiphop-php.git] / hphp / hack / src / typing / typing_env_types.ml
blob67c06ae80666b62496d09616546a2825efe3ec6a
1 (**
2 * Copyright (c) 2015, 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 (* cf: typing_env_types_sig.mli - These files should be the same *)
11 open Core_kernel
12 open Typing_defs
13 open Type_parameter_env
14 module TySet = Typing_set
16 let show_locl_ty _ = "<locl_ty>"
17 let pp_locl_ty _ _ = Printf.printf "%s\n" "<locl_ty>"
18 type locl_ty = locl ty
20 type fake_members = {
21 last_call : Pos.t option;
22 invalid : SSet.t;
23 valid : SSet.t;
24 } [@@deriving show]
25 (* Along with a type, each local variable has a expression id associated with
26 * it. This is used when generating expression dependent types for the 'this'
27 * type. The idea is that if two local variables have the same expression_id
28 * then they refer to the same late bound type, and thus have compatible
29 * 'this' types.
31 type expression_id = Ident.t [@@deriving show]
32 type local = locl_ty * expression_id [@@deriving show]
34 let show_local_id_map _ = "<local_id_map>"
35 let pp_local_id_map _ _ = Printf.printf "%s\n" "<local_id_map>"
36 type local_id_map = local Local_id.Map.t
38 let show_local_types _ = "<local_types>"
39 let pp_local_types _ _ = Printf.printf "%s\n" "<local_types>"
40 type local_types = local_id_map Typing_continuations.Map.t
42 let show_local_id_set_t _ = "<local_id_set_t>"
43 let pp_local_id_set_t _ _ = Printf.printf "%s\n" "<local_id_set_t>"
44 type local_id_set_t = Local_id.Set.t
46 let show_local_env _ = "<local_env>"
47 let pp_local_env _ _ = Printf.printf "%s\n" "<local_env>"
49 (* Local environment includes types of locals and bounds on type parameters. *)
50 type local_env = {
51 (* Fake members are used when we want member variables to be treated like
52 * locals. We want to handle the following:
53 * if($this->x) {
54 * ... $this->x ...
55 * }
56 * The trick consists in replacing $this->x with a "fake" local. So that
57 * all the logic that normally applies to locals is applied in cases like
58 * this. Hence the name: FakeMembers.
59 * All the fake members are thrown away at the first call.
60 * We keep the invalidated fake members for better error messages.
62 fake_members : fake_members;
63 (* Local types per continuation. For example, the local types of the
64 * break continuation correspond to the local types that there were at the
65 * last encountered break in the current scope. These are kept to be merged
66 * at the appropriate merge points. *)
67 local_types : local_types;
68 local_mutability : Typing_mutability_env.mutability_env;
70 (* Whether current environment is reactive *)
71 local_reactive : reactivity;
72 (* Local variables that were assigned in a `using` clause *)
73 local_using_vars : local_id_set_t;
74 (* Type parameter environment
75 * Lower and upper bounds on generic type parameters and abstract types
76 * For constraints of the form Tu <: Tv where both Tu and Tv are type
77 * parameters, we store an upper bound for Tu and a lower bound for Tv.
78 * Contrasting with tenv and subst, bounds are *assumptions* for type
79 * inference, not conclusions.
81 tpenv : tpenv;
84 let show_env _ = "<env>"
85 let pp_env _ _ = Printf.printf "%s\n" "<env>"
87 let show_genv _ = "<genv>"
88 let pp_genv _ _ = Printf.printf "%s\n" "<genv>"
90 let show_anon _ = "<anon>"
91 let pp_anon _ _ = Printf.printf "%s\n" "<anon>"
93 let show_tfun _ = "<tfun>"
94 let pp_tfun _ _ = Printf.printf "%s\n" "<tfun>"
96 type tvar_info = {
97 (* Does this type variable appear covariantly in the type of the expression?
99 appears_covariantly: bool;
100 (* Does this type variable appear contravariantly in the type of the expression?
101 * If it appears in an invariant position then both will be true; if it doesn't
102 * appear at all then both will be false
104 appears_contravariantly: bool;
105 lower_bounds : TySet.t;
106 upper_bounds : TySet.t;
108 type tvenv = tvar_info IMap.t
110 type env = {
111 (* position of the function/method being checked *)
112 function_pos: Pos.t;
113 pos : Pos.t ;
114 (* Position and reason information on entry to a subtype or unification check *)
115 outer_pos : Pos.t;
116 outer_reason : Typing_reason.ureason;
117 tenv : locl_ty IMap.t ;
118 subst : int IMap.t ;
119 lenv : local_env ;
120 genv : genv ;
121 decl_env: Decl_env.env;
122 todo : tfun list ;
123 checking_todos : bool;
124 in_loop : bool ;
125 in_try : bool ;
126 in_case : bool ;
127 inside_constructor: bool;
128 inside_ppl_class: bool;
129 (* A set of constraints that are global to a given method *)
130 global_tpenv : tpenv ;
131 subtype_prop : Typing_logic.subtype_prop;
132 log_levels : int SMap.t ;
133 tvenv : tvenv;
134 tyvars_stack : Ident.t list list;
136 and genv = {
137 tcopt : TypecheckerOptions.t;
138 return : Typing_env_return_info.t;
139 (* For each function parameter, its type and calling convention. *)
140 params : (locl_ty * param_mode) Local_id.Map.t;
141 (* condition types associated with parameters.
142 For every mayberx parameter that has condition type we create
143 fresh type parameter (see: make_local_param_ty) and store mapping
144 fresh type name -> condition type in env so it can be retrieved later *)
145 condition_types: decl ty SMap.t;
146 parent_id : string;
147 parent : decl ty;
148 (* Identifier of the enclosing class *)
149 self_id : string;
150 (* Type of the enclosing class, instantiated at its generic parameters *)
151 self : locl_ty;
152 static : bool;
153 fun_kind : Ast.fun_kind;
154 fun_mutable : param_mutability option;
155 anons : anon IMap.t;
156 file : Relative_path.t;
159 (* A type-checker for an anonymous function
160 * Parameters are
161 * - the environment
162 * - types of the parameters under which the body should be checked
163 * - the arity of the function
164 * - the expected return type of the body (optional)
166 and anon_log = locl_ty list * locl ty list
168 and anon =
169 reactivity *
170 Nast.is_coroutine *
171 anon_log ref *
172 Pos.t *
173 (?el:Nast.expr list ->
174 ?ret_ty: locl_ty ->
175 env ->
176 locl fun_params ->
177 locl fun_arity ->
178 env * Tast.expr * locl_ty)
180 (* A deferred check; return true if the check should now be removed from the list *)
181 and tfun = env -> env * bool