Allow quickfixes on secondary type errors
[hiphop-php.git] / hphp / hack / src / errors / typing_error.ml
blob77d457934cddbf055a082b0a3085da443c253d66
1 (*
2 * Copyright (c) Facebook, Inc. and its affiliates.
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the "hack" directory of this source tree.
7 *)
9 open Hh_prelude
10 module Error_code = Error_codes.Typing
12 module Eval_result : sig
13 type 'a t
15 val empty : 'a t
17 val single : 'a -> 'a t
19 val multiple : 'a t list -> 'a t
21 val union : 'a t list -> 'a t
23 val intersect : 'a t list -> 'a t
25 val of_option : 'a option -> 'a t
27 val map : 'a t -> f:('a -> 'b) -> 'b t
29 val bind : 'a t -> f:('a -> 'b t) -> 'b t
31 val iter : 'a t -> f:('a -> unit) -> unit
33 val suppress_intersection : 'a t -> is_suppressed:('a -> bool) -> 'a t
34 end = struct
35 type 'a t =
36 | Empty
37 | Single of 'a
38 | Multiple of 'a t list
39 | Union of 'a t list
40 | Intersect of 'a t list
42 let empty = Empty
44 let single a = Single a
46 let multiple = function
47 | [] -> Empty
48 | xs -> Multiple xs
50 let union = function
51 | [] -> Empty
52 | xs -> Union xs
54 let intersect = function
55 | [] -> Empty
56 | xs -> Intersect xs
58 let of_option = function
59 | Some x -> Single x
60 | _ -> Empty
62 let map t ~f =
63 let rec aux ~k = function
64 | Empty -> k Empty
65 | Single x -> k @@ single @@ f x
66 | Multiple xs -> auxs xs ~k:(fun ys -> k @@ multiple ys)
67 | Union xs -> auxs xs ~k:(fun ys -> k @@ union ys)
68 | Intersect xs -> auxs xs ~k:(fun ys -> k @@ intersect ys)
69 and auxs ~k = function
70 | [] -> k []
71 | next :: rest ->
72 aux next ~k:(fun x -> auxs rest ~k:(fun xs -> k @@ x :: xs))
74 aux ~k:Fn.id t
76 let bind t ~f =
77 let rec aux ~k = function
78 | Empty -> k Empty
79 | Single x -> k @@ f x
80 | Multiple xs -> auxs xs ~k:(fun ys -> k @@ multiple ys)
81 | Union xs -> auxs xs ~k:(fun ys -> k @@ union ys)
82 | Intersect xs -> auxs xs ~k:(fun ys -> k @@ intersect ys)
83 and auxs ~k = function
84 | [] -> k []
85 | next :: rest ->
86 aux next ~k:(fun x -> auxs rest ~k:(fun xs -> k @@ x :: xs))
88 aux ~k:Fn.id t
90 let iter t ~f =
91 let rec aux = function
92 | Empty -> ()
93 | Single x -> f x
94 | Multiple xs
95 | Union xs
96 | Intersect xs ->
97 List.iter ~f:aux xs
99 aux t
101 let is_suppressed t p =
102 let rec f = function
103 | Intersect xs -> List.exists ~f xs
104 | Multiple xs
105 | Union xs ->
106 List.for_all ~f xs
107 | Empty -> false
108 | Single x -> p x
112 let suppress_intersection t ~is_suppressed:p =
113 let p t = is_suppressed t p in
114 let rec aux t =
115 match t with
116 | Intersect xs -> auxs [] xs
117 | Multiple xs -> multiple @@ List.map ~f:aux xs
118 | Union xs -> union @@ List.map ~f:aux xs
119 | _ -> t
120 and auxs acc = function
121 | [] -> intersect @@ List.rev acc
122 | next :: rest ->
123 if p next then
124 aux next
125 else
126 auxs (next :: acc) rest
128 aux t
131 type on_error =
132 ?code:int ->
133 ?quickfixes:Quickfix.t list ->
134 Pos_or_decl.t Message.t list ->
135 unit
137 type error =
138 Error_code.t
139 * Pos.t Message.t
140 * Pos_or_decl.t Message.t list
141 * Quickfix.t list
143 module Common = struct
144 let reasons_of_trail trail =
145 List.map trail ~f:(fun pos -> (pos, "Typedef definition comes from here"))
147 let typing_too_many_args pos decl_pos actual expected =
148 let claim =
149 ( pos,
150 Printf.sprintf
151 "Too many arguments (expected %d but got %d)"
152 expected
153 actual )
154 and reasons = [(decl_pos, "Definition is here")] in
155 (Error_code.TypingTooManyArgs, claim, reasons)
157 let typing_too_few_args pos decl_pos actual expected =
158 let claim =
159 ( pos,
160 Printf.sprintf
161 "Too few arguments (required %d but got %d)"
162 expected
163 actual )
164 and reasons = [(decl_pos, "Definition is here")] in
165 (Error_code.TypingTooFewArgs, claim, reasons)
167 let snot_found_suggestion orig similar kind =
168 match similar with
169 | (`instance, pos, v) ->
170 begin
171 match kind with
172 | `static_method ->
173 Render.suggestion_message ~modifier:"instance method " orig v pos
174 | `class_constant ->
175 Render.suggestion_message ~modifier:"instance property " orig v pos
176 | `class_variable
177 | `class_typeconst ->
178 Render.suggestion_message orig v pos
180 | (`static, pos, v) -> Render.suggestion_message orig v pos
182 let smember_not_found pos kind member_name class_name class_pos hint =
183 let msg =
184 Printf.sprintf
185 "No %s %s in %s"
186 (Render.string_of_class_member_kind kind)
187 (Markdown_lite.md_codify member_name)
188 (Markdown_lite.md_codify @@ Render.strip_ns class_name)
190 let default =
192 ( class_pos,
193 "Declaration of "
194 ^ (Markdown_lite.md_codify @@ Render.strip_ns class_name)
195 ^ " is here" );
198 let reasons =
199 Option.value_map hint ~default ~f:(fun similar ->
200 snot_found_suggestion member_name similar kind :: default)
203 (Error_code.SmemberNotFound, (pos, msg), reasons)
205 let non_object_member pos ctxt ty_name member_name kind decl_pos =
206 let code =
207 match ctxt with
208 | `read -> Error_code.NonObjectMemberRead
209 | `write -> Error_code.NonObjectMemberWrite
211 let msg_start =
212 Printf.sprintf
213 "You are trying to access the %s %s but this is %s"
214 (Render.string_of_class_member_kind kind)
215 (Markdown_lite.md_codify member_name)
216 ty_name
218 let msg =
219 if String.equal ty_name "a shape" then
220 msg_start ^ ". Did you mean `$foo['" ^ member_name ^ "']` instead?"
221 else
222 msg_start
224 let claim = (pos, msg) and reasons = [(decl_pos, "Definition is here")] in
225 (code, claim, reasons)
227 let badpos_message =
228 Printf.sprintf
229 "Incomplete position information! Your type error is in this file, but we could only find related positions in another file. %s"
230 Error_message_sentinel.please_file_a_bug_message
232 let badpos_message_2 =
233 Printf.sprintf
234 "Incomplete position information! We couldn't find the exact line of your type error in this definition. %s"
235 Error_message_sentinel.please_file_a_bug_message
237 let wrap_error_in_different_file ~current_file ~current_span reasons =
238 let message =
239 List.map reasons ~f:(fun (pos, msg) ->
240 Pos.print_verbose_relative (Pos_or_decl.unsafe_to_raw_pos pos)
241 ^ ": "
242 ^ msg)
244 let stack =
245 Exception.get_current_callstack_string 99 |> Exception.clean_stack
247 HackEventLogger.type_check_primary_position_bug
248 ~current_file
249 ~message
250 ~stack;
251 let claim =
252 if Pos.equal current_span Pos.none then
253 (Pos.make_from current_file, badpos_message)
254 else
255 (current_span, badpos_message_2)
257 (claim, reasons)
259 let eval_assert ctx current_span = function
260 | (code, ((pos, msg) :: rest as reasons), quickfixes) ->
261 let (claim, reasons) =
262 match
263 Pos_or_decl.fill_in_filename_if_in_current_decl
264 ~current_decl_and_file:ctx
266 with
267 | Some pos -> ((pos, msg), rest)
268 | _ ->
269 wrap_error_in_different_file
270 ~current_file:ctx.Pos_or_decl.file
271 ~current_span
272 reasons
274 Some (code, claim, reasons, quickfixes)
275 | _ -> None
278 module Primary = struct
279 module Shape = struct
280 type t =
281 | Invalid_shape_field_name of {
282 pos: Pos.t;
283 is_empty: bool;
285 | Invalid_shape_field_literal of {
286 pos: Pos.t;
287 witness_pos: Pos.t;
289 | Invalid_shape_field_const of {
290 pos: Pos.t;
291 witness_pos: Pos.t;
293 | Invalid_shape_field_type of {
294 pos: Pos.t;
295 ty_pos: Pos_or_decl.t;
296 ty_name: string Lazy.t;
297 trail: Pos_or_decl.t list;
299 | Shape_field_class_mismatch of {
300 pos: Pos.t;
301 class_name: string;
302 witness_pos: Pos.t;
303 witness_class_name: string;
305 | Shape_field_type_mismatch of {
306 pos: Pos.t;
307 ty_name: string Lazy.t;
308 witness_pos: Pos.t;
309 witness_ty_name: string Lazy.t;
311 | Invalid_shape_remove_key of Pos.t
312 | Shapes_key_exists_always_true of {
313 pos: Pos.t;
314 field_name: string;
315 decl_pos: Pos_or_decl.t;
317 | Shapes_key_exists_always_false of {
318 pos: Pos.t;
319 field_name: string;
320 decl_pos: Pos_or_decl.t;
321 reason: [ `Nothing of Pos_or_decl.t Message.t list | `Undefined ];
323 | Shapes_method_access_with_non_existent_field of {
324 pos: Pos.t;
325 field_name: string;
326 decl_pos: Pos_or_decl.t;
327 method_name: string;
328 reason: [ `Nothing of Pos_or_decl.t Message.t list | `Undefined ];
330 | Shapes_access_with_non_existent_field of {
331 pos: Pos.t;
332 field_name: string;
333 decl_pos: Pos_or_decl.t;
334 reason: [ `Nothing of Pos_or_decl.t Message.t list | `Undefined ];
337 let invalid_shape_field_type pos ty_pos ty_name trail =
338 let reasons =
339 (ty_pos, "Not " ^ Lazy.force ty_name) :: Common.reasons_of_trail trail
340 and claim = (pos, "A shape field name must be an `int` or `string`") in
341 (Error_code.InvalidShapeFieldType, claim, reasons, [])
343 let invalid_shape_field_name pos =
344 let msg =
345 "Was expecting a constant string, class constant, or int (for shape access)"
347 (Error_code.InvalidShapeFieldName, (pos, msg), [], [])
349 let invalid_shape_field_name_empty pos =
350 let msg = "A shape field name cannot be an empty string" in
352 (Error_code.InvalidShapeFieldNameEmpty, (pos, msg), [], [])
354 let invalid_shape_field_literal pos witness_pos =
355 let claim = (pos, "Shape uses literal string as field name")
356 and reason =
357 [(Pos_or_decl.of_raw_pos witness_pos, "But expected a class constant")]
359 (Error_code.InvalidShapeFieldLiteral, claim, reason, [])
361 let invalid_shape_field_const pos witness_pos =
362 let claim = (pos, "Shape uses class constant as field name")
363 and reason =
364 [(Pos_or_decl.of_raw_pos witness_pos, "But expected a literal string")]
366 (Error_code.InvalidShapeFieldConst, claim, reason, [])
368 let shape_field_class_mismatch pos class_name witness_pos witness_class_name
370 let claim =
371 ( pos,
372 "Shape field name is class constant from "
373 ^ Markdown_lite.md_codify class_name )
374 and reason =
376 ( Pos_or_decl.of_raw_pos witness_pos,
377 "But expected constant from "
378 ^ Markdown_lite.md_codify witness_class_name );
381 (Error_code.ShapeFieldClassMismatch, claim, reason, [])
383 let shape_field_type_mismatch pos ty_name witness_pos witness_ty_name =
384 let claim =
385 (pos, "Shape field name is " ^ Lazy.force ty_name ^ " class constant")
386 and reason =
388 ( Pos_or_decl.of_raw_pos witness_pos,
389 "But expected " ^ Lazy.force witness_ty_name );
392 (Error_code.ShapeFieldTypeMismatch, claim, reason, [])
394 let invalid_shape_remove_key pos =
395 let msg = "You can only unset fields of **local** variables" in
396 (Error_code.InvalidShapeRemoveKey, (pos, msg), [], [])
398 let shapes_key_exists_always_true pos field_name decl_pos =
399 let claim = (pos, "This `Shapes::keyExists()` check is always true")
400 and reason =
402 ( decl_pos,
403 "The field "
404 ^ Markdown_lite.md_codify field_name
405 ^ " exists because of this definition" );
408 (Error_code.ShapesKeyExistsAlwaysTrue, claim, reason, [])
410 let shape_field_non_existence_reason pos name = function
411 | `Undefined ->
413 ( pos,
414 "The field "
415 ^ Markdown_lite.md_codify name
416 ^ " is not defined in this shape" );
418 | `Nothing reason ->
419 ( pos,
420 "The type of the field "
421 ^ Markdown_lite.md_codify name
422 ^ " in this shape doesn't allow any values" )
423 :: reason
425 let shapes_key_exists_always_false pos field_name decl_pos reason =
426 let claim = (pos, "This `Shapes::keyExists()` check is always false")
427 and reason =
428 shape_field_non_existence_reason decl_pos field_name reason
430 (Error_code.ShapesKeyExistsAlwaysFalse, claim, reason, [])
432 let shapes_method_access_with_non_existent_field
433 pos field_name method_name decl_pos reason =
434 let claim =
435 ( pos,
436 "You are calling "
437 ^ Markdown_lite.md_codify ("Shapes::" ^ method_name ^ "()")
438 ^ " on a field known to not exist" )
439 and reason =
440 shape_field_non_existence_reason decl_pos field_name reason
442 (Error_code.ShapesMethodAccessWithNonExistentField, claim, reason, [])
444 let shapes_access_with_non_existent_field pos field_name decl_pos reason =
445 let claim = (pos, "You are accessing a field known to not exist")
446 and reason =
447 shape_field_non_existence_reason decl_pos field_name reason
449 (Error_code.ShapeAccessWithNonExistentField, claim, reason, [])
451 let to_error = function
452 | Invalid_shape_field_type { pos; ty_pos; ty_name; trail } ->
453 invalid_shape_field_type pos ty_pos ty_name trail
454 | Invalid_shape_field_name { pos; is_empty = false } ->
455 invalid_shape_field_name pos
456 | Invalid_shape_field_name { pos; is_empty = true } ->
457 invalid_shape_field_name_empty pos
458 | Invalid_shape_field_literal { pos; witness_pos } ->
459 invalid_shape_field_literal pos witness_pos
460 | Invalid_shape_field_const { pos; witness_pos } ->
461 invalid_shape_field_const pos witness_pos
462 | Shape_field_class_mismatch
463 { pos; class_name; witness_pos; witness_class_name } ->
464 shape_field_class_mismatch pos class_name witness_pos witness_class_name
465 | Shape_field_type_mismatch { pos; ty_name; witness_pos; witness_ty_name }
467 shape_field_type_mismatch pos ty_name witness_pos witness_ty_name
468 | Invalid_shape_remove_key pos -> invalid_shape_remove_key pos
469 | Shapes_key_exists_always_true { pos; field_name; decl_pos } ->
470 shapes_key_exists_always_true pos field_name decl_pos
471 | Shapes_key_exists_always_false { pos; field_name; decl_pos; reason } ->
472 shapes_key_exists_always_false pos field_name decl_pos reason
473 | Shapes_method_access_with_non_existent_field
474 { pos; field_name; method_name; decl_pos; reason } ->
475 shapes_method_access_with_non_existent_field
477 field_name
478 method_name
479 decl_pos
480 reason
481 | Shapes_access_with_non_existent_field
482 { pos; field_name; decl_pos; reason } ->
483 shapes_access_with_non_existent_field pos field_name decl_pos reason
486 module Enum = struct
487 type t =
488 | Enum_switch_redundant of {
489 pos: Pos.t;
490 first_pos: Pos.t;
491 const_name: string;
493 | Enum_switch_nonexhaustive of {
494 pos: Pos.t;
495 kind: string;
496 decl_pos: Pos_or_decl.t;
497 missing: string list;
499 | Enum_switch_redundant_default of {
500 pos: Pos.t;
501 kind: string;
502 decl_pos: Pos_or_decl.t;
504 | Enum_switch_not_const of Pos.t
505 | Enum_switch_wrong_class of {
506 pos: Pos.t;
507 kind: string;
508 expected: string;
509 actual: string;
511 | Enum_type_bad of {
512 pos: Pos.t;
513 ty_name: string Lazy.t;
514 is_enum_class: bool;
515 trail: Pos_or_decl.t list;
517 | Enum_constant_type_bad of {
518 pos: Pos.t;
519 ty_pos: Pos_or_decl.t;
520 ty_name: string Lazy.t;
521 trail: Pos_or_decl.t list;
523 | Enum_type_typedef_nonnull of Pos.t
524 | Enum_class_label_unknown of {
525 pos: Pos.t;
526 label_name: string;
527 class_name: string;
529 | Enum_class_label_as_expr of Pos.t
530 | Enum_class_label_member_mismatch of {
531 pos: Pos.t;
532 label: string;
533 expected_ty_msg_opt: Pos_or_decl.t Message.t list Lazy.t option;
535 | Incompatible_enum_inclusion_base of {
536 pos: Pos.t;
537 classish_name: string;
538 src_classish_name: string;
540 | Incompatible_enum_inclusion_constraint of {
541 pos: Pos.t;
542 classish_name: string;
543 src_classish_name: string;
545 | Enum_inclusion_not_enum of {
546 pos: Pos.t;
547 classish_name: string;
548 src_classish_name: string;
550 | Enum_classes_reserved_syntax of Pos.t
551 | Enum_supertyping_reserved_syntax of Pos.t
553 let enum_class_label_member_mismatch pos label expected_ty_msg_opt =
554 let claim = (pos, "Enum class label/member mismatch")
555 and reasons =
556 match expected_ty_msg_opt with
557 | Some expected_ty_msg ->
558 Lazy.force expected_ty_msg
560 ( Pos_or_decl.of_raw_pos pos,
561 Format.sprintf "But got an enum class label: `#%s`" label );
563 | None ->
565 ( Pos_or_decl.of_raw_pos pos,
566 Format.sprintf "Unexpected enum class label: `#%s`" label );
569 (Error_code.UnifyError, claim, reasons, [])
571 let enum_type_bad pos is_enum_class ty_name trail =
572 let ty = Markdown_lite.md_codify @@ Lazy.force ty_name in
573 let msg =
574 if is_enum_class then
575 "Invalid base type for an enum class: "
576 else
577 "Enums must be `int` or `string` or `arraykey`, not "
579 let claim = (pos, msg ^ ty) and reasons = Common.reasons_of_trail trail in
580 (Error_code.EnumTypeBad, claim, reasons, [])
582 let enum_constant_type_bad pos ty_pos ty_name trail =
583 let claim = (pos, "Enum constants must be an `int` or `string`")
584 and reasons =
585 (ty_pos, "Not " ^ Markdown_lite.md_codify @@ Lazy.force ty_name)
586 :: Common.reasons_of_trail trail
588 (Error_code.EnumConstantTypeBad, claim, reasons, [])
590 let enum_type_typedef_nonnull pos =
591 let claim =
592 (pos, "Can't use `typedef` that resolves to nonnull in enum")
594 (Error_code.EnumTypeTypedefNonnull, claim, [], [])
596 let enum_switch_redundant pos first_pos const_name =
597 let claim = (pos, "Redundant `case` statement")
598 and reason =
600 ( Pos_or_decl.of_raw_pos first_pos,
601 Markdown_lite.md_codify const_name ^ " already handled here" );
604 (Error_code.EnumSwitchRedundant, claim, reason, [])
606 let enum_switch_nonexhaustive pos kind decl_pos missing =
607 let claim =
608 ( pos,
609 "`switch` statement nonexhaustive; the following cases are missing: "
610 ^ (List.map ~f:Markdown_lite.md_codify missing
611 |> String.concat ~sep:", ") )
612 and reason = [(decl_pos, kind ^ " declared here")] in
613 (Error_code.EnumSwitchNonexhaustive, claim, reason, [])
615 let enum_switch_redundant_default pos kind decl_pos =
616 let claim =
617 ( pos,
618 "All cases already covered; a redundant `default` case prevents "
619 ^ "detecting future errors. If your goal is to guard against "
620 ^ "invalid values for this type, do an `is` check before the switch."
622 and reason = [(decl_pos, kind ^ " declared here")] in
623 (Error_code.EnumSwitchRedundantDefault, claim, reason, [])
625 let enum_switch_not_const pos =
626 let claim = (pos, "Case in `switch` on enum is not an enum constant") in
627 (Error_code.EnumSwitchNotConst, claim, [], [])
629 let enum_switch_wrong_class pos kind expected actual =
630 let claim =
631 ( pos,
632 "Switching on "
633 ^ kind
634 ^ Markdown_lite.md_codify expected
635 ^ " but using constant from "
636 ^ Markdown_lite.md_codify actual )
638 (Error_code.EnumSwitchWrongClass, claim, [], [])
640 let enum_class_label_unknown pos label_name class_name =
641 let class_name = Render.strip_ns class_name in
642 let claim =
643 (pos, "Unknown constant " ^ label_name ^ " in " ^ class_name)
645 (Error_code.EnumClassLabelUnknown, claim, [], [])
647 let enum_class_label_as_expr pos =
648 let claim =
649 ( pos,
650 "Not enough type information to infer the type of this enum class label."
653 (Error_code.EnumClassLabelAsExpression, claim, [], [])
655 let incompatible_enum_inclusion_base pos classish_name src_classish_name =
656 let claim =
657 ( pos,
658 "Enum "
659 ^ Render.strip_ns classish_name
660 ^ " includes enum "
661 ^ Render.strip_ns src_classish_name
662 ^ " but their base types are incompatible" )
664 (Error_code.IncompatibleEnumInclusion, claim, [], [])
666 let incompatible_enum_inclusion_constraint
667 pos classish_name src_classish_name =
668 let claim =
669 ( pos,
670 "Enum "
671 ^ Render.strip_ns classish_name
672 ^ " includes enum "
673 ^ Render.strip_ns src_classish_name
674 ^ " but their constraints are incompatible" )
676 (Error_code.IncompatibleEnumInclusion, claim, [], [])
678 let enum_inclusion_not_enum pos classish_name src_classish_name =
679 let claim =
680 ( pos,
681 "Enum "
682 ^ Render.strip_ns classish_name
683 ^ " includes "
684 ^ Render.strip_ns src_classish_name
685 ^ " which is not an enum" )
687 (Error_code.IncompatibleEnumInclusion, claim, [], [])
689 let enum_classes_reserved_syntax pos =
690 ( Error_code.EnumClassesReservedSyntax,
691 ( pos,
692 "This syntax is reserved for the Enum Classes feature.\n"
693 ^ "Enable it with the enable_enum_classes option in .hhconfig" ),
695 [] )
697 let enum_supertyping_reserved_syntax pos =
698 ( Error_code.EnumSupertypingReservedSyntax,
699 ( pos,
700 "This Enum uses syntax reserved for the Enum Supertyping feature.\n"
701 ^ "Enable it with the enable_enum_supertyping option in .hhconfig" ),
703 [] )
705 let to_error = function
706 | Enum_type_bad { pos; is_enum_class; ty_name; trail } ->
707 enum_type_bad pos is_enum_class ty_name trail
708 | Enum_constant_type_bad { pos; ty_pos; ty_name; trail } ->
709 enum_constant_type_bad pos ty_pos ty_name trail
710 | Enum_type_typedef_nonnull pos -> enum_type_typedef_nonnull pos
711 | Enum_switch_redundant { pos; first_pos; const_name } ->
712 enum_switch_redundant pos first_pos const_name
713 | Enum_switch_nonexhaustive { pos; kind; decl_pos; missing } ->
714 enum_switch_nonexhaustive pos kind decl_pos missing
715 | Enum_switch_redundant_default { pos; kind; decl_pos } ->
716 enum_switch_redundant_default pos kind decl_pos
717 | Enum_switch_not_const pos -> enum_switch_not_const pos
718 | Enum_switch_wrong_class { pos; kind; expected; actual } ->
719 enum_switch_wrong_class pos kind expected actual
720 | Enum_class_label_unknown { pos; label_name; class_name } ->
721 enum_class_label_unknown pos label_name class_name
722 | Enum_class_label_as_expr pos -> enum_class_label_as_expr pos
723 | Enum_class_label_member_mismatch { pos; label; expected_ty_msg_opt } ->
724 enum_class_label_member_mismatch pos label expected_ty_msg_opt
725 | Incompatible_enum_inclusion_base
726 { pos; classish_name; src_classish_name } ->
727 incompatible_enum_inclusion_base pos classish_name src_classish_name
728 | Incompatible_enum_inclusion_constraint
729 { pos; classish_name; src_classish_name } ->
730 incompatible_enum_inclusion_constraint
732 classish_name
733 src_classish_name
734 | Enum_inclusion_not_enum { pos; classish_name; src_classish_name } ->
735 enum_inclusion_not_enum pos classish_name src_classish_name
736 | Enum_classes_reserved_syntax pos -> enum_classes_reserved_syntax pos
737 | Enum_supertyping_reserved_syntax pos ->
738 enum_supertyping_reserved_syntax pos
741 module Expr_tree = struct
742 type t =
743 | Expression_tree_non_public_member of {
744 pos: Pos.t;
745 decl_pos: Pos_or_decl.t;
747 | Reified_static_method_in_expr_tree of Pos.t
748 | This_var_in_expr_tree of Pos.t
749 | Experimental_expression_trees of Pos.t
750 | Expression_tree_unsupported_operator of {
751 pos: Pos.t;
752 member_name: string;
753 class_name: string;
756 let expression_tree_non_public_member pos decl_pos =
757 let claim =
758 (pos, "Cannot access non-public members within expression trees.")
759 and reason = [(decl_pos, "Member defined here")] in
760 (Error_code.ExpressionTreeNonPublicProperty, claim, reason, [])
762 let reified_static_method_in_expr_tree pos =
763 let claim =
764 ( pos,
765 "Static method calls on reified generics are not permitted in Expression Trees."
768 (Error_code.ReifiedStaticMethodInExprTree, claim, [], [])
770 let this_var_in_expr_tree pos =
771 let claim = (pos, "`$this` is not bound inside expression trees") in
772 (Error_code.ThisVarOutsideClass, claim, [], [])
774 let experimental_expression_trees pos =
775 let claim =
776 ( pos,
777 "This type is not permitted as an expression tree visitor. It is not included in "
778 ^ "`allowed_expression_tree_visitors` in `.hhconfig`, and this file does not "
779 ^ "contain `<<file:__EnableUnstableFeatures('expression_trees')>>`."
782 (Error_code.ExperimentalExpressionTrees, claim, [], [])
784 let expression_tree_unsupported_operator pos member_name class_name =
785 let msg =
786 match member_name with
787 | "__bool" ->
788 (* If the user writes `if ($not_bool)`, provide a more specific
789 error rather than a generic missing method error for
790 `$not_bool->__bool()`. *)
791 Printf.sprintf
792 "`%s` cannot be used as a boolean (it has no instance method named `__bool`)"
793 class_name
794 | _ ->
795 (* If the user writes `$not_int + ...`, provide a more specific
796 error rather than a generic missing method error for
797 `$not_int->__plus(...)`. *)
798 Printf.sprintf
799 "`%s` does not support this operator (it has no instance method named `%s`)"
800 class_name
801 member_name
803 (Error_code.MemberNotFound, (pos, msg), [], [])
805 let to_error = function
806 | Expression_tree_non_public_member { pos; decl_pos } ->
807 expression_tree_non_public_member pos decl_pos
808 | Reified_static_method_in_expr_tree pos ->
809 reified_static_method_in_expr_tree pos
810 | This_var_in_expr_tree pos -> this_var_in_expr_tree pos
811 | Experimental_expression_trees pos -> experimental_expression_trees pos
812 | Expression_tree_unsupported_operator { pos; member_name; class_name } ->
813 expression_tree_unsupported_operator pos member_name class_name
816 module Readonly = struct
817 type t =
818 | Readonly_modified of {
819 pos: Pos.t;
820 reason_opt: Pos_or_decl.t Message.t option;
822 | Readonly_mismatch of {
823 pos: Pos.t;
824 what: [ `arg_readonly | `arg_mut | `collection_mod | `prop_assign ];
825 pos_sub: Pos_or_decl.t;
826 pos_super: Pos_or_decl.t;
828 | Readonly_invalid_as_mut of Pos.t
829 | Readonly_exception of Pos.t
830 | Explicit_readonly_cast of {
831 pos: Pos.t;
832 decl_pos: Pos_or_decl.t;
833 kind: [ `fn_call | `property | `static_property ];
835 | Readonly_method_call of {
836 pos: Pos.t;
837 decl_pos: Pos_or_decl.t;
839 | Readonly_closure_call of {
840 pos: Pos.t;
841 decl_pos: Pos_or_decl.t;
842 suggestion: string;
845 let readonly_modified pos reason_opt =
846 let claim =
847 (pos, "This value is readonly, its properties cannot be modified")
848 and reason = Option.value_map reason_opt ~default:[] ~f:List.return in
849 (Error_code.ReadonlyValueModified, claim, reason, [])
851 let readonly_mismatch pos what pos_sub pos_super =
852 let (msg, msg_sub, msg_super) =
853 match what with
854 | `prop_assign ->
855 ( "property assignment",
856 "readonly",
857 "But it's being assigned to a mutable property" )
858 | `collection_mod ->
859 ("collection modification", "readonly", "But this value is mutable")
860 | `arg_readonly ->
861 ( "argument",
862 "readonly",
863 "It is incompatible with this parameter, which is mutable" )
864 | `arg_mut ->
865 ( "argument",
866 "mutable",
867 "It is incompatible with this parameter, which is readonly" )
869 let claim = (pos, Format.sprintf "Invalid %s" msg)
870 and reason =
872 (pos_sub, Format.sprintf "This expression is %s" msg_sub);
873 (pos_super, msg_super);
876 (Error_code.ReadonlyMismatch, claim, reason, [])
878 let readonly_invalid_as_mut pos =
879 let claim =
880 ( pos,
881 "Only value types and arrays can be converted to mutable. This value can never be a primitive."
884 (Error_code.ReadonlyInvalidAsMut, claim, [], [])
886 let readonly_exception pos =
887 let claim =
888 ( pos,
889 "This exception is readonly; throwing readonly exceptions is not currently supported."
892 (Error_code.ReadonlyException, claim, [], [])
894 let explicit_readonly_cast pos decl_pos kind =
895 let (start_line, start_column) = Pos.line_column pos in
896 (* Create a zero-width position at the start of the offending
897 expression, so we can insert text without overwriting anything. *)
898 let qf_pos =
899 pos |> Pos.set_line_end start_line |> Pos.set_col_end start_column
901 let quickfixes =
902 [Quickfix.make ~title:"Insert `readonly`" ~new_text:"readonly " qf_pos]
904 let kind_str =
905 match kind with
906 | `fn_call -> "function call"
907 | `property -> "property"
908 | `static_property -> "static property"
910 let claim =
911 ( pos,
912 "This "
913 ^ kind_str
914 ^ " returns a readonly value. It must be explicitly wrapped in a readonly expression."
916 and reason = [(decl_pos, "The " ^ kind_str ^ " is defined here.")] in
917 (Error_code.ExplicitReadonlyCast, claim, reason, quickfixes)
919 let readonly_method_call pos decl_pos =
920 let claim =
921 ( pos,
922 "This expression is readonly, so it can only call readonly methods" )
923 and reason = [(decl_pos, "This method is not readonly")] in
924 (Error_code.ReadonlyMethodCall, claim, reason, [])
926 let readonly_closure_call pos decl_pos suggestion =
927 let claim =
928 ( pos,
929 "This function is readonly, so it must be marked readonly at declaration time to be called."
931 and reason = [(decl_pos, "Did you mean to " ^ suggestion ^ "?")] in
932 (Error_code.ReadonlyClosureCall, claim, reason, [])
934 let to_error = function
935 | Readonly_modified { pos; reason_opt } ->
936 readonly_modified pos reason_opt
937 | Readonly_mismatch { pos; what; pos_sub; pos_super } ->
938 readonly_mismatch pos what pos_sub pos_super
939 | Readonly_invalid_as_mut pos -> readonly_invalid_as_mut pos
940 | Readonly_exception pos -> readonly_exception pos
941 | Explicit_readonly_cast { pos; decl_pos; kind } ->
942 explicit_readonly_cast pos decl_pos kind
943 | Readonly_method_call { pos; decl_pos } ->
944 readonly_method_call pos decl_pos
945 | Readonly_closure_call { pos; decl_pos; suggestion } ->
946 readonly_closure_call pos decl_pos suggestion
949 module Ifc = struct
950 type t =
951 | Illegal_information_flow of {
952 pos: Pos.t;
953 secondaries: Pos_or_decl.t list;
954 source_poss: Pos_or_decl.t list;
955 source: string;
956 sink_poss: Pos_or_decl.t list;
957 sink: string;
959 | Context_implicit_policy_leakage of {
960 pos: Pos.t;
961 secondaries: Pos_or_decl.t list;
962 source_poss: Pos_or_decl.t list;
963 source: string;
964 sink_poss: Pos_or_decl.t list;
965 sink: string;
967 | Unknown_information_flow of {
968 pos: Pos.t;
969 what: string;
971 | Ifc_internal_error of {
972 pos: Pos.t;
973 msg: string;
976 let illegal_information_flow
977 pos secondaries source_poss source sink_poss sink =
978 let explain poss node printer reasons =
979 let msg = printer node in
980 List.map ~f:(fun pos -> (pos, msg)) poss @ reasons
982 let source = Markdown_lite.md_codify source in
983 let sink = Markdown_lite.md_codify sink in
984 let sprintf_main = sprintf "Data with policy %s appears in context %s." in
985 let claim = (pos, sprintf_main source sink) in
986 let reasons =
987 let sprintf = Printf.sprintf in
988 let sprintf_source =
989 sprintf "This may be the data source with policy %s"
991 let sprintf_sink = sprintf "This may be the data sink with policy %s" in
992 let other_occurrences =
993 let f p =
994 (p, "Another program point contributing to the illegal flow")
996 List.map ~f secondaries
999 |> explain source_poss source sprintf_source
1000 |> explain sink_poss sink sprintf_sink
1001 |> List.append other_occurrences
1002 |> List.rev
1004 (Error_code.IllegalInformationFlow, claim, reasons, [])
1006 let ifc_internal_error pos msg =
1007 let claim =
1008 ( pos,
1009 "IFC Internal Error: "
1010 ^ msg
1011 ^ ". If you see this error and aren't expecting it, please `hh rage` and let the Hack team know."
1014 (Error_code.IFCInternalError, claim, [], [])
1016 let unknown_information_flow pos what =
1017 let claim =
1018 ( pos,
1019 "Unable to analyze information flow for "
1020 ^ what
1021 ^ ". This might be unsafe." )
1023 (Error_code.UnknownInformationFlow, claim, [], [])
1025 let context_implicit_policy_leakage
1026 pos secondaries source_poss source sink_poss sink =
1027 let program_point p =
1028 (p, "Another program point contributing to the leakage")
1030 let explain_source p = (p, "Leakage source") in
1031 let explain_sink p = (p, "Leakage sink") in
1032 let claim =
1033 ( pos,
1034 Printf.sprintf
1035 "Context-implicit policy leaks into %s via %s."
1036 (Markdown_lite.md_codify sink)
1037 (Markdown_lite.md_codify source) )
1039 let reasons =
1040 List.map ~f:program_point secondaries
1041 @ List.map ~f:explain_source source_poss
1042 @ List.map ~f:explain_sink sink_poss
1044 (Error_code.ContextImplicitPolicyLeakage, claim, reasons, [])
1046 let to_error = function
1047 | Illegal_information_flow
1048 { pos; secondaries; source_poss; source; sink_poss; sink } ->
1049 illegal_information_flow
1051 secondaries
1052 source_poss
1053 source
1054 sink_poss
1055 sink
1056 | Ifc_internal_error { pos; msg } -> ifc_internal_error pos msg
1057 | Unknown_information_flow { pos; what } ->
1058 unknown_information_flow pos what
1059 | Context_implicit_policy_leakage
1060 { pos; secondaries; source_poss; source; sink_poss; sink } ->
1061 context_implicit_policy_leakage
1063 secondaries
1064 source_poss
1065 source
1066 sink_poss
1067 sink
1070 module Record = struct
1071 type t =
1072 | Unexpected_record_field_name of {
1073 pos: Pos.t;
1074 field_name: string;
1075 record_name: string;
1076 decl_pos: Pos_or_decl.t;
1078 | Missing_record_field_name of {
1079 pos: Pos.t;
1080 field_name: string;
1081 record_name: string;
1082 decl_pos: Pos_or_decl.t;
1084 | Type_not_record of {
1085 pos: Pos.t;
1086 ty_name: string;
1088 | New_abstract_record of {
1089 pos: Pos.t;
1090 name: string;
1093 let unexpected_record_field_name pos field_name record_name decl_pos =
1094 let claim =
1095 ( pos,
1096 Printf.sprintf
1097 "Record %s has no field %s"
1098 (Render.strip_ns record_name |> Markdown_lite.md_codify)
1099 (Markdown_lite.md_codify field_name) )
1100 and reasons = [(decl_pos, "Definition is here")] in
1101 (Error_code.RecordUnknownField, claim, reasons, [])
1103 let missing_record_field_name pos field_name record_name decl_pos =
1104 let claim =
1105 ( pos,
1106 Printf.sprintf
1107 "Mising required field %s in %s"
1108 (Markdown_lite.md_codify field_name)
1109 (Render.strip_ns record_name |> Markdown_lite.md_codify) )
1110 and reasons = [(decl_pos, "Field definition is here")] in
1111 (Error_code.RecordMissingRequiredField, claim, reasons, [])
1113 let type_not_record pos ty_name =
1114 let claim =
1115 ( pos,
1116 Printf.sprintf
1117 "Expected a record type, but got %s."
1118 (Render.strip_ns ty_name |> Markdown_lite.md_codify) )
1120 (Error_code.NotARecord, claim, [], [])
1122 let new_abstract_record pos name =
1123 let name = Render.strip_ns name in
1124 let msg =
1125 Printf.sprintf
1126 "Cannot create instance of abstract record %s"
1127 (Markdown_lite.md_codify name)
1129 (Error_code.NewAbstractRecord, (pos, msg), [], [])
1131 let to_error = function
1132 | Unexpected_record_field_name { pos; field_name; record_name; decl_pos }
1134 unexpected_record_field_name pos field_name record_name decl_pos
1135 | Missing_record_field_name { pos; field_name; record_name; decl_pos } ->
1136 missing_record_field_name pos field_name record_name decl_pos
1137 | Type_not_record { pos; ty_name } -> type_not_record pos ty_name
1138 | New_abstract_record { pos; name } -> new_abstract_record pos name
1141 module Coeffect = struct
1142 type t =
1143 | Call_coeffect of {
1144 pos: Pos.t;
1145 available_pos: Pos_or_decl.t;
1146 available_incl_unsafe: string Lazy.t;
1147 required_pos: Pos_or_decl.t;
1148 required: string Lazy.t;
1150 | Op_coeffect_error of {
1151 pos: Pos.t;
1152 op_name: string;
1153 locally_available: string Lazy.t;
1154 available_pos: Pos_or_decl.t;
1155 err_code: Error_code.t;
1156 required: string Lazy.t;
1157 suggestion: Pos_or_decl.t Message.t list option;
1160 let call_coeffect
1161 pos available_pos available_incl_unsafe required_pos required =
1162 let reasons =
1164 ( available_pos,
1165 "From this declaration, the context of this function body provides "
1166 ^ Lazy.force available_incl_unsafe );
1167 ( required_pos,
1168 "But the function being called requires " ^ Lazy.force required );
1170 and claim =
1171 ( pos,
1172 "This call is not allowed because its coeffects are incompatible with the context"
1175 (Error_code.CallCoeffects, claim, reasons, [])
1177 let op_coeffect_error
1178 pos op_name required available_pos locally_available suggestion err_code
1180 let reasons =
1181 ( available_pos,
1182 "The local (enclosing) context provides "
1183 ^ Lazy.force locally_available )
1184 :: Option.value ~default:[] suggestion
1185 and claim =
1186 ( pos,
1187 op_name
1188 ^ " requires "
1189 ^ Lazy.force required
1190 ^ ", which is not provided by the context." )
1192 (err_code, claim, reasons, [])
1194 let to_error = function
1195 | Op_coeffect_error
1197 pos;
1198 op_name;
1199 required;
1200 available_pos;
1201 locally_available;
1202 suggestion;
1203 err_code;
1204 } ->
1205 op_coeffect_error
1207 op_name
1208 required
1209 available_pos
1210 locally_available
1211 suggestion
1212 err_code
1213 | Call_coeffect
1214 { pos; available_pos; available_incl_unsafe; required_pos; required }
1216 call_coeffect
1218 available_pos
1219 available_incl_unsafe
1220 required_pos
1221 required
1224 module Wellformedness = struct
1225 type t =
1226 | Missing_return of Pos.t
1227 | Dollardollar_lvalue of Pos.t
1228 | Void_usage of {
1229 pos: Pos.t;
1230 reason: Pos_or_decl.t Message.t list;
1232 | Noreturn_usage of {
1233 pos: Pos.t;
1234 reason: Pos_or_decl.t Message.t list;
1236 | Returns_with_and_without_value of {
1237 pos: Pos.t;
1238 with_value_pos: Pos.t;
1239 without_value_pos_opt: Pos.t option;
1241 | Missing_assign of Pos.t
1242 | Non_void_annotation_on_return_void_function of {
1243 is_async: bool;
1244 pos: Pos.t;
1245 hint_pos: Pos.t option;
1247 | Tuple_syntax of Pos.t
1249 let missing_return pos =
1250 let claim = (pos, "Invalid return type") in
1251 (Error_code.MissingReturnInNonVoidFunction, claim, [], [])
1253 let dollardollar_lvalue pos =
1254 let claim =
1255 (pos, "Cannot assign a value to the special pipe variable `$$`")
1257 (Error_code.DollardollarLvalue, claim, [], [])
1259 let void_usage pos reason =
1260 let msg = "You are using the return value of a `void` function" in
1261 (Error_code.VoidUsage, (pos, msg), reason, [])
1263 let noreturn_usage pos reason =
1264 let msg = "You are using the return value of a `noreturn` function" in
1265 (Error_code.NoreturnUsage, (pos, msg), reason, [])
1267 let returns_with_and_without_value pos with_value_pos without_value_pos_opt
1269 let claim =
1270 (pos, "This function can exit with and without returning a value")
1271 and reason =
1272 (Pos_or_decl.of_raw_pos with_value_pos, "Returning a value here.")
1274 Option.value_map
1275 without_value_pos_opt
1276 ~default:
1278 ( Pos_or_decl.of_raw_pos pos,
1279 "This function does not always return a value" );
1281 ~f:(fun p ->
1282 [(Pos_or_decl.of_raw_pos p, "Returning without a value here")])
1284 (Error_code.ReturnsWithAndWithoutValue, claim, reason, [])
1286 let missing_assign pos =
1287 (Error_code.MissingAssign, (pos, "Please assign a value"), [], [])
1289 let non_void_annotation_on_return_void_function is_async pos hint_pos =
1290 let (async_indicator, return_type) =
1291 if is_async then
1292 ("Async f", "Awaitable<void>")
1293 else
1294 ("F", "void")
1296 let message =
1297 Printf.sprintf
1298 "%sunctions that do not return a value must have a type of %s"
1299 async_indicator
1300 return_type
1302 let quickfixes =
1303 match hint_pos with
1304 | None -> []
1305 | Some hint_pos ->
1307 Quickfix.make
1308 ~title:("Change to " ^ Markdown_lite.md_codify return_type)
1309 ~new_text:return_type
1310 hint_pos;
1314 ( Error_code.NonVoidAnnotationOnReturnVoidFun,
1315 (pos, message),
1317 quickfixes )
1319 let tuple_syntax p =
1320 ( Error_code.TupleSyntax,
1321 (p, "Did you want a *tuple*? Try `(X,Y)`, not `tuple<X,Y>`"),
1323 [] )
1325 let to_error = function
1326 | Missing_return pos -> missing_return pos
1327 | Dollardollar_lvalue pos -> dollardollar_lvalue pos
1328 | Void_usage { pos; reason } -> void_usage pos reason
1329 | Noreturn_usage { pos; reason } -> noreturn_usage pos reason
1330 | Returns_with_and_without_value
1331 { pos; with_value_pos; without_value_pos_opt } ->
1332 returns_with_and_without_value pos with_value_pos without_value_pos_opt
1333 | Missing_assign pos -> missing_assign pos
1334 | Non_void_annotation_on_return_void_function { is_async; pos; hint_pos }
1336 non_void_annotation_on_return_void_function is_async pos hint_pos
1337 | Tuple_syntax pos -> tuple_syntax pos
1340 module Modules = struct
1341 type t =
1342 | Module_hint of {
1343 pos: Pos.t;
1344 decl_pos: Pos_or_decl.t;
1346 | Module_mismatch of {
1347 pos: Pos.t;
1348 current_module_opt: string option;
1349 decl_pos: Pos_or_decl.t;
1350 target_module: string;
1353 let module_hint pos decl_pos =
1354 let claim = (pos, "You cannot use this type in a public declaration.")
1355 and reason = [(decl_pos, "It is declared as `internal` here")] in
1356 (Error_code.ModuleHintError, claim, reason, [])
1358 let module_mismatch pos current_module_opt decl_pos target_module =
1359 let claim =
1360 ( pos,
1361 Printf.sprintf
1362 "Cannot access an internal element from module `%s` %s"
1363 target_module
1364 (match current_module_opt with
1365 | Some m -> Printf.sprintf "in module `%s`" m
1366 | None -> "outside of a module") )
1367 and reason =
1368 [(decl_pos, Printf.sprintf "This is from module `%s`" target_module)]
1370 (Error_code.ModuleError, claim, reason, [])
1372 let to_error = function
1373 | Module_hint { pos; decl_pos } -> module_hint pos decl_pos
1374 | Module_mismatch { pos; current_module_opt; decl_pos; target_module } ->
1375 module_mismatch pos current_module_opt decl_pos target_module
1378 module Xhp = struct
1379 type t =
1380 | Xhp_required of {
1381 pos: Pos.t;
1382 why_xhp: string;
1383 ty_reason_msg: Pos_or_decl.t Message.t list Lazy.t;
1385 | Illegal_xhp_child of {
1386 pos: Pos.t;
1387 ty_reason_msg: Pos_or_decl.t Message.t list Lazy.t;
1389 | Missing_xhp_required_attr of {
1390 pos: Pos.t;
1391 attr: string;
1392 ty_reason_msg: Pos_or_decl.t Message.t list Lazy.t;
1395 let xhp_required pos why_xhp ty_reason_msg =
1396 let msg = "An XHP instance was expected" in
1397 ( Error_code.XhpRequired,
1398 (pos, msg),
1399 (Pos_or_decl.of_raw_pos pos, why_xhp) :: ty_reason_msg,
1400 [] )
1402 let illegal_xhp_child pos ty_reason_msg =
1403 let msg = "XHP children must be compatible with XHPChild" in
1404 (Error_code.IllegalXhpChild, (pos, msg), ty_reason_msg, [])
1406 let missing_xhp_required_attr pos attr ty_reason_msg =
1407 let msg =
1408 "Required attribute " ^ Markdown_lite.md_codify attr ^ " is missing."
1410 (Error_code.MissingXhpRequiredAttr, (pos, msg), ty_reason_msg, [])
1412 let to_error = function
1413 | Xhp_required { pos; why_xhp; ty_reason_msg } ->
1414 xhp_required pos why_xhp @@ Lazy.force ty_reason_msg
1415 | Illegal_xhp_child { pos; ty_reason_msg } ->
1416 illegal_xhp_child pos @@ Lazy.force ty_reason_msg
1417 | Missing_xhp_required_attr { pos; attr; ty_reason_msg } ->
1418 missing_xhp_required_attr pos attr @@ Lazy.force ty_reason_msg
1421 type t =
1422 (* == Factorised errors ================================================= *)
1423 | Coeffect of Coeffect.t
1424 | Enum of Enum.t
1425 | Expr_tree of Expr_tree.t
1426 | Ifc of Ifc.t
1427 | Modules of Modules.t
1428 | Readonly of Readonly.t
1429 | Record of Record.t
1430 | Shape of Shape.t
1431 | Wellformedness of Wellformedness.t
1432 | Xhp of Xhp.t
1433 (* == Primary only ====================================================== *)
1434 | Exception_occurred of {
1435 pos: Pos.t;
1436 exn: Exception.t;
1438 | Invariant_violation of {
1439 pos: Pos.t;
1440 telemetry: Telemetry.t;
1441 desc: string;
1442 report_to_user: bool;
1444 | Internal_error of {
1445 pos: Pos.t;
1446 msg: string;
1448 | Typechecker_timeout of {
1449 pos: Pos.t;
1450 fn_name: string;
1451 seconds: int;
1453 | Unresolved_tyvar of Pos.t
1454 | Unify_error of {
1455 pos: Pos.t;
1456 msg_opt: string option;
1457 reasons_opt: Pos_or_decl.t Message.t list Lazy.t option;
1459 | Generic_unify of {
1460 pos: Pos.t;
1461 msg: string;
1463 | Using_error of {
1464 pos: Pos.t;
1465 has_await: bool;
1467 | Bad_enum_decl of Pos.t
1468 | Bad_conditional_support_dynamic of {
1469 pos: Pos.t;
1470 child: string;
1471 parent: string;
1472 ty_name: string Lazy.t;
1473 self_ty_name: string Lazy.t;
1475 | Bad_decl_override of {
1476 pos: Pos.t;
1477 name: string;
1478 parent_pos: Pos_or_decl.t;
1479 parent_name: string;
1481 | Explain_where_constraint of {
1482 pos: Pos.t;
1483 in_class: bool;
1484 decl_pos: Pos_or_decl.t;
1486 | Explain_constraint of Pos.t
1487 | Rigid_tvar_escape of {
1488 pos: Pos.t;
1489 what: string;
1491 | Invalid_type_hint of Pos.t
1492 | Unsatisfied_req of {
1493 pos: Pos.t;
1494 trait_pos: Pos_or_decl.t;
1495 req_pos: Pos_or_decl.t;
1496 req_name: string;
1498 | Invalid_echo_argument of Pos.t
1499 | Index_type_mismatch of {
1500 pos: Pos.t;
1501 is_covariant_container: bool;
1502 msg_opt: string option;
1503 reasons_opt: Pos_or_decl.t Message.t list Lazy.t option;
1505 | Member_not_found of {
1506 pos: Pos.t;
1507 kind: [ `method_ | `property ];
1508 class_name: string;
1509 class_pos: Pos_or_decl.t;
1510 member_name: string;
1511 hint: ([ `instance | `static ] * Pos_or_decl.t * string) option Lazy.t;
1512 reason: Pos_or_decl.t Message.t list;
1514 | Construct_not_instance_method of Pos.t
1515 | Ambiguous_inheritance of {
1516 pos: Pos.t;
1517 class_name: string;
1518 origin: string;
1520 | Expected_tparam of {
1521 pos: Pos.t;
1522 decl_pos: Pos_or_decl.t;
1523 n: int;
1525 | Typeconst_concrete_concrete_override of {
1526 pos: Pos.t;
1527 decl_pos: Pos_or_decl.t;
1529 | Invalid_memoized_param of {
1530 pos: Pos.t;
1531 ty_name: string Lazy.t;
1532 reason: Pos_or_decl.t Message.t list Lazy.t;
1534 | Invalid_arraykey of {
1535 pos: Pos.t;
1536 ctxt: [ `read | `write ];
1537 container_pos: Pos_or_decl.t;
1538 container_ty_name: string Lazy.t;
1539 key_pos: Pos_or_decl.t;
1540 key_ty_name: string Lazy.t;
1542 | Invalid_keyset_value of {
1543 pos: Pos.t;
1544 container_pos: Pos_or_decl.t;
1545 container_ty_name: string Lazy.t;
1546 value_pos: Pos_or_decl.t;
1547 value_ty_name: string Lazy.t;
1549 | Invalid_set_value of {
1550 pos: Pos.t;
1551 container_pos: Pos_or_decl.t;
1552 container_ty_name: string Lazy.t;
1553 value_pos: Pos_or_decl.t;
1554 value_ty_name: string Lazy.t;
1556 | HKT_alias_with_implicit_constraints of {
1557 pos: Pos.t;
1558 typedef_pos: Pos_or_decl.t;
1559 used_class_in_def_pos: Pos_or_decl.t;
1560 typedef_name: string;
1561 typedef_tparam_name: string;
1562 used_class_in_def_name: string;
1563 used_class_tparam_name: string;
1565 | Invalid_substring of {
1566 pos: Pos.t;
1567 ty_name: string Lazy.t;
1569 | Unset_nonidx_in_strict of {
1570 pos: Pos.t;
1571 reason: Pos_or_decl.t Message.t list;
1573 | Nullable_cast of {
1574 pos: Pos.t;
1575 ty_pos: Pos_or_decl.t;
1576 ty_name: string Lazy.t;
1578 | Hh_expect of {
1579 pos: Pos.t;
1580 equivalent: bool;
1582 | Null_member of {
1583 pos: Pos.t;
1584 ctxt: [ `read | `write ];
1585 kind: [ `method_ | `property ];
1586 member_name: string;
1587 reason: Pos_or_decl.t Message.t list;
1589 | Nullsafe_property_write_context of Pos.t
1590 | Uninstantiable_class of {
1591 pos: Pos.t;
1592 class_name: string;
1593 reason_ty_opt: (Pos.t * string Lazy.t) option;
1594 decl_pos: Pos_or_decl.t;
1596 | Abstract_const_usage of {
1597 pos: Pos.t;
1598 decl_pos: Pos_or_decl.t;
1599 name: string;
1601 | Member_not_implemented of {
1602 pos: Pos.t;
1603 member_name: string;
1604 parent_pos: Pos_or_decl.t;
1605 decl_pos: Pos_or_decl.t;
1606 quickfixes: Quickfix.t list;
1608 | Attribute_too_many_arguments of {
1609 pos: Pos.t;
1610 name: string;
1611 expected: int;
1613 | Attribute_too_few_arguments of {
1614 pos: Pos.t;
1615 name: string;
1616 expected: int;
1618 | Attribute_not_exact_number_of_args of {
1619 pos: Pos.t;
1620 name: string;
1621 actual: int;
1622 expected: int;
1624 | Kind_mismatch of {
1625 pos: Pos.t;
1626 decl_pos: Pos_or_decl.t;
1627 tparam_name: string;
1628 expected_kind: string;
1629 actual_kind: string;
1631 | Trait_parent_construct_inconsistent of {
1632 pos: Pos.t;
1633 decl_pos: Pos_or_decl.t;
1635 | Top_member of {
1636 pos: Pos.t;
1637 ctxt: [ `read | `write ];
1638 ty_name: string Lazy.t;
1639 decl_pos: Pos_or_decl.t;
1640 kind: [ `method_ | `property ];
1641 name: string;
1642 is_nullable: bool;
1644 | Unresolved_tyvar_projection of {
1645 pos: Pos.t;
1646 proj_pos: Pos_or_decl.t;
1647 tconst_name: string;
1649 | Cyclic_class_constant of {
1650 pos: Pos.t;
1651 class_name: string;
1652 const_name: string;
1654 | Inout_annotation_missing of {
1655 pos: Pos.t;
1656 decl_pos: Pos_or_decl.t;
1658 | Inout_annotation_unexpected of {
1659 pos: Pos.t;
1660 decl_pos: Pos_or_decl.t;
1661 param_is_variadic: bool;
1662 qfx_pos: Pos.t;
1664 | Inout_argument_bad_type of {
1665 pos: Pos.t;
1666 reasons: Pos_or_decl.t Message.t list Lazy.t;
1668 | Invalid_meth_caller_calling_convention of {
1669 pos: Pos.t;
1670 decl_pos: Pos_or_decl.t;
1671 convention: string;
1673 | Invalid_meth_caller_readonly_return of {
1674 pos: Pos.t;
1675 decl_pos: Pos_or_decl.t;
1677 | Invalid_new_disposable of Pos.t
1678 | Invalid_return_disposable of Pos.t
1679 | Invalid_disposable_hint of {
1680 pos: Pos.t;
1681 class_name: string;
1683 | Invalid_disposable_return_hint of {
1684 pos: Pos.t;
1685 class_name: string;
1687 | Ambiguous_lambda of {
1688 pos: Pos.t;
1689 uses: Pos_or_decl.t Message.t list;
1691 | Wrong_extend_kind of {
1692 pos: Pos.t;
1693 kind: Ast_defs.classish_kind;
1694 name: string;
1695 parent_pos: Pos_or_decl.t;
1696 parent_kind: Ast_defs.classish_kind;
1697 parent_name: string;
1699 | Cyclic_class_def of {
1700 pos: Pos.t;
1701 stack: SSet.t;
1703 | Cyclic_record_def of {
1704 pos: Pos.t;
1705 names: string list;
1707 | Trait_reuse_with_final_method of {
1708 pos: Pos.t;
1709 trait_name: string;
1710 parent_cls_name: string;
1711 trace: Pos_or_decl.t Message.t list;
1713 | Trait_reuse of {
1714 pos: Pos.t;
1715 class_name: string;
1716 trait_name: string;
1717 parent_pos: Pos_or_decl.t;
1718 parent_name: string;
1720 | Trait_reuse_inside_class of {
1721 pos: Pos.t;
1722 class_name: string;
1723 trait_name: string;
1724 occurrences: Pos_or_decl.t list;
1726 | Invalid_is_as_expression_hint of {
1727 pos: Pos.t;
1728 op: [ `is | `as_ ];
1729 reasons: Pos_or_decl.t Message.t list;
1731 | Invalid_enforceable_type of {
1732 pos: Pos.t;
1733 ty_info: Pos_or_decl.t Message.t list;
1734 tp_pos: Pos_or_decl.t;
1735 tp_name: string;
1736 kind: [ `constant | `param ];
1738 | Reifiable_attr of {
1739 pos: Pos.t;
1740 ty_info: Pos_or_decl.t Message.t list;
1741 attr_pos: Pos_or_decl.t;
1742 kind: [ `ty | `cnstr | `super_cnstr ];
1744 | Invalid_newable_type_argument of {
1745 pos: Pos.t;
1746 tp_pos: Pos_or_decl.t;
1747 tp_name: string;
1749 | Invalid_newable_typaram_constraints of {
1750 pos: Pos.t;
1751 tp_name: string;
1752 constraints: string list;
1754 | Override_per_trait of {
1755 pos: Pos.t;
1756 class_name: string;
1757 meth_name: string;
1758 trait_name: string;
1759 meth_pos: Pos_or_decl.t;
1761 | Generic_at_runtime of {
1762 pos: Pos.t;
1763 prefix: string;
1765 | Generics_not_allowed of Pos.t
1766 | Trivial_strict_eq of {
1767 pos: Pos.t;
1768 result: bool;
1769 left: Pos_or_decl.t Message.t list Lazy.t;
1770 right: Pos_or_decl.t Message.t list Lazy.t;
1771 left_trail: Pos_or_decl.t list;
1772 right_trail: Pos_or_decl.t list;
1774 | Trivial_strict_not_nullable_compare_null of {
1775 pos: Pos.t;
1776 result: bool;
1777 ty_reason_msg: Pos_or_decl.t Message.t list Lazy.t;
1779 | Eq_incompatible_types of {
1780 pos: Pos.t;
1781 left: Pos_or_decl.t Message.t list Lazy.t;
1782 right: Pos_or_decl.t Message.t list Lazy.t;
1784 | Comparison_invalid_types of {
1785 pos: Pos.t;
1786 left: Pos_or_decl.t Message.t list Lazy.t;
1787 right: Pos_or_decl.t Message.t list Lazy.t;
1789 | Strict_eq_value_incompatible_types of {
1790 pos: Pos.t;
1791 left: Pos_or_decl.t Message.t list Lazy.t;
1792 right: Pos_or_decl.t Message.t list Lazy.t;
1794 | Attribute_param_type of {
1795 pos: Pos.t;
1796 x: string;
1798 | Deprecated_use of {
1799 pos: Pos.t;
1800 decl_pos_opt: Pos_or_decl.t option;
1801 msg: string;
1803 | Cannot_declare_constant of {
1804 pos: Pos.t;
1805 kind: [ `enum | `record ];
1806 class_pos: Pos.t;
1807 class_name: string;
1809 | Local_variable_modified_and_used of {
1810 pos: Pos.t;
1811 pos_useds: Pos.t list;
1813 | Local_variable_modified_twice of {
1814 pos: Pos.t;
1815 pos_modifieds: Pos.t list;
1817 | Assign_during_case of Pos.t
1818 | Invalid_classname of Pos.t
1819 | Illegal_type_structure of Pos.t
1820 | Illegal_typeconst_direct_access of Pos.t
1821 | Wrong_expression_kind_attribute of {
1822 pos: Pos.t;
1823 attr_name: string;
1824 expr_kind: string;
1825 attr_class_pos: Pos_or_decl.t;
1826 attr_class_name: string;
1827 intf_name: string;
1829 | Wrong_expression_kind_builtin_attribute of {
1830 pos: Pos.t;
1831 attr_name: string;
1832 expr_kind: string;
1834 | Ambiguous_object_access of {
1835 pos: Pos.t;
1836 name: string;
1837 self_pos: Pos_or_decl.t;
1838 vis: string;
1839 subclass_pos: Pos_or_decl.t;
1840 class_self: string;
1841 class_subclass: string;
1843 | Lateinit_with_default of Pos.t
1844 | Unserializable_type of {
1845 pos: Pos.t;
1846 message: string;
1848 | Invalid_arraykey_constraint of {
1849 pos: Pos.t;
1850 ty_name: string Lazy.t;
1852 | Redundant_covariant of {
1853 pos: Pos.t;
1854 msg: string;
1855 suggest: string;
1857 | Meth_caller_trait of {
1858 pos: Pos.t;
1859 trait_name: string;
1861 | Duplicate_interface of {
1862 pos: Pos.t;
1863 name: string;
1864 others: Pos_or_decl.t list;
1866 | Tparam_non_shadowing_reuse of {
1867 pos: Pos.t;
1868 tparam_name: string;
1870 | Reified_function_reference of Pos.t
1871 | Class_meth_abstract_call of {
1872 pos: Pos.t;
1873 class_name: string;
1874 meth_name: string;
1875 decl_pos: Pos_or_decl.t;
1877 | Reinheriting_classish_const of {
1878 pos: Pos.t;
1879 classish_name: string;
1880 src_pos: Pos.t;
1881 src_classish_name: string;
1882 existing_const_origin: string;
1883 const_name: string;
1885 | Redeclaring_classish_const of {
1886 pos: Pos.t;
1887 classish_name: string;
1888 redeclaration_pos: Pos.t;
1889 existing_const_origin: string;
1890 const_name: string;
1892 | Abstract_function_pointer of {
1893 pos: Pos.t;
1894 class_name: string;
1895 meth_name: string;
1896 decl_pos: Pos_or_decl.t;
1898 | Unnecessary_attribute of {
1899 pos: Pos.t;
1900 attr: string;
1901 reason: Pos.t Message.t;
1902 suggestion: string option;
1904 | Inherited_class_member_with_different_case of {
1905 pos: Pos.t;
1906 member_type: string;
1907 name: string;
1908 name_prev: string;
1909 child_class: string;
1910 prev_class: string;
1911 prev_class_pos: Pos_or_decl.t;
1913 | Multiple_inherited_class_member_with_different_case of {
1914 pos: Pos.t;
1915 child_class_name: string;
1916 member_type: string;
1917 class1_name: string;
1918 class1_pos: Pos_or_decl.t;
1919 name1: string;
1920 class2_name: string;
1921 class2_pos: Pos_or_decl.t;
1922 name2: string;
1924 | Parent_support_dynamic_type of {
1925 pos: Pos.t;
1926 child_name: string;
1927 child_kind: Ast_defs.classish_kind;
1928 parent_name: string;
1929 parent_kind: Ast_defs.classish_kind;
1930 child_support_dyn: bool;
1932 | Property_is_not_enforceable of {
1933 pos: Pos.t;
1934 prop_name: string;
1935 class_name: string;
1936 prop_pos: Pos_or_decl.t;
1937 prop_type: string;
1939 | Property_is_not_dynamic of {
1940 pos: Pos.t;
1941 prop_name: string;
1942 class_name: string;
1943 prop_pos: Pos_or_decl.t;
1944 prop_type: string;
1946 | Private_property_is_not_enforceable of {
1947 pos: Pos.t;
1948 prop_name: string;
1949 class_name: string;
1950 prop_pos: Pos_or_decl.t;
1951 prop_type: string;
1953 | Private_property_is_not_dynamic of {
1954 pos: Pos.t;
1955 prop_name: string;
1956 class_name: string;
1957 prop_pos: Pos_or_decl.t;
1958 prop_type: string;
1960 | Immutable_local of Pos.t
1961 | Nonsense_member_selection of {
1962 pos: Pos.t;
1963 kind: string;
1965 | Consider_meth_caller of {
1966 pos: Pos.t;
1967 class_name: string;
1968 meth_name: string;
1970 | Method_import_via_diamond of {
1971 pos: Pos.t;
1972 class_name: string;
1973 method_pos: Pos_or_decl.t;
1974 method_name: string;
1975 trace1: Pos_or_decl.t Message.t list;
1976 trace2: Pos_or_decl.t Message.t list;
1978 | Generic_property_import_via_diamond of {
1979 pos: Pos.t;
1980 class_name: string;
1981 property_pos: Pos_or_decl.t;
1982 property_name: string;
1983 trace1: Pos_or_decl.t Message.t list;
1984 trace2: Pos_or_decl.t Message.t list;
1986 | Unification_cycle of {
1987 pos: Pos.t;
1988 ty_name: string Lazy.t;
1990 | Method_variance of Pos.t
1991 | Explain_tconst_where_constraint of {
1992 pos: Pos.t;
1993 decl_pos: Pos_or_decl.t;
1994 msgs: Pos_or_decl.t Message.t list;
1996 | Format_string of {
1997 pos: Pos.t;
1998 snippet: string;
1999 fmt_string: string;
2000 class_pos: Pos_or_decl.t;
2001 fn_name: string;
2002 class_suggest: string;
2004 | Expected_literal_format_string of Pos.t
2005 | Re_prefixed_non_string of {
2006 pos: Pos.t;
2007 reason: [ `non_string | `embedded_expr ];
2009 | Bad_regex_pattern of {
2010 pos: Pos.t;
2011 reason:
2012 [ `missing_delim
2013 | `empty_patt
2014 | `invalid_option
2015 | `bad_patt of string
2018 | Generic_array_strict of Pos.t
2019 | Option_return_only_typehint of {
2020 pos: Pos.t;
2021 kind: [ `void | `noreturn ];
2023 | Redeclaring_missing_method of {
2024 pos: Pos.t;
2025 trait_method: string;
2027 | Expecting_type_hint of Pos.t
2028 | Expecting_type_hint_variadic of Pos.t
2029 | Expecting_return_type_hint of Pos.t
2030 | Duplicate_using_var of Pos.t
2031 | Illegal_disposable of {
2032 pos: Pos.t;
2033 verb: [ `assigned ];
2035 | Escaping_disposable of Pos.t
2036 | Escaping_disposable_param of Pos.t
2037 | Escaping_this of Pos.t
2038 | Must_extend_disposable of Pos.t
2039 | Field_kinds of {
2040 pos: Pos.t;
2041 decl_pos: Pos_or_decl.t;
2043 | Unbound_name of {
2044 pos: Pos.t;
2045 name: string;
2047 | Previous_default of Pos.t
2048 | Return_in_void of {
2049 pos: Pos.t;
2050 decl_pos: Pos.t;
2052 | This_var_outside_class of Pos.t
2053 | Unbound_global of Pos.t
2054 | Private_inst_meth of {
2055 pos: Pos.t;
2056 decl_pos: Pos_or_decl.t;
2058 | Protected_inst_meth of {
2059 pos: Pos.t;
2060 decl_pos: Pos_or_decl.t;
2062 | Private_meth_caller of {
2063 pos: Pos.t;
2064 decl_pos: Pos_or_decl.t;
2066 | Protected_meth_caller of {
2067 pos: Pos.t;
2068 decl_pos: Pos_or_decl.t;
2070 | Private_class_meth of {
2071 pos: Pos.t;
2072 decl_pos: Pos_or_decl.t;
2074 | Protected_class_meth of {
2075 pos: Pos.t;
2076 decl_pos: Pos_or_decl.t;
2078 | Array_cast of Pos.t
2079 | String_cast of {
2080 pos: Pos.t;
2081 ty_name: string Lazy.t;
2083 | Static_outside_class of Pos.t
2084 | Self_outside_class of Pos.t
2085 | New_inconsistent_construct of {
2086 pos: Pos.t;
2087 class_pos: Pos_or_decl.t;
2088 class_name: string;
2089 kind: [ `static | `classname ];
2091 | Undefined_parent of Pos.t
2092 | Parent_outside_class of Pos.t
2093 | Parent_abstract_call of {
2094 pos: Pos.t;
2095 meth_name: string;
2096 decl_pos: Pos_or_decl.t;
2098 | Self_abstract_call of {
2099 pos: Pos.t;
2100 self_pos: Pos.t;
2101 meth_name: string;
2102 decl_pos: Pos_or_decl.t;
2104 | Classname_abstract_call of {
2105 pos: Pos.t;
2106 meth_name: string;
2107 class_name: string;
2108 decl_pos: Pos_or_decl.t;
2110 | Static_synthetic_method of {
2111 pos: Pos.t;
2112 meth_name: string;
2113 class_name: string;
2114 decl_pos: Pos_or_decl.t;
2116 | Isset_in_strict of Pos.t
2117 | Isset_inout_arg of Pos.t
2118 | Unpacking_disallowed_builtin_function of {
2119 pos: Pos.t;
2120 fn_name: string;
2122 | Array_get_arity of {
2123 pos: Pos.t;
2124 name: string;
2125 decl_pos: Pos_or_decl.t;
2127 | Undefined_field of {
2128 pos: Pos.t;
2129 name: string;
2130 decl_pos: Pos_or_decl.t;
2132 | Array_access of {
2133 pos: Pos.t;
2134 ctxt: [ `read | `write ];
2135 ty_name: string Lazy.t;
2136 decl_pos: Pos_or_decl.t;
2138 | Keyset_set of {
2139 pos: Pos.t;
2140 decl_pos: Pos_or_decl.t;
2142 | Array_append of {
2143 pos: Pos.t;
2144 ty_name: string Lazy.t;
2145 decl_pos: Pos_or_decl.t;
2147 | Const_mutation of {
2148 pos: Pos.t;
2149 ty_name: string Lazy.t;
2150 decl_pos: Pos_or_decl.t;
2152 | Expected_class of {
2153 pos: Pos.t;
2154 suffix: string Lazy.t option;
2156 | Unknown_type of {
2157 pos: Pos.t;
2158 expected: string;
2159 reason: Pos_or_decl.t Message.t list;
2161 | Parent_in_trait of Pos.t
2162 | Parent_undefined of Pos.t
2163 | Constructor_no_args of Pos.t
2164 | Visibility of {
2165 pos: Pos.t;
2166 msg: string;
2167 decl_pos: Pos_or_decl.t;
2168 reason_msg: string;
2170 | Bad_call of {
2171 pos: Pos.t;
2172 ty_name: string Lazy.t;
2174 | Extend_final of {
2175 pos: Pos.t;
2176 name: string;
2177 decl_pos: Pos_or_decl.t;
2179 | Extend_non_abstract_record of {
2180 pos: Pos.t;
2181 name: string;
2182 decl_pos: Pos_or_decl.t;
2184 | Extend_sealed of {
2185 pos: Pos.t;
2186 parent_pos: Pos_or_decl.t;
2187 parent_name: string;
2188 parent_kind: [ `intf | `trait | `class_ | `enum | `enum_class ];
2189 verb: [ `extend | `implement | `use ];
2191 | Sealed_not_subtype of {
2192 pos: Pos.t;
2193 name: string;
2194 child_kind: Ast_defs.classish_kind;
2195 child_pos: Pos_or_decl.t;
2196 child_name: string;
2198 | Trait_prop_const_class of {
2199 pos: Pos.t;
2200 name: string;
2202 | Read_before_write of {
2203 pos: Pos.t;
2204 member_name: string;
2206 | Implement_abstract of {
2207 pos: Pos.t;
2208 is_final: bool;
2209 decl_pos: Pos_or_decl.t;
2210 name: string;
2211 kind: [ `meth | `prop | `const | `ty_const ];
2212 quickfixes: Quickfix.t list;
2214 | Generic_static of {
2215 pos: Pos.t;
2216 typaram_name: string;
2218 | Ellipsis_strict_mode of {
2219 pos: Pos.t;
2220 require: [ `Param_name | `Type_and_param_name ];
2222 | Untyped_lambda_strict_mode of Pos.t
2223 | Object_string of {
2224 pos: Pos.t;
2225 decl_pos: Pos_or_decl.t;
2227 | Object_string_deprecated of Pos.t
2228 | Cyclic_typedef of {
2229 pos: Pos.t;
2230 decl_pos: Pos_or_decl.t;
2232 | Require_args_reify of {
2233 pos: Pos.t;
2234 decl_pos: Pos_or_decl.t;
2236 | Require_generic_explicit of {
2237 pos: Pos.t;
2238 param_name: string;
2239 decl_pos: Pos_or_decl.t;
2241 | Invalid_reified_arg of {
2242 pos: Pos.t;
2243 param_name: string;
2244 decl_pos: Pos_or_decl.t;
2245 arg_info: Pos_or_decl.t Message.t list;
2247 | Invalid_reified_arg_reifiable of {
2248 pos: Pos.t;
2249 param_name: string;
2250 decl_pos: Pos_or_decl.t;
2251 ty_pos: Pos_or_decl.t;
2252 ty_msg: string Lazy.t;
2254 | New_class_reified of {
2255 pos: Pos.t;
2256 class_kind: string;
2257 suggested_class_name: string option;
2259 | Class_get_reified of Pos.t
2260 | Static_meth_with_class_reified_generic of {
2261 pos: Pos.t;
2262 generic_pos: Pos.t;
2264 | Consistent_construct_reified of Pos.t
2265 | Bad_fn_ptr_construction of Pos.t
2266 | Reified_generics_not_allowed of Pos.t
2267 | New_without_newable of {
2268 pos: Pos.t;
2269 name: string;
2271 | Discarded_awaitable of {
2272 pos: Pos.t;
2273 decl_pos: Pos_or_decl.t;
2275 | Static_redeclared_as_dynamic of {
2276 pos: Pos.t;
2277 static_pos: Pos_or_decl.t;
2278 member_name: string;
2279 elt: [ `meth | `prop ];
2281 | Dynamic_redeclared_as_static of {
2282 pos: Pos.t;
2283 dyn_pos: Pos_or_decl.t;
2284 member_name: string;
2285 elt: [ `meth | `prop ];
2287 | Unknown_object_member of {
2288 pos: Pos.t;
2289 member_name: string;
2290 elt: [ `meth | `prop ];
2291 reason: Pos_or_decl.t Message.t list;
2293 | Non_class_member of {
2294 pos: Pos.t;
2295 member_name: string;
2296 elt: [ `meth | `prop ];
2297 ty_name: string Lazy.t;
2298 decl_pos: Pos_or_decl.t;
2300 | Null_container of {
2301 pos: Pos.t;
2302 null_witness: Pos_or_decl.t Message.t list;
2304 | Option_mixed of Pos.t
2305 | Option_null of Pos.t
2306 | Declared_covariant of {
2307 pos: Pos.t;
2308 param_pos: Pos.t;
2309 msgs: Pos.t Message.t list;
2311 | Declared_contravariant of {
2312 pos: Pos.t;
2313 param_pos: Pos.t;
2314 msgs: Pos.t Message.t list;
2316 | Static_prop_type_generic_param of {
2317 pos: Pos.t;
2318 var_ty_pos: Pos_or_decl.t;
2319 class_pos: Pos_or_decl.t;
2321 | Contravariant_this of {
2322 pos: Pos.t;
2323 class_name: string;
2324 typaram_name: string;
2326 | Cyclic_typeconst of {
2327 pos: Pos.t;
2328 tyconst_names: string list;
2330 | Array_get_with_optional_field of {
2331 pos: Pos.t;
2332 field_name: string;
2333 decl_pos: Pos_or_decl.t;
2335 | Mutating_const_property of Pos.t
2336 | Self_const_parent_not of Pos.t
2337 | Unexpected_ty_in_tast of {
2338 pos: Pos.t;
2339 expected_ty: string Lazy.t;
2340 actual_ty: string Lazy.t;
2342 | Call_lvalue of Pos.t
2343 | Unsafe_cast_await of Pos.t
2344 (* == Primary and secondary =============================================== *)
2345 | Smember_not_found of {
2346 pos: Pos.t;
2347 kind:
2348 [ `class_constant
2349 | `class_typeconst
2350 | `class_variable
2351 | `static_method
2353 class_name: string;
2354 class_pos: Pos_or_decl.t;
2355 member_name: string;
2356 hint: ([ `instance | `static ] * Pos_or_decl.t * string) option;
2358 | Type_arity_mismatch of {
2359 pos: Pos.t;
2360 actual: int;
2361 decl_pos: Pos_or_decl.t;
2362 expected: int;
2364 | Typing_too_many_args of {
2365 pos: Pos.t;
2366 decl_pos: Pos_or_decl.t;
2367 actual: int;
2368 expected: int;
2370 | Typing_too_few_args of {
2371 pos: Pos.t;
2372 decl_pos: Pos_or_decl.t;
2373 actual: int;
2374 expected: int;
2376 | Non_object_member of {
2377 pos: Pos.t;
2378 decl_pos: Pos_or_decl.t;
2379 ty_name: string Lazy.t;
2380 ctxt: [ `read | `write ];
2381 member_name: string;
2382 kind: [ `class_typeconst | `method_ | `property ];
2385 (* == User error helpers ================================================== *)
2387 let unify_error pos msg_opt reasons_opt =
2388 let claim = (pos, Option.value ~default:"Typing error" msg_opt)
2389 and reasons = Option.value_map ~default:[] ~f:Lazy.force reasons_opt in
2390 (Error_code.UnifyError, claim, reasons, [])
2392 let generic_unify pos msg =
2393 let claim = (pos, msg) in
2394 (Error_code.GenericUnify, claim, [], [])
2396 let internal_error pos msg =
2397 (Error_code.InternalError, (pos, "Internal error: " ^ msg), [], [])
2399 let typechecker_timeout pos fn_name seconds =
2400 let claim =
2401 ( pos,
2402 Printf.sprintf
2403 "Type checker timed out after %d seconds whilst checking function %s"
2404 seconds
2405 fn_name )
2407 (Error_code.TypecheckerTimeout, claim, [], [])
2409 let unresolved_tyvar pos =
2410 let claim =
2411 (pos, "The type of this expression contains an unresolved type variable")
2413 (Error_code.UnresolvedTypeVariable, claim, [], [])
2415 let using_error pos has_await =
2416 let (note, cls) =
2417 if has_await then
2418 (" with await", Naming_special_names.Classes.cIAsyncDisposable)
2419 else
2420 ("", Naming_special_names.Classes.cIDisposable)
2422 let claim =
2423 ( pos,
2424 Printf.sprintf
2425 "This expression is used in a `using` clause%s so it must have type `%s`"
2426 note
2427 cls )
2429 (Error_code.UnifyError, claim, [], [])
2431 let bad_enum_decl pos =
2432 ( Error_code.BadEnumExtends,
2433 (pos, "This enum declaration is invalid."),
2435 [] )
2437 let bad_conditional_support_dynamic pos child parent ty_name self_ty_name =
2438 let statement =
2439 Lazy.force ty_name
2440 ^ " is subtype of dynamic implies "
2441 ^ Lazy.force self_ty_name
2442 ^ " is subtype of dynamic"
2444 ( Error_code.BadConditionalSupportDynamic,
2445 ( pos,
2446 "Class "
2447 ^ Render.strip_ns child
2448 ^ " must support dynamic at least as often as "
2449 ^ Render.strip_ns parent
2450 ^ ":\n"
2451 ^ statement ),
2453 [] )
2455 let bad_decl_override pos name parent_pos parent_name =
2456 ( Error_code.BadDeclOverride,
2457 ( pos,
2458 "Class "
2459 ^ (Render.strip_ns name |> Markdown_lite.md_codify)
2460 ^ " does not correctly implement all required members " ),
2462 ( parent_pos,
2463 "Some members are incompatible with those declared in type "
2464 ^ (Render.strip_ns parent_name |> Markdown_lite.md_codify) );
2466 [] )
2468 let explain_where_constraint pos decl_pos in_class =
2469 ( Error_code.TypeConstraintViolation,
2470 (pos, "A `where` type constraint is violated here"),
2472 ( decl_pos,
2473 Printf.sprintf "This is the %s with `where` type constraints"
2475 if in_class then
2476 "class"
2477 else
2478 "method" );
2480 [] )
2482 let explain_constraint pos =
2483 ( Error_code.TypeConstraintViolation,
2484 (pos, "Some type arguments violate their constraints"),
2486 [] )
2488 let rigid_tvar_escape pos what =
2489 ( Error_code.RigidTVarEscape,
2490 (pos, "Rigid type variable escapes its " ^ what),
2492 [] )
2494 let invalid_type_hint pos =
2495 (Error_code.InvalidTypeHint, (pos, "Invalid type hint"), [], [])
2497 let unsatisfied_req pos trait_pos req_name req_pos =
2498 let reasons =
2499 let r =
2500 ( trait_pos,
2501 "This requires to extend or implement " ^ Render.strip_ns req_name )
2503 if Pos_or_decl.equal trait_pos req_pos then
2505 else
2506 [r; (req_pos, "Required here")]
2507 and claim =
2508 ( pos,
2509 "This class does not satisfy all the requirements of its traits or interfaces."
2512 (Error_code.UnsatisfiedReq, claim, reasons, [])
2514 let invalid_echo_argument pos =
2515 let claim =
2516 ( pos,
2517 "Invalid "
2518 ^ Markdown_lite.md_codify "echo"
2519 ^ "/"
2520 ^ Markdown_lite.md_codify "print"
2521 ^ " argument" )
2523 (Error_code.InvalidEchoArgument, claim, [], [])
2525 let index_type_mismatch pos is_covariant_container msg_opt reasons_opt =
2526 let code =
2527 if is_covariant_container then
2528 Error_code.CovariantIndexTypeMismatch
2529 else
2530 Error_code.IndexTypeMismatch
2531 and claim = (pos, Option.value ~default:"Invalid index expression" msg_opt)
2532 and reasons = Option.value_map reasons_opt ~default:[] ~f:Lazy.force in
2533 (code, claim, reasons, [])
2535 let member_not_found pos kind member_name class_name class_pos hint reason =
2536 let kind_str =
2537 match kind with
2538 | `method_ -> "instance method"
2539 | `property -> "property"
2541 let msg =
2542 Printf.sprintf
2543 "No %s %s in %s"
2544 kind_str
2545 (Markdown_lite.md_codify member_name)
2546 (Markdown_lite.md_codify @@ Render.strip_ns class_name)
2548 let default =
2549 reason
2551 ( class_pos,
2552 "Declaration of "
2553 ^ (Markdown_lite.md_codify @@ Render.strip_ns class_name)
2554 ^ " is here" );
2557 let reasons =
2558 Option.value_map hint ~default ~f:(function
2559 | (`instance, pos, v) ->
2560 Render.suggestion_message member_name v pos :: default
2561 | (`static, pos, v) ->
2562 let modifier =
2563 match kind with
2564 | `method_ -> "static method "
2565 | `property -> "static property "
2567 Render.suggestion_message member_name ~modifier v pos :: default)
2569 let quickfixes =
2570 Option.value_map hint ~default:[] ~f:(fun (_, _, new_text) ->
2571 [Quickfix.make ~title:("Change to ->" ^ new_text) ~new_text pos])
2573 (Error_code.MemberNotFound, (pos, msg), reasons, quickfixes)
2575 let construct_not_instance_method pos =
2576 let claim =
2577 ( pos,
2578 "`__construct` is not an instance method and shouldn't be invoked directly"
2581 (Error_code.ConstructNotInstanceMethod, claim, [], [])
2583 let ambiguous_inheritance pos origin class_name =
2584 let claim =
2585 ( pos,
2586 "This declaration was inherited from an object of type "
2587 ^ Markdown_lite.md_codify origin
2588 ^ ". Redeclare this member in "
2589 ^ Markdown_lite.md_codify class_name
2590 ^ " with a compatible signature." )
2592 (Error_code.UnifyError, claim, [], [])
2594 let expected_tparam pos n decl_pos =
2595 let claim =
2596 ( pos,
2597 "Expected "
2599 match n with
2600 | 0 -> "no type parameters"
2601 | 1 -> "exactly one type parameter"
2602 | n -> string_of_int n ^ " type parameters" )
2603 and reasons = [(decl_pos, "Definition is here")] in
2604 (Error_code.ExpectedTparam, claim, reasons, [])
2606 let typeconst_concrete_concrete_override pos decl_pos =
2607 let reasons = [(decl_pos, "Previously defined here")]
2608 and claim = (pos, "Cannot re-declare this type constant") in
2609 (Error_code.TypeconstConcreteConcreteOverride, claim, reasons, [])
2611 let invalid_memoized_param pos reason =
2612 let claim =
2613 ( pos,
2614 "Parameters to memoized function must be null, bool, int, float, string, an object deriving IMemoizeParam, or a Container thereof. See also http://docs.hhvm.com/hack/attributes/special#__memoize"
2617 (Error_code.InvalidMemoizedParam, claim, Lazy.force reason, [])
2619 let invalid_arraykey
2620 pos container_pos container_ty_name key_pos key_ty_name ctxt =
2621 let reasons =
2623 (container_pos, "This container is " ^ container_ty_name);
2624 ( key_pos,
2625 String.capitalize key_ty_name
2626 ^ " cannot be used as a key for "
2627 ^ container_ty_name );
2629 and claim = (pos, "This value is not a valid key type for this container")
2630 and code =
2631 Error_code.(
2632 match ctxt with
2633 | `read -> InvalidArrayKeyRead
2634 | `write -> InvalidArrayKeyWrite)
2636 (code, claim, reasons, [])
2638 let invalid_keyset_value
2639 pos container_pos container_ty_name value_pos value_ty_name =
2640 let reasons =
2642 (container_pos, "This container is " ^ container_ty_name);
2643 (value_pos, String.capitalize value_ty_name ^ " is not an arraykey");
2645 and claim = (pos, "Keyset values must be arraykeys") in
2646 (Error_code.InvalidKeysetValue, claim, reasons, [])
2648 let invalid_set_value
2649 pos container_pos container_ty_name value_pos value_ty_name =
2650 let reasons =
2652 (container_pos, "This container is " ^ container_ty_name);
2653 (value_pos, String.capitalize value_ty_name ^ " is not an arraykey");
2655 and claim = (pos, "Set values must be arraykeys") in
2656 (Error_code.InvalidKeysetValue, claim, reasons, [])
2658 let hkt_alias_with_implicit_constraints
2660 typedef_name
2661 typedef_pos
2662 used_class_in_def_pos
2663 used_class_in_def_name
2664 used_class_tparam_name
2665 typedef_tparam_name =
2666 let reasons =
2668 ( typedef_pos,
2669 "The definition of " ^ Render.strip_ns typedef_name ^ " is here." );
2670 ( used_class_in_def_pos,
2671 "The definition of "
2672 ^ Render.strip_ns typedef_name
2673 ^ " relies on "
2674 ^ Render.strip_ns used_class_in_def_name
2675 ^ " and the constraints that "
2676 ^ Render.strip_ns used_class_in_def_name
2677 ^ " imposes on its type parameter "
2678 ^ Render.strip_ns used_class_tparam_name
2679 ^ " then become implicit constraints on the type parameter "
2680 ^ typedef_tparam_name
2681 ^ " of "
2682 ^ Render.strip_ns typedef_name
2683 ^ "." );
2685 and claim =
2686 ( pos,
2687 Format.sprintf
2688 "The type %s implicitly imposes constraints on its type parameters. Therefore, it cannot be used as a higher-kinded type at this time."
2689 @@ Render.strip_ns typedef_name )
2691 (Error_code.HigherKindedTypesUnsupportedFeature, claim, reasons, [])
2693 let invalid_substring pos ty_name =
2694 let claim =
2695 ( pos,
2696 "Expected an object convertible to string but got " ^ Lazy.force ty_name
2699 (Error_code.InvalidSubString, claim, [], [])
2701 let nullable_cast pos ty_pos ty_name =
2702 let reasons =
2703 [(ty_pos, "This is " ^ Markdown_lite.md_codify (Lazy.force ty_name))]
2704 and claim = (pos, "Casting from a nullable type is forbidden") in
2705 (Error_code.NullableCast, claim, reasons, [])
2707 let hh_expect pos equivalent =
2708 let (msg, error_code) =
2709 if equivalent then
2710 ( "hh_expect_equivalent type mismatch",
2711 Error_code.HHExpectEquivalentFailure )
2712 else
2713 ("hh_expect type mismatch", Error_code.HHExpectFailure)
2716 (error_code, (pos, msg), [], [])
2718 let null_member pos ctxt kind member_name reason =
2719 let msg =
2720 Printf.sprintf
2721 "You are trying to access the %s %s but this object can be null."
2722 (match kind with
2723 | `method_ -> "method"
2724 | `property -> "property")
2725 (Markdown_lite.md_codify member_name)
2727 let error_code =
2728 match ctxt with
2729 | `read -> Error_code.NullMemberRead
2730 | `write -> Error_code.NullMemberWrite
2732 (error_code, (pos, msg), reason, [])
2734 let typing_too_many_args pos decl_pos actual expected =
2735 let (code, claim, reasons) =
2736 Common.typing_too_many_args pos decl_pos actual expected
2738 (code, claim, reasons, [])
2740 let typing_too_few_args pos decl_pos actual expected =
2741 let (code, claim, reasons) =
2742 Common.typing_too_few_args pos decl_pos actual expected
2744 (code, claim, reasons, [])
2746 let non_object_member pos ctxt ty_name member_name kind decl_pos =
2747 let (code, claim, reasons) =
2748 Common.non_object_member
2750 ctxt
2751 (Lazy.force ty_name)
2752 member_name
2753 kind
2754 decl_pos
2756 (code, claim, reasons, [])
2758 let nullsafe_property_write_context pos =
2759 let msg =
2760 "`?->` syntax not supported here, this function effectively does a write"
2762 (Error_code.NullsafePropertyWriteContext, (pos, msg), [], [])
2764 let uninstantiable_class pos class_name reason_ty_opt decl_pos =
2765 let name = Render.strip_ns class_name in
2766 let default =
2767 ( (pos, Markdown_lite.md_codify name ^ " is uninstantiable"),
2768 [(decl_pos, "Declaration is here")] )
2770 let (claim, reasons) =
2771 Option.value_map reason_ty_opt ~default ~f:(fun (reason_pos, ty_name) ->
2772 let msg =
2773 "This would be "
2774 ^ Lazy.force ty_name
2775 ^ " which must be instantiable"
2777 let reasons =
2778 Message.map ~f:Pos_or_decl.of_raw_pos (fst default) :: snd default
2780 let claim = (reason_pos, msg) in
2781 (claim, reasons))
2783 (Error_code.UninstantiableClass, claim, reasons, [])
2785 let abstract_const_usage pos name decl_pos =
2786 let name = Render.strip_ns name in
2787 let msg =
2788 "Cannot reference abstract constant "
2789 ^ Markdown_lite.md_codify name
2790 ^ " directly"
2791 and reason = [(decl_pos, "Declaration is here")] in
2792 (Error_code.AbstractConstUsage, (pos, msg), reason, [])
2794 let type_arity_mismatch pos decl_pos actual expected =
2795 let msg =
2796 Printf.sprintf
2797 "Wrong number of type arguments (expected %d, got %d)"
2798 expected
2799 actual
2800 and reasons = [(decl_pos, "Definition is here")] in
2801 (Error_code.TypeArityMismatch, (pos, msg), reasons, [])
2803 let member_not_implemented pos parent_pos member_name decl_pos quickfixes =
2804 let claim =
2805 ( pos,
2806 "This type doesn't implement the method "
2807 ^ Markdown_lite.md_codify member_name )
2808 and reasons =
2810 (parent_pos, "Which is required by this interface");
2811 (decl_pos, "As defined here");
2814 (Error_code.MemberNotImplemented, claim, reasons, quickfixes)
2816 let attribute_too_many_arguments pos name expected =
2817 let msg =
2818 "The attribute "
2819 ^ Markdown_lite.md_codify name
2820 ^ " expects at most "
2821 ^ Render.pluralize_arguments expected
2823 (Error_code.AttributeTooManyArguments, (pos, msg), [], [])
2825 let attribute_too_few_arguments pos name expected =
2826 let msg =
2827 "The attribute "
2828 ^ Markdown_lite.md_codify name
2829 ^ " expects at least "
2830 ^ Render.pluralize_arguments expected
2832 (Error_code.AttributeTooFewArguments, (pos, msg), [], [])
2834 let attribute_not_exact_number_of_args pos name actual expected =
2835 let code =
2836 if actual > expected then
2837 Error_code.AttributeTooManyArguments
2838 else
2839 Error_code.AttributeTooFewArguments
2840 and msg =
2841 "The attribute "
2842 ^ Markdown_lite.md_codify name
2843 ^ " expects "
2845 match expected with
2846 | 0 -> "no arguments"
2847 | 1 -> "exactly 1 argument"
2848 | _ -> "exactly " ^ string_of_int expected ^ " arguments"
2850 (code, (pos, msg), [], [])
2852 let kind_mismatch pos decl_pos tparam_name expected_kind actual_kind =
2853 let msg =
2854 "This is "
2855 ^ actual_kind
2856 ^ ", but "
2857 ^ expected_kind
2858 ^ " was expected here."
2859 and reason =
2861 ( decl_pos,
2862 "We are expecting "
2863 ^ expected_kind
2864 ^ " due to the definition of "
2865 ^ tparam_name
2866 ^ " here." );
2869 (Error_code.KindMismatch, (pos, msg), reason, [])
2871 let trait_parent_construct_inconsistent pos decl_pos =
2872 let msg =
2873 "This use of `parent::__construct` requires that the parent class be marked <<__ConsistentConstruct>>"
2874 and reason = [(decl_pos, "Parent definition is here")] in
2875 (Error_code.TraitParentConstructInconsistent, (pos, msg), reason, [])
2877 let top_member pos ctxt ty_name decl_pos kind name is_nullable =
2878 let kind_str =
2879 match kind with
2880 | `method_ -> "method"
2881 | `property -> "property"
2883 let claim =
2884 ( pos,
2885 Printf.sprintf
2886 "You are trying to access the %s %s but this is %s. Use a **specific** class or interface name."
2887 kind_str
2888 (Markdown_lite.md_codify name)
2889 (Lazy.force ty_name) )
2890 and reason = [(decl_pos, "Definition is here")]
2891 and code =
2892 Error_code.(
2893 match ctxt with
2894 | `read when is_nullable -> NullMemberRead
2895 | `write when is_nullable -> NullMemberWrite
2896 | `read -> NonObjectMemberRead
2897 | `write -> NonObjectMemberWrite)
2899 (code, claim, reason, [])
2901 let unresolved_tyvar_projection pos proj_pos tconst_name =
2902 let claim =
2903 ( pos,
2904 "Can't access a type constant "
2905 ^ tconst_name
2906 ^ " from an unresolved type" )
2907 and reason =
2909 (proj_pos, "Access happens here");
2910 ( Pos_or_decl.of_raw_pos pos,
2911 "Disambiguate the types using explicit type annotations here." );
2914 (Error_code.UnresolvedTypeVariableProjection, claim, reason, [])
2916 let cyclic_class_constant pos class_name const_name =
2917 let claim =
2918 ( pos,
2919 "Cannot declare self-referencing constant "
2920 ^ const_name
2921 ^ " in "
2922 ^ Render.strip_ns class_name )
2924 (Error_code.CyclicClassConstant, claim, [], [])
2926 let inout_annotation_missing pos1 pos2 =
2927 let msg1 = (pos1, "This argument should be annotated with `inout`") in
2928 let msg2 = (pos2, "Because this is an `inout` parameter") in
2929 let (_, start_column) = Pos.line_column pos1 in
2930 let pos = Pos.set_col_end start_column pos1 in
2932 ( Error_code.InoutAnnotationMissing,
2933 msg1,
2934 [msg2],
2935 [Quickfix.make ~title:"Insert `inout` annotation" ~new_text:"inout " pos]
2938 let inout_annotation_unexpected pos1 pos2 pos2_is_variadic pos3 =
2939 let msg1 = (pos1, "Unexpected `inout` annotation for argument") in
2940 let msg2 =
2941 ( pos2,
2942 if pos2_is_variadic then
2943 "A variadic parameter can never be `inout`"
2944 else
2945 "This is a normal parameter (does not have `inout`)" )
2947 ( Error_code.InoutAnnotationUnexpected,
2948 msg1,
2949 [msg2],
2950 [Quickfix.make ~title:"Remove `inout` annotation" ~new_text:"" pos3] )
2952 let inout_argument_bad_type pos reasons =
2953 let claim =
2954 ( pos,
2955 "Expected argument marked `inout` to be contained in a local or "
2956 ^ "a value-typed container (e.g. vec, dict, keyset, array). "
2957 ^ "To use `inout` here, assign to/from a temporary local variable." )
2959 (Error_code.InoutArgumentBadType, claim, Lazy.force reasons, [])
2961 let invalid_meth_caller_calling_convention pos decl_pos convention =
2962 let claim =
2963 ( pos,
2964 "`meth_caller` does not support methods with the "
2965 ^ convention
2966 ^ " calling convention" )
2967 and reason =
2969 ( decl_pos,
2970 "This is why I think this method uses the `inout` calling convention"
2974 (Error_code.InvalidMethCallerCallingConvention, claim, reason, [])
2976 let invalid_meth_caller_readonly_return pos decl_pos =
2977 let claim =
2978 ( pos,
2979 "`meth_caller` does not support methods that return `readonly` objects"
2982 let reason =
2984 (decl_pos, "This is why I think this method returns a `readonly` object");
2987 (Error_code.InvalidMethCallerReadonlyReturn, claim, reason, [])
2989 let invalid_new_disposable pos =
2990 let claim =
2991 ( pos,
2992 "Disposable objects may only be created in a `using` statement or `return` from function marked `<<__ReturnDisposable>>`"
2995 (Error_code.InvalidNewDisposable, claim, [], [])
2997 let invalid_return_disposable pos =
2998 let claim =
2999 ( pos,
3000 "Return expression must be new disposable in function marked `<<__ReturnDisposable>>`"
3003 (Error_code.InvalidReturnDisposable, claim, [], [])
3005 let invalid_disposable_hint pos class_name =
3006 let claim =
3007 ( pos,
3008 "Parameter with type "
3009 ^ Markdown_lite.md_codify class_name
3010 ^ " must not implement `IDisposable` or `IAsyncDisposable`. "
3011 ^ "Please use `<<__AcceptDisposable>>` attribute or create disposable object with `using` statement instead."
3014 (Error_code.InvalidDisposableHint, claim, [], [])
3016 let invalid_disposable_return_hint pos class_name =
3017 let claim =
3018 ( pos,
3019 "Return type "
3020 ^ Markdown_lite.md_codify class_name
3021 ^ " must not implement `IDisposable` or `IAsyncDisposable`. Please add `<<__ReturnDisposable>>` attribute."
3024 (Error_code.InvalidDisposableReturnHint, claim, [], [])
3026 let ambiguous_lambda pos uses =
3027 let claim =
3028 ( pos,
3029 "Lambda has parameter types that could not be determined at definition site."
3031 and reason =
3032 ( Pos_or_decl.of_raw_pos pos,
3033 Printf.sprintf
3034 "%d distinct use types were determined: please add type hints to lambda parameters."
3035 (List.length uses) )
3037 List.map uses ~f:(fun (pos, ty) ->
3038 (pos, "This use has type " ^ Markdown_lite.md_codify ty))
3040 (Error_code.AmbiguousLambda, claim, reason, [])
3042 let smember_not_found pos kind member_name class_name class_pos hint =
3043 let (code, claim, reasons) =
3044 Common.smember_not_found pos kind member_name class_name class_pos hint
3046 let quickfixes =
3047 Option.value_map hint ~default:[] ~f:(fun (_, _, new_text) ->
3048 Quickfix.[make ~title:("Change to ::" ^ new_text) ~new_text pos])
3050 (code, claim, reasons, quickfixes)
3052 let wrong_extend_kind pos kind name parent_pos parent_kind parent_name =
3053 let parent_kind_str = Ast_defs.string_of_classish_kind parent_kind in
3054 let parent_name = Render.strip_ns parent_name in
3055 let child_name = Render.strip_ns name in
3056 let use_msg =
3057 Printf.sprintf
3058 " Did you mean to add `use %s;` within the body of %s?"
3059 parent_name
3060 (Markdown_lite.md_codify child_name)
3062 let child_msg =
3063 match kind with
3064 | Ast_defs.Cclass _ ->
3065 let extends_msg = "Classes can only extend other classes." in
3066 let suggestion =
3067 if Ast_defs.is_c_interface parent_kind then
3068 " Did you mean `implements " ^ parent_name ^ "`?"
3069 else if Ast_defs.is_c_trait parent_kind then
3070 use_msg
3071 else
3074 extends_msg ^ suggestion
3075 | Ast_defs.Cinterface ->
3076 let extends_msg = "Interfaces can only extend other interfaces." in
3077 let suggestion =
3078 if Ast_defs.is_c_trait parent_kind then
3079 use_msg
3080 else
3083 extends_msg ^ suggestion
3084 | Ast_defs.Cenum_class _ ->
3085 "Enum classes can only extend other enum classes."
3086 | Ast_defs.Cenum ->
3087 (* This case should never happen, as the type checker will have already caught
3088 it with EnumTypeBad. But just in case, report this error here too. *)
3089 "Enums can only extend int, string, or arraykey."
3090 | Ast_defs.Ctrait ->
3091 (* This case should never happen, as the parser will have caught it before
3092 we get here. *)
3093 "A trait cannot use `extends`. This is a parser error."
3095 let msg1 = (pos, child_msg) in
3096 let msg2 = (parent_pos, "This is " ^ parent_kind_str ^ ".") in
3097 (Error_code.WrongExtendKind, msg1, [msg2], [])
3099 let cyclic_class_def pos stack =
3100 let stack =
3101 SSet.fold
3102 (fun x y -> (Render.strip_ns x |> Markdown_lite.md_codify) ^ " " ^ y)
3103 stack
3106 ( Error_code.CyclicClassDef,
3107 (pos, "Cyclic class definition : " ^ stack),
3109 [] )
3111 let cyclic_record_def pos names =
3112 let names =
3113 List.map ~f:(fun n -> Render.strip_ns n |> Markdown_lite.md_codify) names
3115 ( Error_code.CyclicRecordDef,
3116 ( pos,
3117 Printf.sprintf
3118 "Record inheritance cycle: %s"
3119 (String.concat ~sep:" " names) ),
3121 [] )
3123 let trait_reuse_with_final_method use_pos trait_name parent_cls_name trace =
3124 let msg =
3125 Printf.sprintf
3126 "Traits with final methods cannot be reused, and `%s` is already used by `%s`."
3127 (Render.strip_ns trait_name)
3128 (Render.strip_ns parent_cls_name)
3130 (Error_code.TraitReuse, (use_pos, msg), trace, [])
3132 let trait_reuse pos c_name trait_name parent_pos parent_name =
3133 let c_name = Render.strip_ns c_name |> Markdown_lite.md_codify in
3134 let trait = Render.strip_ns trait_name |> Markdown_lite.md_codify in
3135 let err =
3136 "Class " ^ c_name ^ " reuses trait " ^ trait ^ " in its hierarchy"
3138 let err' =
3139 "It is already used through "
3140 ^ (Render.strip_ns parent_name |> Markdown_lite.md_codify)
3142 (Error_code.TraitReuse, (pos, err), [(parent_pos, err')], [])
3144 let trait_reuse_inside_class c_pos c_name trait occurrences =
3145 let c_name = Render.strip_ns c_name |> Markdown_lite.md_codify in
3146 let trait = Render.strip_ns trait |> Markdown_lite.md_codify in
3147 let err = "Class " ^ c_name ^ " uses trait " ^ trait ^ " multiple times" in
3148 ( Error_code.TraitReuseInsideClass,
3149 (c_pos, err),
3150 List.map ~f:(fun p -> (p, "used here")) occurrences,
3151 [] )
3153 let invalid_is_as_expression_hint hint_pos op reasons =
3154 let op =
3155 match op with
3156 | `is -> "is"
3157 | `as_ -> "as"
3159 ( Error_code.InvalidIsAsExpressionHint,
3160 (hint_pos, "Invalid " ^ Markdown_lite.md_codify op ^ " expression hint"),
3161 List.map reasons ~f:(fun (ty_pos, ty_str) ->
3162 ( ty_pos,
3163 "The "
3164 ^ Markdown_lite.md_codify op
3165 ^ " operator cannot be used with "
3166 ^ ty_str )),
3167 [] )
3169 let invalid_enforceable_type targ_pos ty_info kind tp_pos tp_name =
3170 let kind_str =
3171 match kind with
3172 | `constant -> "constant"
3173 | `param -> "parameter"
3175 let (ty_pos, ty_str) = List.hd_exn ty_info in
3176 ( Error_code.InvalidEnforceableTypeArgument,
3177 (targ_pos, "Invalid type"),
3179 ( tp_pos,
3180 "Type "
3181 ^ kind_str
3182 ^ " "
3183 ^ Markdown_lite.md_codify tp_name
3184 ^ " was declared `__Enforceable` here" );
3185 (ty_pos, "This type is not enforceable because it has " ^ ty_str);
3187 [] )
3189 let reifiable_attr attr_pos kind decl_pos ty_info =
3190 let decl_kind =
3191 match kind with
3192 | `ty -> "type"
3193 | `cnstr -> "constraint"
3194 | `super_cnstr -> "super_constraint"
3196 let (ty_pos, ty_msg) = List.hd_exn ty_info in
3197 ( Error_code.DisallowPHPArraysAttr,
3198 (decl_pos, "Invalid " ^ decl_kind),
3200 (attr_pos, "This type constant has the `__Reifiable` attribute");
3201 (ty_pos, "It cannot contain " ^ ty_msg);
3203 [] )
3205 let invalid_newable_type_argument pos tp_pos tp_name =
3206 ( Error_code.InvalidNewableTypeArgument,
3207 ( pos,
3208 "A newable type argument must be a concrete class or a newable type parameter."
3211 ( tp_pos,
3212 "Type parameter "
3213 ^ Markdown_lite.md_codify tp_name
3214 ^ " was declared `__Newable` here" );
3216 [] )
3218 let invalid_newable_type_param_constraints
3219 (tparam_pos, tparam_name) constraint_list =
3220 let partial =
3221 if List.is_empty constraint_list then
3222 "No constraints"
3223 else
3224 "The constraints "
3225 ^ String.concat ~sep:", " (List.map ~f:Render.strip_ns constraint_list)
3227 let msg =
3228 "The type parameter "
3229 ^ Markdown_lite.md_codify tparam_name
3230 ^ " has the `<<__Newable>>` attribute. "
3231 ^ "Newable type parameters must be constrained with `as`, and exactly one of those constraints must be a valid newable class. "
3232 ^ "The class must either be final, or it must have the `<<__ConsistentConstruct>>` attribute or extend a class that has it. "
3233 ^ partial
3234 ^ " are valid newable classes"
3236 (Error_code.InvalidNewableTypeParamConstraints, (tparam_pos, msg), [], [])
3238 let override_per_trait class_name meth_name trait_name m_pos =
3239 let (c_pos, c_name) = class_name in
3240 let err_msg =
3241 Printf.sprintf
3242 "`%s::%s` is marked `__Override` but `%s` does not define or inherit a `%s` method."
3243 (Render.strip_ns trait_name)
3244 meth_name
3245 (Render.strip_ns c_name)
3246 meth_name
3248 ( Error_code.OverridePerTrait,
3249 (c_pos, err_msg),
3251 ( m_pos,
3252 "Declaration of " ^ Markdown_lite.md_codify meth_name ^ " is here" );
3254 [] )
3256 let generic_at_runtime p prefix =
3257 ( Error_code.ErasedGenericAtRuntime,
3258 ( p,
3259 prefix
3260 ^ " generics can only be used in type hints because they do not exist at runtime."
3263 [] )
3265 let generics_not_allowed p =
3266 ( Error_code.GenericsNotAllowed,
3267 (p, "Generics are not allowed in this position."),
3269 [] )
3271 let typedef_trail_entry pos = (pos, "Typedef definition comes from here")
3273 let trivial_strict_eq p b left right left_trail right_trail =
3274 let b =
3275 Markdown_lite.md_codify
3276 (if b then
3277 "true"
3278 else
3279 "false")
3281 let msg = sprintf "This expression is always %s" b in
3282 let left_trail = List.map left_trail ~f:typedef_trail_entry in
3283 let right_trail = List.map right_trail ~f:typedef_trail_entry in
3284 ( Error_code.TrivialStrictEq,
3285 (p, msg),
3286 left @ left_trail @ right @ right_trail,
3287 [] )
3289 let trivial_strict_not_nullable_compare_null p result type_reason =
3290 let b =
3291 Markdown_lite.md_codify
3292 (if result then
3293 "true"
3294 else
3295 "false")
3297 let msg = sprintf "This expression is always %s" b in
3298 (Error_code.NotNullableCompareNullTrivial, (p, msg), type_reason, [])
3300 let eq_incompatible_types p left right =
3301 let msg = "This equality test has incompatible types" in
3302 (Error_code.EqIncompatibleTypes, (p, msg), left @ right, [])
3304 let comparison_invalid_types p left right =
3305 let msg =
3306 "This comparison has invalid types. Only comparisons in which both arguments are strings, nums, DateTime, or DateTimeImmutable are allowed"
3308 (Error_code.ComparisonInvalidTypes, (p, msg), left @ right, [])
3310 let strict_eq_value_incompatible_types p left right =
3311 let msg =
3312 "The arguments to this value equality test are not the same types or are not the allowed types (int, bool, float, string, vec, keyset, dict). The behavior for this test is changing and will soon either be universally false or throw an exception."
3314 (Error_code.StrictEqValueIncompatibleTypes, (p, msg), left @ right, [])
3316 let attribute_param_type pos x =
3317 ( Error_code.AttributeParamType,
3318 (pos, "This attribute parameter should be " ^ x),
3320 [] )
3322 let deprecated_use pos ?(pos_def = None) msg =
3323 let def_message =
3324 match pos_def with
3325 | Some pos_def -> [(pos_def, "Definition is here")]
3326 | None -> []
3328 (Error_code.DeprecatedUse, (pos, msg), def_message, [])
3330 let cannot_declare_constant kind pos (class_pos, class_name) =
3331 let kind_str =
3332 match kind with
3333 | `enum -> "an enum"
3334 | `record -> "a record"
3336 ( Error_code.CannotDeclareConstant,
3337 (pos, "Cannot declare a constant in " ^ kind_str),
3339 ( Pos_or_decl.of_raw_pos class_pos,
3340 (Render.strip_ns class_name |> Markdown_lite.md_codify)
3341 ^ " was defined as "
3342 ^ kind_str
3343 ^ " here" );
3345 [] )
3347 let local_variable_modified_and_used pos_modified pos_used_l =
3348 let used_msg p = (Pos_or_decl.of_raw_pos p, "And accessed here") in
3349 ( Error_code.LocalVariableModifedAndUsed,
3350 ( pos_modified,
3351 "Unsequenced modification and access to local variable. Modified here"
3353 List.map pos_used_l ~f:used_msg,
3354 [] )
3356 let local_variable_modified_twice pos_modified pos_modified_l =
3357 let modified_msg p = (Pos_or_decl.of_raw_pos p, "And also modified here") in
3358 ( Error_code.LocalVariableModifedTwice,
3359 ( pos_modified,
3360 "Unsequenced modifications to local variable. Modified here" ),
3361 List.map pos_modified_l ~f:modified_msg,
3362 [] )
3364 let assign_during_case p =
3365 ( Error_code.AssignDuringCase,
3366 (p, "Don't assign to variables inside of case labels"),
3368 [] )
3370 let invalid_classname p =
3371 (Error_code.InvalidClassname, (p, "Not a valid class name"), [], [])
3373 let illegal_type_structure pos =
3374 let errmsg = "second argument is not a string" in
3375 let msg =
3376 "The two arguments to `type_structure()` must be:"
3377 ^ "\n - first: `ValidClassname::class` or an object of that class"
3378 ^ "\n - second: a single-quoted string literal containing the name"
3379 ^ " of a type constant of that class"
3380 ^ "\n"
3381 ^ errmsg
3383 (Error_code.IllegalTypeStructure, (pos, msg), [], [])
3385 let illegal_typeconst_direct_access pos =
3386 let msg =
3387 "Type constants cannot be directly accessed. "
3388 ^ "Use `type_structure(ValidClassname::class, 'TypeConstName')` instead"
3390 (Error_code.IllegalTypeStructure, (pos, msg), [], [])
3392 let wrong_expression_kind_attribute
3393 expr_kind pos attr attr_class_pos attr_class_name intf_name =
3394 let msg1 =
3395 Printf.sprintf
3396 "The %s attribute cannot be used on %s."
3397 (Render.strip_ns attr |> Markdown_lite.md_codify)
3398 expr_kind
3400 let msg2 =
3401 Printf.sprintf
3402 "The attribute's class is defined here. To be available for use on %s, the %s class must implement %s."
3403 expr_kind
3404 (Render.strip_ns attr_class_name |> Markdown_lite.md_codify)
3405 (Render.strip_ns intf_name |> Markdown_lite.md_codify)
3407 ( Error_code.WrongExpressionKindAttribute,
3408 (pos, msg1),
3409 [(attr_class_pos, msg2)],
3410 [] )
3412 let wrong_expression_kind_builtin_attribute expr_kind pos attr =
3413 let msg1 =
3414 Printf.sprintf
3415 "The %s attribute cannot be used on %s."
3416 (Render.strip_ns attr |> Markdown_lite.md_codify)
3417 expr_kind
3419 (Error_code.WrongExpressionKindAttribute, (pos, msg1), [], [])
3421 let ambiguous_object_access
3422 pos name self_pos vis subclass_pos class_self class_subclass =
3423 let class_self = Render.strip_ns class_self in
3424 let class_subclass = Render.strip_ns class_subclass in
3425 ( Error_code.AmbiguousObjectAccess,
3426 ( pos,
3427 "This object access to "
3428 ^ Markdown_lite.md_codify name
3429 ^ " is ambiguous" ),
3431 ( self_pos,
3432 "You will access the private instance declared in "
3433 ^ Markdown_lite.md_codify class_self );
3434 ( subclass_pos,
3435 "Instead of the "
3436 ^ vis
3437 ^ " instance declared in "
3438 ^ Markdown_lite.md_codify class_subclass );
3440 [] )
3442 let lateinit_with_default pos =
3443 ( Error_code.LateInitWithDefault,
3444 (pos, "A late-initialized property cannot have a default value"),
3446 [] )
3448 let unserializable_type pos message =
3449 ( Error_code.UnserializableType,
3450 ( pos,
3451 "Unserializable type (could not be converted to JSON and back again): "
3452 ^ message ),
3454 [] )
3456 let invalid_arraykey_constraint pos t =
3457 ( Error_code.InvalidArrayKeyConstraint,
3458 ( pos,
3459 "This type is "
3461 ^ ", which cannot be used as an arraykey (string | int)" ),
3463 [] )
3465 let redundant_covariant pos msg suggest =
3466 ( Error_code.RedundantGeneric,
3467 ( pos,
3468 "This generic parameter is redundant because it only appears in a covariant (output) position"
3469 ^ msg
3470 ^ ". Consider replacing uses of generic parameter with "
3471 ^ Markdown_lite.md_codify suggest
3472 ^ " or specifying `<<__Explicit>>` on the generic parameter" ),
3474 [] )
3476 let meth_caller_trait pos trait_name =
3477 ( Error_code.MethCallerTrait,
3478 ( pos,
3479 (Render.strip_ns trait_name |> Markdown_lite.md_codify)
3480 ^ " is a trait which cannot be used with `meth_caller`. Use a class instead."
3483 [] )
3485 let duplicate_interface pos name others =
3486 ( Error_code.DuplicateInterface,
3487 ( pos,
3488 Printf.sprintf
3489 "Interface %s is used more than once in this declaration."
3490 (Render.strip_ns name |> Markdown_lite.md_codify) ),
3491 List.map others ~f:(fun pos -> (pos, "Here is another occurrence")),
3492 [] )
3494 let tparam_non_shadowing_reuse pos var_name =
3495 ( Error_code.TypeParameterNameAlreadyUsedNonShadow,
3496 ( pos,
3497 "The name "
3498 ^ Markdown_lite.md_codify var_name
3499 ^ " was already used for another generic parameter. Please use a different name to avoid confusion."
3502 [] )
3504 let reified_function_reference call_pos =
3505 ( Error_code.ReifiedFunctionReference,
3506 ( call_pos,
3507 "Invalid function reference. This function requires reified generics. Prefer using a lambda instead."
3510 [] )
3512 let class_meth_abstract_call cname meth_name call_pos decl_pos =
3513 let cname = Render.strip_ns cname in
3514 ( Error_code.ClassMethAbstractCall,
3515 ( call_pos,
3516 "Cannot create a class_meth of "
3517 ^ cname
3518 ^ "::"
3519 ^ meth_name
3520 ^ "; it is abstract." ),
3521 [(decl_pos, "Declaration is here")],
3522 [] )
3524 let reinheriting_classish_const
3525 dest_classish_pos
3526 dest_classish_name
3527 src_classish_pos
3528 src_classish_name
3529 existing_const_origin
3530 const_name =
3531 ( Error_code.RedeclaringClassishConstant,
3532 ( src_classish_pos,
3533 Render.strip_ns dest_classish_name
3534 ^ " cannot re-inherit constant "
3535 ^ const_name
3536 ^ " from "
3537 ^ Render.strip_ns src_classish_name ),
3539 ( Pos_or_decl.of_raw_pos dest_classish_pos,
3540 "because it already inherited it via "
3541 ^ Render.strip_ns existing_const_origin );
3543 [] )
3545 let redeclaring_classish_const
3546 classish_pos
3547 classish_name
3548 redeclaration_pos
3549 existing_const_origin
3550 const_name =
3551 ( Error_code.RedeclaringClassishConstant,
3552 ( redeclaration_pos,
3553 Render.strip_ns classish_name
3554 ^ " cannot re-declare constant "
3555 ^ const_name ),
3557 ( Pos_or_decl.of_raw_pos classish_pos,
3558 "because it already inherited it via "
3559 ^ Render.strip_ns existing_const_origin );
3561 [] )
3563 let abstract_function_pointer cname meth_name call_pos decl_pos =
3564 let cname = Render.strip_ns cname in
3565 ( Error_code.AbstractFunctionPointer,
3566 ( call_pos,
3567 "Cannot create a function pointer to "
3568 ^ Markdown_lite.md_codify (cname ^ "::" ^ meth_name)
3569 ^ "; it is abstract" ),
3570 [(decl_pos, "Declaration is here")],
3571 [] )
3573 let unnecessary_attribute pos ~attr ~reason ~suggestion =
3574 let attr = Render.strip_ns attr in
3575 let (reason_pos, reason_msg) = reason in
3576 let suggestion =
3577 match suggestion with
3578 | None -> "Try deleting this attribute"
3579 | Some s -> s
3581 ( Error_code.UnnecessaryAttribute,
3582 (pos, sprintf "The attribute `%s` is unnecessary" attr),
3584 ( Pos_or_decl.of_raw_pos reason_pos,
3585 "It is unnecessary because " ^ reason_msg );
3586 (Pos_or_decl.of_raw_pos pos, suggestion);
3588 [] )
3590 let inherited_class_member_with_different_case
3591 member_type name name_prev p child_class prev_class prev_class_pos =
3592 let name = Render.strip_ns name in
3593 let name_prev = Render.strip_ns name_prev in
3594 let child_class = Render.strip_ns child_class in
3595 let prev_class = Render.strip_ns prev_class in
3596 let claim =
3597 ( p,
3598 child_class
3599 ^ " inherits a "
3600 ^ member_type
3601 ^ " named "
3602 ^ Markdown_lite.md_codify name_prev
3603 ^ " whose name differs from this one ("
3604 ^ Markdown_lite.md_codify name
3605 ^ ") only by case." )
3607 let reasons =
3609 ( prev_class_pos,
3610 "It was inherited from "
3611 ^ prev_class
3612 ^ " as "
3613 ^ (Render.highlight_differences name name_prev
3614 |> Markdown_lite.md_codify)
3615 ^ ". If you meant to override it, please use the same casing as the inherited "
3616 ^ member_type
3617 ^ "."
3618 ^ " Otherwise, please choose a different name for the new "
3619 ^ member_type );
3622 (Error_code.InheritedMethodCaseDiffers, claim, reasons, [])
3624 let multiple_inherited_class_member_with_different_case
3625 ~member_type ~name1 ~name2 ~class1 ~class2 ~child_class ~child_p ~p1 ~p2 =
3626 let name1 = Render.strip_ns name1 in
3627 let name2 = Render.strip_ns name2 in
3628 let class1 = Render.strip_ns class1 in
3629 let class2 = Render.strip_ns class2 in
3630 let child_class = Render.strip_ns child_class in
3631 let claim =
3632 ( child_p,
3633 Markdown_lite.md_codify child_class
3634 ^ " inherited two versions of the "
3635 ^ member_type
3636 ^ " "
3637 ^ Markdown_lite.md_codify name1
3638 ^ " whose names differ only by case." )
3640 let reasons =
3642 ( p1,
3643 "It inherited "
3644 ^ Markdown_lite.md_codify name1
3645 ^ " from "
3646 ^ class1
3647 ^ " here." );
3648 ( p2,
3649 "And "
3650 ^ Markdown_lite.md_codify name2
3651 ^ " from "
3652 ^ class2
3653 ^ " here. Please rename these "
3654 ^ member_type
3655 ^ "s to the same casing." );
3658 (Error_code.InheritedMethodCaseDiffers, claim, reasons, [])
3660 let classish_kind_to_string = function
3661 | Ast_defs.Cclass _ -> "class "
3662 | Ast_defs.Ctrait -> "trait "
3663 | Ast_defs.Cinterface -> "interface "
3664 | Ast_defs.Cenum_class _ -> "enum class "
3665 | Ast_defs.Cenum -> "enum "
3667 let parent_support_dynamic_type
3669 (child_name, child_kind)
3670 (parent_name, parent_kind)
3671 child_support_dynamic_type =
3672 let kinds_to_use child_kind parent_kind =
3673 match (child_kind, parent_kind) with
3674 | (_, Ast_defs.Cclass _) -> "extends "
3675 | (_, Ast_defs.Ctrait) -> "uses "
3676 | (Ast_defs.Cinterface, Ast_defs.Cinterface) -> "extends "
3677 | (_, Ast_defs.Cinterface) -> "implements "
3678 | (_, Ast_defs.Cenum_class _)
3679 | (_, Ast_defs.Cenum) ->
3682 let child_name = Markdown_lite.md_codify (Render.strip_ns child_name) in
3683 let child_kind_s = classish_kind_to_string child_kind in
3684 let parent_name = Markdown_lite.md_codify (Render.strip_ns parent_name) in
3685 let parent_kind_s = classish_kind_to_string parent_kind in
3686 ( Error_code.ImplementsDynamic,
3687 ( pos,
3688 String.capitalize child_kind_s
3689 ^ child_name
3690 ^ (if child_support_dynamic_type then
3691 " cannot "
3692 else
3693 " must ")
3694 ^ "declare <<__SupportDynamicType>> because it "
3695 ^ kinds_to_use child_kind parent_kind
3696 ^ parent_kind_s
3697 ^ parent_name
3698 ^ " which does"
3700 if child_support_dynamic_type then
3701 " not"
3702 else
3703 "" ),
3705 [] )
3707 let property_is_not_enforceable pos prop_name class_name (prop_pos, prop_type)
3709 let class_name = Markdown_lite.md_codify (Render.strip_ns class_name) in
3710 let prop_name = Markdown_lite.md_codify prop_name in
3711 let prop_type = Markdown_lite.md_codify prop_type in
3712 ( Error_code.ImplementsDynamic,
3713 ( pos,
3714 "Class "
3715 ^ class_name
3716 ^ " cannot support dynamic because property "
3717 ^ prop_name
3718 ^ " does not have an enforceable type" ),
3719 [(prop_pos, "Property " ^ prop_name ^ " has type " ^ prop_type)],
3720 [] )
3722 let property_is_not_dynamic pos prop_name class_name (prop_pos, prop_type) =
3723 let class_name = Markdown_lite.md_codify (Render.strip_ns class_name) in
3724 let prop_name = Markdown_lite.md_codify prop_name in
3725 let prop_type = Markdown_lite.md_codify prop_type in
3726 ( Error_code.ImplementsDynamic,
3727 ( pos,
3728 "Class "
3729 ^ class_name
3730 ^ " cannot support dynamic because property "
3731 ^ prop_name
3732 ^ " cannot be assigned to dynamic" ),
3733 [(prop_pos, "Property " ^ prop_name ^ " has type " ^ prop_type)],
3734 [] )
3736 let private_property_is_not_enforceable
3737 pos prop_name class_name (prop_pos, prop_type) =
3738 let class_name = Markdown_lite.md_codify (Render.strip_ns class_name) in
3739 let prop_name = Markdown_lite.md_codify prop_name in
3740 let prop_type = Markdown_lite.md_codify prop_type in
3741 ( Error_code.PrivateDynamicWrite,
3742 ( pos,
3743 "Cannot write to property "
3744 ^ prop_name
3745 ^ " through dynamic type because private property in "
3746 ^ class_name
3747 ^ " does not have an enforceable type" ),
3748 [(prop_pos, "Property " ^ prop_name ^ " has type " ^ prop_type)],
3749 [] )
3751 let private_property_is_not_dynamic
3752 pos prop_name class_name (prop_pos, prop_type) =
3753 let class_name = Markdown_lite.md_codify (Render.strip_ns class_name) in
3754 let prop_name = Markdown_lite.md_codify prop_name in
3755 let prop_type = Markdown_lite.md_codify prop_type in
3756 ( Error_code.PrivateDynamicRead,
3757 ( pos,
3758 "Cannot read from property "
3759 ^ prop_name
3760 ^ " through dynamic type because private property in "
3761 ^ class_name
3762 ^ " cannot be assigned to dynamic" ),
3763 [(prop_pos, "Property " ^ prop_name ^ " has type " ^ prop_type)],
3764 [] )
3766 let immutable_local pos =
3767 ( Error_code.ImmutableLocal,
3768 ( pos,
3769 (* TODO: generalize this error message in the future for arbitrary immutable locals *)
3770 "This variable cannot be reassigned because it is used for a dependent context"
3773 [] )
3775 let nonsense_member_selection pos kind =
3776 ( Error_code.NonsenseMemberSelection,
3777 ( pos,
3778 "Dynamic member access requires a local variable, not `" ^ kind ^ "`."
3781 [] )
3783 let consider_meth_caller pos class_name meth_name =
3784 ( Error_code.ConsiderMethCaller,
3785 ( pos,
3786 "Function pointer syntax requires a static method. "
3787 ^ "Use `meth_caller("
3788 ^ Render.strip_ns class_name
3789 ^ "::class, '"
3790 ^ meth_name
3791 ^ "')` to create a function pointer to the instance method" ),
3793 [] )
3795 let method_import_via_diamond
3796 pos class_name method_pos method_name trace1 trace2 =
3797 let class_name = Markdown_lite.md_codify (Render.strip_ns class_name) in
3798 let method_name = Markdown_lite.md_codify (Render.strip_ns method_name) in
3799 let msg1 =
3800 ( pos,
3801 "Class "
3802 ^ class_name
3803 ^ " inherits trait method "
3804 ^ method_name
3805 ^ " via multiple traits. Remove the multiple paths or override the method"
3808 let msg2 = (method_pos, "Trait method is defined here") in
3809 (Error_code.DiamondTraitMethod, msg1, msg2 :: trace1 @ trace2, [])
3811 let generic_property_import_via_diamond
3812 pos class_name property_pos property_name trace1 trace2 =
3813 let class_name = Markdown_lite.md_codify (Render.strip_ns class_name) in
3814 let property_name =
3815 Markdown_lite.md_codify (Render.strip_ns property_name)
3817 let msg1 =
3818 ( pos,
3819 "Class "
3820 ^ class_name
3821 ^ " inherits generic trait property "
3822 ^ property_name
3823 ^ " via multiple traits. Remove the multiple paths" )
3825 let msg2 = (property_pos, "Trait property is defined here") in
3826 (Error_code.DiamondTraitProperty, msg1, msg2 :: trace1 @ trace2, [])
3828 let unification_cycle pos ty =
3829 ( Error_code.UnificationCycle,
3830 ( pos,
3831 "Type circularity: in order to type-check this expression it "
3832 ^ "is necessary for a type [rec] to be equal to type "
3833 ^ Markdown_lite.md_codify ty ),
3835 [] )
3837 let method_variance pos =
3838 ( Error_code.MethodVariance,
3839 ( pos,
3840 "Covariance or contravariance is not allowed in type parameters of methods or functions."
3843 [] )
3845 let explain_tconst_where_constraint use_pos definition_pos msgl =
3846 let inst_msg = "A `where` type constraint is violated here" in
3848 ( Error_code.TypeConstraintViolation,
3849 (use_pos, inst_msg),
3851 ( definition_pos,
3852 "This method's `where` constraints contain a generic type access" );
3854 @ msgl,
3855 [] )
3857 let format_string pos snippet s class_pos fname class_suggest =
3858 ( Error_code.FormatString,
3859 ( pos,
3860 "Invalid format string "
3861 ^ Markdown_lite.md_codify snippet
3862 ^ " in "
3863 ^ Markdown_lite.md_codify ("\"" ^ s ^ "\"") ),
3865 ( class_pos,
3866 "You can add a new format specifier by adding "
3867 ^ Markdown_lite.md_codify (fname ^ "()")
3868 ^ " to "
3869 ^ Markdown_lite.md_codify class_suggest );
3871 [] )
3873 let expected_literal_format_string pos =
3874 ( Error_code.ExpectedLiteralFormatString,
3875 (pos, "This argument must be a literal format string"),
3877 [] )
3879 let re_prefixed_non_string pos reason =
3880 let non_strings =
3881 match reason with
3882 | `embedded_expr -> "Strings with embedded expressions"
3883 | `non_string -> "Non-strings"
3885 ( Error_code.RePrefixedNonString,
3886 (pos, non_strings ^ " are not allowed to be to be `re`-prefixed"),
3888 [] )
3890 let bad_regex_pattern pos reason =
3891 let s =
3892 match reason with
3893 | `bad_patt s -> s
3894 | `empty_patt -> "This pattern is empty"
3895 | `missing_delim -> "Missing delimiter(s)"
3896 | `invalid_option -> "Invalid global option(s)"
3898 (Error_code.BadRegexPattern, (pos, "Bad regex pattern; " ^ s ^ "."), [], [])
3900 let generic_array_strict p =
3901 ( Error_code.GenericArrayStrict,
3902 (p, "You cannot have an array without generics in strict mode"),
3904 [] )
3906 let option_return_only_typehint p kind =
3907 let (typehint, reason) =
3908 match kind with
3909 | `void -> ("?void", "only return implicitly")
3910 | `noreturn -> ("?noreturn", "never return")
3912 ( Error_code.OptionReturnOnlyTypehint,
3913 ( p,
3914 Markdown_lite.md_codify typehint
3915 ^ " is a nonsensical typehint; a function cannot both "
3916 ^ reason
3917 ^ " and return null." ),
3919 [] )
3921 let redeclaring_missing_method p trait_method =
3922 ( Error_code.RedeclaringMissingMethod,
3923 ( p,
3924 "Attempting to redeclare a trait method "
3925 ^ Markdown_lite.md_codify trait_method
3926 ^ " which was never inherited. "
3927 ^ "You might be trying to redeclare a non-static method as `static` or vice-versa."
3930 [] )
3932 let expecting_type_hint p =
3933 (Error_code.ExpectingTypeHint, (p, "Was expecting a type hint"), [], [])
3935 let expecting_type_hint_variadic p =
3936 ( Error_code.ExpectingTypeHintVariadic,
3937 (p, "Was expecting a type hint on this variadic parameter"),
3939 [] )
3941 let expecting_return_type_hint p =
3942 ( Error_code.ExpectingReturnTypeHint,
3943 (p, "Was expecting a return type hint"),
3945 [] )
3947 let duplicate_using_var pos =
3948 ( Error_code.DuplicateUsingVar,
3949 (pos, "Local variable already used in `using` statement"),
3951 [] )
3953 let illegal_disposable pos verb =
3954 let verb =
3955 match verb with
3956 | `assigned -> "assigned"
3958 ( Error_code.IllegalDisposable,
3959 ( pos,
3960 "Disposable objects must only be " ^ verb ^ " in a `using` statement" ),
3962 [] )
3964 let escaping_disposable pos =
3965 ( Error_code.EscapingDisposable,
3966 ( pos,
3967 "Variable from `using` clause may only be used as receiver in method invocation "
3968 ^ "or passed to function with `<<__AcceptDisposable>>` parameter attribute"
3971 [] )
3973 let escaping_disposable_parameter pos =
3974 ( Error_code.EscapingDisposableParameter,
3975 ( pos,
3976 "Parameter with `<<__AcceptDisposable>>` attribute may only be used as receiver in method invocation "
3977 ^ "or passed to another function with `<<__AcceptDisposable>>` parameter attribute"
3980 [] )
3982 let escaping_this pos =
3983 ( Error_code.EscapingThis,
3984 ( pos,
3985 "`$this` implementing `IDisposable` or `IAsyncDisposable` may only be used as receiver in method invocation "
3986 ^ "or passed to another function with `<<__AcceptDisposable>>` parameter attribute"
3989 [] )
3991 let must_extend_disposable pos =
3992 ( Error_code.MustExtendDisposable,
3993 ( pos,
3994 "A disposable type may not extend a class or use a trait that is not disposable"
3997 [] )
3999 let field_kinds pos1 pos2 =
4000 ( Error_code.FieldKinds,
4001 (pos1, "You cannot use this kind of field (value)"),
4002 [(pos2, "Mixed with this kind of field (key => value)")],
4003 [] )
4005 let unbound_name_typing pos name =
4006 ( Error_code.UnboundNameTyping,
4007 ( pos,
4008 "Unbound name (typing): "
4009 ^ Markdown_lite.md_codify (Render.strip_ns name) ),
4011 [] )
4013 let previous_default p =
4014 ( Error_code.PreviousDefault,
4015 ( p,
4016 "A previous parameter has a default value.\n"
4017 ^ "Remove all the default values for the preceding parameters,\n"
4018 ^ "or add a default value to this one." ),
4020 [] )
4022 let return_in_void pos1 pos2 =
4023 ( Error_code.ReturnInVoid,
4024 (pos1, "You cannot return a value"),
4025 [(Pos_or_decl.of_raw_pos pos2, "This is a `void` function")],
4026 [] )
4028 let this_var_outside_class p =
4029 ( Error_code.ThisVarOutsideClass,
4030 (p, "Can't use `$this` outside of a class"),
4032 [] )
4034 let unbound_global cst_pos =
4035 ( Error_code.UnboundGlobal,
4036 (cst_pos, "Unbound global constant (Typing)"),
4038 [] )
4040 let private_inst_meth use_pos def_pos =
4041 ( Error_code.PrivateInstMeth,
4042 ( use_pos,
4043 "You cannot use this method with `inst_meth` (whether you are in the same class or not)."
4045 [(def_pos, "It is declared as `private` here")],
4046 [] )
4048 let protected_inst_meth use_pos def_pos =
4049 ( Error_code.ProtectedInstMeth,
4050 ( use_pos,
4051 "You cannot use this method with `inst_meth` (whether you are in the same class hierarchy or not)."
4053 [(def_pos, "It is declared as `protected` here")],
4054 [] )
4056 let private_meth_caller use_pos def_pos =
4057 ( Error_code.PrivateMethCaller,
4058 ( use_pos,
4059 "You cannot access this method with `meth_caller` (even from the same class hierarchy)"
4061 [(def_pos, "It is declared as `private` here")],
4062 [] )
4064 let protected_meth_caller use_pos def_pos =
4065 ( Error_code.ProtectedMethCaller,
4066 ( use_pos,
4067 "You cannot access this method with `meth_caller` (even from the same class hierarchy)"
4069 [(def_pos, "It is declared as `protected` here")],
4070 [] )
4072 let private_class_meth use_pos def_pos =
4073 ( Error_code.PrivateClassMeth,
4074 ( use_pos,
4075 "You cannot use this method with `class_meth` (whether you are in the same class or not)."
4077 [(def_pos, "It is declared as `private` here")],
4078 [] )
4080 let protected_class_meth use_pos def_pos =
4081 ( Error_code.ProtectedClassMeth,
4082 ( use_pos,
4083 "You cannot use this method with `class_meth` (whether you are in the same class hierarchy or not)."
4085 [(def_pos, "It is declared as `protected` here")],
4086 [] )
4088 let array_cast pos =
4089 ( Error_code.ArrayCast,
4090 ( pos,
4091 "(array) cast forbidden; arrays with unspecified key and value types are not allowed"
4094 [] )
4096 let string_cast pos ty =
4097 ( Error_code.StringCast,
4098 ( pos,
4099 Printf.sprintf
4100 "Cannot cast a value of type %s to string. Only primitives may be used in a `(string)` cast."
4101 (Markdown_lite.md_codify ty) ),
4103 [] )
4105 let static_outside_class pos =
4106 ( Error_code.StaticOutsideClass,
4107 (pos, "`static` is undefined outside of a class"),
4109 [] )
4111 let self_outside_class pos =
4112 ( Error_code.SelfOutsideClass,
4113 (pos, "`self` is undefined outside of a class"),
4115 [] )
4117 let new_inconsistent_construct new_pos (cpos, cname) kind =
4118 let name = Render.strip_ns cname in
4119 let preamble =
4120 match kind with
4121 | `static ->
4122 "Can't use `new static()` for " ^ Markdown_lite.md_codify name
4123 | `classname ->
4124 "Can't use `new` on "
4125 ^ Markdown_lite.md_codify ("classname<" ^ name ^ ">")
4127 ( Error_code.NewStaticInconsistent,
4128 ( new_pos,
4129 preamble
4130 ^ "; `__construct` arguments are not guaranteed to be consistent in child classes"
4133 ( cpos,
4134 "This declaration is neither `final` nor uses the `<<__ConsistentConstruct>>` attribute"
4137 [] )
4139 let undefined_parent pos =
4140 (Error_code.UndefinedParent, (pos, "The parent class is undefined"), [], [])
4142 let parent_outside_class pos =
4143 ( Error_code.ParentOutsideClass,
4144 (pos, "`parent` is undefined outside of a class"),
4146 [] )
4148 let parent_abstract_call call_pos meth_name decl_pos =
4149 ( Error_code.AbstractCall,
4150 ( call_pos,
4151 "Cannot call "
4152 ^ Markdown_lite.md_codify ("parent::" ^ meth_name ^ "()")
4153 ^ "; it is abstract" ),
4154 [(decl_pos, "Declaration is here")],
4155 [] )
4157 let self_abstract_call call_pos meth_name self_pos decl_pos =
4158 let quickfixes =
4160 Quickfix.make
4161 ~title:
4162 ("Change to " ^ Markdown_lite.md_codify ("static::" ^ meth_name))
4163 ~new_text:"static"
4164 self_pos;
4167 ( Error_code.AbstractCall,
4168 ( call_pos,
4169 "Cannot call "
4170 ^ Markdown_lite.md_codify ("self::" ^ meth_name ^ "()")
4171 ^ "; it is abstract. Did you mean "
4172 ^ Markdown_lite.md_codify ("static::" ^ meth_name ^ "()")
4173 ^ "?" ),
4174 [(decl_pos, "Declaration is here")],
4175 quickfixes )
4177 let classname_abstract_call call_pos meth_name cname decl_pos =
4178 let cname = Render.strip_ns cname in
4179 ( Error_code.AbstractCall,
4180 ( call_pos,
4181 "Cannot call "
4182 ^ Markdown_lite.md_codify (cname ^ "::" ^ meth_name ^ "()")
4183 ^ "; it is abstract" ),
4184 [(decl_pos, "Declaration is here")],
4185 [] )
4187 let static_synthetic_method call_pos meth_name cname decl_pos =
4188 let cname = Render.strip_ns cname in
4189 ( Error_code.StaticSyntheticMethod,
4190 ( call_pos,
4191 "Cannot call "
4192 ^ Markdown_lite.md_codify (cname ^ "::" ^ meth_name ^ "()")
4193 ^ "; "
4194 ^ Markdown_lite.md_codify meth_name
4195 ^ " is not defined in "
4196 ^ Markdown_lite.md_codify cname ),
4197 [(decl_pos, "Declaration is here")],
4198 [] )
4200 let isset_in_strict pos =
4201 ( Error_code.IssetEmptyInStrict,
4202 ( pos,
4203 "`isset` tends to hide errors due to variable typos and so is limited to dynamic checks in "
4204 ^ "`strict` mode" ),
4206 [] )
4208 let isset_inout_arg pos =
4209 ( Error_code.InoutInPseudofunction,
4210 (pos, "`isset` does not allow arguments to be passed by `inout`"),
4212 [] )
4214 let unset_nonidx_in_strict pos msgs =
4215 ( Error_code.UnsetNonidxInStrict,
4216 ( pos,
4217 "In `strict` mode, `unset` is banned except on dynamic, "
4218 ^ "darray, keyset, or dict indexing" ),
4219 msgs,
4220 [] )
4222 let unpacking_disallowed_builtin_function pos name =
4223 let name = Render.strip_ns name in
4224 ( Error_code.UnpackingDisallowed,
4225 (pos, "Arg unpacking is disallowed for " ^ Markdown_lite.md_codify name),
4227 [] )
4229 let array_get_arity pos1 name pos2 =
4230 ( Error_code.ArrayGetArity,
4231 ( pos1,
4232 "You cannot use this "
4233 ^ (Render.strip_ns name |> Markdown_lite.md_codify) ),
4234 [(pos2, "It is missing its type parameters")],
4235 [] )
4237 let undefined_field use_pos name shape_type_pos =
4238 ( Error_code.UndefinedField,
4239 (use_pos, "The field " ^ Markdown_lite.md_codify name ^ " is undefined"),
4240 [(shape_type_pos, "Definition is here")],
4241 [] )
4243 let array_access code pos1 pos2 ty =
4244 ( code,
4245 (pos1, "This is not an object of type `KeyedContainer`, this is " ^ ty),
4246 (if not Pos_or_decl.(equal pos2 none) then
4247 [(pos2, "Definition is here")]
4248 else
4249 []),
4250 [] )
4252 let array_access_read = array_access Error_code.ArrayAccessRead
4254 let array_access_write = array_access Error_code.ArrayAccessWrite
4256 let keyset_set pos1 pos2 =
4257 ( Error_code.KeysetSet,
4258 (pos1, "Elements in a keyset cannot be assigned, use append instead."),
4259 (if not Pos_or_decl.(equal pos2 none) then
4260 [(pos2, "Definition is here")]
4261 else
4262 []),
4263 [] )
4265 let array_append pos1 pos2 ty =
4266 ( Error_code.ArrayAppend,
4267 (pos1, ty ^ " does not allow array append"),
4268 (if not Pos_or_decl.(equal pos2 none) then
4269 [(pos2, "Definition is here")]
4270 else
4271 []),
4272 [] )
4274 let const_mutation pos1 pos2 ty =
4275 ( Error_code.ConstMutation,
4276 (pos1, "You cannot mutate this"),
4277 (if not Pos_or_decl.(equal pos2 none) then
4278 [(pos2, "This is " ^ ty)]
4279 else
4280 []),
4281 [] )
4283 let expected_class pos suffix =
4284 (Error_code.ExpectedClass, (pos, "Was expecting a class" ^ suffix), [], [])
4286 let unknown_type pos description r =
4287 let msg = "Was expecting " ^ description ^ " but type is unknown" in
4288 (Error_code.UnknownType, (pos, msg), r, [])
4290 let parent_in_trait pos =
4291 ( Error_code.ParentInTrait,
4292 ( pos,
4293 "You can only use `parent::` in traits that specify `require extends SomeClass`"
4296 [] )
4298 let parent_undefined pos =
4299 (Error_code.ParentUndefined, (pos, "parent is undefined"), [], [])
4301 let constructor_no_args pos =
4302 ( Error_code.ConstructorNoArgs,
4303 (pos, "This constructor expects no argument"),
4305 [] )
4307 let visibility p msg1 p_vis msg2 =
4308 (Error_code.Visibility, (p, msg1), [(p_vis, msg2)], [])
4310 let bad_call pos ty =
4311 ( Error_code.BadCall,
4312 (pos, "This call is invalid, this is not a function, it is " ^ ty),
4314 [] )
4316 let extend_final extend_pos decl_pos name =
4317 let name = Render.strip_ns name in
4318 ( Error_code.ExtendFinal,
4319 ( extend_pos,
4320 "You cannot extend final class " ^ Markdown_lite.md_codify name ),
4321 [(decl_pos, "Declaration is here")],
4322 [] )
4324 let extend_non_abstract_record extend_pos name decl_pos =
4325 let name = Render.strip_ns name in
4326 let msg =
4327 Printf.sprintf
4328 "Cannot extend record %s because it isn't abstract"
4329 (Markdown_lite.md_codify name)
4331 ( Error_code.ExtendFinal,
4332 (extend_pos, msg),
4333 [(decl_pos, "Declaration is here")],
4334 [] )
4336 let extend_sealed child_pos parent_pos parent_name parent_kind verb =
4337 let parent_kind =
4338 match parent_kind with
4339 | `intf -> "interface"
4340 | `trait -> "trait"
4341 | `class_ -> "class"
4342 | `enum -> "enum"
4343 | `enum_class -> "enum class"
4344 and verb =
4345 match verb with
4346 | `extend -> "extend"
4347 | `implement -> "implement"
4348 | `use -> "use"
4349 and name = Render.strip_ns parent_name in
4350 ( Error_code.ExtendSealed,
4351 ( child_pos,
4352 "You cannot "
4353 ^ verb
4354 ^ " sealed "
4355 ^ parent_kind
4356 ^ " "
4357 ^ Markdown_lite.md_codify name ),
4358 [(parent_pos, "Declaration is here")],
4359 [] )
4361 let sealed_not_subtype parent_pos parent_name child_name child_kind child_pos
4363 let parent_name = Render.strip_ns parent_name
4364 and child_name = Render.strip_ns child_name
4365 and (child_kind, verb) =
4366 match child_kind with
4367 | Ast_defs.Cclass _ -> ("Class", "extend")
4368 | Ast_defs.Cinterface -> ("Interface", "implement")
4369 | Ast_defs.Ctrait -> ("Trait", "use")
4370 | Ast_defs.Cenum -> ("Enum", "use")
4371 | Ast_defs.Cenum_class _ -> ("Enum Class", "extend")
4374 ( Error_code.SealedNotSubtype,
4375 ( parent_pos,
4376 child_kind
4377 ^ " "
4378 ^ Markdown_lite.md_codify child_name
4379 ^ " in sealed whitelist for "
4380 ^ Markdown_lite.md_codify parent_name
4381 ^ ", but does not "
4382 ^ verb
4383 ^ " "
4384 ^ Markdown_lite.md_codify parent_name ),
4385 [(child_pos, "Definition is here")],
4386 [] )
4388 let trait_prop_const_class pos x =
4389 ( Error_code.TraitPropConstClass,
4390 ( pos,
4391 "Trait declaration of non-const property "
4392 ^ Markdown_lite.md_codify x
4393 ^ " is incompatible with a const class" ),
4395 [] )
4397 let read_before_write (pos, v) =
4398 ( Error_code.ReadBeforeWrite,
4399 ( pos,
4400 Utils.sl
4402 "Read access to ";
4403 Markdown_lite.md_codify ("$this->" ^ v);
4404 " before initialization";
4405 ] ),
4407 [] )
4409 let implement_abstract pos1 is_final pos2 x kind qfxs =
4410 let kind =
4411 match kind with
4412 | `meth -> "method"
4413 | `prop -> "property"
4414 | `const -> "constant"
4415 | `ty_const -> "type constant"
4417 let name = "abstract " ^ kind ^ " " ^ Markdown_lite.md_codify x in
4418 let msg1 =
4419 if is_final then
4420 "This class was declared as `final`. It must provide an implementation for the "
4421 ^ name
4422 else
4423 "This class must be declared `abstract`, or provide an implementation for the "
4424 ^ name
4426 ( Error_code.ImplementAbstract,
4427 (pos1, msg1),
4428 [(pos2, "Declaration is here")],
4429 qfxs )
4431 let generic_static pos x =
4432 ( Error_code.GenericStatic,
4433 ( pos,
4434 "This static variable cannot use the type parameter "
4435 ^ Markdown_lite.md_codify x
4436 ^ "." ),
4438 [] )
4440 let ellipsis_strict_mode pos require =
4441 let msg =
4442 match require with
4443 | `Param_name ->
4444 "Variadic function arguments require a name in strict mode, e.g. `...$args`."
4445 | `Type_and_param_name ->
4446 "Variadic function arguments require a name and type in strict mode, e.g. `int ...$args`."
4448 (Error_code.EllipsisStrictMode, (pos, msg), [], [])
4450 let untyped_lambda_strict_mode pos =
4451 let msg =
4452 "Cannot determine types of lambda parameters in strict mode. Please add type hints on parameters."
4454 (Error_code.UntypedLambdaStrictMode, (pos, msg), [], [])
4456 let object_string pos1 pos2 =
4457 ( Error_code.ObjectString,
4458 (pos1, "You cannot use this object as a string"),
4459 [(pos2, "This object doesn't implement `__toString`")],
4460 [] )
4462 let object_string_deprecated pos =
4463 ( Error_code.ObjectString,
4464 ( pos,
4465 "You cannot use this object as a string\nImplicit conversions of Stringish objects to string are deprecated."
4468 [] )
4470 let cyclic_typedef def_pos use_pos =
4471 ( Error_code.CyclicTypedef,
4472 (def_pos, "Cyclic type definition"),
4473 [(use_pos, "Cyclic use is here")],
4474 [] )
4476 let require_args_reify arg_pos def_pos =
4477 ( Error_code.RequireArgsReify,
4478 ( arg_pos,
4479 "All type arguments must be specified because a type parameter is reified"
4481 [(def_pos, "Definition is here")],
4482 [] )
4484 let require_generic_explicit arg_pos def_pos def_name =
4485 ( Error_code.RequireGenericExplicit,
4486 ( arg_pos,
4487 "Generic type parameter "
4488 ^ Markdown_lite.md_codify def_name
4489 ^ " must be specified explicitly" ),
4490 [(def_pos, "Definition is here")],
4491 [] )
4493 let invalid_reified_argument hint_pos def_name def_pos arg_info =
4494 let (arg_pos, arg_kind) = List.hd_exn arg_info in
4495 ( Error_code.InvalidReifiedArgument,
4496 (hint_pos, "Invalid reified hint"),
4498 ( arg_pos,
4499 "This is "
4500 ^ arg_kind
4501 ^ ", it cannot be used as a reified type argument" );
4502 (def_pos, Markdown_lite.md_codify def_name ^ " is reified");
4504 [] )
4506 let invalid_reified_argument_reifiable arg_pos def_name def_pos ty_pos ty_msg
4508 ( Error_code.InvalidReifiedArgument,
4509 (arg_pos, "PHP arrays cannot be used as a reified type argument"),
4511 (ty_pos, String.capitalize ty_msg);
4512 (def_pos, Markdown_lite.md_codify def_name ^ " is reified");
4514 [] )
4516 let new_class_reified pos class_type suggested_class =
4517 let suggestion =
4518 match suggested_class with
4519 | Some s ->
4520 let s = Render.strip_ns s in
4521 sprintf ". Try `new %s` instead." s
4522 | None -> ""
4524 ( Error_code.NewClassReified,
4525 ( pos,
4526 sprintf
4527 "Cannot call `new %s` because the current class has reified generics%s"
4528 class_type
4529 suggestion ),
4531 [] )
4533 let class_get_reified pos =
4534 ( Error_code.ClassGetReified,
4535 (pos, "Cannot access static properties on reified generics"),
4537 [] )
4539 let static_meth_with_class_reified_generic meth_pos generic_pos =
4540 ( Error_code.StaticMethWithClassReifiedGeneric,
4541 ( meth_pos,
4542 "Static methods cannot use generics reified at the class level. Try reifying them at the static method itself."
4545 ( Pos_or_decl.of_raw_pos generic_pos,
4546 "Class-level reified generic used here." );
4548 [] )
4550 let consistent_construct_reified pos =
4551 ( Error_code.ConsistentConstructReified,
4552 ( pos,
4553 "This class or one of its ancestors is annotated with `<<__ConsistentConstruct>>`. It cannot have reified generics."
4556 [] )
4558 let bad_function_pointer_construction pos =
4559 ( Error_code.BadFunctionPointerConstruction,
4560 (pos, "Function pointers must be explicitly named"),
4562 [] )
4564 let reified_generics_not_allowed pos =
4565 ( Error_code.InvalidReifiedFunctionPointer,
4566 ( pos,
4567 "Creating function pointers with reified generics is not currently allowed"
4570 [] )
4572 let new_without_newable pos name =
4573 ( Error_code.NewWithoutNewable,
4574 ( pos,
4575 Markdown_lite.md_codify name
4576 ^ " cannot be used with `new` because it does not have the `<<__Newable>>` attribute"
4579 [] )
4581 let discarded_awaitable pos1 pos2 =
4582 ( Error_code.DiscardedAwaitable,
4583 ( pos1,
4584 "This expression is of type `Awaitable`, but it's "
4585 ^ "either being discarded or used in a dangerous way before "
4586 ^ "being awaited" ),
4587 [(pos2, "This is why I think it is `Awaitable`")],
4588 [] )
4590 let elt_type_to_string = function
4591 | `meth -> "method"
4592 | `prop -> "property"
4594 let static_redeclared_as_dynamic
4595 dyn_position static_position member_name elt_type =
4596 let dollar =
4597 match elt_type with
4598 | `prop -> "$"
4599 | _ -> ""
4601 let elt_type = elt_type_to_string elt_type in
4602 let msg_dynamic =
4603 "The "
4604 ^ elt_type
4605 ^ " "
4606 ^ Markdown_lite.md_codify (dollar ^ member_name)
4607 ^ " is declared here as non-static"
4609 let msg_static =
4610 "But it conflicts with an inherited static declaration here"
4612 ( Error_code.StaticDynamic,
4613 (dyn_position, msg_dynamic),
4614 [(static_position, msg_static)],
4615 [] )
4617 let dynamic_redeclared_as_static
4618 static_position dyn_position member_name elt_type =
4619 let dollar =
4620 match elt_type with
4621 | `prop -> "$"
4622 | _ -> ""
4624 let elt_type = elt_type_to_string elt_type in
4625 let msg_static =
4626 "The "
4627 ^ elt_type
4628 ^ " "
4629 ^ Markdown_lite.md_codify (dollar ^ member_name)
4630 ^ " is declared here as static"
4632 let msg_dynamic =
4633 "But it conflicts with an inherited non-static declaration here"
4635 ( Error_code.StaticDynamic,
4636 (static_position, msg_static),
4637 [(dyn_position, msg_dynamic)],
4638 [] )
4640 let unknown_object_member pos s elt r =
4641 let elt = elt_type_to_string elt in
4642 let msg =
4643 Printf.sprintf
4644 "You are trying to access the %s %s on a value whose class is unknown."
4646 (Markdown_lite.md_codify s)
4648 (Error_code.UnknownObjectMember, (pos, msg), r, [])
4650 let non_class_member pos1 s elt ty pos2 =
4651 let elt = elt_type_to_string elt in
4652 let msg =
4653 Printf.sprintf
4654 "You are trying to access the static %s %s but this is %s"
4656 (Markdown_lite.md_codify s)
4659 (Error_code.NonClassMember, (pos1, msg), [(pos2, "Definition is here")], [])
4661 let null_container p null_witness =
4662 ( Error_code.NullContainer,
4663 ( p,
4664 "You are trying to access an element of this container"
4665 ^ " but the container could be `null`. " ),
4666 null_witness,
4667 [] )
4669 let option_mixed pos =
4670 ( Error_code.OptionMixed,
4671 (pos, "`?mixed` is a redundant typehint - just use `mixed`"),
4673 [] )
4675 let option_null pos =
4676 ( Error_code.OptionNull,
4677 (pos, "`?null` is a redundant typehint - just use `null`"),
4679 [] )
4681 let declared_covariant pos1 pos2 emsg =
4682 ( Error_code.DeclaredCovariant,
4683 (pos2, "Illegal usage of a covariant type parameter"),
4685 ( Pos_or_decl.of_raw_pos pos1,
4686 "This is where the parameter was declared as covariant `+`" );
4688 @ List.map emsg ~f:(Message.map ~f:Pos_or_decl.of_raw_pos),
4689 [] )
4691 let declared_contravariant pos1 pos2 emsg =
4692 ( Error_code.DeclaredContravariant,
4693 (pos2, "Illegal usage of a contravariant type parameter"),
4695 ( Pos_or_decl.of_raw_pos pos1,
4696 "This is where the parameter was declared as contravariant `-`" );
4698 @ List.map emsg ~f:(Message.map ~f:Pos_or_decl.of_raw_pos),
4699 [] )
4701 let static_property_type_generic_param generic_pos class_pos var_type_pos =
4702 ( Error_code.ClassVarTypeGenericParam,
4703 ( generic_pos,
4704 "A generic parameter cannot be used in the type of a static property" ),
4706 ( var_type_pos,
4707 "This is where the type of the static property was declared" );
4708 (class_pos, "This is the class containing the static property");
4710 [] )
4712 let contravariant_this pos class_name tp =
4713 ( Error_code.ContravariantThis,
4714 ( pos,
4715 "The `this` type cannot be used in this "
4716 ^ "contravariant position because its enclosing class "
4717 ^ Markdown_lite.md_codify class_name
4718 ^ " "
4719 ^ "is final and has a variant type parameter "
4720 ^ Markdown_lite.md_codify tp ),
4722 [] )
4724 let cyclic_typeconst pos sl =
4725 let sl =
4726 List.map sl ~f:(fun s -> Render.strip_ns s |> Markdown_lite.md_codify)
4728 ( Error_code.CyclicTypeconst,
4729 (pos, "Cyclic type constant:\n " ^ String.concat ~sep:" -> " sl),
4731 [] )
4733 let array_get_with_optional_field pos1 name pos2 =
4734 ( Error_code.ArrayGetWithOptionalField,
4735 ( pos1,
4736 Printf.sprintf
4737 "The field %s may not be present in this shape. Use `Shapes::idx()` instead."
4738 (Markdown_lite.md_codify name) ),
4739 [(pos2, "This is where the field was declared as optional.")],
4740 [] )
4742 let mutating_const_property pos =
4743 ( Error_code.AssigningToConst,
4744 (pos, "Cannot mutate a `__Const` property"),
4746 [] )
4748 let self_const_parent_not pos =
4749 ( Error_code.SelfConstParentNot,
4750 (pos, "A `__Const` class may only extend other `__Const` classes"),
4752 [] )
4754 let unexpected_ty_in_tast pos ~actual_ty ~expected_ty =
4755 ( Error_code.UnexpectedTy,
4756 ( pos,
4757 "Unexpected type in TAST: expected "
4758 ^ Markdown_lite.md_codify expected_ty
4759 ^ ", got "
4760 ^ Markdown_lite.md_codify actual_ty ),
4762 [] )
4764 let call_lvalue pos =
4765 ( Error_code.CallLvalue,
4766 ( pos,
4767 "Array updates cannot be applied to function results. Use a local variable instead."
4770 [] )
4772 let unsafe_cast_await pos =
4773 ( Error_code.UnsafeCastAwait,
4774 (pos, "UNSAFE_CAST cannot be used as the operand of an await operation"),
4776 [] )
4778 let internal_compiler_error_msg =
4779 Printf.sprintf
4780 "Encountered an internal compiler error while typechecking this. %s %s"
4781 Error_message_sentinel.remediation_message
4782 Error_message_sentinel.please_file_a_bug_message
4784 let invariant_violation pos =
4785 (Error_code.InvariantViolated, (pos, internal_compiler_error_msg), [], [])
4787 let exception_occurred pos =
4788 (Error_code.ExceptionOccurred, (pos, internal_compiler_error_msg), [], [])
4790 let to_error_ = function
4791 | Coeffect err -> Coeffect.to_error err
4792 | Enum err -> Enum.to_error err
4793 | Expr_tree err -> Expr_tree.to_error err
4794 | Ifc err -> Ifc.to_error err
4795 | Modules err -> Modules.to_error err
4796 | Readonly err -> Readonly.to_error err
4797 | Record err -> Record.to_error err
4798 | Shape err -> Shape.to_error err
4799 | Wellformedness err -> Wellformedness.to_error err
4800 | Xhp err -> Xhp.to_error err
4801 | Unify_error { pos; msg_opt; reasons_opt } ->
4802 unify_error pos msg_opt reasons_opt
4803 | Generic_unify { pos; msg } -> generic_unify pos msg
4804 | Exception_occurred { pos; _ } -> exception_occurred pos
4805 | Invariant_violation { pos; _ } -> invariant_violation pos
4806 | Internal_error { pos; msg } -> internal_error pos msg
4807 | Typechecker_timeout { pos; fn_name; seconds } ->
4808 typechecker_timeout pos fn_name seconds
4809 | Unresolved_tyvar pos -> unresolved_tyvar pos
4810 | Using_error { pos; has_await } -> using_error pos has_await
4811 | Bad_enum_decl pos -> bad_enum_decl pos
4812 | Bad_conditional_support_dynamic
4813 { pos; child; parent; ty_name; self_ty_name } ->
4814 bad_conditional_support_dynamic pos child parent ty_name self_ty_name
4815 | Bad_decl_override { pos; name; parent_pos; parent_name } ->
4816 bad_decl_override pos name parent_pos parent_name
4817 | Explain_where_constraint { pos; decl_pos; in_class } ->
4818 explain_where_constraint pos decl_pos in_class
4819 | Explain_constraint pos -> explain_constraint pos
4820 | Rigid_tvar_escape { pos; what } -> rigid_tvar_escape pos what
4821 | Invalid_type_hint pos -> invalid_type_hint pos
4822 | Unsatisfied_req { pos; trait_pos; req_name; req_pos } ->
4823 unsatisfied_req pos trait_pos req_name req_pos
4824 | Invalid_echo_argument pos -> invalid_echo_argument pos
4825 | Index_type_mismatch { pos; is_covariant_container; msg_opt; reasons_opt }
4827 index_type_mismatch pos is_covariant_container msg_opt reasons_opt
4828 | Member_not_found
4829 { pos; kind; member_name; class_name; class_pos; hint; reason } ->
4830 member_not_found
4832 kind
4833 member_name
4834 class_name
4835 class_pos
4836 (Lazy.force hint)
4837 reason
4838 | Construct_not_instance_method pos -> construct_not_instance_method pos
4839 | Ambiguous_inheritance { pos; origin; class_name } ->
4840 ambiguous_inheritance pos origin class_name
4841 | Expected_tparam { pos; n; decl_pos } -> expected_tparam pos n decl_pos
4842 | Typeconst_concrete_concrete_override { pos; decl_pos } ->
4843 typeconst_concrete_concrete_override pos decl_pos
4844 | Invalid_memoized_param { pos; reason; _ } ->
4845 invalid_memoized_param pos reason
4846 | Invalid_arraykey
4847 { pos; container_pos; container_ty_name; key_pos; key_ty_name; ctxt } ->
4848 invalid_arraykey
4850 container_pos
4851 (Lazy.force container_ty_name)
4852 key_pos
4853 (Lazy.force key_ty_name)
4854 ctxt
4855 | Invalid_keyset_value
4856 { pos; container_pos; container_ty_name; value_pos; value_ty_name } ->
4857 invalid_keyset_value
4859 container_pos
4860 (Lazy.force container_ty_name)
4861 value_pos
4862 (Lazy.force value_ty_name)
4863 | Invalid_set_value
4864 { pos; container_pos; container_ty_name; value_pos; value_ty_name } ->
4865 invalid_set_value
4867 container_pos
4868 (Lazy.force container_ty_name)
4869 value_pos
4870 (Lazy.force value_ty_name)
4871 | HKT_alias_with_implicit_constraints
4873 pos;
4874 typedef_name;
4875 typedef_pos;
4876 used_class_in_def_pos;
4877 used_class_in_def_name;
4878 used_class_tparam_name;
4879 typedef_tparam_name;
4881 } ->
4882 hkt_alias_with_implicit_constraints
4884 typedef_name
4885 typedef_pos
4886 used_class_in_def_pos
4887 used_class_in_def_name
4888 used_class_tparam_name
4889 typedef_tparam_name
4890 | Object_string_deprecated pos -> object_string_deprecated pos
4891 | Invalid_substring { pos; ty_name } -> invalid_substring pos ty_name
4892 | Unset_nonidx_in_strict { pos; reason } ->
4893 unset_nonidx_in_strict pos reason
4894 | Nullable_cast { pos; ty_pos; ty_name } -> nullable_cast pos ty_pos ty_name
4895 | Hh_expect { pos; equivalent } -> hh_expect pos equivalent
4896 | Null_member { pos; ctxt; kind; member_name; reason } ->
4897 null_member pos ctxt kind member_name reason
4898 | Typing_too_many_args { pos; decl_pos; actual; expected } ->
4899 typing_too_many_args pos decl_pos actual expected
4900 | Typing_too_few_args { pos; decl_pos; actual; expected } ->
4901 typing_too_few_args pos decl_pos actual expected
4902 | Non_object_member { pos; ctxt; ty_name; member_name; kind; decl_pos } ->
4903 non_object_member pos ctxt ty_name member_name kind decl_pos
4904 | Nullsafe_property_write_context pos -> nullsafe_property_write_context pos
4905 | Uninstantiable_class { pos; class_name; reason_ty_opt; decl_pos } ->
4906 uninstantiable_class pos class_name reason_ty_opt decl_pos
4907 | Abstract_const_usage { pos; name; decl_pos } ->
4908 abstract_const_usage pos name decl_pos
4909 | Type_arity_mismatch { pos; decl_pos; actual; expected } ->
4910 type_arity_mismatch pos decl_pos actual expected
4911 | Member_not_implemented
4912 { pos; parent_pos; member_name; decl_pos; quickfixes } ->
4913 member_not_implemented pos parent_pos member_name decl_pos quickfixes
4914 | Attribute_too_many_arguments { pos; name; expected } ->
4915 attribute_too_many_arguments pos name expected
4916 | Attribute_too_few_arguments { pos; name; expected } ->
4917 attribute_too_few_arguments pos name expected
4918 | Attribute_not_exact_number_of_args { pos; name; actual; expected } ->
4919 attribute_not_exact_number_of_args pos name actual expected
4920 | Kind_mismatch { pos; decl_pos; tparam_name; expected_kind; actual_kind }
4922 kind_mismatch pos decl_pos tparam_name expected_kind actual_kind
4923 | Trait_parent_construct_inconsistent { pos; decl_pos } ->
4924 trait_parent_construct_inconsistent pos decl_pos
4925 | Top_member { pos; ctxt; ty_name; decl_pos; kind; name; is_nullable } ->
4926 top_member pos ctxt ty_name decl_pos kind name is_nullable
4927 | Unresolved_tyvar_projection { pos; proj_pos; tconst_name } ->
4928 unresolved_tyvar_projection pos proj_pos tconst_name
4929 | Cyclic_class_constant { pos; class_name; const_name } ->
4930 cyclic_class_constant pos class_name const_name
4931 | Inout_annotation_missing { pos; decl_pos } ->
4932 inout_annotation_missing pos decl_pos
4933 | Inout_annotation_unexpected { pos; decl_pos; param_is_variadic; qfx_pos }
4935 inout_annotation_unexpected pos decl_pos param_is_variadic qfx_pos
4936 | Inout_argument_bad_type { pos; reasons } ->
4937 inout_argument_bad_type pos reasons
4938 | Invalid_meth_caller_calling_convention { pos; decl_pos; convention } ->
4939 invalid_meth_caller_calling_convention pos decl_pos convention
4940 | Invalid_meth_caller_readonly_return { pos; decl_pos } ->
4941 invalid_meth_caller_readonly_return pos decl_pos
4942 | Invalid_new_disposable pos -> invalid_new_disposable pos
4943 | Invalid_return_disposable pos -> invalid_return_disposable pos
4944 | Invalid_disposable_hint { pos; class_name } ->
4945 invalid_disposable_hint pos class_name
4946 | Invalid_disposable_return_hint { pos; class_name } ->
4947 invalid_disposable_return_hint pos class_name
4948 | Ambiguous_lambda { pos; uses } -> ambiguous_lambda pos uses
4949 | Wrong_extend_kind
4950 { pos; kind; name; parent_pos; parent_kind; parent_name } ->
4951 wrong_extend_kind pos kind name parent_pos parent_kind parent_name
4952 | Smember_not_found { pos; kind; member_name; class_name; class_pos; hint }
4954 smember_not_found pos kind member_name class_name class_pos hint
4955 | Cyclic_class_def { pos; stack } -> cyclic_class_def pos stack
4956 | Cyclic_record_def { pos; names } -> cyclic_record_def pos names
4957 | Trait_reuse_with_final_method { pos; trait_name; parent_cls_name; trace }
4959 trait_reuse_with_final_method pos trait_name parent_cls_name trace
4960 | Trait_reuse { pos; class_name; trait_name; parent_pos; parent_name } ->
4961 trait_reuse pos class_name trait_name parent_pos parent_name
4962 | Trait_reuse_inside_class { pos; class_name; trait_name; occurrences } ->
4963 trait_reuse_inside_class pos class_name trait_name occurrences
4964 | Invalid_is_as_expression_hint { pos; op; reasons } ->
4965 invalid_is_as_expression_hint pos op reasons
4966 | Invalid_enforceable_type { pos; ty_info; tp_pos; tp_name; kind } ->
4967 invalid_enforceable_type pos ty_info kind tp_pos tp_name
4968 | Reifiable_attr { pos; ty_info; attr_pos; kind } ->
4969 reifiable_attr attr_pos kind pos ty_info
4970 | Invalid_newable_type_argument { pos; tp_pos; tp_name } ->
4971 invalid_newable_type_argument pos tp_pos tp_name
4972 | Invalid_newable_typaram_constraints { pos; tp_name; constraints } ->
4973 invalid_newable_type_param_constraints (pos, tp_name) constraints
4974 | Override_per_trait { pos; class_name; meth_name; trait_name; meth_pos } ->
4975 override_per_trait (pos, class_name) meth_name trait_name meth_pos
4976 | Generic_at_runtime { pos; prefix } -> generic_at_runtime pos prefix
4977 | Generics_not_allowed pos -> generics_not_allowed pos
4978 | Trivial_strict_eq { pos; result; left; right; left_trail; right_trail } ->
4979 trivial_strict_eq
4981 result
4982 (Lazy.force left)
4983 (Lazy.force right)
4984 left_trail
4985 right_trail
4986 | Trivial_strict_not_nullable_compare_null { pos; result; ty_reason_msg } ->
4987 trivial_strict_not_nullable_compare_null pos result
4988 @@ Lazy.force ty_reason_msg
4989 | Eq_incompatible_types { pos; left; right } ->
4990 eq_incompatible_types pos (Lazy.force left) (Lazy.force right)
4991 | Comparison_invalid_types { pos; left; right } ->
4992 comparison_invalid_types pos (Lazy.force left) (Lazy.force right)
4993 | Strict_eq_value_incompatible_types { pos; left; right } ->
4994 strict_eq_value_incompatible_types
4996 (Lazy.force left)
4997 (Lazy.force right)
4998 | Attribute_param_type { pos; x } -> attribute_param_type pos x
4999 | Deprecated_use { pos; decl_pos_opt; msg } ->
5000 deprecated_use pos ~pos_def:decl_pos_opt msg
5001 | Cannot_declare_constant { pos; kind; class_pos; class_name } ->
5002 cannot_declare_constant kind pos (class_pos, class_name)
5003 | Local_variable_modified_and_used { pos; pos_useds } ->
5004 local_variable_modified_and_used pos pos_useds
5005 | Local_variable_modified_twice { pos; pos_modifieds } ->
5006 local_variable_modified_twice pos pos_modifieds
5007 | Assign_during_case pos -> assign_during_case pos
5008 | Invalid_classname pos -> invalid_classname pos
5009 | Illegal_type_structure pos -> illegal_type_structure pos
5010 | Illegal_typeconst_direct_access pos -> illegal_typeconst_direct_access pos
5011 | Wrong_expression_kind_attribute
5013 pos;
5014 attr_name;
5015 expr_kind;
5016 attr_class_pos;
5017 attr_class_name;
5018 intf_name;
5019 } ->
5020 wrong_expression_kind_attribute
5021 expr_kind
5023 attr_name
5024 attr_class_pos
5025 attr_class_name
5026 intf_name
5027 | Wrong_expression_kind_builtin_attribute { pos; attr_name; expr_kind } ->
5028 wrong_expression_kind_builtin_attribute expr_kind pos attr_name
5029 | Ambiguous_object_access
5030 { pos; name; self_pos; vis; subclass_pos; class_self; class_subclass }
5032 ambiguous_object_access
5034 name
5035 self_pos
5037 subclass_pos
5038 class_self
5039 class_subclass
5040 | Lateinit_with_default pos -> lateinit_with_default pos
5041 | Unserializable_type { pos; message } -> unserializable_type pos message
5042 | Invalid_arraykey_constraint { pos; ty_name } ->
5043 invalid_arraykey_constraint pos @@ Lazy.force ty_name
5044 | Redundant_covariant { pos; msg; suggest } ->
5045 redundant_covariant pos msg suggest
5046 | Meth_caller_trait { pos; trait_name } -> meth_caller_trait pos trait_name
5047 | Duplicate_interface { pos; name; others } ->
5048 duplicate_interface pos name others
5049 | Tparam_non_shadowing_reuse { pos; tparam_name } ->
5050 tparam_non_shadowing_reuse pos tparam_name
5051 | Reified_function_reference pos -> reified_function_reference pos
5052 | Class_meth_abstract_call { pos; class_name; meth_name; decl_pos } ->
5053 class_meth_abstract_call class_name meth_name pos decl_pos
5054 | Reinheriting_classish_const
5056 pos;
5057 classish_name;
5058 src_pos;
5059 src_classish_name;
5060 existing_const_origin;
5061 const_name;
5062 } ->
5063 reinheriting_classish_const
5065 classish_name
5066 src_pos
5067 src_classish_name
5068 existing_const_origin
5069 const_name
5070 | Redeclaring_classish_const
5072 pos;
5073 classish_name;
5074 redeclaration_pos;
5075 existing_const_origin;
5076 const_name;
5077 } ->
5078 redeclaring_classish_const
5080 classish_name
5081 redeclaration_pos
5082 existing_const_origin
5083 const_name
5084 | Abstract_function_pointer { pos; class_name; meth_name; decl_pos } ->
5085 abstract_function_pointer class_name meth_name pos decl_pos
5086 | Unnecessary_attribute { pos; attr; reason; suggestion } ->
5087 unnecessary_attribute pos ~attr ~reason ~suggestion
5088 | Inherited_class_member_with_different_case
5090 pos;
5091 member_type;
5092 name;
5093 name_prev;
5094 child_class;
5095 prev_class;
5096 prev_class_pos;
5097 } ->
5098 inherited_class_member_with_different_case
5099 member_type
5100 name
5101 name_prev
5103 child_class
5104 prev_class
5105 prev_class_pos
5106 | Multiple_inherited_class_member_with_different_case
5108 pos;
5109 child_class_name;
5110 member_type;
5111 class1_name;
5112 class1_pos;
5113 name1;
5114 class2_name;
5115 class2_pos;
5116 name2;
5117 } ->
5118 multiple_inherited_class_member_with_different_case
5119 ~member_type
5120 ~name1
5121 ~name2
5122 ~class1:class1_name
5123 ~class2:class2_name
5124 ~child_class:child_class_name
5125 ~child_p:pos
5126 ~p1:class1_pos
5127 ~p2:class2_pos
5128 | Parent_support_dynamic_type
5130 pos;
5131 child_name;
5132 child_kind;
5133 parent_name;
5134 parent_kind;
5135 child_support_dyn;
5136 } ->
5137 parent_support_dynamic_type
5139 (child_name, child_kind)
5140 (parent_name, parent_kind)
5141 child_support_dyn
5142 | Property_is_not_enforceable
5143 { pos; prop_name; class_name; prop_pos; prop_type } ->
5144 property_is_not_enforceable pos prop_name class_name (prop_pos, prop_type)
5145 | Property_is_not_dynamic
5146 { pos; prop_name; class_name; prop_pos; prop_type } ->
5147 property_is_not_dynamic pos prop_name class_name (prop_pos, prop_type)
5148 | Private_property_is_not_enforceable
5149 { pos; prop_name; class_name; prop_pos; prop_type } ->
5150 private_property_is_not_enforceable
5152 prop_name
5153 class_name
5154 (prop_pos, prop_type)
5155 | Private_property_is_not_dynamic
5156 { pos; prop_name; class_name; prop_pos; prop_type } ->
5157 private_property_is_not_dynamic
5159 prop_name
5160 class_name
5161 (prop_pos, prop_type)
5162 | Immutable_local pos -> immutable_local pos
5163 | Nonsense_member_selection { pos; kind } ->
5164 nonsense_member_selection pos kind
5165 | Consider_meth_caller { pos; class_name; meth_name } ->
5166 consider_meth_caller pos class_name meth_name
5167 | Method_import_via_diamond
5168 { pos; class_name; method_pos; method_name; trace1; trace2 } ->
5169 method_import_via_diamond
5171 class_name
5172 method_pos
5173 method_name
5174 trace1
5175 trace2
5176 | Generic_property_import_via_diamond
5177 { pos; class_name; property_pos; property_name; trace1; trace2 } ->
5178 generic_property_import_via_diamond
5180 class_name
5181 property_pos
5182 property_name
5183 trace1
5184 trace2
5185 | Unification_cycle { pos; ty_name } ->
5186 unification_cycle pos @@ Lazy.force ty_name
5187 | Method_variance pos -> method_variance pos
5188 | Explain_tconst_where_constraint { pos; decl_pos; msgs } ->
5189 explain_tconst_where_constraint pos decl_pos msgs
5190 | Format_string
5191 { pos; snippet; fmt_string; class_pos; fn_name; class_suggest } ->
5192 format_string pos snippet fmt_string class_pos fn_name class_suggest
5193 | Expected_literal_format_string pos -> expected_literal_format_string pos
5194 | Re_prefixed_non_string { pos; reason } ->
5195 re_prefixed_non_string pos reason
5196 | Bad_regex_pattern { pos; reason } -> bad_regex_pattern pos reason
5197 | Generic_array_strict pos -> generic_array_strict pos
5198 | Option_return_only_typehint { pos; kind } ->
5199 option_return_only_typehint pos kind
5200 | Redeclaring_missing_method { pos; trait_method } ->
5201 redeclaring_missing_method pos trait_method
5202 | Expecting_type_hint pos -> expecting_type_hint pos
5203 | Expecting_type_hint_variadic pos -> expecting_type_hint_variadic pos
5204 | Expecting_return_type_hint pos -> expecting_return_type_hint pos
5205 | Duplicate_using_var pos -> duplicate_using_var pos
5206 | Illegal_disposable { pos; verb } -> illegal_disposable pos verb
5207 | Escaping_disposable pos -> escaping_disposable pos
5208 | Escaping_disposable_param pos -> escaping_disposable_parameter pos
5209 | Escaping_this pos -> escaping_this pos
5210 | Must_extend_disposable pos -> must_extend_disposable pos
5211 | Field_kinds { pos; decl_pos } -> field_kinds pos decl_pos
5212 | Unbound_name { pos; name } -> unbound_name_typing pos name
5213 | Previous_default pos -> previous_default pos
5214 | Return_in_void { pos; decl_pos } -> return_in_void pos decl_pos
5215 | This_var_outside_class pos -> this_var_outside_class pos
5216 | Unbound_global pos -> unbound_global pos
5217 | Private_inst_meth { pos; decl_pos } -> private_inst_meth pos decl_pos
5218 | Protected_inst_meth { pos; decl_pos } -> protected_inst_meth pos decl_pos
5219 | Private_meth_caller { pos; decl_pos } -> private_meth_caller pos decl_pos
5220 | Protected_meth_caller { pos; decl_pos } ->
5221 protected_meth_caller pos decl_pos
5222 | Private_class_meth { pos; decl_pos } -> private_class_meth pos decl_pos
5223 | Protected_class_meth { pos; decl_pos } ->
5224 protected_class_meth pos decl_pos
5225 | Array_cast pos -> array_cast pos
5226 | String_cast { pos; ty_name } -> string_cast pos @@ Lazy.force ty_name
5227 | Static_outside_class pos -> static_outside_class pos
5228 | Self_outside_class pos -> self_outside_class pos
5229 | New_inconsistent_construct { pos; class_pos; class_name; kind } ->
5230 new_inconsistent_construct pos (class_pos, class_name) kind
5231 | Undefined_parent pos -> undefined_parent pos
5232 | Parent_outside_class pos -> parent_outside_class pos
5233 | Parent_abstract_call { pos; meth_name; decl_pos } ->
5234 parent_abstract_call pos meth_name decl_pos
5235 | Self_abstract_call { pos; self_pos; meth_name; decl_pos } ->
5236 self_abstract_call pos meth_name self_pos decl_pos
5237 | Classname_abstract_call { pos; meth_name; class_name; decl_pos } ->
5238 classname_abstract_call pos meth_name class_name decl_pos
5239 | Static_synthetic_method { pos; meth_name; class_name; decl_pos } ->
5240 static_synthetic_method pos meth_name class_name decl_pos
5241 | Isset_in_strict pos -> isset_in_strict pos
5242 | Isset_inout_arg pos -> isset_inout_arg pos
5243 | Unpacking_disallowed_builtin_function { pos; fn_name } ->
5244 unpacking_disallowed_builtin_function pos fn_name
5245 | Array_get_arity { pos; name; decl_pos } ->
5246 array_get_arity pos name decl_pos
5247 | Undefined_field { pos; name; decl_pos } ->
5248 undefined_field pos name decl_pos
5249 | Array_access { pos; ctxt = `read; ty_name; decl_pos } ->
5250 array_access_read pos decl_pos @@ Lazy.force ty_name
5251 | Array_access { pos; ctxt = `write; ty_name; decl_pos } ->
5252 array_access_write pos decl_pos @@ Lazy.force ty_name
5253 | Keyset_set { pos; decl_pos } -> keyset_set pos decl_pos
5254 | Array_append { pos; ty_name; decl_pos } ->
5255 array_append pos decl_pos @@ Lazy.force ty_name
5256 | Const_mutation { pos; ty_name; decl_pos } ->
5257 const_mutation pos decl_pos @@ Lazy.force ty_name
5258 | Expected_class { pos; suffix } ->
5259 expected_class pos Option.(value_map ~default:"" ~f:Lazy.force suffix)
5260 | Unknown_type { pos; expected; reason } -> unknown_type pos expected reason
5261 | Parent_in_trait pos -> parent_in_trait pos
5262 | Parent_undefined pos -> parent_undefined pos
5263 | Constructor_no_args pos -> constructor_no_args pos
5264 | Visibility { pos; msg; decl_pos; reason_msg } ->
5265 visibility pos msg decl_pos reason_msg
5266 | Bad_call { pos; ty_name } -> bad_call pos @@ Lazy.force ty_name
5267 | Extend_final { pos; name; decl_pos } -> extend_final pos decl_pos name
5268 | Extend_non_abstract_record { pos; name; decl_pos } ->
5269 extend_non_abstract_record pos name decl_pos
5270 | Extend_sealed { pos; parent_pos; parent_name; parent_kind; verb } ->
5271 extend_sealed pos parent_pos parent_name parent_kind verb
5272 | Sealed_not_subtype { pos; name; child_kind; child_pos; child_name } ->
5273 sealed_not_subtype pos name child_name child_kind child_pos
5274 | Trait_prop_const_class { pos; name } -> trait_prop_const_class pos name
5275 | Read_before_write { pos; member_name } ->
5276 read_before_write (pos, member_name)
5277 | Implement_abstract { pos; is_final; decl_pos; name; kind; quickfixes } ->
5278 implement_abstract pos is_final decl_pos name kind quickfixes
5279 | Generic_static { pos; typaram_name } -> generic_static pos typaram_name
5280 | Ellipsis_strict_mode { pos; require } -> ellipsis_strict_mode pos require
5281 | Untyped_lambda_strict_mode pos -> untyped_lambda_strict_mode pos
5282 | Object_string { pos; decl_pos } -> object_string pos decl_pos
5283 | Cyclic_typedef { pos; decl_pos } -> cyclic_typedef pos decl_pos
5284 | Require_args_reify { pos; decl_pos } -> require_args_reify pos decl_pos
5285 | Require_generic_explicit { pos; param_name; decl_pos } ->
5286 require_generic_explicit pos decl_pos param_name
5287 | Invalid_reified_arg { pos; param_name; decl_pos; arg_info } ->
5288 invalid_reified_argument pos param_name decl_pos arg_info
5289 | Invalid_reified_arg_reifiable
5290 { pos; param_name : string; decl_pos; ty_pos; ty_msg } ->
5291 invalid_reified_argument_reifiable pos param_name decl_pos ty_pos
5292 @@ Lazy.force ty_msg
5293 | New_class_reified { pos; class_kind; suggested_class_name } ->
5294 new_class_reified pos class_kind suggested_class_name
5295 | Class_get_reified pos -> class_get_reified pos
5296 | Static_meth_with_class_reified_generic { pos; generic_pos } ->
5297 static_meth_with_class_reified_generic pos generic_pos
5298 | Consistent_construct_reified pos -> consistent_construct_reified pos
5299 | Bad_fn_ptr_construction pos -> bad_function_pointer_construction pos
5300 | Reified_generics_not_allowed pos -> reified_generics_not_allowed pos
5301 | New_without_newable { pos; name } -> new_without_newable pos name
5302 | Discarded_awaitable { pos; decl_pos } -> discarded_awaitable pos decl_pos
5303 | Static_redeclared_as_dynamic { pos; static_pos; member_name; elt } ->
5304 static_redeclared_as_dynamic pos static_pos member_name elt
5305 | Dynamic_redeclared_as_static { pos; dyn_pos; member_name; elt } ->
5306 dynamic_redeclared_as_static pos dyn_pos member_name elt
5307 | Unknown_object_member { pos; member_name; elt; reason } ->
5308 unknown_object_member pos member_name elt reason
5309 | Non_class_member { pos; member_name; elt; ty_name; decl_pos } ->
5310 non_class_member pos member_name elt (Lazy.force ty_name) decl_pos
5311 | Null_container { pos; null_witness } -> null_container pos null_witness
5312 | Option_mixed pos -> option_mixed pos
5313 | Option_null pos -> option_null pos
5314 | Declared_covariant { pos; param_pos; msgs } ->
5315 declared_covariant param_pos pos msgs
5316 | Declared_contravariant { pos; param_pos; msgs } ->
5317 declared_contravariant pos param_pos msgs
5318 | Static_prop_type_generic_param { pos; var_ty_pos; class_pos } ->
5319 static_property_type_generic_param pos class_pos var_ty_pos
5320 | Contravariant_this { pos; class_name; typaram_name } ->
5321 contravariant_this pos class_name typaram_name
5322 | Cyclic_typeconst { pos; tyconst_names } ->
5323 cyclic_typeconst pos tyconst_names
5324 | Array_get_with_optional_field { pos; field_name; decl_pos } ->
5325 array_get_with_optional_field pos field_name decl_pos
5326 | Mutating_const_property pos -> mutating_const_property pos
5327 | Self_const_parent_not pos -> self_const_parent_not pos
5328 | Unexpected_ty_in_tast { pos; expected_ty; actual_ty } ->
5329 unexpected_ty_in_tast
5331 ~expected_ty:(Lazy.force expected_ty)
5332 ~actual_ty:(Lazy.force actual_ty)
5333 | Call_lvalue pos -> call_lvalue pos
5334 | Unsafe_cast_await pos -> unsafe_cast_await pos
5336 let to_error = function
5337 | Invariant_violation { report_to_user = false; _ } -> None
5338 | err -> Some (to_error_ err)
5340 let code err =
5341 let (code, _, _, _) = to_error_ err in
5342 code
5344 let to_user_error t =
5345 Option.map ~f:(fun (code, claim, reasons, quickfixes) ->
5346 User_error.make (Error_code.to_enum code) claim reasons ~quickfixes)
5347 @@ to_error t
5350 module rec Error : sig
5351 type t
5353 val iter :
5354 t -> on_prim:(Primary.t -> unit) -> on_snd:(Secondary.t -> unit) -> unit
5356 val eval : t -> current_span:Pos.t -> error Eval_result.t
5358 val to_user_error :
5359 t -> current_span:Pos.t -> (Pos.t, Pos_or_decl.t) User_error.t Eval_result.t
5361 val primary : Primary.t -> t
5363 val coeffect : Primary.Coeffect.t -> t
5365 val enum : Primary.Enum.t -> t
5367 val expr_tree : Primary.Expr_tree.t -> t
5369 val ifc : Primary.Ifc.t -> t
5371 val modules : Primary.Modules.t -> t
5373 val readonly : Primary.Readonly.t -> t
5375 val record : Primary.Record.t -> t
5377 val shape : Primary.Shape.t -> t
5379 val wellformedness : Primary.Wellformedness.t -> t
5381 val xhp : Primary.Xhp.t -> t
5383 val apply_reasons : Secondary.t -> on_error:Reasons_callback.t -> t
5385 val apply : t -> on_error:Callback.t -> t
5387 val assert_in_current_decl : Secondary.t -> ctx:Pos_or_decl.ctx -> t
5389 val intersect : t list -> t
5391 val union : t list -> t
5393 val multiple : t list -> t
5394 end = struct
5395 type kind =
5396 | Intersection
5397 | Union
5398 | Multiple
5400 type t =
5401 | Primary of Primary.t
5402 | Apply of Callback.t * t
5403 | Apply_reasons of Reasons_callback.t * Secondary.t
5404 | Assert_in_current_decl of Secondary.t * Pos_or_decl.ctx
5405 | Group of kind * t list
5407 let iter t ~on_prim ~on_snd =
5408 let rec aux = function
5409 | Primary prim -> on_prim prim
5410 | Apply (cb, t) ->
5411 aux t;
5412 Callback.iter cb ~on_prim
5413 | Apply_reasons (cb, snd_err) ->
5414 Secondary.iter snd_err ~on_prim ~on_snd;
5415 Reasons_callback.iter cb ~on_prim ~on_snd
5416 | Assert_in_current_decl (snd_err, _ctx) ->
5417 Secondary.iter snd_err ~on_prim ~on_snd
5418 | Group (_, ts) -> List.iter ~f:aux ts
5420 aux t
5422 (* -- Evaluation ------------------------------------------------------------ *)
5424 let eval t ~current_span =
5425 let rec aux ~k = function
5426 | Primary base -> k @@ Eval_result.of_option @@ Primary.to_error base
5427 | Group (Intersection, ts) ->
5428 auxs ~k:(fun xs -> k @@ Eval_result.intersect xs) ts
5429 | Group (Union, ts) -> auxs ~k:(fun xs -> k @@ Eval_result.union xs) ts
5430 | Group (Multiple, ts) ->
5431 auxs ~k:(fun xs -> k @@ Eval_result.multiple xs) ts
5432 | Apply (cb, err) ->
5433 aux err ~k:(fun t ->
5435 @@ Eval_result.bind t ~f:(fun (code, claim, reasons, quickfixes) ->
5436 Eval_result.of_option
5437 @@ Callback.apply cb ~code ~claim ~reasons ~quickfixes))
5438 | Apply_reasons (cb, snd_err) ->
5440 @@ Eval_result.bind ~f:(fun (code, reasons, quickfixes) ->
5441 Reasons_callback.apply_help
5443 ~code
5444 ~reasons
5445 ~quickfixes
5446 ~current_span)
5447 @@ Secondary.eval snd_err ~current_span
5448 | Assert_in_current_decl (snd_err, ctx) ->
5450 @@ Eval_result.bind ~f:(fun e ->
5451 Eval_result.of_option @@ Common.eval_assert ctx current_span e)
5452 @@ Secondary.eval snd_err ~current_span
5453 and auxs ~k = function
5454 | [] -> k []
5455 | next :: rest ->
5456 aux next ~k:(fun x -> auxs rest ~k:(fun xs -> k @@ x :: xs))
5458 aux ~k:Fn.id t
5460 let make_error (code, claim, reasons, quickfixes) =
5461 User_error.make (Error_code.to_enum code) claim reasons ~quickfixes
5463 let to_user_error t ~current_span =
5464 Eval_result.map ~f:make_error @@ eval t ~current_span
5466 (* -- Constructors ---------------------------------------------------------- *)
5467 let primary prim_err = Primary prim_err
5469 let coeffect err = primary @@ Primary.Coeffect err
5471 let enum err = primary @@ Primary.Enum err
5473 let expr_tree err = primary @@ Primary.Expr_tree err
5475 let ifc err = primary @@ Primary.Ifc err
5477 let modules err = primary @@ Primary.Modules err
5479 let readonly err = primary @@ Primary.Readonly err
5481 let record err = primary @@ Primary.Record err
5483 let shape err = primary @@ Primary.Shape err
5485 let wellformedness err = primary @@ Primary.Wellformedness err
5487 let xhp err = primary @@ Primary.Xhp err
5489 let apply_reasons t ~on_error = Apply_reasons (on_error, t)
5491 let apply t ~on_error = Apply (on_error, t)
5493 let assert_in_current_decl snd ~ctx = Assert_in_current_decl (snd, ctx)
5495 let intersect ts = Group (Intersection, ts)
5497 let union ts = Group (Union, ts)
5499 let multiple ts = Group (Multiple, ts)
5502 and Secondary : sig
5503 type t =
5504 | Of_error of Error.t
5505 (* == Primary and secondary =============================================== *)
5506 | Smember_not_found of {
5507 pos: Pos_or_decl.t;
5508 kind:
5509 [ `class_constant
5510 | `class_typeconst
5511 | `class_variable
5512 | `static_method
5514 class_name: string;
5515 class_pos: Pos_or_decl.t;
5516 member_name: string;
5517 hint: ([ `instance | `static ] * Pos_or_decl.t * string) option;
5519 | Type_arity_mismatch of {
5520 pos: Pos_or_decl.t;
5521 actual: int;
5522 decl_pos: Pos_or_decl.t;
5523 expected: int;
5525 | Typing_too_many_args of {
5526 pos: Pos_or_decl.t;
5527 decl_pos: Pos_or_decl.t;
5528 actual: int;
5529 expected: int;
5531 | Typing_too_few_args of {
5532 pos: Pos_or_decl.t;
5533 decl_pos: Pos_or_decl.t;
5534 actual: int;
5535 expected: int;
5537 | Non_object_member of {
5538 pos: Pos_or_decl.t;
5539 decl_pos: Pos_or_decl.t;
5540 ty_name: string Lazy.t;
5541 ctxt: [ `read | `write ];
5542 member_name: string;
5543 kind: [ `class_typeconst | `method_ | `property ];
5545 | Rigid_tvar_escape of {
5546 pos: Pos_or_decl.t;
5547 name: string;
5549 (* == Secondary only ====================================================== *)
5550 | Violated_constraint of {
5551 cstrs: (Pos_or_decl.t * Pos_or_decl.t Message.t) list;
5552 reasons: Pos_or_decl.t Message.t list;
5554 | Concrete_const_interface_override of {
5555 pos: Pos_or_decl.t;
5556 parent_pos: Pos_or_decl.t;
5557 parent_origin: string;
5558 name: string;
5560 | Interface_or_trait_const_multiple_defs of {
5561 pos: Pos_or_decl.t;
5562 origin: string;
5563 name: string;
5564 parent_pos: Pos_or_decl.t;
5565 parent_origin: string;
5567 | Interface_typeconst_multiple_defs of {
5568 pos: Pos_or_decl.t;
5569 origin: string;
5570 is_abstract: bool;
5571 name: string;
5572 parent_pos: Pos_or_decl.t;
5573 parent_origin: string;
5575 | Visibility_extends of {
5576 pos: Pos_or_decl.t;
5577 vis: string;
5578 parent_pos: Pos_or_decl.t;
5579 parent_vis: string;
5581 | Visibility_override_internal of {
5582 pos: Pos_or_decl.t;
5583 module_name: string option;
5584 parent_pos: Pos_or_decl.t;
5585 parent_module: string;
5587 | Abstract_tconst_not_allowed of {
5588 pos: Pos_or_decl.t;
5589 decl_pos: Pos_or_decl.t;
5590 tconst_name: string;
5592 | Missing_constructor of Pos_or_decl.t
5593 | Missing_field of {
5594 pos: Pos_or_decl.t;
5595 name: string;
5596 decl_pos: Pos_or_decl.t;
5598 | Shape_fields_unknown of {
5599 pos: Pos_or_decl.t;
5600 decl_pos: Pos_or_decl.t;
5602 | Accept_disposable_invariant of {
5603 pos: Pos_or_decl.t;
5604 decl_pos: Pos_or_decl.t;
5606 | Ifc_external_contravariant of {
5607 pos_sub: Pos_or_decl.t;
5608 pos_super: Pos_or_decl.t;
5610 | Invalid_destructure of {
5611 pos: Pos_or_decl.t;
5612 decl_pos: Pos_or_decl.t;
5613 ty_name: string Lazy.t;
5615 | Unpack_array_required_argument of {
5616 pos: Pos_or_decl.t;
5617 decl_pos: Pos_or_decl.t;
5619 | Unpack_array_variadic_argument of {
5620 pos: Pos_or_decl.t;
5621 decl_pos: Pos_or_decl.t;
5623 | Fun_too_many_args of {
5624 pos: Pos_or_decl.t;
5625 decl_pos: Pos_or_decl.t;
5626 actual: int;
5627 expected: int;
5629 | Fun_too_few_args of {
5630 pos: Pos_or_decl.t;
5631 decl_pos: Pos_or_decl.t;
5632 actual: int;
5633 expected: int;
5635 | Fun_unexpected_nonvariadic of {
5636 pos: Pos_or_decl.t;
5637 decl_pos: Pos_or_decl.t;
5639 | Fun_variadicity_hh_vs_php56 of {
5640 pos: Pos_or_decl.t;
5641 decl_pos: Pos_or_decl.t;
5643 | Required_field_is_optional of {
5644 pos: Pos_or_decl.t;
5645 decl_pos: Pos_or_decl.t;
5646 name: string;
5648 | Return_disposable_mismatch of {
5649 pos_sub: Pos_or_decl.t;
5650 is_marked_return_disposable: bool;
5651 pos_super: Pos_or_decl.t;
5653 | Ifc_policy_mismatch of {
5654 pos: Pos_or_decl.t;
5655 policy: string;
5656 pos_super: Pos_or_decl.t;
5657 policy_super: string;
5659 | Overriding_prop_const_mismatch of {
5660 pos: Pos_or_decl.t;
5661 is_const: bool;
5662 parent_pos: Pos_or_decl.t;
5663 parent_is_const: bool;
5665 | Override_final of {
5666 pos: Pos_or_decl.t;
5667 parent_pos: Pos_or_decl.t;
5669 | Override_lsb of {
5670 pos: Pos_or_decl.t;
5671 member_name: string;
5672 parent_pos: Pos_or_decl.t;
5674 | Multiple_concrete_defs of {
5675 pos: Pos_or_decl.t;
5676 name: string;
5677 origin: string;
5678 class_name: string;
5679 parent_pos: Pos_or_decl.t;
5680 parent_origin: string;
5682 | Cyclic_enum_constraint of Pos_or_decl.t
5683 | Inoutness_mismatch of {
5684 pos: Pos_or_decl.t;
5685 decl_pos: Pos_or_decl.t;
5687 | Decl_override_missing_hint of Pos_or_decl.t
5688 | Bad_lateinit_override of {
5689 pos: Pos_or_decl.t;
5690 parent_pos: Pos_or_decl.t;
5691 parent_is_lateinit: bool;
5693 | Bad_method_override of {
5694 pos: Pos_or_decl.t;
5695 member_name: string;
5697 | Bad_prop_override of {
5698 pos: Pos_or_decl.t;
5699 member_name: string;
5701 | Bad_xhp_attr_required_override of {
5702 pos: Pos_or_decl.t;
5703 tag: string;
5704 parent_pos: Pos_or_decl.t;
5705 parent_tag: string;
5707 | Coeffect_subtyping of {
5708 pos: Pos_or_decl.t;
5709 cap: string Lazy.t;
5710 pos_expected: Pos_or_decl.t;
5711 cap_expected: string Lazy.t;
5713 | Override_method_support_dynamic_type of {
5714 pos: Pos_or_decl.t;
5715 method_name: string;
5716 parent_pos: Pos_or_decl.t;
5717 parent_origin: string;
5719 | Readonly_mismatch of {
5720 pos: Pos_or_decl.t;
5721 kind: [ `fn | `fn_return | `param ];
5722 reason_sub: Pos_or_decl.t Message.t list;
5723 reason_super: Pos_or_decl.t Message.t list;
5725 | Not_sub_dynamic of {
5726 pos: Pos_or_decl.t;
5727 ty_name: string Lazy.t;
5728 dynamic_part: Pos_or_decl.t Message.t list;
5730 | Subtyping_error of Pos_or_decl.t Message.t list
5731 | Method_not_dynamically_callable of {
5732 pos: Pos_or_decl.t;
5733 parent_pos: Pos_or_decl.t;
5735 | This_final of {
5736 pos_sub: Pos_or_decl.t;
5737 pos_super: Pos_or_decl.t;
5738 class_name: string;
5740 | Typeconst_concrete_concrete_override of {
5741 pos: Pos_or_decl.t;
5742 parent_pos: Pos_or_decl.t;
5744 | Abstract_concrete_override of {
5745 pos: Pos_or_decl.t;
5746 parent_pos: Pos_or_decl.t;
5747 kind: [ `constant | `method_ | `property | `typeconst ];
5749 | Should_not_be_override of {
5750 pos: Pos_or_decl.t;
5751 class_id: string;
5752 id: string;
5754 | Override_no_default_typeconst of {
5755 pos: Pos_or_decl.t;
5756 parent_pos: Pos_or_decl.t;
5759 val iter :
5760 t -> on_prim:(Primary.t -> unit) -> on_snd:(Secondary.t -> unit) -> unit
5762 val eval :
5763 t ->
5764 current_span:Pos.t ->
5765 (Error_code.t * Pos_or_decl.t Message.t list * Quickfix.t list)
5766 Eval_result.t
5767 end = struct
5768 type t =
5769 | Of_error of Error.t
5770 (* == Primary and secondary =============================================== *)
5771 | Smember_not_found of {
5772 pos: Pos_or_decl.t;
5773 kind:
5774 [ `class_constant
5775 | `class_typeconst
5776 | `class_variable
5777 | `static_method
5779 class_name: string;
5780 class_pos: Pos_or_decl.t;
5781 member_name: string;
5782 hint: ([ `instance | `static ] * Pos_or_decl.t * string) option;
5784 | Type_arity_mismatch of {
5785 pos: Pos_or_decl.t;
5786 actual: int;
5787 decl_pos: Pos_or_decl.t;
5788 expected: int;
5790 | Typing_too_many_args of {
5791 pos: Pos_or_decl.t;
5792 decl_pos: Pos_or_decl.t;
5793 actual: int;
5794 expected: int;
5796 | Typing_too_few_args of {
5797 pos: Pos_or_decl.t;
5798 decl_pos: Pos_or_decl.t;
5799 actual: int;
5800 expected: int;
5802 | Non_object_member of {
5803 pos: Pos_or_decl.t;
5804 decl_pos: Pos_or_decl.t;
5805 ty_name: string Lazy.t;
5806 ctxt: [ `read | `write ];
5807 member_name: string;
5808 kind: [ `class_typeconst | `method_ | `property ];
5810 | Rigid_tvar_escape of {
5811 pos: Pos_or_decl.t;
5812 name: string;
5814 (* == Secondary only ====================================================== *)
5815 | Violated_constraint of {
5816 cstrs: (Pos_or_decl.t * Pos_or_decl.t Message.t) list;
5817 reasons: Pos_or_decl.t Message.t list;
5819 | Concrete_const_interface_override of {
5820 pos: Pos_or_decl.t;
5821 parent_pos: Pos_or_decl.t;
5822 parent_origin: string;
5823 name: string;
5825 | Interface_or_trait_const_multiple_defs of {
5826 pos: Pos_or_decl.t;
5827 origin: string;
5828 name: string;
5829 parent_pos: Pos_or_decl.t;
5830 parent_origin: string;
5832 | Interface_typeconst_multiple_defs of {
5833 pos: Pos_or_decl.t;
5834 origin: string;
5835 is_abstract: bool;
5836 name: string;
5837 parent_pos: Pos_or_decl.t;
5838 parent_origin: string;
5840 | Visibility_extends of {
5841 pos: Pos_or_decl.t;
5842 vis: string;
5843 parent_pos: Pos_or_decl.t;
5844 parent_vis: string;
5846 | Visibility_override_internal of {
5847 pos: Pos_or_decl.t;
5848 module_name: string option;
5849 parent_pos: Pos_or_decl.t;
5850 parent_module: string;
5852 | Abstract_tconst_not_allowed of {
5853 pos: Pos_or_decl.t;
5854 decl_pos: Pos_or_decl.t;
5855 tconst_name: string;
5857 | Missing_constructor of Pos_or_decl.t
5858 | Missing_field of {
5859 pos: Pos_or_decl.t;
5860 name: string;
5861 decl_pos: Pos_or_decl.t;
5863 | Shape_fields_unknown of {
5864 pos: Pos_or_decl.t;
5865 decl_pos: Pos_or_decl.t;
5867 | Accept_disposable_invariant of {
5868 pos: Pos_or_decl.t;
5869 decl_pos: Pos_or_decl.t;
5871 | Ifc_external_contravariant of {
5872 pos_sub: Pos_or_decl.t;
5873 pos_super: Pos_or_decl.t;
5875 | Invalid_destructure of {
5876 pos: Pos_or_decl.t;
5877 decl_pos: Pos_or_decl.t;
5878 ty_name: string Lazy.t;
5880 | Unpack_array_required_argument of {
5881 pos: Pos_or_decl.t;
5882 decl_pos: Pos_or_decl.t;
5884 | Unpack_array_variadic_argument of {
5885 pos: Pos_or_decl.t;
5886 decl_pos: Pos_or_decl.t;
5888 | Fun_too_many_args of {
5889 pos: Pos_or_decl.t;
5890 decl_pos: Pos_or_decl.t;
5891 actual: int;
5892 expected: int;
5894 | Fun_too_few_args of {
5895 pos: Pos_or_decl.t;
5896 decl_pos: Pos_or_decl.t;
5897 actual: int;
5898 expected: int;
5900 | Fun_unexpected_nonvariadic of {
5901 pos: Pos_or_decl.t;
5902 decl_pos: Pos_or_decl.t;
5904 | Fun_variadicity_hh_vs_php56 of {
5905 pos: Pos_or_decl.t;
5906 decl_pos: Pos_or_decl.t;
5908 | Required_field_is_optional of {
5909 pos: Pos_or_decl.t;
5910 decl_pos: Pos_or_decl.t;
5911 name: string;
5913 | Return_disposable_mismatch of {
5914 pos_sub: Pos_or_decl.t;
5915 is_marked_return_disposable: bool;
5916 pos_super: Pos_or_decl.t;
5918 | Ifc_policy_mismatch of {
5919 pos: Pos_or_decl.t;
5920 policy: string;
5921 pos_super: Pos_or_decl.t;
5922 policy_super: string;
5924 | Overriding_prop_const_mismatch of {
5925 pos: Pos_or_decl.t;
5926 is_const: bool;
5927 parent_pos: Pos_or_decl.t;
5928 parent_is_const: bool;
5930 | Override_final of {
5931 pos: Pos_or_decl.t;
5932 parent_pos: Pos_or_decl.t;
5934 | Override_lsb of {
5935 pos: Pos_or_decl.t;
5936 member_name: string;
5937 parent_pos: Pos_or_decl.t;
5939 | Multiple_concrete_defs of {
5940 pos: Pos_or_decl.t;
5941 name: string;
5942 origin: string;
5943 class_name: string;
5944 parent_pos: Pos_or_decl.t;
5945 parent_origin: string;
5947 | Cyclic_enum_constraint of Pos_or_decl.t
5948 | Inoutness_mismatch of {
5949 pos: Pos_or_decl.t;
5950 decl_pos: Pos_or_decl.t;
5952 | Decl_override_missing_hint of Pos_or_decl.t
5953 | Bad_lateinit_override of {
5954 pos: Pos_or_decl.t;
5955 parent_pos: Pos_or_decl.t;
5956 parent_is_lateinit: bool;
5958 | Bad_method_override of {
5959 pos: Pos_or_decl.t;
5960 member_name: string;
5962 | Bad_prop_override of {
5963 pos: Pos_or_decl.t;
5964 member_name: string;
5966 | Bad_xhp_attr_required_override of {
5967 pos: Pos_or_decl.t;
5968 tag: string;
5969 parent_pos: Pos_or_decl.t;
5970 parent_tag: string;
5972 | Coeffect_subtyping of {
5973 pos: Pos_or_decl.t;
5974 cap: string Lazy.t;
5975 pos_expected: Pos_or_decl.t;
5976 cap_expected: string Lazy.t;
5978 | Override_method_support_dynamic_type of {
5979 pos: Pos_or_decl.t;
5980 method_name: string;
5981 parent_pos: Pos_or_decl.t;
5982 parent_origin: string;
5984 | Readonly_mismatch of {
5985 pos: Pos_or_decl.t;
5986 kind: [ `fn | `fn_return | `param ];
5987 reason_sub: Pos_or_decl.t Message.t list;
5988 reason_super: Pos_or_decl.t Message.t list;
5990 | Not_sub_dynamic of {
5991 pos: Pos_or_decl.t;
5992 ty_name: string Lazy.t;
5993 dynamic_part: Pos_or_decl.t Message.t list;
5995 | Subtyping_error of Pos_or_decl.t Message.t list
5996 | Method_not_dynamically_callable of {
5997 pos: Pos_or_decl.t;
5998 parent_pos: Pos_or_decl.t;
6000 | This_final of {
6001 pos_sub: Pos_or_decl.t;
6002 pos_super: Pos_or_decl.t;
6003 class_name: string;
6005 | Typeconst_concrete_concrete_override of {
6006 pos: Pos_or_decl.t;
6007 parent_pos: Pos_or_decl.t;
6009 | Abstract_concrete_override of {
6010 pos: Pos_or_decl.t;
6011 parent_pos: Pos_or_decl.t;
6012 kind: [ `constant | `method_ | `property | `typeconst ];
6014 | Should_not_be_override of {
6015 pos: Pos_or_decl.t;
6016 class_id: string;
6017 id: string;
6019 | Override_no_default_typeconst of {
6020 pos: Pos_or_decl.t;
6021 parent_pos: Pos_or_decl.t;
6024 let iter t ~on_prim ~on_snd =
6025 match t with
6026 | Of_error err -> Error.iter ~on_prim ~on_snd err
6027 | snd_err -> on_snd snd_err
6029 (* -- Evaluation ---------------------------------------------------------- *)
6031 let fun_too_many_args pos decl_pos actual expected =
6032 let reasons =
6034 ( pos,
6035 Printf.sprintf
6036 "Too many mandatory arguments (expected %d but got %d)"
6037 expected
6038 actual );
6039 (decl_pos, "Because of this definition");
6042 (Error_code.FunTooManyArgs, reasons, [])
6044 let fun_too_few_args pos decl_pos actual expected =
6045 let reasons =
6047 ( pos,
6048 Printf.sprintf
6049 "Too few arguments (required %d but got %d)"
6050 expected
6051 actual );
6052 (decl_pos, "Because of this definition");
6055 (Error_code.FunTooFewArgs, reasons, [])
6057 let fun_unexpected_nonvariadic pos decl_pos =
6058 let reasons =
6060 (pos, "Should have a variadic argument");
6061 (decl_pos, "Because of this definition");
6064 (Error_code.FunUnexpectedNonvariadic, reasons, [])
6066 let fun_variadicity_hh_vs_php56 pos decl_pos =
6067 let reasons =
6069 (pos, "Variadic arguments: `...`-style is not a subtype of `...$args`");
6070 (decl_pos, "Because of this definition");
6073 (Error_code.FunVariadicityHhVsPhp56, reasons, [])
6075 let type_arity_mismatch pos actual decl_pos expected =
6076 let reasons =
6078 (pos, "This type has " ^ string_of_int actual ^ " arguments");
6079 (decl_pos, "This one has " ^ string_of_int expected);
6082 (Error_code.TypeArityMismatch, reasons, [])
6084 let violated_constraint cstrs reasons =
6085 let pos_msg = "This type constraint is violated" in
6086 let f (p_cstr, (p_tparam, tparam)) =
6088 ( p_tparam,
6089 Printf.sprintf
6090 "%s is a constrained type parameter"
6091 (Markdown_lite.md_codify tparam) );
6092 (p_cstr, pos_msg);
6095 let msgs = List.concat_map ~f cstrs in
6096 (Error_code.TypeConstraintViolation, msgs @ reasons, [])
6098 let concrete_const_interface_override pos parent_pos name parent_origin =
6099 let reasons =
6101 ( parent_pos,
6102 "You could make "
6103 ^ Markdown_lite.md_codify name
6104 ^ " abstract in "
6105 ^ (Markdown_lite.md_codify @@ Render.strip_ns parent_origin)
6106 ^ "." );
6108 and claim =
6109 ( pos,
6110 "Non-abstract constants defined in an interface cannot be overridden when implementing or extending that interface."
6113 (Error_code.ConcreteConstInterfaceOverride, claim :: reasons, [])
6115 let interface_or_trait_const_multiple_defs
6116 pos origin parent_pos parent_origin name =
6117 let parent_origin = Render.strip_ns parent_origin
6118 and child_origin = Render.strip_ns origin in
6119 let reasons =
6121 ( pos,
6122 "Non-abstract constants defined in an interface or trait cannot conflict with other inherited constants."
6124 ( parent_pos,
6125 Markdown_lite.md_codify name
6126 ^ " inherited from "
6127 ^ Markdown_lite.md_codify parent_origin );
6128 ( pos,
6129 "conflicts with constant "
6130 ^ Markdown_lite.md_codify name
6131 ^ " inherited from "
6132 ^ Markdown_lite.md_codify child_origin
6133 ^ "." );
6136 (Error_code.ConcreteConstInterfaceOverride, reasons, [])
6138 let interface_typeconst_multiple_defs
6139 pos parent_pos name origin parent_origin is_abstract =
6140 let parent_origin = Render.strip_ns parent_origin
6141 and child_origin = Render.strip_ns origin
6142 and child_pos = pos
6143 and child =
6144 if is_abstract then
6145 "abstract type constant with default value"
6146 else
6147 "concrete type constant"
6149 let reasons =
6151 ( pos,
6152 "Concrete and abstract type constants with default values in an interface cannot conflict with inherited"
6153 ^ " concrete or abstract type constants with default values." );
6154 ( parent_pos,
6155 Markdown_lite.md_codify name
6156 ^ " inherited from "
6157 ^ Markdown_lite.md_codify parent_origin );
6158 ( child_pos,
6159 "conflicts with "
6160 ^ Markdown_lite.md_codify child
6161 ^ " "
6162 ^ Markdown_lite.md_codify name
6163 ^ " inherited from "
6164 ^ Markdown_lite.md_codify child_origin
6165 ^ "." );
6168 (Error_code.ConcreteConstInterfaceOverride, reasons, [])
6170 let missing_field pos name decl_pos =
6171 let reasons =
6173 (pos, "The field " ^ Markdown_lite.md_codify name ^ " is missing");
6174 (decl_pos, "The field " ^ Markdown_lite.md_codify name ^ " is defined");
6177 (Error_code.MissingField, reasons, [])
6179 let shape_fields_unknown pos decl_pos =
6180 let reasons =
6182 ( pos,
6183 "This shape type allows unknown fields, and so it may contain fields other than those explicitly declared in its declaration."
6185 ( decl_pos,
6186 "It is incompatible with a shape that does not allow unknown fields."
6190 (Error_code.ShapeFieldsUnknown, reasons, [])
6192 let abstract_tconst_not_allowed pos decl_pos tconst_name =
6193 let reasons =
6195 (pos, "An abstract type constant is not allowed in this position.");
6196 ( decl_pos,
6197 Printf.sprintf
6198 "%s is abstract here."
6199 (Markdown_lite.md_codify tconst_name) );
6202 (Error_code.AbstractTconstNotAllowed, reasons, [])
6204 let invalid_destructure pos decl_pos ty_name =
6205 let reasons =
6207 ( pos,
6208 "This expression cannot be destructured with a `list(...)` expression"
6210 (decl_pos, "This is " ^ Markdown_lite.md_codify @@ Lazy.force ty_name);
6213 (Error_code.InvalidDestructure, reasons, [])
6215 let unpack_array_required_argument pos decl_pos =
6216 let reasons =
6218 ( pos,
6219 "An array cannot be unpacked into the required arguments of a function"
6221 (decl_pos, "Definition is here");
6224 (Error_code.SplatArrayRequired, reasons, [])
6226 let unpack_array_variadic_argument pos decl_pos =
6227 let reasons =
6229 ( pos,
6230 "A function that receives an unpacked array as an argument must have a variadic parameter to accept the elements of the array"
6232 (decl_pos, "Definition is here");
6235 (Error_code.SplatArrayRequired, reasons, [])
6237 let overriding_prop_const_mismatch pos is_const parent_pos =
6238 let (msg, reason_msg) =
6239 if is_const then
6240 ("This property is `__Const`", "This property is not `__Const`")
6241 else
6242 ("This property is not `__Const`", "This property is `__Const`")
6244 let reasons = [(pos, msg); (parent_pos, reason_msg)] in
6245 (Error_code.OverridingPropConstMismatch, reasons, [])
6247 let visibility_extends pos vis parent_pos parent_vis =
6248 let reasons =
6250 (pos, "This member visibility is: " ^ Markdown_lite.md_codify vis);
6251 (parent_pos, Markdown_lite.md_codify parent_vis ^ " was expected");
6254 (Error_code.VisibilityExtends, reasons, [])
6256 let visibility_override_internal pos module_name parent_module parent_pos =
6257 let msg =
6258 match module_name with
6259 | None ->
6260 Printf.sprintf
6261 "Cannot override this member outside module `%s`"
6262 parent_module
6263 | Some m -> Printf.sprintf "Cannot override this member in module `%s`" m
6265 let reasons =
6267 (pos, msg);
6268 ( parent_pos,
6269 Printf.sprintf "This member is internal to module `%s`" parent_module
6273 (Error_code.ModuleError, reasons, [])
6275 let missing_constructor pos =
6276 let reasons = [(pos, "The constructor is not implemented")] in
6277 (Error_code.MissingConstructor, reasons, [])
6279 let accept_disposable_invariant pos decl_pos =
6280 let reasons =
6282 (pos, "This parameter is marked `<<__AcceptDisposable>>`");
6283 (decl_pos, "This parameter is not marked `<<__AcceptDisposable>>`");
6286 (Error_code.AcceptDisposableInvariant, reasons, [])
6288 let ifc_external_contravariant pos_sub pos_super =
6289 let reasons =
6291 ( pos_super,
6292 "Parameters with `<<__External>>` must be overridden by other parameters with <<__External>>. This parameter is marked `<<__External>>`"
6294 (pos_sub, "But this parameter is not marked `<<__External>>`");
6297 (Error_code.IFCExternalContravariant, reasons, [])
6299 let required_field_is_optional pos name decl_pos =
6300 let reasons =
6302 (pos, "The field " ^ Markdown_lite.md_codify name ^ " is **optional**");
6303 ( decl_pos,
6304 "The field "
6305 ^ Markdown_lite.md_codify name
6306 ^ " is defined as **required**" );
6309 (Error_code.RequiredFieldIsOptional, reasons, [])
6311 let return_disposable_mismatch pos_sub is_marked_return_disposable pos_super =
6312 let (msg, reason_msg) =
6313 if is_marked_return_disposable then
6314 ( "This is marked `<<__ReturnDisposable>>`.",
6315 "This is not marked `<<__ReturnDisposable>>`." )
6316 else
6317 ( "This is not marked `<<__ReturnDisposable>>`.",
6318 "This is marked `<<__ReturnDisposable>>`." )
6320 let reasons = [(pos_super, msg); (pos_sub, reason_msg)] in
6321 (Error_code.ReturnDisposableMismatch, reasons, [])
6323 let ifc_policy_mismatch pos policy pos_super policy_super =
6324 let reasons =
6326 ( pos,
6327 "IFC policies must be invariant with respect to inheritance. This method is policied with "
6328 ^ policy );
6329 ( pos_super,
6330 "This is incompatible with its inherited policy, which is "
6331 ^ policy_super );
6334 (Error_code.IFCPolicyMismatch, reasons, [])
6336 let override_final pos parent_pos =
6337 let reasons =
6339 (pos, "You cannot override this method");
6340 (parent_pos, "It was declared as final");
6343 (Error_code.OverrideFinal, reasons, [])
6345 let override_lsb pos member_name parent_pos =
6346 let reasons =
6348 ( pos,
6349 "Member "
6350 ^ Markdown_lite.md_codify member_name
6351 ^ " may not override `__LSB` member of parent" );
6352 (parent_pos, "This is being overridden");
6355 (Error_code.OverrideLSB, reasons, [])
6357 let multiple_concrete_defs pos origin name parent_pos parent_origin class_name
6359 let child_origin = Markdown_lite.md_codify @@ Render.strip_ns origin
6360 and parent_origin = Markdown_lite.md_codify @@ Render.strip_ns parent_origin
6361 and class_ = Markdown_lite.md_codify @@ Render.strip_ns class_name
6362 and name = Markdown_lite.md_codify name in
6363 let reasons =
6365 ( pos,
6366 child_origin
6367 ^ " and "
6368 ^ parent_origin
6369 ^ " both declare ambiguous implementations of "
6370 ^ name
6371 ^ "." );
6372 (pos, child_origin ^ "'s definition is here.");
6373 (parent_pos, parent_origin ^ "'s definition is here.");
6374 ( pos,
6375 "Redeclare "
6376 ^ name
6377 ^ " in "
6378 ^ class_
6379 ^ " with a compatible signature." );
6382 (Error_code.MultipleConcreteDefs, reasons, [])
6384 let cyclic_enum_constraint pos =
6385 let reasons = [(pos, "Cyclic enum constraint")] in
6386 (Error_code.CyclicEnumConstraint, reasons, [])
6388 let inoutness_mismatch pos decl_pos =
6389 let reasons =
6391 (pos, "This is an `inout` parameter");
6392 (decl_pos, "It is incompatible with a normal parameter");
6395 (Error_code.InoutnessMismatch, reasons, [])
6397 let decl_override_missing_hint pos =
6398 let reasons =
6400 ( pos,
6401 "When redeclaring class members, both declarations must have a typehint"
6405 (Error_code.DeclOverrideMissingHint, reasons, [])
6407 let bad_lateinit_override pos parent_pos parent_is_lateinit =
6408 let verb =
6409 if parent_is_lateinit then
6410 "is"
6411 else
6412 "is not"
6414 let reasons =
6416 (pos, "Redeclared properties must be consistently declared `__LateInit`");
6417 (parent_pos, "The property " ^ verb ^ " declared `__LateInit` here");
6421 (Error_code.BadLateInitOverride, reasons, [])
6423 let bad_xhp_attr_required_override pos parent_pos parent_tag tag =
6424 let reasons =
6426 (pos, "Redeclared attribute must not be less strict");
6427 ( parent_pos,
6428 "The attribute is " ^ parent_tag ^ ", which is stricter than " ^ tag
6432 (Error_code.BadXhpAttrRequiredOverride, reasons, [])
6434 let coeffect_subtyping pos cap pos_expected cap_expected =
6435 let reasons =
6437 ( pos_expected,
6438 "Expected a function that requires " ^ Lazy.force cap_expected );
6439 (pos, "But got a function that requires " ^ Lazy.force cap);
6442 (Error_code.SubtypeCoeffects, reasons, [])
6444 let not_sub_dynamic pos ty_name dynamic_part =
6445 let reasons =
6447 ( pos,
6448 "Type "
6449 ^ (Markdown_lite.md_codify @@ Lazy.force ty_name)
6450 ^ " is not a subtype of `dynamic` under dynamic-aware subtyping" );
6453 (Error_code.UnifyError, dynamic_part @ reasons, [])
6455 let override_method_support_dynamic_type
6456 pos method_name parent_origin parent_pos =
6457 let reasons =
6459 ( pos,
6460 "Method "
6461 ^ method_name
6462 ^ " must be declared <<__SupportDynamicType>> because it overrides method in class "
6463 ^ Render.strip_ns parent_origin
6464 ^ " which does." );
6465 (parent_pos, "Overridden method is defined here.");
6468 (Error_code.ImplementsDynamic, reasons, [])
6470 let readonly_mismatch pos kind reason_sub reason_super =
6471 let reasons =
6472 ( pos,
6473 match kind with
6474 | `fn -> "Function readonly mismatch"
6475 | `fn_return -> "Function readonly return mismatch"
6476 | `param -> "Mismatched parameter readonlyness" )
6477 :: reason_sub
6478 @ reason_super
6480 (Error_code.ReadonlyMismatch, reasons, [])
6482 let typing_too_many_args pos decl_pos actual expected =
6483 let (code, claim, reasons) =
6484 Common.typing_too_many_args pos decl_pos actual expected
6486 (code, claim :: reasons, [])
6488 let typing_too_few_args pos decl_pos actual expected =
6489 let (code, claim, reasons) =
6490 Common.typing_too_few_args pos decl_pos actual expected
6492 (code, claim :: reasons, [])
6494 let non_object_member pos ctxt ty_name member_name kind decl_pos =
6495 let (code, claim, reasons) =
6496 Common.non_object_member
6498 ctxt
6499 (Lazy.force ty_name)
6500 member_name
6501 kind
6502 decl_pos
6504 (code, claim :: reasons, [])
6506 let rigid_tvar_escape pos name =
6507 ( Error_code.RigidTVarEscape,
6508 [(pos, "Rigid type variable " ^ name ^ " is escaping")],
6509 [] )
6511 let smember_not_found pos kind member_name class_name class_pos hint =
6512 let (code, claim, reasons) =
6513 Common.smember_not_found pos kind member_name class_name class_pos hint
6515 (code, claim :: reasons, [])
6517 let bad_method_override pos member_name =
6518 let reasons =
6520 ( pos,
6521 "The method "
6522 ^ (Render.strip_ns member_name |> Markdown_lite.md_codify)
6523 ^ " is not compatible with the overridden method" );
6526 (Error_code.BadMethodOverride, reasons, [])
6528 let bad_prop_override pos member_name =
6529 let reasons =
6531 ( pos,
6532 "The property "
6533 ^ (Render.strip_ns member_name |> Markdown_lite.md_codify)
6534 ^ " has the wrong type" );
6537 (Error_code.BadMethodOverride, reasons, [])
6539 let subtyping_error reasons = (Error_code.UnifyError, reasons, [])
6541 let method_not_dynamically_callable pos parent_pos =
6542 let reasons =
6544 (parent_pos, "This method is `__DynamicallyCallable`.");
6545 (pos, "This method is **not**.");
6548 (Error_code.BadMethodOverride, reasons, [])
6550 let this_final pos_sub pos_super class_name =
6551 let n = Render.strip_ns class_name |> Markdown_lite.md_codify in
6552 let message1 = "Since " ^ n ^ " is not final" in
6553 let message2 = "this might not be a " ^ n in
6554 (Error_code.ThisFinal, [(pos_super, message1); (pos_sub, message2)], [])
6556 let typeconst_concrete_concrete_override pos parent_pos =
6557 ( Error_code.TypeconstConcreteConcreteOverride,
6559 (pos, "Cannot re-declare this type constant");
6560 (parent_pos, "Previously defined here");
6562 [] )
6564 let abstract_concrete_override pos parent_pos kind =
6565 let kind_str =
6566 match kind with
6567 | `method_ -> "method"
6568 | `typeconst -> "type constant"
6569 | `constant -> "constant"
6570 | `property -> "property"
6572 ( Error_code.AbstractConcreteOverride,
6574 (pos, "Cannot re-declare this " ^ kind_str ^ " as abstract");
6575 (parent_pos, "Previously defined here");
6577 [] )
6579 let should_not_be_override pos class_id id =
6580 ( Error_code.ShouldNotBeOverride,
6582 ( pos,
6583 Printf.sprintf
6584 "%s has no parent class with a method %s to override"
6585 (Render.strip_ns class_id |> Markdown_lite.md_codify)
6586 (Markdown_lite.md_codify id) );
6588 [] )
6590 let override_no_default_typeconst pos parent_pos =
6591 ( Error_code.OverrideNoDefaultTypeconst,
6593 (pos, "This abstract type constant does not have a default type");
6594 ( parent_pos,
6595 "It cannot override an abstract type constant that has a default type"
6598 [] )
6600 let eval t ~current_span =
6601 match t with
6602 | Of_error err ->
6603 Eval_result.map ~f:(fun (code, claim, reasons, _) ->
6604 (code, Message.map ~f:Pos_or_decl.of_raw_pos claim :: reasons, []))
6605 @@ Error.eval err ~current_span
6606 | Fun_too_many_args { pos; decl_pos; actual; expected } ->
6607 Eval_result.single (fun_too_many_args pos decl_pos actual expected)
6608 | Fun_too_few_args { pos; decl_pos; actual; expected } ->
6609 Eval_result.single (fun_too_few_args pos decl_pos actual expected)
6610 | Fun_unexpected_nonvariadic { pos; decl_pos } ->
6611 Eval_result.single (fun_unexpected_nonvariadic pos decl_pos)
6612 | Fun_variadicity_hh_vs_php56 { pos; decl_pos } ->
6613 Eval_result.single (fun_variadicity_hh_vs_php56 pos decl_pos)
6614 | Type_arity_mismatch { pos; actual; decl_pos; expected } ->
6615 Eval_result.single (type_arity_mismatch pos actual decl_pos expected)
6616 | Violated_constraint { cstrs; reasons; _ } ->
6617 Eval_result.single (violated_constraint cstrs reasons)
6618 | Concrete_const_interface_override { pos; parent_pos; name; parent_origin }
6620 Eval_result.single
6621 (concrete_const_interface_override pos parent_pos name parent_origin)
6622 | Interface_or_trait_const_multiple_defs
6623 { pos; origin; parent_pos; parent_origin; name } ->
6624 Eval_result.single
6625 (interface_or_trait_const_multiple_defs
6627 origin
6628 parent_pos
6629 parent_origin
6630 name)
6631 | Interface_typeconst_multiple_defs
6632 { pos; parent_pos; name; origin; parent_origin; is_abstract } ->
6633 Eval_result.single
6634 (interface_typeconst_multiple_defs
6636 parent_pos
6637 name
6638 origin
6639 parent_origin
6640 is_abstract)
6641 | Missing_field { pos; name; decl_pos } ->
6642 Eval_result.single (missing_field pos name decl_pos)
6643 | Shape_fields_unknown { pos; decl_pos } ->
6644 Eval_result.single (shape_fields_unknown pos decl_pos)
6645 | Abstract_tconst_not_allowed { pos; decl_pos; tconst_name } ->
6646 Eval_result.single (abstract_tconst_not_allowed pos decl_pos tconst_name)
6647 | Invalid_destructure { pos; decl_pos; ty_name } ->
6648 Eval_result.single (invalid_destructure pos decl_pos ty_name)
6649 | Unpack_array_required_argument { pos; decl_pos } ->
6650 Eval_result.single (unpack_array_required_argument pos decl_pos)
6651 | Unpack_array_variadic_argument { pos; decl_pos } ->
6652 Eval_result.single (unpack_array_variadic_argument pos decl_pos)
6653 | Overriding_prop_const_mismatch { pos; is_const; parent_pos; _ } ->
6654 Eval_result.single
6655 (overriding_prop_const_mismatch pos is_const parent_pos)
6656 | Visibility_extends { pos; vis; parent_pos; parent_vis } ->
6657 Eval_result.single (visibility_extends pos vis parent_pos parent_vis)
6658 | Visibility_override_internal
6659 { pos; module_name; parent_module; parent_pos } ->
6660 Eval_result.single
6661 (visibility_override_internal pos module_name parent_module parent_pos)
6662 | Missing_constructor pos -> Eval_result.single (missing_constructor pos)
6663 | Accept_disposable_invariant { pos; decl_pos } ->
6664 Eval_result.single (accept_disposable_invariant pos decl_pos)
6665 | Ifc_external_contravariant { pos_sub; pos_super } ->
6666 Eval_result.single (ifc_external_contravariant pos_sub pos_super)
6667 | Required_field_is_optional { pos; name; decl_pos } ->
6668 Eval_result.single (required_field_is_optional pos name decl_pos)
6669 | Return_disposable_mismatch
6670 { pos_sub; is_marked_return_disposable; pos_super } ->
6671 Eval_result.single
6672 (return_disposable_mismatch
6673 pos_sub
6674 is_marked_return_disposable
6675 pos_super)
6676 | Ifc_policy_mismatch { pos; policy; pos_super; policy_super } ->
6677 Eval_result.single (ifc_policy_mismatch pos policy pos_super policy_super)
6678 | Override_final { pos; parent_pos } ->
6679 Eval_result.single (override_final pos parent_pos)
6680 | Override_lsb { pos; member_name; parent_pos } ->
6681 Eval_result.single (override_lsb pos member_name parent_pos)
6682 | Multiple_concrete_defs
6683 { pos; origin; name; parent_pos; parent_origin; class_name } ->
6684 Eval_result.single
6685 (multiple_concrete_defs
6687 origin
6688 name
6689 parent_pos
6690 parent_origin
6691 class_name)
6692 | Cyclic_enum_constraint pos ->
6693 Eval_result.single (cyclic_enum_constraint pos)
6694 | Inoutness_mismatch { pos; decl_pos } ->
6695 Eval_result.single (inoutness_mismatch pos decl_pos)
6696 | Decl_override_missing_hint pos ->
6697 Eval_result.single (decl_override_missing_hint pos)
6698 | Bad_lateinit_override { pos; parent_pos; parent_is_lateinit } ->
6699 Eval_result.single
6700 (bad_lateinit_override pos parent_pos parent_is_lateinit)
6701 | Bad_xhp_attr_required_override { pos; parent_pos; parent_tag; tag } ->
6702 Eval_result.single
6703 (bad_xhp_attr_required_override pos parent_pos parent_tag tag)
6704 | Coeffect_subtyping { pos; cap; pos_expected; cap_expected } ->
6705 Eval_result.single (coeffect_subtyping pos cap pos_expected cap_expected)
6706 | Not_sub_dynamic { pos; ty_name; dynamic_part } ->
6707 Eval_result.single (not_sub_dynamic pos ty_name dynamic_part)
6708 | Override_method_support_dynamic_type
6709 { pos; method_name; parent_origin; parent_pos } ->
6710 Eval_result.single
6711 (override_method_support_dynamic_type
6713 method_name
6714 parent_origin
6715 parent_pos)
6716 | Readonly_mismatch { pos; kind; reason_sub; reason_super } ->
6717 Eval_result.single (readonly_mismatch pos kind reason_sub reason_super)
6718 | Typing_too_many_args { pos; decl_pos; actual; expected } ->
6719 Eval_result.single (typing_too_many_args pos decl_pos actual expected)
6720 | Typing_too_few_args { pos; decl_pos; actual; expected } ->
6721 Eval_result.single (typing_too_few_args pos decl_pos actual expected)
6722 | Non_object_member { pos; ctxt; ty_name; member_name; kind; decl_pos } ->
6723 Eval_result.single
6724 (non_object_member pos ctxt ty_name member_name kind decl_pos)
6725 | Rigid_tvar_escape { pos; name } ->
6726 Eval_result.single (rigid_tvar_escape pos name)
6727 | Smember_not_found { pos; kind; member_name; class_name; class_pos; hint }
6729 Eval_result.single
6730 (smember_not_found pos kind member_name class_name class_pos hint)
6731 | Bad_method_override { pos; member_name } ->
6732 Eval_result.single (bad_method_override pos member_name)
6733 | Bad_prop_override { pos; member_name } ->
6734 Eval_result.single (bad_prop_override pos member_name)
6735 | Subtyping_error reasons -> Eval_result.single (subtyping_error reasons)
6736 | Method_not_dynamically_callable { pos; parent_pos } ->
6737 Eval_result.single (method_not_dynamically_callable pos parent_pos)
6738 | This_final { pos_sub; pos_super; class_name } ->
6739 Eval_result.single (this_final pos_sub pos_super class_name)
6740 | Typeconst_concrete_concrete_override { pos; parent_pos } ->
6741 Eval_result.single (typeconst_concrete_concrete_override pos parent_pos)
6742 | Abstract_concrete_override { pos; parent_pos; kind } ->
6743 Eval_result.single (abstract_concrete_override pos parent_pos kind)
6744 | Should_not_be_override { pos; class_id; id } ->
6745 Eval_result.single (should_not_be_override pos class_id id)
6746 | Override_no_default_typeconst { pos; parent_pos } ->
6747 Eval_result.single (override_no_default_typeconst pos parent_pos)
6750 and Callback : sig
6751 type t
6753 val iter : t -> on_prim:(Primary.t -> unit) -> unit
6755 val apply :
6756 ?code:Error_code.t ->
6757 ?reasons:Pos_or_decl.t Message.t list ->
6758 ?quickfixes:Quickfix.t list ->
6759 t ->
6760 claim:Pos.t Message.t ->
6761 error option
6763 val always : Primary.t -> t
6765 val with_side_effect : t -> eff:(unit -> unit) -> t
6766 [@@ocaml.deprecated
6767 "This function will be removed. Please avoid adding side effects to error callbacks."]
6769 val of_primary_error : Primary.t -> t
6771 val with_code : code:Error_code.t -> t
6773 val retain_code : t -> t
6775 val with_claim_as_reason : t -> new_claim:Primary.t -> t
6777 val unify_error : t
6779 val index_type_mismatch : t
6781 val covariant_index_type_mismatch : t
6783 val expected_stringlike : t
6785 val constant_does_not_match_enum_type : t
6787 val enum_underlying_type_must_be_arraykey : t
6789 val enum_constraint_must_be_arraykey : t
6791 val enum_subtype_must_have_compatible_constraint : t
6793 val parameter_default_value_wrong_type : t
6795 val newtype_alias_must_satisfy_constraint : t
6797 val missing_return : t
6799 val inout_return_type_mismatch : t
6801 val class_constant_value_does_not_match_hint : t
6803 val class_property_initializer_type_does_not_match_hint : t
6805 val xhp_attribute_does_not_match_hint : t
6807 val record_init_value_does_not_match_hint : t
6809 val strict_str_concat_type_mismatch : t
6811 val strict_str_interp_type_mismatch : t
6813 val bitwise_math_invalid_argument : t
6815 val inc_dec_invalid_argument : t
6817 val math_invalid_argument : t
6819 val using_error : Pos.t -> has_await:bool -> t
6820 end = struct
6821 type t =
6822 | Always of Primary.t
6823 | With_claim_as_reason of t * Primary.t
6824 | With_code of Error_code.t
6825 | Retain_code of t
6826 | With_side_effect of t * (unit -> unit)
6828 let iter t ~on_prim =
6829 let rec aux = function
6830 | Always prim -> on_prim prim
6831 | With_claim_as_reason (t, prim) ->
6832 on_prim prim;
6833 aux t
6834 | Retain_code t
6835 | With_side_effect (t, _) ->
6836 aux t
6837 | With_code _ -> ()
6839 aux t
6841 (* -- Evaluation ---------------------------------------------------------- *)
6842 type error_state = {
6843 code_opt: Error_code.t option;
6844 claim_opt: Pos.t Message.t option;
6845 reasons: Pos_or_decl.t Message.t list;
6846 quickfixes: Quickfix.t list;
6849 let with_code code { claim_opt; reasons; quickfixes; _ } =
6850 Some (code, claim_opt, reasons, quickfixes)
6852 let rec eval t st =
6853 match t with
6854 | With_side_effect (t, eff) ->
6855 eff ();
6856 eval t st
6857 | Always err ->
6858 Option.map ~f:(fun (code, claim, reasons, quickfixes) ->
6859 (code, Some claim, reasons, quickfixes))
6860 @@ Primary.to_error err
6861 | With_claim_as_reason (err, claim_from) ->
6862 let reasons =
6863 Option.value_map
6864 ~default:st.reasons
6865 ~f:(fun claim ->
6866 Tuple2.map_fst ~f:Pos_or_decl.of_raw_pos claim :: st.reasons)
6867 st.claim_opt
6869 let claim_opt =
6870 Option.map ~f:(fun (_, claim, _, _) -> claim)
6871 @@ Primary.to_error claim_from
6873 eval err { st with claim_opt; reasons }
6874 | Retain_code t -> eval t { st with code_opt = None }
6875 | With_code default -> with_code (Option.value ~default st.code_opt) st
6877 let apply ?code ?(reasons = []) ?(quickfixes = []) t ~claim =
6878 let st = { code_opt = code; claim_opt = Some claim; reasons; quickfixes } in
6879 Option.map ~f:(fun (code, claim_opt, reasons, quickfixes) ->
6880 (code, Option.value ~default:claim claim_opt, reasons, quickfixes))
6881 @@ eval t st
6883 (* -- Constructors -------------------------------------------------------- *)
6885 let always err = Always err
6887 let with_side_effect t ~eff = (With_side_effect (t, eff) [@alert.deprecated])
6889 let with_code ~code = With_code code
6891 let of_primary_error err = with_code ~code:(Primary.code err)
6893 let retain_code t = Retain_code t
6895 let with_claim_as_reason t ~new_claim = With_claim_as_reason (t, new_claim)
6897 (* -- Specific errors ----------------------------------------------------- *)
6898 let unify_error = with_code ~code:Error_code.UnifyError
6900 let index_type_mismatch = with_code ~code:Error_code.IndexTypeMismatch
6902 let covariant_index_type_mismatch =
6903 with_code ~code:Error_code.CovariantIndexTypeMismatch
6905 let expected_stringlike = with_code ~code:Error_code.ExpectedStringlike
6907 let constant_does_not_match_enum_type =
6908 with_code ~code:Error_code.ConstantDoesNotMatchEnumType
6910 let enum_underlying_type_must_be_arraykey =
6911 with_code ~code:Error_code.EnumUnderlyingTypeMustBeArraykey
6913 let enum_constraint_must_be_arraykey =
6914 with_code ~code:Error_code.EnumConstraintMustBeArraykey
6916 let enum_subtype_must_have_compatible_constraint =
6917 with_code ~code:Error_code.EnumSubtypeMustHaveCompatibleConstraint
6919 let parameter_default_value_wrong_type =
6920 with_code ~code:Error_code.ParameterDefaultValueWrongType
6922 let newtype_alias_must_satisfy_constraint =
6923 with_code ~code:Error_code.NewtypeAliasMustSatisfyConstraint
6925 let missing_return = with_code ~code:Error_code.MissingReturnInNonVoidFunction
6927 let inout_return_type_mismatch =
6928 with_code ~code:Error_code.InoutReturnTypeMismatch
6930 let class_constant_value_does_not_match_hint =
6931 with_code ~code:Error_code.ClassConstantValueDoesNotMatchHint
6933 let class_property_initializer_type_does_not_match_hint =
6934 with_code ~code:Error_code.ClassPropertyInitializerTypeDoesNotMatchHint
6936 let xhp_attribute_does_not_match_hint =
6937 with_code ~code:Error_code.XhpAttributeValueDoesNotMatchHint
6939 let record_init_value_does_not_match_hint =
6940 with_code ~code:Error_code.RecordInitValueDoesNotMatchHint
6942 let strict_str_concat_type_mismatch =
6943 with_code ~code:Error_code.StrictStrConcatTypeMismatch
6945 let strict_str_interp_type_mismatch =
6946 with_code ~code:Error_code.StrictStrInterpTypeMismatch
6948 let bitwise_math_invalid_argument =
6949 with_code ~code:Error_code.BitwiseMathInvalidArgument
6951 let inc_dec_invalid_argument =
6952 with_code ~code:Error_code.IncDecInvalidArgument
6954 let math_invalid_argument = with_code ~code:Error_code.MathInvalidArgument
6956 let using_error pos ~has_await =
6957 let new_claim = Primary.Using_error { pos; has_await } in
6958 with_claim_as_reason ~new_claim @@ retain_code unify_error
6961 and Reasons_callback : sig
6962 type t
6964 val iter :
6965 t -> on_prim:(Primary.t -> unit) -> on_snd:(Secondary.t -> unit) -> unit
6967 val from_on_error : on_error -> t
6968 [@@ocaml.deprecated
6969 "This function will be removed. Please use the provided combinators for constructing error callbacks."]
6971 val ignore_error : t
6973 val always : Error.t -> t
6975 val of_error : Error.t -> t
6977 val of_primary_error : Primary.t -> t
6979 val with_claim : Callback.t -> claim:Pos.t Message.t -> t
6981 val with_code : t -> code:Error_code.t -> t
6983 val with_reasons : t -> reasons:Pos_or_decl.t Message.t list -> t
6985 val prepend_reason : t -> reason:Pos_or_decl.t Message.t -> t
6987 val append_reason : t -> reason:Pos_or_decl.t Message.t -> t
6989 val append_incoming_reasons : t -> t
6991 val prepend_incoming_reasons : t -> t
6993 val retain_code : t -> t
6995 val retain_reasons : t -> t
6997 val retain_quickfixes : t -> t
6999 val prepend_on_apply : t -> Secondary.t -> t
7001 val assert_in_current_decl : Error_code.t -> ctx:Pos_or_decl.ctx -> t
7003 val apply_help :
7004 ?code:Error_code.t ->
7005 ?claim:Pos.t Message.t ->
7006 ?reasons:Pos_or_decl.t Message.t list ->
7007 ?quickfixes:Quickfix.t list ->
7008 t ->
7009 current_span:Pos.t ->
7010 error Eval_result.t
7012 val apply :
7013 ?code:Error_code.t ->
7014 ?claim:Pos.t Message.t ->
7015 ?reasons:Pos_or_decl.t Message.t list ->
7016 ?quickfixes:Quickfix.t list ->
7017 t ->
7018 current_span:Pos.t ->
7019 (Pos.t, Pos_or_decl.t) User_error.t Eval_result.t
7021 val unify_error_at : Pos.t -> t
7023 val bad_enum_decl : Pos.t -> t
7025 val bad_conditional_support_dynamic :
7026 Pos.t ->
7027 child:string ->
7028 parent:string ->
7029 ty_name:string Lazy.t ->
7030 self_ty_name:string Lazy.t ->
7033 val bad_decl_override :
7034 Pos.t -> name:string -> parent_pos:Pos_or_decl.t -> parent_name:string -> t
7036 val explain_where_constraint :
7037 Pos.t -> in_class:bool -> decl_pos:Pos_or_decl.t -> t
7039 val explain_constraint : Pos.t -> t
7041 val rigid_tvar_escape_at : Pos.t -> string -> t
7043 val invalid_type_hint : Pos.t -> t
7045 val type_constant_mismatch : t -> t
7047 val class_constant_type_mismatch : t -> t
7049 val unsatisfied_req_callback :
7050 class_pos:Pos.t ->
7051 trait_pos:Pos_or_decl.t ->
7052 req_pos:Pos_or_decl.t ->
7053 string ->
7056 val invalid_echo_argument_at : Pos.t -> t
7058 val index_type_mismatch_at : Pos.t -> t
7060 val unify_error_assert_primary_pos_in_current_decl : Pos_or_decl.ctx -> t
7062 val invalid_type_hint_assert_primary_pos_in_current_decl :
7063 Pos_or_decl.ctx -> t
7064 end = struct
7065 type op =
7066 | Append
7067 | Prepend
7069 type component =
7070 | Code
7071 | Reasons
7072 | Quickfixes
7074 type t =
7075 | Ignore
7076 | Always of Error.t
7077 | Of_error of Error.t
7078 | Of_callback of Callback.t * Pos.t Message.t
7079 | Retain of t * component
7080 | Incoming_reasons of t * op
7081 | With_code of t * Error_code.t
7082 | With_reasons of t * Pos_or_decl.t Message.t list
7083 | Add_reason of t * op * Pos_or_decl.t Message.t
7084 | From_on_error of on_error
7085 | Prepend_on_apply of t * Secondary.t
7086 | Assert_in_current_decl of Error_code.t * Pos_or_decl.ctx
7088 let iter t ~on_prim ~on_snd =
7089 let rec aux = function
7090 | Always err
7091 | Of_error err ->
7092 Error.iter err ~on_prim ~on_snd
7093 | Of_callback (cb, _) -> Callback.iter cb ~on_prim
7094 | Retain (t, _)
7095 | Incoming_reasons (t, _)
7096 | With_code (t, _)
7097 | With_reasons (t, _)
7098 | Add_reason (t, _, _)
7099 | Prepend_on_apply (t, _) ->
7100 aux t
7101 | From_on_error _
7102 | Ignore
7103 | Assert_in_current_decl _ ->
7106 aux t
7108 (* -- Constructors -------------------------------------------------------- *)
7110 let from_on_error f = From_on_error f
7112 let ignore_error = Ignore
7114 let of_error err = Of_error err
7116 let of_primary_error prim_err = Of_error (Error.primary prim_err)
7118 let with_claim no_claim ~claim = Of_callback (no_claim, claim)
7120 let with_code t ~code = With_code (t, code)
7122 let with_reasons t ~reasons = With_reasons (t, reasons)
7124 let prepend_reason t ~reason = Add_reason (t, Prepend, reason)
7126 let append_reason t ~reason = Add_reason (t, Append, reason)
7128 let append_incoming_reasons t = Incoming_reasons (t, Append)
7130 let prepend_incoming_reasons t = Incoming_reasons (t, Prepend)
7132 let retain_code t = Retain (t, Code)
7134 let retain_reasons t = Retain (t, Reasons)
7136 let retain_quickfixes t = Retain (t, Quickfixes)
7138 let always err = Always err
7140 let prepend_on_apply t snd_err = Prepend_on_apply (t, snd_err)
7142 let assert_in_current_decl code ~ctx = Assert_in_current_decl (code, ctx)
7144 (* -- Evaluation ------------------------------------------------------------ *)
7146 module Error_state = struct
7147 type t = {
7148 code_opt: Error_code.t option;
7149 claim_opt: Pos.t Message.t option;
7150 reasons_opt: Pos_or_decl.t Message.t list option;
7151 quickfixes_opt: Quickfix.t list option;
7154 let with_code t code_opt =
7155 { t with code_opt = Option.first_some t.code_opt code_opt }
7157 let prepend_secondary
7158 { claim_opt; reasons_opt; quickfixes_opt; _ } snd_err ~current_span =
7159 Eval_result.map
7160 (Secondary.eval snd_err ~current_span)
7161 ~f:(fun (code, reasons, quickfixes) ->
7163 code_opt = Some code;
7164 claim_opt;
7165 reasons_opt = Some (reasons @ Option.value ~default:[] reasons_opt);
7166 quickfixes_opt =
7167 Some (quickfixes @ Option.value ~default:[] quickfixes_opt);
7170 (** Replace any missing values in the error state with those of the error *)
7171 let with_defaults
7172 { code_opt; claim_opt; reasons_opt; quickfixes_opt } err ~current_span =
7173 Eval_result.map ~f:(fun (code, claim, reasons, quickfixes) ->
7174 Option.
7175 ( value code_opt ~default:code,
7176 value claim_opt ~default:claim,
7177 value reasons_opt ~default:reasons,
7178 value quickfixes_opt ~default:quickfixes ))
7179 @@ Error.eval err ~current_span
7182 let eval_callback
7183 k Error_state.{ code_opt; reasons_opt; quickfixes_opt; _ } ~claim =
7184 Callback.apply
7185 ?code:code_opt
7186 ?reasons:reasons_opt
7187 ?quickfixes:quickfixes_opt
7188 ~claim
7191 let eval t ~st ~current_span =
7192 let rec aux t st =
7193 match t with
7194 | From_on_error f ->
7195 let code = Option.map ~f:Error_code.to_enum st.Error_state.code_opt
7196 and quickfixes = st.Error_state.quickfixes_opt
7197 and reasons = Option.value ~default:[] st.Error_state.reasons_opt in
7198 f ?code ?quickfixes reasons;
7199 Eval_result.empty
7200 | Ignore -> Eval_result.empty
7201 | Always err -> Error.eval err ~current_span
7202 | Of_error err -> Error_state.with_defaults st err ~current_span
7203 | Of_callback (k, claim) ->
7204 Eval_result.of_option @@ eval_callback k st ~claim
7205 | Assert_in_current_decl (default, ctx) ->
7206 let Error_state.{ code_opt; reasons_opt; quickfixes_opt; _ } = st in
7207 let crs =
7208 Option.
7209 ( value ~default code_opt,
7210 value ~default:[] reasons_opt,
7211 value ~default:[] quickfixes_opt )
7213 let res_opt = Common.eval_assert ctx current_span crs in
7214 Eval_result.of_option res_opt
7215 | With_code (err, code) ->
7216 let st = Error_state.with_code st @@ Some code in
7217 aux err st
7218 | With_reasons (err, reasons) ->
7219 aux err Error_state.{ st with reasons_opt = Some reasons }
7220 | Add_reason (err, op, reason) -> aux_reason_op op err reason st
7221 | Retain (t, comp) -> aux_retain t comp st
7222 | Incoming_reasons (err, op) ->
7223 Eval_result.map ~f:(fun ((code, claim, reasons, qfxs) as err) ->
7224 match (st.Error_state.reasons_opt, op) with
7225 | (None, _)
7226 | (Some [], _) ->
7228 | (Some rs, Append) -> (code, claim, reasons @ rs, qfxs)
7229 | (Some rs, Prepend) -> (code, claim, rs @ reasons, qfxs))
7230 @@ aux err Error_state.{ st with reasons_opt = None }
7231 | Prepend_on_apply (t, snd_err) ->
7232 Eval_result.bind
7233 ~f:(aux t)
7234 (Error_state.prepend_secondary st snd_err ~current_span)
7235 and aux_reason_op op err base_reason (Error_state.{ reasons_opt; _ } as st)
7237 let reasons_opt =
7238 match op with
7239 | Append ->
7240 Option.(
7241 first_some (map reasons_opt ~f:(fun rs -> rs @ [base_reason]))
7242 @@ Some [base_reason])
7243 | Prepend ->
7244 Option.(
7245 first_some (map reasons_opt ~f:(fun rs -> base_reason :: rs))
7246 @@ Some [base_reason])
7248 aux err Error_state.{ st with reasons_opt }
7249 and aux_retain t comp st =
7250 match comp with
7251 | Code -> aux t Error_state.{ st with code_opt = None }
7252 | Reasons -> aux t Error_state.{ st with reasons_opt = None }
7253 | Quickfixes -> aux t Error_state.{ st with quickfixes_opt = None }
7255 aux t st
7257 let apply_help ?code ?claim ?reasons ?quickfixes t ~current_span =
7258 let claim = Option.map claim ~f:(Message.map ~f:Pos_or_decl.of_raw_pos) in
7259 let reasons_opt =
7260 match (claim, reasons) with
7261 | (Some claim, Some reasons) -> Some (claim :: reasons)
7262 | (Some claim, _) -> Some [claim]
7263 | _ -> reasons
7265 eval
7267 ~st:
7268 Error_state.
7270 code_opt = code;
7271 claim_opt = None;
7272 reasons_opt;
7273 quickfixes_opt = quickfixes;
7275 ~current_span
7277 let apply ?code ?claim ?reasons ?quickfixes t ~current_span =
7278 let f (code, claim, reasons, quickfixes) =
7279 User_error.make (Error_code.to_enum code) claim reasons ~quickfixes
7281 Eval_result.map ~f
7282 @@ apply_help ?code ?claim ?reasons ?quickfixes t ~current_span
7283 (* -- Specific callbacks -------------------------------------------------- *)
7285 let unify_error_at pos =
7286 of_error
7287 @@ Error.primary
7288 @@ Primary.Unify_error { pos; msg_opt = None; reasons_opt = None }
7290 let bad_enum_decl pos =
7291 retain_code
7292 @@ retain_quickfixes
7293 @@ of_error
7294 @@ Error.primary
7295 @@ Primary.Bad_enum_decl pos
7297 let bad_conditional_support_dynamic pos ~child ~parent ~ty_name ~self_ty_name
7299 retain_code
7300 @@ retain_quickfixes
7301 @@ of_primary_error
7302 @@ Primary.Bad_conditional_support_dynamic
7303 { pos; child; parent; ty_name; self_ty_name }
7305 let bad_decl_override pos ~name ~parent_pos ~parent_name =
7306 append_incoming_reasons
7307 @@ retain_quickfixes
7308 @@ of_primary_error
7309 @@ Primary.Bad_decl_override { pos; name; parent_pos; parent_name }
7311 let explain_where_constraint pos ~in_class ~decl_pos =
7312 append_incoming_reasons
7313 @@ retain_code
7314 @@ retain_quickfixes
7315 @@ of_primary_error
7316 @@ Primary.Explain_where_constraint { pos; in_class; decl_pos }
7318 let explain_constraint pos =
7319 retain_code @@ of_primary_error @@ Primary.Explain_constraint pos
7321 let rigid_tvar_escape_at pos what =
7322 retain_quickfixes
7323 @@ retain_code
7324 @@ of_primary_error
7325 @@ Primary.Rigid_tvar_escape { pos; what }
7327 let invalid_type_hint pos =
7328 retain_quickfixes @@ of_primary_error @@ Primary.Invalid_type_hint pos
7330 let type_constant_mismatch t =
7331 retain_quickfixes @@ with_code ~code:Error_code.TypeConstantMismatch t
7333 let class_constant_type_mismatch t =
7334 retain_quickfixes @@ with_code ~code:Error_code.ClassConstantTypeMismatch t
7336 let unsatisfied_req_callback ~class_pos ~trait_pos ~req_pos req_name =
7337 append_incoming_reasons
7338 @@ retain_code
7339 @@ of_primary_error
7340 @@ Primary.Unsatisfied_req { pos = class_pos; trait_pos; req_pos; req_name }
7342 let invalid_echo_argument_at pos =
7343 of_primary_error @@ Primary.Invalid_echo_argument pos
7345 let index_type_mismatch_at pos =
7346 of_primary_error
7347 @@ Primary.Index_type_mismatch
7349 pos;
7350 msg_opt = None;
7351 reasons_opt = None;
7352 is_covariant_container = false;
7355 let unify_error_assert_primary_pos_in_current_decl ctx =
7356 assert_in_current_decl Error_code.UnifyError ~ctx
7358 let invalid_type_hint_assert_primary_pos_in_current_decl ctx =
7359 assert_in_current_decl Error_code.InvalidTypeHint ~ctx
7362 include Error