Remove hackc support for (unset) cast
[hiphop-php.git] / hphp / hack / src / naming / naming_special_names.rs
blobc75f263d13d4e2766c159f54c5e1333700602184
1 /*
2  * Copyright (c) 2015, 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  *
8  */
10 /** Module consisting of the special names known to the typechecker */
12 pub mod classes {
14     pub const PARENT: &str = "parent";
16     pub const STATIC: &str = "static";
18     pub const SELF: &str = "self";
20     pub const UNKNOWN: &str = "\\*Unknown*";
22     /* Used for dynamic classnames, e.g. new $foo(); */
24     pub const AWAITABLE: &str = "\\HH\\Awaitable";
26     pub const GENERATOR: &str = "\\Generator";
28     pub const ASYNC_GENERATOR: &str = "\\HH\\AsyncGenerator";
30     pub const FORMAT_STRING: &str = "\\FormatString";
32     pub const HH_FORMAT_STRING: &str = "\\HH\\FormatString";
34     pub fn is_format_string(x: &str) -> bool {
35         match x {
36             FORMAT_STRING | HH_FORMAT_STRING => true,
37             _ => false,
38         }
39     }
41     pub const HH_BUILTIN_ENUM: &str = "\\HH\\BuiltinEnum";
43     pub const THROWABLE: &str = "\\Throwable";
45     pub const STD_CLASS: &str = "\\stdClass";
47     pub const DATE_TIME: &str = "\\DateTime";
49     pub const DATE_TIME_IMMUTABLE: &str = "\\DateTimeImmutable";
51     pub const ASYNC_ITERATOR: &str = "\\HH\\AsyncIterator";
53     pub const ASYNC_KEYED_ITERATOR: &str = "\\HH\\AsyncKeyedIterator";
55     pub const STRINGISH: &str = "\\Stringish";
57     pub const XHP_CHILD: &str = "\\XHPChild";
59     pub const IMEMOIZE_PARAM: &str = "\\HH\\IMemoizeParam";
61     pub const CLASS_NAME: &str = "\\HH\\classname";
63     pub const TYPE_NAME: &str = "\\HH\\typename";
65     pub const IDISPOSABLE: &str = "\\IDisposable";
67     pub const IASYNC_DISPOSABLE: &str = "\\IAsyncDisposable";
70 pub mod collections {
71     /* concrete classes */
72     pub const VECTOR: &str = "\\HH\\Vector";
74     pub const IMM_VECTOR: &str = "\\HH\\ImmVector";
76     pub const SET: &str = "\\HH\\Set";
78     pub const IMM_SET: &str = "\\HH\\ImmSet";
80     pub const MAP: &str = "\\HH\\Map";
82     pub const IMM_MAP: &str = "\\HH\\ImmMap";
84     pub const PAIR: &str = "\\HH\\Pair";
86     /* interfaces */
87     pub const CONTAINER: &str = "\\HH\\Container";
89     pub const KEYED_CONTAINER: &str = "\\HH\\KeyedContainer";
91     pub const TRAVERSABLE: &str = "\\HH\\Traversable";
93     pub const KEYED_TRAVERSABLE: &str = "\\HH\\KeyedTraversable";
95     pub const COLLECTION: &str = "\\Collection";
97     pub const CONST_VECTOR: &str = "\\ConstVector";
99     pub const CONST_MAP: &str = "\\ConstMap";
101     pub const CONST_COLLECTION: &str = "\\ConstCollection";
103     pub const DICT: &str = "\\HH\\dict";
105     pub const VEC: &str = "\\HH\\vec";
107     pub const KEYSET: &str = "\\HH\\keyset";
110 pub mod members {
112     use lazy_static::lazy_static;
113     use std::collections::HashSet;
115     pub const M_CLASS: &str = "class";
117     pub const __CONSTRUCT: &str = "__construct";
119     pub const __DESTRUCT: &str = "__destruct";
121     pub const __CALL: &str = "__call";
123     pub const __CALL_STATIC: &str = "__callStatic";
125     pub const __CLONE: &str = "__clone";
127     pub const __DEBUG_INFO: &str = "__debugInfo";
129     pub const __DISPOSE: &str = "__dispose";
131     pub const __DISPOSE_ASYNC: &str = "__disposeAsync";
133     pub const __GET: &str = "__get";
135     pub const __INVOKE: &str = "__invoke";
137     pub const __ISSET: &str = "__isset";
139     pub const __SET: &str = "__set";
141     pub const __SET_STATE: &str = "__set_state";
143     pub const __SLEEP: &str = "__sleep";
145     pub const __TO_STRING: &str = "__toString";
147     pub const __UNSET: &str = "__unset";
149     pub const __WAKEUP: &str = "__wakeup";
151     lazy_static! {
152         static ref AS_SET: HashSet<&'static str> = vec![
153             __CONSTRUCT,
154             __DESTRUCT,
155             __CALL,
156             __CALL_STATIC,
157             __CLONE,
158             __DEBUG_INFO,
159             __DISPOSE,
160             __DISPOSE_ASYNC,
161             __GET,
162             __INVOKE,
163             __ISSET,
164             __SET,
165             __SET_STATE,
166             __SLEEP,
167             __TO_STRING,
168             __UNSET,
169             __WAKEUP
170         ]
171         .iter()
172         .cloned()
173         .collect();
174         pub static ref AS_LOWERCASE_SET: HashSet<String> = {
175             AS_SET
176                 .iter()
177                 .fold(HashSet::<String>::new(), |mut set, special_name| {
178                     set.insert(special_name.to_ascii_lowercase());
179                     set
180                 })
181         };
182     }
184     /* Any data- or aria- attribute is always valid, even if it is not declared
185      * for a given XHP element */
186     pub fn is_special_xhp_attribute(s: &str) -> bool {
187         s.len() >= 6
188             && match &s[..6] {
189                 ":data-" | ":aria-" => true,
190                 _ => false,
191             }
192     }
195 pub mod user_attributes {
197     use lazy_static::lazy_static;
198     use std::collections::HashSet;
200     pub const OVERRIDE: &str = "__Override";
202     pub const CONSISTENT_CONSTRUCT: &str = "__ConsistentConstruct";
204     pub const CONST: &str = "__Const";
206     pub const DEPRECATED: &str = "__Deprecated";
208     pub const ENTRY_POINT: &str = "__EntryPoint";
210     pub const MEMOIZE: &str = "__Memoize";
212     pub const MEMOIZE_LSB: &str = "__MemoizeLSB";
214     pub const PHP_STD_LIB: &str = "__PHPStdLib";
216     pub const HIPHOP_SPECIFIC: &str = "__HipHopSpecific";
218     pub const ACCEPT_DISPOSABLE: &str = "__AcceptDisposable";
220     pub const RETURN_DISPOSABLE: &str = "__ReturnDisposable";
222     pub const REACTIVE: &str = "__Rx";
224     pub const LOCAL_REACTIVE: &str = "__RxLocal";
226     pub const SHALLOW_REACTIVE: &str = "__RxShallow";
228     pub const MUTABLE: &str = "__Mutable";
230     pub const MUTABLE_RETURN: &str = "__MutableReturn";
232     pub const ONLY_RX_IF_IMPL: &str = "__OnlyRxIfImpl";
234     pub const PROBABILISTIC_MODEL: &str = "__PPL";
236     pub const LSB: &str = "__LSB";
238     pub const AT_MOST_RX_AS_FUNC: &str = "__AtMostRxAsFunc";
240     pub const AT_MOST_RX_AS_ARGS: &str = "__AtMostRxAsArgs";
242     pub const SEALED: &str = "__Sealed";
244     pub const RETURNS_VOID_TO_RX: &str = "__ReturnsVoidToRx";
246     pub const MAYBE_MUTABLE: &str = "__MaybeMutable";
248     pub const LATE_INIT: &str = "__LateInit";
250     pub const OWNED_MUTABLE: &str = "__OwnedMutable";
252     pub const NON_RX: &str = "__NonRx";
254     pub const NEWABLE: &str = "__Newable";
256     pub const ENFORCEABLE: &str = "__Enforceable";
258     pub const EXPLICIT: &str = "__Explicit";
260     pub const SOFT: &str = "__Soft";
262     pub const WARN: &str = "__Warn";
264     pub const MOCK_CLASS: &str = "__MockClass";
266     pub const PROVENANCE_SKIP_FRAME: &str = "__ProvenanceSkipFrame";
268     pub const DYNAMICALLY_CALLABLE: &str = "__DynamicallyCallable";
270     pub const DYNAMICALLY_CONSTRUCTIBLE: &str = "__DynamicallyConstructible";
272     pub const REIFIABLE: &str = "__Reifiable";
274     pub const NEVER_INLINE: &str = "__NEVER_INLINE";
276     lazy_static! {
277         static ref AS_SET: HashSet<&'static str> = vec![
278             OVERRIDE,
279             CONSISTENT_CONSTRUCT,
280             CONST,
281             DEPRECATED,
282             ENTRY_POINT,
283             MEMOIZE,
284             MEMOIZE_LSB,
285             PHP_STD_LIB,
286             HIPHOP_SPECIFIC,
287             ACCEPT_DISPOSABLE,
288             RETURN_DISPOSABLE,
289             REACTIVE,
290             LOCAL_REACTIVE,
291             MUTABLE,
292             MUTABLE_RETURN,
293             SHALLOW_REACTIVE,
294             ONLY_RX_IF_IMPL,
295             PROBABILISTIC_MODEL,
296             LSB,
297             SEALED,
298             RETURNS_VOID_TO_RX,
299             MAYBE_MUTABLE,
300             LATE_INIT,
301             AT_MOST_RX_AS_FUNC,
302             AT_MOST_RX_AS_ARGS,
303             OWNED_MUTABLE,
304             NON_RX,
305             NEWABLE,
306             ENFORCEABLE,
307             EXPLICIT,
308             SOFT,
309             WARN,
310             MOCK_CLASS,
311             PROVENANCE_SKIP_FRAME,
312             DYNAMICALLY_CALLABLE,
313             DYNAMICALLY_CONSTRUCTIBLE,
314             REIFIABLE,
315             NEVER_INLINE,
316         ]
317         .iter()
318         .cloned()
319         .collect();
320     }
322     pub fn is_memoized(name: &str) -> bool {
323         name == MEMOIZE || name == MEMOIZE_LSB
324     }
326     // TODO(hrust) these should probably be added to the above map/fields, too
328     pub fn is_native(name: &str) -> bool {
329         name == "__Native"
330     }
332     pub fn is_foldable(name: &str) -> bool {
333         name == "__IsFoldable"
334     }
336     pub fn is_meth_caller(name: &str) -> bool {
337         name == "__MethCaller"
338     }
341 pub mod attribute_kinds {
342     use lazy_static::lazy_static;
343     use std::collections::HashMap;
345     pub const CLS: &str = "\\HH\\ClassAttribute";
347     pub const ENUM: &str = "\\HH\\EnumAttribute";
349     pub const TYPE_ALIAS: &str = "\\HH\\TypeAliasAttribute";
351     pub const FN: &str = "\\HH\\FunctionAttribute";
353     pub const MTHD: &str = "\\HH\\MethodAttribute";
355     pub const INST_PROPERTY: &str = "\\HH\\InstancePropertyAttribute";
357     pub const STATIC_PROPERTY: &str = "\\HH\\StaticPropertyAttribute";
359     pub const PARAMETER: &str = "\\HH\\ParameterAttribute";
361     pub const TYPE_PARAM: &str = "\\HH\\TypeParameterAttribute";
363     pub const FILE: &str = "\\HH\\FileAttribute";
365     pub const TYPE_CONST: &str = "\\HH\\TypeConstantAttribute";
367     lazy_static! {
368         pub static ref PLAIN_ENGLISH_MAP: HashMap<&'static str, &'static str> = [
369             (CLS, "a class"),
370             (ENUM, "an enum"),
371             (TYPE_ALIAS, "a typealias"),
372             (FN, "a function"),
373             (MTHD, "a method"),
374             (INST_PROPERTY, "an instance property"),
375             (STATIC_PROPERTY, "a static property"),
376             (PARAMETER, "a parameter"),
377             (TYPE_PARAM, "a type parameter"),
378             (FILE, "a file"),
379             (TYPE_CONST, "a type pub constant")
380         ]
381         .iter()
382         .cloned()
383         .collect();
384     }
387 /* Tested before \\-prepending name-canonicalization */
388 pub mod special_functions {
389     pub const TUPLE: &str = "tuple"; /* pseudo-function */
391     pub const ECHO: &str = "echo"; /* pseudo-function */
393     pub const ASSERT_: &str = "assert";
395     pub const INVARIANT: &str = "invariant";
397     pub const INVARIANT_VIOLATION: &str = "invariant_violation";
399     pub const FUN_: &str = "fun";
401     pub const INST_METH: &str = "inst_meth";
403     pub const CLASS_METH: &str = "class_meth";
405     pub const METH_CALLER: &str = "meth_caller";
407     pub const CALL_USER_FUNC: &str = "call_user_func";
409     pub const AUTOLOAD: &str = "__autoload";
411     pub const CLONE: &str = "__clone";
414 pub mod special_idents {
415     pub const THIS: &str = "$this";
417     pub const PLACEHOLDER: &str = "$_";
419     pub const DOLLAR_DOLLAR: &str = "$$";
421     /* Intentionally using an invalid variable name to ensure it's translated */
422     pub const TMP_VAR_PREFIX: &str = "__tmp$";
424     pub fn is_tmp_var(name: &str) -> bool {
425         name.len() > 6 && &name[..6] == TMP_VAR_PREFIX
426     }
428     pub fn assert_tmp_var(name: &str) {
429         assert!(is_tmp_var(name))
430     }
433 pub mod pseudo_functions {
434     use lazy_static::lazy_static;
436     pub const ISSET: &str = "\\isset";
438     pub const UNSET: &str = "\\unset";
440     pub const HH_SHOW: &str = "\\hh_show";
442     pub const HH_SHOW_ENV: &str = "\\hh_show_env";
444     pub const HH_LOG_LEVEL: &str = "\\hh_log_level";
446     pub const HH_FORCE_SOLVE: &str = "\\hh_force_solve";
448     pub const HH_LOOP_FOREVER: &str = "\\hh_loop_forever";
450     pub const ASSERT: &str = "\\assert";
452     pub const ECHO: &str = "\\echo";
454     pub const EXIT: &str = "\\exit";
456     pub const DIE: &str = "\\die";
458     lazy_static! {
459         pub static ref ALL_PSEUDO_FUNCTIONS: Vec<&'static str> = vec![
460             ISSET,
461             UNSET,
462             HH_SHOW,
463             HH_SHOW_ENV,
464             HH_LOG_LEVEL,
465             HH_FORCE_SOLVE,
466             HH_LOOP_FOREVER,
467             ASSERT,
468             ECHO,
469             EXIT,
470             DIE,
471         ];
472     }
475 pub mod std_lib_functions {
476     pub const IS_ARRAY: &str = "\\is_array";
478     pub const IS_NULL: &str = "\\is_null";
480     pub const GET_CLASS: &str = "\\get_class";
482     pub const ARRAY_FILTER: &str = "\\array_filter";
484     pub const ARRAY_MAP: &str = "\\array_map";
486     pub const TYPE_STRUCTURE: &str = "\\HH\\type_structure";
488     pub const MARK_LEGACY_HACK_ARRAY: &str = "\\HH\\mark_legacy_hack_array";
491 pub mod typehints {
492     use lazy_static::lazy_static;
493     use std::collections::HashSet;
495     pub const NULL: &str = "null";
497     pub const VOID: &str = "void";
499     pub const RESOURCE: &str = "resource";
501     pub const NUM: &str = "num";
503     pub const ARRAYKEY: &str = "arraykey";
505     pub const NORETURN: &str = "noreturn";
507     pub const MIXED: &str = "mixed";
509     pub const NONNULL: &str = "nonnull";
511     pub const THIS: &str = "this";
513     pub const DYNAMIC: &str = "dynamic";
515     pub const NOTHING: &str = "nothing";
517     pub const INT: &str = "int";
519     pub const BOOL: &str = "bool";
521     pub const FLOAT: &str = "float";
523     pub const STRING: &str = "string";
525     pub const ARRAY: &str = "array";
527     pub const DARRAY: &str = "darray";
529     pub const VARRAY: &str = "varray";
531     pub const VARRAY_OR_DARRAY: &str = "varray_or_darray";
533     pub const CALLABLE: &str = "callable";
535     pub const OBJECT_CAST: &str = "object";
537     pub const WILDCARD: &str = "_";
539     lazy_static! {
540         static ref RESERVED_GLOBAL_NAMES: HashSet<&'static str> = vec![
541             ARRAY,
542             CALLABLE,
543             crate::classes::SELF,
544             crate::classes::PARENT
545         ]
546         .into_iter()
547         .collect();
548     }
550     pub fn is_reserved_global_name(x: &str) -> bool {
551         RESERVED_GLOBAL_NAMES.contains(x)
552     }
554     lazy_static! {
555         static ref RESERVED_HH_NAMES: HashSet<&'static str> = vec![
556             VOID, NORETURN, INT, BOOL, FLOAT, NUM, STRING, RESOURCE, MIXED, ARRAY, ARRAYKEY,
557             DYNAMIC, WILDCARD, NONNULL, NOTHING, THIS
558         ]
559         .into_iter()
560         .collect();
561     }
563     pub fn is_reserved_hh_name(x: &str) -> bool {
564         RESERVED_HH_NAMES.contains(x)
565     }
567     // This function checks if this is a namespace of the "(not HH)\\(...)*\\(reserved_name)"
568     pub fn is_namespace_with_reserved_hh_name(x: &str) -> bool {
569         // This splits the string into its namespaces
570         fn unqualify(x: &str) -> (Vec<&str>, &str) {
571             let mut as_list = x.split("\\").collect::<Vec<&str>>();
572             // Retain if not empty
573             as_list.retain(|&split| match split {
574                 "" => false,
575                 _ => true,
576             });
577             let last_split = match as_list.pop() {
578                 None => "",
579                 Some(x) => x,
580             };
582             (as_list, last_split)
583         }
585         // This returns a bool whether or not the list is just the string "HH"
586         fn is_hh(qualifier: &Vec<&str>) -> bool {
587             match qualifier.len() {
588                 1 => qualifier[0] == "HH",
589                 _ => false,
590             }
591         }
592         let (qualifier, name) = unqualify(x);
593         !is_hh(&qualifier) && !qualifier.is_empty() && is_reserved_hh_name(name)
594     }
597 pub mod pseudo_consts {
598     use lazy_static::lazy_static;
599     use std::collections::HashSet;
601     pub const G__LINE__: &str = "\\__LINE__";
603     pub const G__CLASS__: &str = "\\__CLASS__";
605     pub const G__TRAIT__: &str = "\\__TRAIT__";
607     pub const G__FILE__: &str = "\\__FILE__";
609     pub const G__DIR__: &str = "\\__DIR__";
611     pub const G__FUNCTION__: &str = "\\__FUNCTION__";
613     pub const G__METHOD__: &str = "\\__METHOD__";
615     pub const G__NAMESPACE__: &str = "\\__NAMESPACE__";
617     pub const G__COMPILER_FRONTEND__: &str = "\\__COMPILER_FRONTEND__";
619     pub const G__FUNCTION_CREDENTIAL__: &str = "\\__FUNCTION_CREDENTIAL__";
621     lazy_static! {
622         static ref ALL_PSEUDO_CONSTS: Vec<&'static str> = vec![
623             G__LINE__,
624             G__CLASS__,
625             G__TRAIT__,
626             G__FILE__,
627             G__DIR__,
628             G__FUNCTION__,
629             G__METHOD__,
630             G__NAMESPACE__,
631             G__COMPILER_FRONTEND__,
632             G__FUNCTION_CREDENTIAL__
633         ];
634         static ref PSEUDO_SET: HashSet<&'static str> =
635             { ALL_PSEUDO_CONSTS.iter().cloned().collect() };
636     }
638     pub fn is_pseudo_const(x: &str) -> bool {
639         PSEUDO_SET.contains(x)
640     }
643 pub mod fb {
644     pub const ENUM: &str = "\\Enum";
646     pub const UNCHECKED_ENUM: &str = "\\UncheckedEnum";
648     pub const IDX: &str = "\\HH\\idx";
650     pub const TYPE_STRUCTURE: &str = "\\HH\\TypeStructure";
652     pub const INCORRECT_TYPE: &str = "\\HH\\INCORRECT_TYPE";
655 pub mod hh {
656     pub const ASIO_VA: &str = "\\HH\\Asio\\va";
658     pub const LIB_TUPLE_FROM_ASYNC: &str = "\\HH\\Lib\\Tuple\\from_async";
660     pub const LIB_TUPLE_GEN: &str = "\\HH\\Lib\\Tuple\\gen";
662     pub const CONTAINS: &str = "\\HH\\Lib\\C\\contains";
664     pub const CONTAINS_KEY: &str = "\\HH\\Lib\\C\\contains_key";
667 pub mod rx {
668     pub const FREEZE: &str = "\\HH\\Rx\\freeze";
670     pub const MUTABLE_: &str = "\\HH\\Rx\\mutable";
672     pub const TRAVERSABLE: &str = "\\HH\\Rx\\Traversable";
674     pub const IS_ENABLED: &str = "\\HH\\Rx\\IS_ENABLED";
676     pub const KEYED_TRAVERSABLE: &str = "\\HH\\Rx\\KeyedTraversable";
678     pub const ASYNC_ITERATOR: &str = "\\HH\\Rx\\AsyncIterator";
680     pub const MOVE: &str = "\\HH\\Rx\\move";
683 pub mod shapes {
684     pub const SHAPES: &str = "\\HH\\Shapes";
686     pub const IDX: &str = "idx";
688     pub const AT: &str = "at";
690     pub const KEY_EXISTS: &str = "keyExists";
692     pub const REMOVE_KEY: &str = "removeKey";
694     pub const TO_ARRAY: &str = "toArray";
696     pub const TO_DICT: &str = "toDict";
699 pub mod superglobals {
700     use lazy_static::lazy_static;
701     use std::collections::HashSet;
702     pub const GLOBALS: &str = "$GLOBALS";
704     lazy_static! {
705         static ref SUPERGLOBALS: Vec<&'static str> = vec![
706             "$_SERVER",
707             "$_GET",
708             "$_POST",
709             "$_FILES",
710             "$_COOKIE",
711             "$_REQUEST",
712             "$_ENV"
713         ];
714         static ref SUPERGLOBALS_SET: HashSet<&'static str> = SUPERGLOBALS.iter().cloned().collect();
715     }
716     pub fn is_superglobal(x: &str) -> bool {
717         SUPERGLOBALS_SET.contains(x)
718     }
719     pub fn is_any_global(x: &str) -> bool {
720         is_superglobal(x) || x == GLOBALS
721     }
724 pub mod ppl_functions {
725     use lazy_static::lazy_static;
726     use std::collections::HashSet;
727     lazy_static! {
728         static ref ALL_RESERVED: Vec<&'static str> = vec!(
729             "sample",
730             "\\sample",
731             "factor",
732             "\\factor",
733             "observe",
734             "\\observe",
735             "condition",
736             "\\condition",
737             "sample_model",
738             "\\sample_model"
739         );
740         static ref ALL_RESERVED_SET: HashSet<&'static str> = ALL_RESERVED.iter().cloned().collect();
741     }
742     pub fn is_reserved(x: &str) -> bool {
743         ALL_RESERVED_SET.contains(x)
744     }
747 pub mod regex {
748     pub const T_PATTERN: &str = "\\HH\\Lib\\Regex\\Pattern";
751 #[cfg(test)]
752 mod test {
753     use crate::members::is_special_xhp_attribute;
754     use crate::members::AS_LOWERCASE_SET;
755     use crate::special_idents::is_tmp_var;
756     use crate::typehints::is_namespace_with_reserved_hh_name;
758     #[test]
759     fn test_special_idents_is_tmp_var() {
760         assert!(!is_tmp_var("_tmp$Blah"));
761         assert!(!is_tmp_var("__tmp$"));
763         assert!(is_tmp_var("__tmp$Blah"));
764     }
766     #[test]
767     fn test_members_as_lowercase_set() {
768         assert!(AS_LOWERCASE_SET.contains("__tostring"));
769         assert!(!AS_LOWERCASE_SET.contains("__toString"));
770     }
772     #[test]
773     fn test_members_is_special_xhp_attribute() {
774         assert!(is_special_xhp_attribute(":data-blahblah"));
775         assert!(is_special_xhp_attribute(":aria-blahblah"));
777         assert!(!is_special_xhp_attribute(":arla-blahblah"));
778         assert!(!is_special_xhp_attribute(":aria"));
779     }
781     #[test]
782     fn test_typehint_is_namespace_with_reserved_hh_name() {
783         assert!(!is_namespace_with_reserved_hh_name("HH\\void"));
784         assert!(!is_namespace_with_reserved_hh_name("void"));
785         assert!(!is_namespace_with_reserved_hh_name("ReturnType\\Lloyd"));
786         assert!(!is_namespace_with_reserved_hh_name("Lloyd"));
788         assert!(is_namespace_with_reserved_hh_name("Anything\\Else\\void"));
789     }