Transformation for parameter dependent contexts
[hiphop-php.git] / hphp / hack / src / parser / syntax_error.rs
blobb2f5c876eb8f884d4e5ee5028f26450d37aac93c
1 #![allow(non_upper_case_globals)]
2 // Copyright (c) 2019, Facebook, Inc.
3 // All rights reserved.
4 //
5 // This source code is licensed under the MIT license found in the
6 // LICENSE file in the "hack" directory of this source tree.
7 //
9 use crate::token_kind::TokenKind;
10 use ocamlrep_derive::{FromOcamlRep, ToOcamlRep};
11 use std::{borrow::Cow, cmp::Ordering};
13 // many errors are static strings, but not all of them
14 pub type Error = Cow<'static, str>;
16 #[derive(Debug, Clone, FromOcamlRep, ToOcamlRep, PartialEq, Eq)]
17 pub enum ErrorType {
18     ParseError,
19     RuntimeError,
22 #[derive(Debug, Clone, FromOcamlRep, ToOcamlRep, PartialEq, Eq)]
23 pub struct SyntaxError {
24     pub child: Option<Box<SyntaxError>>,
25     pub start_offset: usize,
26     pub end_offset: usize,
27     pub error_type: ErrorType,
28     pub message: Error,
31 impl SyntaxError {
32     pub fn make_with_child_and_type(
33         child: Option<SyntaxError>,
34         start_offset: usize,
35         end_offset: usize,
36         error_type: ErrorType,
37         message: Error,
38     ) -> Self {
39         Self {
40             child: child.map(|x| Box::new(x)),
41             start_offset,
42             end_offset,
43             error_type,
44             message,
45         }
46     }
48     pub fn make(start_offset: usize, end_offset: usize, message: Error) -> Self {
49         Self::make_with_child_and_type(
50             None,
51             start_offset,
52             end_offset,
53             ErrorType::ParseError,
54             message,
55         )
56     }
58     pub fn compare_offset(e1: &Self, e2: &Self) -> Ordering {
59         (e1.start_offset, e1.end_offset).cmp(&(e2.start_offset, e2.end_offset))
60     }
62     pub fn equal_offset(e1: &Self, e2: &Self) -> bool {
63         Self::compare_offset(e1, e2) == Ordering::Equal
64     }
66     pub fn weak_equal(e1: &Self, e2: &Self) -> bool {
67         e1.start_offset == e2.start_offset
68             && e1.end_offset == e2.end_offset
69             && e1.message == e2.message
70     }
73 // Lexical errors
74 pub const error0001: Error = Cow::Borrowed("A hexadecimal literal needs at least one digit.");
75 pub const error0002: Error = Cow::Borrowed("A binary literal needs at least one digit.");
76 pub const error0003: Error = Cow::Borrowed(concat!(
77     "A floating point literal with an exponent needs at least ",
78     "one digit in the exponent."
79 ));
80 pub const error0006: Error = Cow::Borrowed("This character is invalid.");
81 pub const error0007: Error = Cow::Borrowed("This delimited comment is not terminated.");
82 pub const error0008: Error = Cow::Borrowed("A name is expected here.");
83 pub const error0010: Error = Cow::Borrowed("A single quote is expected here.");
84 pub const error0011: Error = Cow::Borrowed("A newline is expected here.");
85 pub const error0012: Error = Cow::Borrowed("This string literal is not terminated.");
86 pub const error0013: Error = Cow::Borrowed("This XHP body is not terminated.");
87 pub const error0014: Error = Cow::Borrowed("This XHP comment is not terminated.");
89 // Syntactic errors
90 pub const error1001: Error = Cow::Borrowed("A .php file must begin with `<?hh`.");
91 pub const error1003: Error = Cow::Borrowed("The `function` keyword is expected here.");
92 pub const error1004: Error = Cow::Borrowed("A name is expected here.");
93 pub const error1006: Error = Cow::Borrowed("A right brace `}` is expected here.");
94 pub const error1007: Error = Cow::Borrowed("A type specifier is expected here.");
95 pub const error1008: Error = Cow::Borrowed("A variable name is expected here.");
96 pub const error1010: Error = Cow::Borrowed("A semicolon `;` is expected here.");
97 pub const error1011: Error = Cow::Borrowed("A right parenthesis `)` is expected here.");
98 pub const error1013: Error = Cow::Borrowed("A closing angle bracket `>` is expected here.");
99 pub const error1014: Error =
100     Cow::Borrowed("A closing angle bracket `>` or comma is expected here.");
101 pub const error1015: Error = Cow::Borrowed("An expression is expected here.");
102 pub const error1016: Error = Cow::Borrowed("An assignment is expected here.");
103 pub const error1017: Error = Cow::Borrowed("An XHP attribute value is expected here.");
104 pub const error1018: Error = Cow::Borrowed("The `while` keyword is expected here.");
105 pub const error1019: Error = Cow::Borrowed("A left parenthesis `(` is expected here.");
106 pub const error1020: Error = Cow::Borrowed("A colon `:` is expected here.");
107 pub const error1021: Error = Cow::Borrowed("An opening angle bracket `<` is expected here.");
108 // TODO: Remove this; redundant to 1009.
109 pub const error1022: Error =
110     Cow::Borrowed("A right parenthesis `)` or comma `,` is expected here.");
111 pub const error1023: Error = Cow::Borrowed("An `as` keyword is expected here.");
112 pub const error1025: Error = Cow::Borrowed("A shape field name is expected here.");
113 pub const error1026: Error = Cow::Borrowed("An opening square bracket `[` is expected here.");
114 pub const error1028: Error = Cow::Borrowed("An arrow `=>` is expected here.");
115 pub const error1029: Error = Cow::Borrowed("A closing double angle bracket `>>` is expected here.");
116 pub const error1031: Error =
117     Cow::Borrowed("A comma `,` or a closing square bracket `]` is expected here.");
118 pub const error1032: Error = Cow::Borrowed("A closing square bracket `]` is expected here.");
119 // TODO: Break this up according to classish type
120 pub const error1033: Error = Cow::Borrowed(concat!(
121     "A class member, method, type, trait usage, trait require, ",
122     "xhp attribute, xhp use, or xhp category is expected here."
124 pub const error1034: Error = Cow::Borrowed("A left brace `{` is expected here.");
125 pub const error1035: Error = Cow::Borrowed("The `class` keyword is expected here.");
126 pub const error1036: Error = Cow::Borrowed("An equals sign `=` is expected here.");
127 pub const error1037: Error = Cow::Borrowed("The `record` keyword is expected here.");
128 pub const error1038: Error = Cow::Borrowed("A semicolon `;` or a namespace body is expected here.");
129 pub const error1039: Error = Cow::Borrowed("A closing XHP tag is expected here.");
130 pub const error1041: Error = Cow::Borrowed("A function body or a semicolon `;` is expected here.");
131 pub const error1044: Error = Cow::Borrowed("A name or `__construct` keyword is expected here.");
132 pub const error1045: Error =
133     Cow::Borrowed("An `extends` or `implements` keyword is expected here.");
134 pub const error1046: Error = Cow::Borrowed("A lambda arrow `==>` is expected here.");
135 pub const error1047: Error = Cow::Borrowed("A scope resolution operator `::` is expected here.");
136 pub const error1048: Error = Cow::Borrowed("A name, variable name or `class` is expected here.");
137 pub const error1050: Error = Cow::Borrowed("A name or variable name is expected here.");
138 pub const error1051: Error =
139     Cow::Borrowed("The `required` or `lateinit` keyword is expected here.");
140 pub const error1052: Error =
141     Cow::Borrowed("An XHP category name beginning with a `%` is expected here.");
142 pub const error1053: Error = Cow::Borrowed("An XHP name or category name is expected here.");
143 pub const error1054: Error = Cow::Borrowed("A comma `,` is expected here.");
144 pub const error1055: Error = Cow::Borrowed(concat!(
145     "A fallthrough directive can only appear at the end of",
146     " a `switch` section."
148 // TODO(20052790): use the specific token's text in the message body.
149 pub const error1056: Error =
150     Cow::Borrowed("This token is not valid as part of a function declaration.");
151 pub fn error1057(text: &str) -> Error {
152     // TODO (kasper): T52404885: why does removing to_string() here segfaults
153     Cow::Owned(format!(
154         "Encountered unexpected token `{}`.",
155         text.to_string()
156     ))
158 pub fn uppercase_kw(text: &str) -> Error {
159     Cow::Owned(format!(
160         "Keyword `{}` must be written in lowercase",
161         text.to_string()
162     ))
164 pub fn error1058(received: &str, required: &str) -> Error {
165     Cow::Owned(format!(
166         "Encountered unexpected token `{}`. Did you mean `{}`?",
167         received.to_string(),
168         required.to_string()
169     ))
171 pub fn error1059(terminator: TokenKind) -> Error {
172     Cow::Owned(format!(
173         "An `{}` is required when using alternate block syntax.",
174         terminator.to_string().to_string(),
175     ))
177 pub fn error1060(extension: &str) -> Error {
178     let kind = if extension == "hack" {
179         "strict"
180     } else {
181         "partial"
182     };
183     Cow::Owned(format!(
184         "Leading markup and `<?hh` are not permitted in `.{}` files, which are always `{}`.",
185         extension.to_string(),
186         kind.to_string()
187     ))
189 pub const error1063: Error = Cow::Borrowed("Expected matching separator here.");
190 pub const error1064: Error = Cow::Borrowed("XHP children declarations are no longer supported.");
191 pub const error1065: Error = Cow::Borrowed("A backtick ``` is expected here.");
192 pub const error2001: Error = Cow::Borrowed("A type annotation is required in `strict` mode.");
193 pub const error2003: Error =
194     Cow::Borrowed("A `case` statement may only appear directly inside a `switch`.");
195 pub const error2004: Error =
196     Cow::Borrowed("A `default` statement may only appear directly inside a `switch`.");
197 pub const error2005: Error =
198     Cow::Borrowed("A `break` statement may only appear inside a `switch` or loop.");
199 pub const error2006: Error = Cow::Borrowed("A `continue` statement may only appear inside a loop.");
200 pub const error2007: Error =
201     Cow::Borrowed("A `try` statement requires a `catch` or a `finally` clause.");
202 pub const error2008: Error = Cow::Borrowed(concat!(
203     "The first statement inside a `switch` statement must ",
204     "be a `case` or `default` label statement."
206 pub fn error2009(class_name: &str, method_name: &str) -> Error {
207     Cow::Owned(format!(
208         "Constructor `{}::{}()` cannot be static",
209         class_name.to_string(),
210         method_name.to_string(),
211     ))
213 pub const error2010: Error = Cow::Borrowed(concat!(
214     "Parameters cannot have visibility modifiers (except in ",
215     "parameter lists of constructors)."
217 pub const error2014: Error = Cow::Borrowed("An abstract method cannot have a method body.");
218 pub fn error2015(class_name: &str, method_name: &str) -> Error {
219     Cow::Owned(format!(
220         "Non-abstract method `{}::{}` must contain body",
221         class_name.to_string(),
222         method_name.to_string(),
223     ))
225 pub fn error2016(class_name: &str, method_name: &str) -> Error {
226     Cow::Owned(format!(
227         "Cannot declare abstract method `{}::{}` `private`",
228         class_name.to_string(),
229         method_name.to_string(),
230     ))
232 pub const error2018: Error =
233     Cow::Borrowed("A constructor cannot have a non-`void` type annotation.");
234 pub fn error2019(class_name: &str, method_name: &str) -> Error {
235     Cow::Owned(format!(
236         "Cannot declare abstract method `{}::{}` `final`",
237         class_name.to_string(),
238         method_name.to_string(),
239     ))
241 pub const error2020: Error = Cow::Borrowed(concat!(
242     "Use of the `{}` subscript operator is deprecated; ",
243     " use `[]` instead."
245 pub const error2021: Error = Cow::Borrowed(concat!(
246     "A variadic parameter `...` may only appear at the end of ",
247     "a parameter list."
249 pub const error2023: Error =
250     Cow::Borrowed("Abstract constructors cannot have parameters with visibility modifiers");
251 pub const error2024: Error =
252     Cow::Borrowed("Traits or interfaces cannot have parameters with visibility modifiers");
253 pub const error2022: Error =
254     Cow::Borrowed("A variadic parameter `...` may not be followed by a comma.");
255 pub fn error2025(class_name: &str, prop_name: &str) -> Error {
256     Cow::Owned(format!(
257         "Cannot redeclare `{}::{}`",
258         class_name.to_string(),
259         prop_name.to_string(),
260     ))
262 pub const error2029: Error = Cow::Borrowed("Only traits and interfaces may use `require extends`.");
263 pub const error2030: Error = Cow::Borrowed("Only traits may use `require implements`.");
264 pub const error2032: Error = Cow::Borrowed("The array type is not allowed in `strict` mode.");
265 pub const error2033: Error = Cow::Borrowed(concat!(
266     "The splat operator `...` for unpacking variadic arguments ",
267     "may only appear at the **end** of an argument list."
269 pub const error2034: Error = Cow::Borrowed(concat!(
270     "A type alias declaration cannot both use `type` and have a ",
271     "constraint. Did you mean `newtype`?"
273 pub const error2035: Error = Cow::Borrowed("Only classes may implement interfaces.");
274 pub const error2036: Error = Cow::Borrowed(concat!(
275     "Only interfaces and classes may extend other interfaces and ",
276     "classes."
278 pub const error2037: Error = Cow::Borrowed("A class may extend at most **one** other class.");
279 pub fn error2038(constructor_name: &str) -> Error {
280     Cow::Owned(format!(
281         concat!(
282             "A constructor initializing an object must be passed a (possibly empty) ",
283             "list of arguments. Did you mean `new {}()`?",
284         ),
285         constructor_name.to_string(),
286     ))
288 pub const error2040: Error = Cow::Borrowed(concat!(
289     "Invalid use of `list(...)`. A list expression may only be ",
290     "used as the left side of a simple assignment, the value clause of a ",
291     "`foreach` loop, or a list item nested inside another list expression."
293 pub const error2041: Error = Cow::Borrowed(concat!(
294     "Unexpected method body: interfaces may contain only",
295     " method signatures, and **not** method implementations."
297 pub const error2042: Error = Cow::Borrowed("Only classes may be declared `abstract`.");
298 pub fn error2046(method_type: &str) -> Error {
299     Cow::Owned(format!(
300         "`async` cannot be used on {}. Use an `Awaitable<...>` return type instead.",
301         method_type.to_string(),
302     ))
305 pub const error2048: Error = Cow::Borrowed("Expected group `use` prefix to end with `\\`");
306 pub const error2049: Error =
307     Cow::Borrowed("A namespace `use` clause may not specify the kind here.");
308 pub const error2050: Error =
309     Cow::Borrowed("A concrete constant declaration must have an initializer.");
310 pub const error2051: Error =
311     Cow::Borrowed("An abstract constant declaration must not have an initializer.");
312 pub const error2052: Error = Cow::Borrowed(concat!(
313     "Cannot mix bracketed namespace declarations with ",
314     "unbracketed namespace declarations"
316 pub const error2053: Error = Cow::Borrowed(concat!(
317     "Use of `var` as synonym for `public` in declaration disallowed in Hack. ",
318     "Use `public` instead."
320 pub const error2054: Error = Cow::Borrowed(concat!(
321     "Method declarations require a visibility modifier ",
322     "such as `public`, `private` or `protected`."
324 pub const error2055: Error = Cow::Borrowed("At least one enumerated item is expected.");
325 pub const error2056: Error = Cow::Borrowed("First unbracketed namespace occurrence here");
326 pub const error2057: Error = Cow::Borrowed("First bracketed namespace occurrence here");
327 pub const invalid_shape_field_name: Error =
328     Cow::Borrowed("Shape field name must be a nonempty single-quoted string or a class constant");
329 pub const shape_field_int_like_string: Error =
330     Cow::Borrowed("Shape field name must not be an int-like string (i.e. \"123\")");
331 pub const error2061: Error = Cow::Borrowed(concat!(
332     "Non-static instance variables are not allowed in abstract ",
333     "final classes."
335 pub const error2062: Error =
336     Cow::Borrowed("Non-static methods are not allowed in `abstract final` classes.");
337 pub const error2063: Error = Cow::Borrowed("Expected integer or string literal.");
338 pub const error2065: Error =
339     Cow::Borrowed("A variadic parameter `...` must not have a default value.");
340 // This was typing error 4077.
341 pub const error2066: Error = Cow::Borrowed(concat!(
342     "A previous parameter has a default value. Remove all the ",
343     "default values for the preceding parameters, or add a default value to ",
344     "this one."
346 pub const error2068: Error = Cow::Borrowed("`hh` blocks and `php` blocks cannot be mixed.");
347 pub const invalid_octal_integer: Error = Cow::Borrowed("Invalid octal integers");
348 pub const prefixed_invalid_string_kind: Error =
349     Cow::Borrowed("Only double-quoted strings may be prefixed.");
350 pub const illegal_interpolated_brace_with_embedded_dollar_expression: Error =
351     Cow::Borrowed(concat!(
352         "The only legal expressions inside a `{$...}`-expression embedded in a string are ",
353         "variables, function calls, subscript expressions, and member access expressions"
354     ));
355 pub const expected_dotdotdot: Error = Cow::Borrowed("`...` is expected here.");
356 pub const invalid_foreach_element: Error = Cow::Borrowed(
357     "An arrow `=>` or right parenthesis `)` \
358      is expected here.",
360 pub const inline_function_def: Error =
361     Cow::Borrowed("Inline function definitions are not supported in Hack");
362 pub const decl_outside_global_scope: Error =
363     Cow::Borrowed("Declarations are not supported outside global scope");
364 pub const type_keyword: Error = Cow::Borrowed("The `type` keyword is expected here.");
365 pub const expected_simple_offset_expression: Error =
366     Cow::Borrowed("A simple offset expression is expected here");
367 pub const expected_user_attribute: Error = Cow::Borrowed("A user attribute is expected here.");
368 pub const expected_as_or_insteadof: Error =
369     Cow::Borrowed("The `as` keyword or the `insteadof` keyword is expected here.");
370 pub const missing_double_quote: Error = /* error0010 analogue */
371     Cow::Borrowed("A double quote is expected here.");
372 pub const instanceof_disabled: Error = Cow::Borrowed(
373     "The `instanceof` operator is not supported in Hack; use the `is` operator or `is_a()`",
375 pub const abstract_instance_property: Error =
376     Cow::Borrowed("Instance property may not be abstract.");
377 pub const memoize_lsb_on_non_static: Error =
378     Cow::Borrowed("`<<__MemoizeLSB>>` can only be applied to static methods");
379 pub const memoize_lsb_on_non_method: Error =
380     Cow::Borrowed("`<<__MemoizeLSB>>` can only be applied to methods");
381 pub const expression_as_attribute_arguments: Error =
382     Cow::Borrowed("Attribute arguments must be literals");
383 pub const instanceof_invalid_scope_resolution: Error = Cow::Borrowed(concat!(
384     "A scope resolution `::` on the right side of an ",
385     "`instanceof` operator must start with a class name, `self`, `parent`, or `static`, and end with ",
386     "a variable",
388 pub const instanceof_memberselection_inside_scoperesolution: Error = Cow::Borrowed(concat!(
389     "A scope resolution `::` on the right ",
390     "side of an instanceof operator cannot contain a member selection `->`",
392 pub const instanceof_missing_subscript_index: Error = Cow::Borrowed(concat!(
393     "A subscript expression `[]` on the right side of an ",
394     "instanceof operator must have an index",
396 pub fn instanceof_new_unknown_node(msg: &str) -> Error {
397     Cow::Owned(format!(
398         "Unexpected node on right hand side of `new` or `instanceof`: `{}`",
399         msg.to_string(),
400     ))
402 pub const invalid_await_use: Error = Cow::Borrowed("`await` cannot be used as an expression");
403 pub const toplevel_await_use: Error =
404     Cow::Borrowed("`await` cannot be used in a toplevel statement");
405 pub const invalid_constructor_method_call: Error = Cow::Borrowed(
406     "Method call following immediate constructor call requires parentheses around constructor call.",
408 pub const invalid_scope_resolution_qualifier: Error =
409     Cow::Borrowed("Only classnames and variables are allowed before `::`.");
410 pub const invalid_variable_name: Error = Cow::Borrowed(
411     "A valid variable name starts with a letter or underscore, followed by any number of letters, numbers, or underscores",
413 pub const invalid_yield: Error =
414     Cow::Borrowed("`yield` can only appear as a statement or on the right of an assignment");
415 pub const invalid_class_in_collection_initializer: Error =
416     Cow::Borrowed("Cannot use collection initialization for non-collection class.");
417 pub const invalid_brace_kind_in_collection_initializer: Error = Cow::Borrowed(
418     "Initializers of `vec`, `dict` and `keyset` should use `[...]` instead of `{...}`.",
420 pub fn invalid_value_initializer(name: &str) -> Error {
421     Cow::Owned(format!(
422         "Cannot use value initializer for `{}`. It requires `key => value`.",
423         name.to_string(),
424     ))
426 pub fn invalid_key_value_initializer(name: &str) -> Error {
427     Cow::Owned(format!(
428         "Cannot use key value initializer for `{}`. It does not allow keys.",
429         name.to_string(),
430     ))
432 pub const nested_ternary: Error = Cow::Borrowed(
433     "Nested ternary expressions inside ternary expressions are ambiguous. Please add parentheses",
435 pub const alternate_control_flow: Error =
436     Cow::Borrowed("Alternate control flow syntax is not allowed in Hack files");
437 pub const execution_operator: Error =
438     Cow::Borrowed("The execution operator is not allowed in Hack files");
439 pub const non_re_prefix: Error = Cow::Borrowed("Only `re`-prefixed strings allowed.");
440 pub const collection_intrinsic_generic: Error =
441     Cow::Borrowed("Cannot initialize collection builtins with type parameters");
442 pub const collection_intrinsic_many_typeargs: Error =
443     Cow::Borrowed("Collection expression must have less than three type arguments");
444 pub const invalid_hack_mode: Error =
445     Cow::Borrowed("Incorrect comment; possible values include `strict`, `partial`, or empty");
446 pub const pair_initializer_needed: Error = Cow::Borrowed("Initializer needed for Pair object");
447 pub const pair_initializer_arity: Error =
448     Cow::Borrowed("Pair objects must have exactly 2 elements");
449 pub const toplevel_statements: Error =
450     Cow::Borrowed("Toplevel statements are not allowed. Use `__EntryPoint` attribute instead");
451 pub const invalid_reified: Error =
452     Cow::Borrowed("`reify` keyword can only appear at function or class type parameter position");
453 pub fn reified_in_invalid_classish(s: &str) -> Error {
454     Cow::Owned(format!(
455         "Invalid to use a reified type within {}'s type parameters",
456         s.to_string(),
457     ))
459 pub const shadowing_reified: Error = Cow::Borrowed("You may not shadow a reified parameter");
460 pub const static_property_in_reified_class: Error =
461     Cow::Borrowed("You may not use static properties in a class with reified type parameters");
462 pub const cls_reified_generic_in_static_method: Error =
463     Cow::Borrowed("You may not use reified generics of the class in a static method");
464 pub const static_method_reified_obj_creation: Error = Cow::Borrowed(
465     "You may not use object creation for potentially reified `self` or `parent` from a static method",
467 pub const non_invariant_reified_generic: Error =
468     Cow::Borrowed("Reified generics cannot be covariant or contravariant");
469 pub const no_generics_on_constructors: Error = Cow::Borrowed(
470     "Generic type parameters are not allowed on constructors. Consider adding a type parameter to the class",
472 pub const no_type_parameters_on_dynamic_method_calls: Error =
473     Cow::Borrowed("Generics type parameters are disallowed on dynamic method calls");
474 pub const dollar_unary: Error =
475     Cow::Borrowed("The dollar sign `$` cannot be used as a unary operator");
476 pub const type_alias_to_type_constant: Error =
477     Cow::Borrowed("Type aliases to type constants are not supported");
478 pub const interface_with_memoize: Error =
479     Cow::Borrowed("`__Memoize` is not allowed on interface methods");
480 pub const multiple_reactivity_annotations: Error = Cow::Borrowed(concat!(
481     "Only one of following annotations is allowed: `__Pure`, `__Rx`, ",
482     "`__RxShallow`, `__RxLocal`, `__NonRx`, `__Cipp`, `__CippLocal`, `__CippGlobal`.",
484 pub const functions_cannot_implement_reactive: Error =
485     Cow::Borrowed("`__OnlyRxIfImpl` annotations are only valid on class methods.");
486 pub const missing_reactivity_for_condition: Error = Cow::Borrowed(concat!(
487     "`__OnlyRxIfImpl` and `__AtMostRxAsArgs` annotations cannot ",
488     "be used without `__Pure`, `__Rx`, `__RxShallow`, or `__RxLocal`.",
490 pub const conflicting_mutable_and_owned_mutable_attributes: Error =
491     Cow::Borrowed("Parameter cannot have both `__Mutable` and `__OwnedMutable` annotations.");
492 pub const conflicting_mutable_and_maybe_mutable_attributes: Error =
493     Cow::Borrowed("Parameter cannot have both `__Mutable` and `__MaybeMutable` annotations.");
494 pub const conflicting_owned_mutable_and_maybe_mutable_attributes: Error =
495     Cow::Borrowed("Parameter cannot have both `__OwnedMutable` and `__MaybeMutable` annotations.");
496 pub const mutably_owned_attribute_on_non_rx_function: Error =
497     Cow::Borrowed("`__OwnedMutable` annotated parameters are only allowed in reactive functions.");
498 pub const invalid_non_rx_argument_for_lambda: Error = Cow::Borrowed(concat!(
499     "Invalid argument list for `__NonRx` attribute that is placed on anonymous function. ",
500     "Argument list for `__NonRx` attribute that is used in this position should be empty.",
502 pub const invalid_non_rx_argument_for_declaration: Error = Cow::Borrowed(concat!(
503     "Invalid argument list for `__NonRx` attribute that is placed on a declaration of function or method. ",
504     "Argument list for `__NonRx` attribute that is used in this position should contain only one string literal value.",
506 pub const nested_concurrent_blocks: Error = Cow::Borrowed("`concurrent` blocks cannot be nested.");
507 pub const fewer_than_two_statements_in_concurrent_block: Error = Cow::Borrowed(concat!(
508     "Expected 2 or more statements in concurrent block. `concurrent` wrapping ",
509     "nothing or a single statement is not useful or already implied.",
511 pub const invalid_syntax_concurrent_block: Error = Cow::Borrowed(concat!(
512     "`concurrent` block must contain a compound statement of two or ",
513     "more expression statements, IE concurrent `{ <expr>; <expr>; }`.",
515 pub const statement_without_await_in_concurrent_block: Error =
516     Cow::Borrowed("Statement without an `await` in a concurrent block");
517 pub const concurrent_is_disabled: Error = Cow::Borrowed("`concurrent` is disabled");
518 pub const static_closures_are_disabled: Error =
519     Cow::Borrowed("Static closures are not supported in Hack");
520 pub const invalid_await_position: Error = Cow::Borrowed(concat!(
521     "`await` cannot be used as an expression in this ",
522     "location because it's conditionally executed.",
524 pub const invalid_await_position_dependent: Error = Cow::Borrowed(concat!(
525     "`await` cannot be used as an expression inside another await expression. ",
526     "Pull the inner `await` out into its own statement.",
528 pub const mutability_annotation_on_constructor: Error = Cow::Borrowed(
529     "`__Mutable`, `__MaybeMutable`, and `__MutableReturn` annotations are not allowed on constructors.",
531 pub const mutability_annotation_on_static_method: Error = Cow::Borrowed(
532     "`__Mutable` and `__MaybeMutable` annotations are not allowed on static methods.",
534 pub const mutability_annotation_on_inout_parameter: Error = Cow::Borrowed(
535     "`__Mutable`, `__MaybeMutable` and `__OwnedMutable` annotations are not allowed on inout parameters.",
537 pub fn mutable_parameter_in_memoize_function(is_this: bool) -> Error {
538     Cow::Owned(format!(
539         "Memoized functions cannot have mutable {}",
540         if is_this { "`$this`." } else { "parameters." }.to_string()
541     ))
543 pub const mutable_return_in_memoize_function: Error =
544     Cow::Borrowed("Memoized functions cannot return mutable objects.");
545 pub const tparams_in_tconst: Error =
546     Cow::Borrowed("Type parameters are not allowed on class type constants");
547 pub const targs_not_allowed: Error =
548     Cow::Borrowed("Type arguments are not allowed in this position");
549 pub const reified_attribute: Error = Cow::Borrowed(
550     "`__Reified` and `__HasReifiedParent` attributes may not be provided by the user",
552 pub const lval_as_expression: Error = Cow::Borrowed(
553     "Assignments can no longer be used as expressions. Pull the assignment out into a separate statement.",
555 pub fn elt_abstract_private(elt: &str) -> Error {
556     Cow::Owned(format!(
557         "Cannot declare abstract {} `private`.",
558         elt.to_string(),
559     ))
561 pub const only_soft_allowed: Error = Cow::Borrowed("Only the `__Soft` attribute is allowed here.");
562 pub const soft_no_arguments: Error =
563     Cow::Borrowed("The `__Soft` attribute does not take arguments.");
564 pub const no_legacy_soft_typehints: Error = Cow::Borrowed(
565     "The `@` syntax for soft typehints is not allowed. Use the `__Soft` attribute instead.",
567 pub const outside_dollar_str_interp: Error =
568     Cow::Borrowed("The `${x}` syntax is disallowed in Hack. Use `{$x}` instead.");
569 pub const no_const_interfaces_traits_enums: Error =
570     Cow::Borrowed("Interfaces, traits and enums may not be declared `__Const`");
571 pub const no_const_late_init_props: Error =
572     Cow::Borrowed("`__Const` properties may not also be `__LateInit`");
573 pub const no_const_static_props: Error = Cow::Borrowed("Static properties may not be `__Const`");
574 pub const no_const_abstract_final_class: Error =
575     Cow::Borrowed("Cannot apply `__Const` attribute to an abstract final class");
576 pub const no_legacy_attribute_syntax: Error = Cow::Borrowed(
577     "The `<<...>>` syntax for user attributes is not allowed. Use the `@` syntax instead.",
579 pub const no_silence: Error = Cow::Borrowed("The error suppression operator `@` is not allowed");
580 pub const const_mutation: Error = Cow::Borrowed("Cannot mutate a class constant");
581 pub const no_attributes_on_variadic_parameter: Error =
582     Cow::Borrowed("Attributes on variadic parameters are not allowed");
583 pub const invalid_constant_initializer: Error =
584     Cow::Borrowed("Invalid expression in constant initializer");
585 pub const parent_static_prop_decl: Error =
586     Cow::Borrowed("Cannot use `static` or `parent::class` in property declaration");
587 pub fn error2070(open_tag: &str, close_tag: &str) -> Error {
588     Cow::Owned(format!(
589         "XHP: mismatched tag: `{}` not the same as `{}`",
590         close_tag.to_string(),
591         open_tag.to_string(),
592     ))
594 pub fn error2071(s: &str) -> Error {
595     Cow::Owned(format!("Decimal number is too big: `{}`", s.to_string(),))
597 pub fn error2072(s: &str) -> Error {
598     Cow::Owned(format!(
599         "Hexadecimal number is too big: `{}`",
600         s.to_string(),
601     ))
603 pub const error2073: Error = Cow::Borrowed(concat!(
604     "A variadic parameter `...` cannot have a modifier ",
605     "that changes the calling convention, like `inout`.",
607 pub fn error2074(call_modifier: &str) -> Error {
608     Cow::Owned(format!(
609         "An `{}` parameter must not have a default value.",
610         call_modifier.to_string(),
611     ))
613 pub const error2077: Error = Cow::Borrowed("Cannot use empty list");
614 pub fn not_allowed_in_write(what: &str) -> Error {
615     Cow::Owned(format!(
616         "{} is not allowed in write context",
617         what.to_string(),
618     ))
620 pub const reassign_this: Error = Cow::Borrowed("Cannot re-assign `$this`");
621 pub const enum_elem_name_is_class: Error = Cow::Borrowed("Enum element cannot be named `class`");
622 pub const sealed_enum: Error = Cow::Borrowed("Enums cannot be sealed.");
623 pub const property_requires_visibility: Error = Cow::Borrowed(concat!(
624     "Property declarations require a visibility modifier ",
625     "such as `public`, `private` or `protected`.",
627 pub const abstract_prop_init: Error =
628     Cow::Borrowed("An `abstract` property must not have an initializer.");
629 pub const const_static_prop_init: Error =
630     Cow::Borrowed("A `const static` property must have an initializer.");
631 pub fn namespace_name_is_already_in_use(name: &str, short_name: &str) -> Error {
632     Cow::Owned(format!(
633         "Cannot use namespace `{}` as `{}` because the name is already in use",
634         name.to_string(),
635         short_name.to_string()
636     ))
638 pub const strict_namespace_hh: Error = Cow::Borrowed(concat!(
639     "To use strict Hack, place `// strict` after the open tag. ",
640     "If it's already there, remove this line. ",
641     "Hack is strict already.",
643 pub fn name_is_already_in_use_hh(line_num: isize, name: &str, short_name: &str) -> Error {
644     Cow::Owned(format!(
645         "Cannot use `{}` as `{}` because the name was explicitly used earlier via a `use` statement on line {}",
646         name.to_string(),
647         short_name.to_string(),
648         line_num.to_string(),
649     ))
651 pub fn name_is_already_in_use_implicit_hh(line_num: isize, name: &str, short_name: &str) -> Error {
652     Cow::Owned(format!(
653         concat!(
654             "Cannot use `{}` as `{}` because the name was implicitly used on line {}",
655             "; implicit use of names from the HH namespace can be suppressed by adding an explicit",
656             " `use` statement earlier in the current namespace block",
657         ),
658         name.to_string(),
659         short_name.to_string(),
660         line_num.to_string(),
661     ))
663 pub fn name_is_already_in_use_php(name: &str, short_name: &str) -> Error {
664     Cow::Owned(format!(
665         "Cannot use `{}` as `{}` because the name is already in use",
666         name.to_string(),
667         short_name.to_string(),
668     ))
670 pub const original_definition: Error = Cow::Borrowed("Original definition");
671 pub fn function_name_is_already_in_use(name: &str, short_name: &str) -> Error {
672     Cow::Owned(format!(
673         "Cannot use function `{}` as `{}` because the name is already in use",
674         name.to_string(),
675         short_name.to_string(),
676     ))
678 pub fn const_name_is_already_in_use(name: &str, short_name: &str) -> Error {
679     Cow::Owned(format!(
680         "Cannot use const `{}` as `{}` because the name is already in use",
681         name.to_string(),
682         short_name.to_string(),
683     ))
685 pub fn type_name_is_already_in_use(name: &str, short_name: &str) -> Error {
686     Cow::Owned(format!(
687         "Cannot use type `{}` as `{}` because the name is already in use",
688         name.to_string(),
689         short_name.to_string(),
690     ))
692 pub const namespace_decl_first_statement: Error = Cow::Borrowed(
693     "Namespace declaration statement has to be the very first statement in the script",
695 pub const code_outside_namespace: Error =
696     Cow::Borrowed("No code may exist outside of namespace {}");
697 pub const global_in_const_decl: Error =
698     Cow::Borrowed("Cannot have globals in constant declaration");
699 pub const parent_static_const_decl: Error =
700     Cow::Borrowed("Cannot use `static` or `parent::class` in constant declaration");
701 pub const no_async_before_lambda_body: Error =
702     Cow::Borrowed("Don't use `() ==> async { ... }`. Instead, use: `async () ==> { ... }`");
703 pub fn invalid_number_of_args(name: &str, n: usize) -> Error {
704     Cow::Owned(format!(
705         "Method `{}` must take exactly {} arguments",
706         name.to_string(),
707         n.to_string(),
708     ))
710 pub fn invalid_inout_args(name: &str) -> Error {
711     Cow::Owned(format!(
712         "Method `{}` cannot take inout arguments",
713         name.to_string(),
714     ))
716 pub fn redeclaration_error(name: &str) -> Error {
717     Cow::Owned(format!("Cannot redeclare `{}`", name.to_string(),))
719 pub fn declared_name_is_already_in_use_implicit_hh(
720     line_num: usize,
721     name: &str,
722     _short_name: &str,
723 ) -> Error {
724     Cow::Owned(format!(
725         concat!(
726             "Cannot declare `{}` because the name was implicitly used on line {}; ",
727             "implicit use of names from the HH namespace can be suppressed by adding an explicit ",
728             "`use` statement earlier in the current namespace block",
729         ),
730         name.to_string(),
731         line_num.to_string(),
732     ))
734 pub fn declared_name_is_already_in_use(line_num: usize, name: &str, _short_name: &str) -> Error {
735     Cow::Owned(format!(
736         concat!(
737             "Cannot declare `{}` because the name was explicitly used earlier via a `use` ",
738             "statement on line {}",
739         ),
740         name.to_string(),
741         line_num.to_string(),
742     ))
744 pub const const_in_trait: Error = Cow::Borrowed("Traits cannot have constants");
745 pub const sealed_val_not_classname: Error =
746     Cow::Borrowed("Values in sealed whitelist must be classname constants.");
747 pub const sealed_qualifier_invalid: Error =
748     Cow::Borrowed("`__Sealed` can only be used with named types, e.g. `Foo::class`");
749 pub const list_must_be_lvar: Error =
750     Cow::Borrowed("`list()` can only be used as an lvar. Did you mean to use `tuple()`?");
751 pub const async_not_last: Error =
752     Cow::Borrowed("The `async` modifier must be directly before the `function` keyword.");
753 pub const using_st_function_scoped_top_level: Error = Cow::Borrowed(concat!(
754     "Using statement in function scoped form may only be used at the top ",
755     "level of a function or a method",
757 pub const double_variadic: Error = Cow::Borrowed("Parameter redundantly marked as variadic `...`.");
758 pub fn conflicting_trait_require_clauses(name: &str) -> Error {
759     Cow::Owned(format!(
760         "Conflicting requirements for `{}`",
761         name.to_string(),
762     ))
764 pub const shape_type_ellipsis_without_trailing_comma: Error =
765     Cow::Borrowed("A comma is required before the `...` in a shape type");
766 pub const yield_in_magic_methods: Error =
767     Cow::Borrowed("`yield` is not allowed in constructors or magic methods");
768 pub const yield_outside_function: Error =
769     Cow::Borrowed("`yield` can only be used inside a function");
770 pub const coloncolonclass_on_dynamic: Error =
771     Cow::Borrowed("Dynamic class names are not allowed in compile-time `::class` fetch");
772 pub const this_in_static: Error =
773     Cow::Borrowed("Don't use `$this` in a static method, use `static::` instead");
774 pub fn async_magic_method(name: &str) -> Error {
775     Cow::Owned(format!(
776         "Cannot declare constructors and magic methods like `{}` as `async`",
777         name.to_string(),
778     ))
780 pub fn unsupported_magic_method(name: &str) -> Error {
781     Cow::Owned(format!(
782         "Magic `{}` methods are no longer supported",
783         name.to_string(),
784     ))
786 pub fn reserved_keyword_as_class_name(class_name: &str) -> Error {
787     Cow::Owned(format!(
788         "Cannot use `{}` as class name as it is reserved",
789         class_name.to_string(),
790     ))
792 pub const xhp_class_multiple_category_decls: Error =
793     Cow::Borrowed("An XHP class cannot have multiple category declarations");
794 pub const xhp_class_multiple_children_decls: Error =
795     Cow::Borrowed("An XHP class cannot have multiple children declarations");
796 pub const inout_param_in_generator: Error =
797     Cow::Borrowed("Parameters may not be marked `inout` on generators");
798 pub const inout_param_in_async_generator: Error =
799     Cow::Borrowed("Parameters may not be marked `inout` on `async` generators");
800 pub const inout_param_in_async: Error =
801     Cow::Borrowed("Parameters may not be marked `inout` on `async` functions");
802 pub const inout_param_in_construct: Error =
803     Cow::Borrowed("Parameters may not be marked `inout` on constructors");
804 pub const fun_arg_inout_set: Error =
805     Cow::Borrowed("You cannot set an `inout` decorated argument while calling a function");
806 pub const fun_arg_inout_const: Error = Cow::Borrowed("You cannot decorate a constant as `inout`");
807 pub const fun_arg_invalid_arg: Error =
808     Cow::Borrowed("You cannot decorate this argument as `inout`");
809 pub const fun_arg_inout_containers: Error = Cow::Borrowed(concat!(
810     "Parameters marked `inout` must be contained in locals, vecs, dicts, keysets,",
811     " and arrays",
813 pub const memoize_with_inout: Error =
814     Cow::Borrowed("`<<__Memoize>>` cannot be used on functions with `inout` parameters");
815 pub const method_calls_on_xhp_attributes: Error =
816     Cow::Borrowed("Method calls are not allowed on XHP attributes");
817 pub const method_calls_on_xhp_expression: Error =
818     Cow::Borrowed("Please add parentheses around the XHP component");
819 pub fn class_with_abstract_method(name: &str) -> Error {
820     Cow::Owned(format!(
821         concat!(
822             "Class `{}` contains an abstract method and must ",
823             "therefore be declared `abstract`",
824         ),
825         name.to_string(),
826     ))
828 pub const interface_has_private_method: Error =
829     Cow::Borrowed("Interface methods must be `public` or `protected`");
830 pub fn redeclaration_of_function(name: &str, loc: &str) -> Error {
831     Cow::Owned(format!(
832         "Cannot redeclare `{}()` (previously declared in {})",
833         name.to_string(),
834         loc.to_string()
835     ))
837 pub fn redeclaration_of_method(name: &str) -> Error {
838     Cow::Owned(format!("Redeclared method `{}`", name.to_string(),))
840 pub fn self_or_parent_colon_colon_class_outside_of_class(name: &str) -> Error {
841     Cow::Owned(format!(
842         "Cannot access `{}::class` when no class scope is active",
843         name.to_string(),
844     ))
846 pub fn invalid_is_as_expression_hint(n: &str, hint: &str) -> Error {
847     Cow::Owned(format!(
848         "`{}` typehints cannot be used with `{}` expressions",
849         hint.to_string(),
850         n.to_string(),
851     ))
853 pub const elvis_operator_space: Error = Cow::Borrowed("An Elvis operator `?:` is expected here.");
854 pub fn clone_takes_no_arguments(class_name: &str, method_name: &str) -> Error {
855     Cow::Owned(format!(
856         "Method `{}::{}` cannot accept any arguments",
857         class_name.to_string(),
858         method_name.to_string(),
859     ))
861 pub fn clone_cannot_be_static(class_name: &str, method_name: &str) -> Error {
862     Cow::Owned(format!(
863         "Clone method `{}::{}()` cannot be static",
864         class_name.to_string(),
865         method_name.to_string(),
866     ))
868 pub const namespace_not_a_classname: Error =
869     Cow::Borrowed("Namespace cannot be used as a classname");
870 pub const for_with_as_expression: Error =
871     Cow::Borrowed("For loops can not use `as` expressions. Did you mean `foreach`?");
872 pub const sealed_final: Error = Cow::Borrowed("Classes cannot be both `final` and `sealed`.");
873 pub const interface_implements: Error =
874     Cow::Borrowed("Interfaces may not implement other interfaces or classes");
875 pub const memoize_on_lambda: Error =
876     Cow::Borrowed("`<<__Memoize>>` attribute is not allowed on lambdas or anonymous functions.");
877 pub fn declared_final(elt: &str) -> Error {
878     Cow::Owned(format!("{} cannot be declared `final`.", elt.to_string(),))
880 pub fn invalid_xhp_classish(elt: &str) -> Error {
881     Cow::Owned(format!("{} are not valid xhp classes.", elt.to_string(),))
883 pub const empty_method_name: Error = Cow::Borrowed("Expected a method name");
884 pub fn lowering_parsing_error(text: &str, syntax: &str) -> Error {
885     Cow::Owned(format!(
886         "Encountered unexpected text `{}`, was expecting a {}.",
887         text.to_string(),
888         syntax.to_string(),
889     ))
891 pub const xhp_class_attribute_type_constant: Error =
892     Cow::Borrowed("Type constants are not allowed on xhp class attributes");
893 pub const globals_disallowed: Error =
894     Cow::Borrowed("`$GLOBALS` variable is removed from the language. Use HH\\global functions");
895 pub const invalid_this: Error =
896     Cow::Borrowed("`$this` cannot be used in functions and static methods");
897 pub const cannot_unset_this: Error = Cow::Borrowed("`$this` cannot be unset");
898 pub const invalid_await_position_pipe: Error =
899     Cow::Borrowed("`await` cannot be used as an expression right of a pipe operator.");
900 pub fn invalid_modifier_for_declaration(decl: &str, modifier: &str) -> Error {
901     Cow::Owned(format!(
902         "{} cannot be declared `{}`",
903         decl.to_string(),
904         modifier.to_string(),
905     ))
907 pub fn duplicate_modifiers_for_declaration(decl: &str) -> Error {
908     Cow::Owned(format!(
909         "{} cannot have duplicate modifiers",
910         decl.to_string(),
911     ))
913 pub fn multiple_visibility_modifiers_for_declaration(decl: &str) -> Error {
914     Cow::Owned(format!(
915         "{} cannot have multiple visibility modifiers",
916         decl.to_string(),
917     ))
919 pub const break_continue_n_not_supported: Error =
920     Cow::Borrowed("`break`/`continue N` operators are not supported.");
921 pub fn invalid_typehint_alias(alias: &str, hint: &str) -> Error {
922     Cow::Owned(format!(
923         "Invalid type hint `{}`. Use `{}` instead",
924         alias.to_string(),
925         hint.to_string(),
926     ))
929 pub const function_pointer_bad_recv: Error = Cow::Borrowed(concat!(
930     "Function pointers `<>` can only be created with toplevel functions and explicitly named static methods. ",
931     "Use lambdas `(...) ==> {...}` for other cases."
934 pub const local_variable_with_type: Error =
935     Cow::Borrowed("Local variables cannot have type annotations in Hack.");
937 pub const empty_expression_illegal: Error =
938     Cow::Borrowed("The `empty()` expression has been removed from Hack.");
940 pub const empty_switch_cases: Error =
941     Cow::Borrowed("`switch` statements need to have at least one `case` or a `default` block");
943 pub const preceding_backslash: Error = Cow::Borrowed("Unnecessary preceding backslash");
945 pub fn multiple_entrypoints(loc: &str) -> Error {
946     Cow::Owned(format!(
947         "Only one `__EntryPoint` annotation is permitted per file (previous `__EntryPoint` annotation in {})",
948         loc.to_string()
949     ))
952 pub fn cannot_use_feature(feature: &str) -> Error {
953     Cow::Owned(format!(
954         "Cannot use unstable feature: `{}`",
955         feature.to_string()
956     ))
959 pub fn invalid_use_of_enable_unstable_feature(message: &str) -> Error {
960     Cow::Owned(format!(
961         "This is an invalid use of `__EnableUnstableFeatures` because {}",
962         message.to_string()
963     ))
966 pub const splice_outside_et: Error =
967     Cow::Borrowed("Splicing can only occur inside expression tree literals (between backticks)");
969 pub const invalid_enum_class_enumerator: Error = Cow::Borrowed("Invalid enum class constant");
971 pub const fun_disabled: Error =
972     Cow::Borrowed("`fun()` is disabled; switch to first-class references like `foo<>`");
974 pub const class_meth_disabled: Error =
975     Cow::Borrowed("`class_meth()` is disabled; switch to first-class references like `C::bar<>`");
977 pub fn ctx_var_invalid_parameter(param_name: &str) -> Error {
978     Cow::Owned(format!(
979         "Could not find parameter {} for dependent context",
980         param_name.to_string()
981     ))
984 pub fn ctx_var_missing_type_hint(param_name: &str) -> Error {
985     Cow::Owned(format!(
986         "Parameter {} used for dependent context must have a type hint",
987         param_name.to_string()
988     ))
991 pub fn ctx_var_invalid_type_hint(param_name: &str) -> Error {
992     Cow::Owned(format!(
993         "Type hint for parameter {} used for dependent context must be a class or a generic",
994         param_name.to_string()
995     ))