|
7 | 7 | *) |
8 | 8 | open Hh_prelude |
9 | 9 | open Common |
10 | | -open Utils |
11 | 10 | open Typing_defs |
12 | 11 | open Typing_kinding_defs |
13 | 12 | module Env = Typing_env |
14 | 13 | module Cls = Folded_class |
15 | 14 | module KindDefs = Typing_kinding_defs |
16 | | -module TGenConstraint = Typing_generic_constraint |
17 | | -module TUtils = Typing_utils |
18 | | -module Subst = Decl_subst |
19 | 15 |
|
20 | 16 | (* TOOD(T222659258) This whole file needs updating once HKTs are removed *) |
21 | 17 |
|
@@ -159,138 +155,6 @@ module Locl_Inst = struct |
159 | 155 | Tsplat t_splat |
160 | 156 | end |
161 | 157 |
|
162 | | -(* TODO(T70068435) |
163 | | - This is a workaround for the problem that alias and newtype definitions do not spell out |
164 | | - the constraints they may implicitly impose on their parameters. |
165 | | - Consider: |
166 | | - class Foo<T1 as num> {...} |
167 | | - type Bar<T2> = Foo<T2>; |
168 | | -
|
169 | | - Here, T2 of Bar implicitly has the bound T2 as num. However, in the current design, we only |
170 | | - ever check that when expanding Bar, the argument in place of T2 satisfies all the |
171 | | - implicit bounds. |
172 | | - However, this is not feasible for using aliases and newtypes as higher-kinded types, where we |
173 | | - use them without expanding them. |
174 | | - In the long-term, we would like to be able to infer the implicit bounds and use those for |
175 | | - the purposes of kind-checking. For now, we just detect if there *are* implicit bounds, and |
176 | | - if so reject using the alias/newtype as an HK type. |
177 | | -*) |
178 | | -let check_typedef_usable_as_hk_type env use_pos typedef_name typedef_info = |
179 | | - let report_constraint violating_type used_class used_class_tparam_name = |
180 | | - let tparams_in_ty = Env.get_tparams env violating_type in |
181 | | - let tparams_of_typedef = |
182 | | - List.fold typedef_info.td_tparams ~init:SSet.empty ~f:(fun s tparam -> |
183 | | - SSet.add (snd tparam.tp_name) s) |
184 | | - in |
185 | | - let intersection = SSet.inter tparams_in_ty tparams_of_typedef in |
186 | | - if SSet.is_empty intersection then |
187 | | - (* Just violated constraints inside the typedef that do not involve |
188 | | - the type parameters of the typedef we are looking at. Nothing to report at this point *) |
189 | | - None |
190 | | - else |
191 | | - (* We choose an arbitrary element. If a constraint violation were to contain multiple |
192 | | - tparams of the typedef, we can live with only showing the user one of them. *) |
193 | | - let typedef_tparam_name = SSet.min_elt intersection in |
194 | | - let (used_class_in_def_pos, used_class_in_def_name) = used_class in |
195 | | - let typedef_pos = typedef_info.td_pos in |
196 | | - Some |
197 | | - Typing_error.( |
198 | | - Reasons_callback.always |
199 | | - @@ primary |
200 | | - @@ Primary.HKT_alias_with_implicit_constraints |
201 | | - { |
202 | | - pos = use_pos; |
203 | | - typedef_pos; |
204 | | - used_class_in_def_pos; |
205 | | - typedef_name; |
206 | | - typedef_tparam_name; |
207 | | - used_class_in_def_name; |
208 | | - used_class_tparam_name; |
209 | | - }) |
210 | | - in |
211 | | - let check_tapply r class_sid type_args = |
212 | | - let decl_ty = Typing_make_type.apply r class_sid type_args in |
213 | | - let ((env, ty_err_opt), locl_ty) = |
214 | | - TUtils.localize_no_subst env ~ignore_errors:true decl_ty |
215 | | - in |
216 | | - Option.iter ~f:(Typing_error_utils.add_typing_error ~env) ty_err_opt; |
217 | | - match get_node (TUtils.get_base_type env locl_ty) with |
218 | | - | Tclass (cls_name, _, tyl) when not (List.is_empty tyl) -> |
219 | | - (match Env.get_class env (snd cls_name) with |
220 | | - | Decl_entry.Found cls -> |
221 | | - let tc_tparams = Cls.tparams cls in |
222 | | - let ety_env = |
223 | | - { empty_expand_env with substs = Subst.make_locl tc_tparams tyl } |
224 | | - in |
225 | | - iter2_shortest |
226 | | - begin |
227 | | - fun { tp_name = (_p, x); tp_constraints = cstrl; _ } ty -> |
228 | | - List.iter cstrl ~f:(fun (ck, cstr_ty) -> |
229 | | - let ((env, ty_err1), cstr_ty) = |
230 | | - TUtils.localize ~ety_env env cstr_ty |
231 | | - in |
232 | | - Option.iter |
233 | | - ~f:(Typing_error_utils.add_typing_error ~env) |
234 | | - ty_err1; |
235 | | - let (_env, ty_err2) = |
236 | | - TGenConstraint.check_constraint env ck ty ~cstr_ty |
237 | | - @@ report_constraint ty cls_name x |
238 | | - in |
239 | | - Option.iter |
240 | | - ty_err2 |
241 | | - ~f:(Typing_error_utils.add_typing_error ~env)) |
242 | | - end |
243 | | - tc_tparams |
244 | | - tyl |
245 | | - | _ -> ()) |
246 | | - | _ -> () |
247 | | - in |
248 | | - |
249 | | - let visitor = |
250 | | - object |
251 | | - inherit [unit] Type_visitor.decl_type_visitor |
252 | | - |
253 | | - method! on_tapply _ r name args = check_tapply r name args |
254 | | - end |
255 | | - in |
256 | | - (match typedef_info.td_type_assignment with |
257 | | - | SimpleTypeDef (_vis, td_type) -> visitor#on_type () td_type |
258 | | - | CaseType (variant, variants) -> |
259 | | - List.iter (List.map (variant :: variants) ~f:fst) ~f:(visitor#on_type ())); |
260 | | - maybe visitor#on_type () typedef_info.td_as_constraint; |
261 | | - maybe visitor#on_type () typedef_info.td_super_constraint |
262 | | - |
263 | | -(* TODO(T70068435) |
264 | | - This is a workaround until we support proper kind-checking of HK types that impose constraints |
265 | | - on their arguments. |
266 | | - For now, we reject using any class as a HK type that has any constraints on its type parameters. |
267 | | -*) |
268 | | -let check_class_usable_as_hk_type pos class_info = |
269 | | - let class_name = Cls.name class_info in |
270 | | - let tparams = Cls.tparams class_info in |
271 | | - let has_tparam_constraints = |
272 | | - List.exists tparams ~f:(fun tp -> not (List.is_empty tp.tp_constraints)) |
273 | | - in |
274 | | - if has_tparam_constraints then |
275 | | - Errors.add_error |
276 | | - Naming_error.( |
277 | | - to_user_error @@ HKT_class_with_constraints_used { pos; class_name }) |
278 | | - |
279 | | -let report_kind_error env ~use_pos ~def_pos ~tparam_name ~expected ~actual = |
280 | | - let actual_kind = Simple.description_of_kind actual in |
281 | | - let expected_kind = Simple.description_of_kind expected in |
282 | | - Typing_error_utils.add_typing_error ~env |
283 | | - @@ Typing_error.( |
284 | | - primary |
285 | | - @@ Primary.Kind_mismatch |
286 | | - { |
287 | | - pos = use_pos; |
288 | | - decl_pos = def_pos; |
289 | | - tparam_name; |
290 | | - actual_kind; |
291 | | - expected_kind; |
292 | | - }) |
293 | | - |
294 | 158 | module Simple = struct |
295 | 159 | (* TODO(T70068435) Once we support constraints on higher-kinded types, this should only be used |
296 | 160 | during the localization of declaration site types, everything else should be doing full |
@@ -364,27 +228,9 @@ module Simple = struct |
364 | 228 | `No |
365 | 229 | in |
366 | 230 | match get_node tyarg with |
367 | | - | Twildcard -> |
368 | | - let is_higher_kinded = Simple.get_arity kind > 0 in |
369 | | - if is_higher_kinded then ( |
370 | | - let pos = |
371 | | - get_reason tyarg |> Reason.to_pos |> Pos_or_decl.unsafe_to_raw_pos |
372 | | - in |
373 | | - Errors.add_error Naming_error.(to_user_error @@ HKT_wildcard pos); |
374 | | - check_well_kinded |
375 | | - ~in_signature |
376 | | - ~should_check_package_boundary |
377 | | - env |
378 | | - tyarg |
379 | | - nkind |
380 | | - ) |
| 231 | + | Twildcard -> () |
381 | 232 | | _ -> |
382 | | - check_well_kinded |
383 | | - ~in_signature |
384 | | - ~should_check_package_boundary |
385 | | - env |
386 | | - tyarg |
387 | | - nkind |
| 233 | + check_well_kinded ~in_signature ~should_check_package_boundary env tyarg |
388 | 234 |
|
389 | 235 | (** Traverse a type and for each encountered type argument of a type X, |
390 | 236 | check that it complies with the corresponding type parameter of X (arity and kinds, but not constraints), |
@@ -466,23 +312,7 @@ module Simple = struct |
466 | 312 | List.iter ft_params ~f:(fun p -> |
467 | 313 | check ~should_check_package_boundary:`No p.fp_type) |
468 | 314 | (* Interesting cases--------------------------------- *) |
469 | | - | Tgeneric name -> begin |
470 | | - let targs = [] in |
471 | | - match Env.get_pos_and_kind_of_generic env name with |
472 | | - | Some (def_pos, (gen_kind : kind)) -> |
473 | | - let (tparams_named_kinds : Simple.named_kind list) = |
474 | | - Simple.from_full_kind gen_kind |> Simple.get_named_parameter_kinds |
475 | | - in |
476 | | - check_targs_well_kinded |
477 | | - ~allow_missing_targs:false |
478 | | - ~in_signature |
479 | | - ~def_pos |
480 | | - ~use_pos |
481 | | - env |
482 | | - targs |
483 | | - tparams_named_kinds |
484 | | - | None -> () |
485 | | - end |
| 315 | + | Tgeneric _ -> () |
486 | 316 | | Tapply ((_p, cid), argl) -> begin |
487 | 317 | match Env.get_class_or_typedef env cid with |
488 | 318 | | Decl_entry.Found (Env.ClassResult class_info) -> |
@@ -530,72 +360,13 @@ module Simple = struct |
530 | 360 | We use the optional arguments `in_typeconst`, `in_typehint`, `in_targ` |
531 | 361 | and in_tp_constraint` to determine whether we should bypass package visibility check. *) |
532 | 362 | and check_well_kinded |
| 363 | + ~in_signature ~should_check_package_boundary env (ty : decl_ty) = |
| 364 | + check_well_kinded_type |
| 365 | + ~allow_missing_targs:false |
533 | 366 | ~in_signature |
534 | 367 | ~should_check_package_boundary |
535 | 368 | env |
536 | | - (ty : decl_ty) |
537 | | - (expected_nkind : Simple.named_kind) = |
538 | | - let (expected_name, (expected_kind : Simple.kind)) = expected_nkind in |
539 | | - let r = get_reason ty in |
540 | | - let use_pos = Reason.to_pos r |> Pos_or_decl.unsafe_to_raw_pos in |
541 | | - let kind_error actual_kind env = |
542 | | - let (def_pos, tparam_name) = expected_name in |
543 | | - report_kind_error |
544 | | - env |
545 | | - ~use_pos |
546 | | - ~def_pos |
547 | | - ~tparam_name |
548 | | - ~actual:actual_kind |
549 | | - ~expected:expected_kind |
550 | | - in |
551 | | - let check_against_tparams tparams = |
552 | | - let overall_kind = Simple.type_with_params_to_simple_kind tparams in |
553 | | - if not (is_subkind env ~sub:overall_kind ~sup:expected_kind) then |
554 | | - kind_error overall_kind env |
555 | | - in |
556 | | - |
557 | | - if Int.( = ) (Simple.get_arity expected_kind) 0 then |
558 | | - check_well_kinded_type |
559 | | - ~allow_missing_targs:false |
560 | | - ~in_signature |
561 | | - ~should_check_package_boundary |
562 | | - env |
563 | | - ty |
564 | | - else |
565 | | - match get_node ty with |
566 | | - | Tapply ((_pos, name), []) -> begin |
567 | | - match Env.get_class_or_typedef env name with |
568 | | - | Decl_entry.Found (Env.ClassResult class_info) -> |
569 | | - let tparams = Cls.tparams class_info in |
570 | | - check_class_usable_as_hk_type use_pos class_info; |
571 | | - check_against_tparams tparams |
572 | | - | Decl_entry.Found (Env.TypedefResult typedef) -> |
573 | | - let tparams = typedef.td_tparams in |
574 | | - check_typedef_usable_as_hk_type env use_pos name typedef; |
575 | | - check_against_tparams tparams |
576 | | - | Decl_entry.DoesNotExist |
577 | | - | Decl_entry.NotYetAvailable -> |
578 | | - () |
579 | | - end |
580 | | - | Tgeneric name -> begin |
581 | | - match Env.get_pos_and_kind_of_generic env name with |
582 | | - | Some (_pos, gen_kind) -> |
583 | | - let get_kind = Simple.from_full_kind gen_kind in |
584 | | - if not (is_subkind env ~sub:get_kind ~sup:expected_kind) then |
585 | | - kind_error get_kind env |
586 | | - | None -> () |
587 | | - end |
588 | | - | Tapply (_, targs) -> |
589 | | - Errors.add_error |
590 | | - Naming_error.( |
591 | | - to_user_error |
592 | | - @@ HKT_partial_application |
593 | | - { |
594 | | - pos = Reason.to_pos r |> Pos_or_decl.unsafe_to_raw_pos; |
595 | | - count = List.length targs; |
596 | | - }) |
597 | | - | Tany _ -> () |
598 | | - | _ -> kind_error (Simple.fully_applied_type ()) env |
| 369 | + ty |
599 | 370 |
|
600 | 371 | let check_well_kinded_hint |
601 | 372 | ~in_signature ~should_check_package_boundary env hint = |
|
0 commit comments