Multiply entities beyond necessity even more (force better build parallelism)
[hiphop-php.git] / hphp / hack / src / parser / type_parser.rs
blob2ecd17008474a8040fb01eb47a9bb41c1af9488b
1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
3 //
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 use crate::declaration_parser::DeclarationParser;
8 use crate::expression_parser::ExpressionParser;
9 use crate::lexer::Lexer;
10 use crate::parser_env::ParserEnv;
11 use crate::parser_trait::Context;
12 use crate::parser_trait::ParserTrait;
13 use crate::smart_constructors::{NodeType, SmartConstructors};
14 use parser_core_types::lexable_token::LexableToken;
15 use parser_core_types::syntax_error::{self as Errors, SyntaxError};
16 use parser_core_types::token_kind::TokenKind;
18 pub struct TypeParser<'a, S, T>
19 where
20     S: SmartConstructors<'a, T>,
21     S::R: NodeType,
23     lexer: Lexer<'a, S::Token>,
24     env: ParserEnv,
25     context: Context<'a, S::Token>,
26     errors: Vec<SyntaxError>,
27     sc: S,
30 impl<'a, S, T: Clone> std::clone::Clone for TypeParser<'a, S, T>
31 where
32     S: SmartConstructors<'a, T>,
33     S::R: NodeType,
35     fn clone(&self) -> Self {
36         Self {
37             lexer: self.lexer.clone(),
38             env: self.env.clone(),
39             context: self.context.clone(),
40             errors: self.errors.clone(),
41             sc: self.sc.clone(),
42         }
43     }
46 impl<'a, S, T: Clone> ParserTrait<'a, S, T> for TypeParser<'a, S, T>
47 where
48     S: SmartConstructors<'a, T>,
49     S::R: NodeType,
51     fn make(
52         mut lexer: Lexer<'a, S::Token>,
53         env: ParserEnv,
54         context: Context<'a, S::Token>,
55         errors: Vec<SyntaxError>,
56         sc: S,
57     ) -> Self {
58         lexer.set_in_type(true);
59         Self {
60             lexer,
61             env,
62             context,
63             errors,
64             sc,
65         }
66     }
68     fn into_parts(
69         mut self,
70     ) -> (
71         Lexer<'a, S::Token>,
72         Context<'a, S::Token>,
73         Vec<SyntaxError>,
74         S,
75     ) {
76         self.lexer.set_in_type(false);
77         (self.lexer, self.context, self.errors, self.sc)
78     }
80     fn lexer(&self) -> &Lexer<'a, S::Token> {
81         &self.lexer
82     }
84     fn lexer_mut(&mut self) -> &mut Lexer<'a, S::Token> {
85         &mut self.lexer
86     }
88     fn continue_from<P: ParserTrait<'a, S, T>>(&mut self, other: P)
89     where
90         T: Clone,
91     {
92         let (mut lexer, context, errors, sc) = other.into_parts();
93         lexer.set_in_type(true);
94         self.lexer = lexer;
95         self.context = context;
96         self.errors = errors;
97         self.sc = sc;
98     }
100     fn add_error(&mut self, error: SyntaxError) {
101         self.errors.push(error)
102     }
104     fn env(&self) -> &ParserEnv {
105         &self.env
106     }
108     fn sc_mut(&mut self) -> &mut S {
109         &mut self.sc
110     }
112     fn skipped_tokens_mut(&mut self) -> &mut Vec<S::Token> {
113         &mut self.context.skipped_tokens
114     }
116     fn skipped_tokens(&self) -> &[S::Token] {
117         &self.context.skipped_tokens
118     }
120     fn context_mut(&mut self) -> &mut Context<'a, S::Token> {
121         &mut self.context
122     }
124     fn context(&self) -> &Context<'a, S::Token> {
125         &self.context
126     }
129 impl<'a, S, T: Clone> TypeParser<'a, S, T>
130 where
131     S: SmartConstructors<'a, T>,
132     S::R: NodeType,
134     fn with_expression_parser<F, U>(&mut self, f: F) -> U
135     where
136         F: Fn(&mut ExpressionParser<'a, S, T>) -> U,
137     {
138         let mut lexer = self.lexer.clone();
139         lexer.set_in_type(false);
140         let mut expression_parser: ExpressionParser<S, T> = ExpressionParser::make(
141             lexer,
142             self.env.clone(),
143             self.context.clone(),
144             self.errors.clone(),
145             self.sc.clone(),
146         );
147         let res = f(&mut expression_parser);
148         self.continue_from(expression_parser);
149         res
150     }
152     fn parse_expression(&mut self) -> S::R {
153         self.with_expression_parser(|p: &mut ExpressionParser<'a, S, T>| p.parse_expression())
154     }
156     fn with_decl_parser<F, U>(&mut self, f: F) -> U
157     where
158         F: Fn(&mut DeclarationParser<'a, S, T>) -> U,
159     {
160         let mut lexer = self.lexer.clone();
161         lexer.set_in_type(false);
163         let mut declaration_parser: DeclarationParser<S, T> = DeclarationParser::make(
164             lexer,
165             self.env.clone(),
166             self.context.clone(),
167             self.errors.clone(),
168             self.sc.clone(),
169         );
170         let res = f(&mut declaration_parser);
171         self.continue_from(declaration_parser);
172         res
173     }
175     // TODO: What about something like for::for? Is that a legal type constant?
176     pub fn parse_type_specifier(&mut self, allow_var: bool, allow_attr: bool) -> S::R {
177         // Strictly speaking, "mixed" is a nullable type specifier. We parse it as
178         // a simple type specifier here.
179         let mut parser1 = self.clone();
180         let token = parser1.next_xhp_class_name_or_other_token();
181         let new_attr_syntax = self.env.allow_new_attribute_syntax;
182         match token.kind() {
183             | TokenKind::Var if allow_var => {
184                 self.continue_from(parser1);
185                 let token = S!(make_token, self, token);
186                 S!(make_simple_type_specifier, self, token)
187             }
188             | TokenKind::This => self.parse_simple_type_or_type_constant(),
189             // Any keyword-type could be a non-keyword type, because PHP, so check whether
190             // these have generics.
191             | TokenKind::Double // TODO: Specification does not mention double; fix it.
192             | TokenKind::Bool
193             | TokenKind::Boolean
194             | TokenKind::Binary
195             | TokenKind::Int
196             | TokenKind::Integer
197             | TokenKind::Float
198             | TokenKind::Real
199             | TokenKind::Num
200             | TokenKind::String
201             | TokenKind::Arraykey
202             | TokenKind::Void
203             | TokenKind::Noreturn
204             | TokenKind::Resource
205             | TokenKind::Object
206             | TokenKind::Mixed
207             | TokenKind::NullLiteral
208             | TokenKind::Name => self.parse_simple_type_or_type_constant_or_generic(),
209             | TokenKind::Namespace => {
210                 let name = self.scan_name_or_qualified_name();
211                 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
212             }
213             | TokenKind::Backslash => {
214                 self.continue_from(parser1);
215                 let missing = S!(make_missing, self, self.pos());
216                 let token = S!(make_token, self, token);
217                 let name = self.scan_qualified_name(missing, token);
218                 self.parse_remaining_simple_type_or_type_constant_or_generic(name)
219             }
220             | TokenKind::SelfToken
221             | TokenKind::Parent => self.parse_simple_type_or_type_constant(),
222             | TokenKind::Category
223             | TokenKind::XHPClassName => self.parse_simple_type_or_type_constant_or_generic(),
224             | TokenKind::Array => self.parse_array_type_specifier(),
225             | TokenKind::Darray => self.parse_darray_type_specifier(),
226             | TokenKind::Varray => self.parse_varray_type_specifier(),
227             | TokenKind::Vec => self.parse_vec_type_specifier(),
228             | TokenKind::Dict => self.parse_dictionary_type_specifier(),
229             | TokenKind::Keyset => self.parse_keyset_type_specifier(),
230             | TokenKind::Tuple => self.parse_tuple_type_explicit_specifier(),
231             | TokenKind::LeftParen => self.parse_tuple_or_closure_type_specifier(),
232             | TokenKind::Shape => self.parse_shape_specifier(),
233             | TokenKind::Question => self.parse_nullable_type_specifier(),
234             | TokenKind::Tilde => self.parse_like_type_specifier(),
235             | TokenKind::At if !new_attr_syntax => self.parse_soft_type_specifier(),
236             | TokenKind::At if new_attr_syntax => self.parse_attributized_specifier(),
237             | TokenKind::LessThanLessThan if allow_attr => self.parse_attributized_specifier(),
238             | TokenKind::Classname => self.parse_classname_type_specifier(),
239             | _ => {
240                 self.with_error_on_whole_token(Errors::error1007);
241                 let token = self.next_xhp_class_name_or_other_token();
242                 let token = S!(make_token, self, token);
243                 S!(make_error, self, token)
244             }
245         }
246     }
248     // SPEC
249     // type-constant-type-name:
250     //   name  ::  name
251     //   self  ::  name
252     //   this  ::  name
253     //   parent  ::  name
254     //   type-constant-type-name  ::  name
255     fn parse_remaining_type_constant(&mut self, left: S::R) -> S::R {
256         let separator = self.fetch_token();
257         let right = self.next_token_as_name();
258         if right.kind() == TokenKind::Name {
259             let right = S!(make_token, self, right);
260             let syntax = S!(make_type_constant, self, left, separator, right);
261             let token = self.peek_token();
262             if token.kind() == TokenKind::ColonColon {
263                 self.parse_remaining_type_constant(syntax)
264             } else {
265                 syntax
266             }
267         } else {
268             // ERROR RECOVERY: Assume that the thing following the ::
269             // that is not a name belongs to the next thing to be
270             // parsed; treat the name as missing.
271             self.with_error(Errors::error1004);
272             let missing = S!(make_missing, self, self.pos());
273             S!(make_type_constant, self, left, separator, missing)
274         }
275     }
277     //  SPEC
278     // pocket-universe-access:
279     //   name  :@  name
280     //   self  :@  name
281     //   this  :@  name
282     //   parent  :@  name
283     //   pocket-universe-access :@  name
284     fn parse_remaining_pocket_universe_access(&mut self, left: S::R) -> S::R {
285         let separator = self.fetch_token();
286         let right = self.next_token_as_name();
287         if right.kind() == TokenKind::Name {
288             let right = S!(make_token, self, right);
289             let syntax = S!(make_pu_access, self, left, separator, right);
290             let token = self.peek_token();
291             if token.kind() == TokenKind::ColonAt {
292                 self.parse_remaining_pocket_universe_access(syntax)
293             } else {
294                 syntax
295             }
296         } else {
297             // ERROR RECOVERY: Assume that the thing following the :@
298             // that is not a name belongs to the next thing to be
299             // parsed; treat the name as missing.
300             self.with_error(Errors::error1004);
301             let missing = S!(make_missing, self, self.pos());
302             S!(make_pu_access, self, left, separator, missing)
303         }
304     }
306     fn parse_remaining_generic(&mut self, name: S::R) -> S::R {
307         let (arguments, _) = self.parse_generic_type_argument_list();
308         S!(make_generic_type_specifier, self, name, arguments)
309     }
311     pub fn parse_simple_type_or_type_constant(&mut self) -> S::R {
312         let name = self.next_xhp_class_name_or_other();
313         self.parse_remaining_simple_type_or_type_constant(name)
314     }
316     pub fn parse_simple_type_or_generic(&mut self) -> S::R {
317         let name = self.next_xhp_class_name_or_other();
318         self.parse_remaining_simple_type_or_generic(name)
319     }
321     fn parse_remaining_simple_type_or_type_constant(&mut self, name: S::R) -> S::R {
322         let token = self.peek_token();
323         match token.kind() {
324             TokenKind::ColonColon => self.parse_remaining_type_constant(name),
325             TokenKind::ColonAt => self.parse_remaining_pocket_universe_access(name),
326             _ => S!(make_simple_type_specifier, self, name),
327         }
328     }
330     fn parse_simple_type_or_type_constant_or_generic(&mut self) -> S::R {
331         let name = self.next_xhp_class_name_or_other();
332         self.parse_remaining_simple_type_or_type_constant_or_generic(name)
333     }
335     pub fn parse_remaining_type_specifier(&mut self, name: S::R) -> S::R {
336         self.parse_remaining_simple_type_or_type_constant_or_generic(name)
337     }
339     fn parse_remaining_simple_type_or_type_constant_or_generic(&mut self, name: S::R) -> S::R {
340         match self.peek_token_kind_with_possible_attributized_type_list() {
341             TokenKind::LessThan => self.parse_remaining_generic(name),
342             _ => self.parse_remaining_simple_type_or_type_constant(name),
343         }
344     }
346     fn parse_remaining_simple_type_or_generic(&mut self, name: S::R) -> S::R {
347         match self.peek_token_kind_with_possible_attributized_type_list() {
348             TokenKind::LessThan => self.parse_remaining_generic(name),
349             _ => S!(make_simple_type_specifier, self, name),
350         }
351     }
353     // SPEC
354     // generic-type-constraint-list:
355     //   generic-type-constraint
356     //   generic-type-constraint generic-type-constraint-list
357     //
358     // generic-type-constraint:
359     //   as type-specifier
360     //   super type-specifier
361     //
362     // TODO: SPEC ISSUES:
363     // https://github.com/hhvm/hack-langspec/issues/83
364     //
365     // TODO: Do we also need to allow "= type-specifier" here?
366     fn parse_generic_type_constraint_opt(&mut self) -> Option<S::R> {
367         let mut parser1 = self.clone();
368         let token = parser1.next_token();
369         match token.kind() {
370             TokenKind::As | TokenKind::Super => {
371                 self.continue_from(parser1);
372                 let constraint_token = S!(make_token, self, token);
373                 let matched_type = self.parse_type_specifier(false, true);
374                 let type_constraint =
375                     S!(make_type_constraint, self, constraint_token, matched_type);
376                 Some(type_constraint)
377             }
378             _ => None,
379         }
380     }
382     fn parse_variance_opt(&mut self) -> S::R {
383         match self.peek_token_kind() {
384             TokenKind::Plus | TokenKind::Minus => self.fetch_token(),
385             _ => S!(make_missing, self, self.pos()),
386         }
387     }
389     // SPEC
390     // generic-type-parameter:
391     //   generic-type-parameter-reified-opt  generic-type-parameter-variance-opt
392     //     name  generic-type-constraint-list-opt
393     //
394     // generic-type-parameter-variance:
395     //   +
396     //   -
397     //
398     // TODO: SPEC ISSUE: We allow any number of type constraints, not just zero
399     // or one as indicated in the spec.
400     // https://github.com/hhvm/hack-langspec/issues/83
401     // TODO: Update the spec with reified
402     fn parse_type_parameter(&mut self) -> S::R {
403         let attributes = self.with_decl_parser(|x: &mut DeclarationParser<'a, S, T>| {
404             x.parse_attribute_specification_opt()
405         });
406         let reified = self.optional_token(TokenKind::Reify);
407         let variance = self.parse_variance_opt();
408         let type_name = self.require_name_allow_all_keywords();
409         let constraints =
410             self.parse_list_until_none(|x: &mut Self| x.parse_generic_type_constraint_opt());
411         S!(
412             make_type_parameter,
413             self,
414             attributes,
415             reified,
416             variance,
417             type_name,
418             constraints
419         )
420     }
422     // SPEC
423     // type-parameter-list:
424     // < generic-type-parameters  ,-opt >
425     //
426     // generic-type-parameters:
427     //   generic-type-parameter
428     //   generic-type-parameter  ,  generic-type-parameter
429     //
431     pub fn parse_generic_type_parameter_list(&mut self) -> S::R {
432         let left = self.assert_left_angle_in_type_list_with_possible_attribute();
433         let (params, _) = self.parse_comma_list_allow_trailing(
434             TokenKind::GreaterThan,
435             Errors::error1007,
436             |x: &mut Self| x.parse_type_parameter(),
437         );
439         let right = self.require_right_angle();
440         S!(make_type_parameters, self, left, params, right)
441     }
443     fn parse_type_list(&mut self, close_kind: TokenKind) -> S::R {
444         // SPEC:
445         // type-specifier-list:
446         //   type-specifiers  ,opt
447         //
448         // type-specifiers:
449         //   type-specifier
450         //   type-specifiers  ,  type-specifier
451         let (items, _) =
452             self.parse_comma_list_allow_trailing(close_kind, Errors::error1007, |x: &mut Self| {
453                 x.parse_type_specifier(false, true)
454             });
455         items
456     }
458     // SPEC
459     //
460     // TODO: Add this to the specification.
461     // (This work is tracked by task T22582676.)
462     //
463     // call-convention:
464     //   inout
466     fn parse_call_convention_opt(&mut self) -> S::R {
467         match self.peek_token_kind() {
468             TokenKind::Inout => {
469                 let token = self.next_token();
470                 S!(make_token, self, token)
471             }
472             _ => S!(make_missing, self, self.pos()),
473         }
474     }
476     // SPEC
477     //
478     // TODO: Add this to the specification.
479     // (This work is tracked by task T22582676.)
480     //
481     // closure-param-type-specifier-list:
482     //   closure-param-type-specifiers  ,opt
483     //
484     // closure-param-type-specifiers:
485     //   closure-param-type-specifier
486     //   closure-param-type-specifiers  ,  closure-param-type-specifier
488     fn parse_closure_param_list(&mut self, close_kind: TokenKind) -> S::R {
489         let (items, _) =
490             self.parse_comma_list_allow_trailing(close_kind, Errors::error1007, |x: &mut Self| {
491                 x.parse_closure_param_type_or_ellipsis()
492             });
493         items
494     }
496     // SPEC
497     //
498     // TODO: Add this to the specification.
499     // (This work is tracked by task T22582676.)
500     //
501     // ERROR RECOVERY: Variadic params cannot be declared inout; this error is
502     // caught in a later pass.
503     //
504     // closure-param-type-specifier:
505     //   call-convention-opt  type-specifier
506     //   type-specifier  ...
507     //   ...
509     fn parse_closure_param_type_or_ellipsis(&mut self) -> S::R {
510         match self.peek_token_kind() {
511             TokenKind::DotDotDot => {
512                 let missing1 = S!(make_missing, self, self.pos());
513                 let missing2 = S!(make_missing, self, self.pos());
514                 let token = self.next_token();
515                 let token = S!(make_token, self, token);
516                 S!(make_variadic_parameter, self, missing1, missing2, token)
517             }
518             _ => {
519                 let callconv = self.parse_call_convention_opt();
520                 let ts = self.parse_type_specifier(false, true);
521                 match self.peek_token_kind() {
522                     TokenKind::DotDotDot => {
523                         let token = self.next_token();
524                         let token = S!(make_token, self, token);
525                         S!(make_variadic_parameter, self, callconv, ts, token)
526                     }
527                     _ => S!(make_closure_parameter_type_specifier, self, callconv, ts),
528                 }
529             }
530         }
531     }
533     fn parse_optionally_reified_type(&mut self) -> S::R {
534         if self.peek_token_kind() == TokenKind::Reify {
535             let token = self.next_token();
536             let reified_kw = S!(make_token, self, token);
537             let type_argument = self.parse_type_specifier(false, true);
538             S!(make_reified_type_argument, self, reified_kw, type_argument)
539         } else {
540             self.parse_type_specifier(false, true)
541         }
542     }
544     pub fn parse_generic_type_argument_list(&mut self) -> (S::R, bool) {
545         // SPEC:
546         // generic-type-argument-list:
547         //   <  generic-type-arguments  ,opt  >
548         //
549         // generic-type-arguments:
550         //   generic-type-argument
551         //   generic-type-arguments  ,  generic-type-argument
552         //
553         // TODO: SPEC ISSUE
554         // https://github.com/hhvm/hack-langspec/issues/84
555         // The specification indicates that "noreturn" is only syntactically valid
556         // as a return type hint, but this is plainly wrong because
557         // Awaitable<noreturn> is a legal type. Likely the correct rule will be to
558         // allow noreturn as a type argument, and then a later semantic analysis
559         // pass can determine when it is being used incorrectly.
560         //
561         // For now, we extend the specification to allow return types, not just
562         // ordinary types.
563         let open_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
564         let (args, no_arg_is_missing) = self.parse_comma_list_allow_trailing(
565             TokenKind::GreaterThan,
566             Errors::error1007,
567             |x: &mut Self| x.parse_optionally_reified_type(),
568         );
569         match self.peek_token_kind() {
570             TokenKind::GreaterThan => {
571                 let close_angle = self.assert_token(TokenKind::GreaterThan);
572                 let result = S!(make_type_arguments, self, open_angle, args, close_angle);
573                 (result, no_arg_is_missing)
574             }
575             _ => {
576                 // ERROR RECOVERY: Don't eat the token that is in the place of the
577                 // missing > or ,.  TokenKind::Assume that it is the > that is missing and
578                 // try to parse whatever is coming after the type.
579                 self.with_error(Errors::error1014);
580                 let missing = S!(make_missing, self, self.pos());
581                 let result = S!(make_type_arguments, self, open_angle, args, missing);
582                 (result, no_arg_is_missing)
583             }
584         }
585     }
587     fn parse_array_type_specifier(&mut self) -> S::R {
588         // We allow
589         // array
590         // array<type>
591         // array<type, type>
592         // TODO: Put a proper reference to the specification in here.
593         // TODO: in HHVM trailing comma is permitted only in the case with one
594         // type argument: array<type, >
595         // so now it is not really comma-separated list
596         let array_token = self.assert_token(TokenKind::Array);
597         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
598             S!(make_simple_type_specifier, self, array_token)
599         } else {
600             let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
601             // ERROR RECOVERY: We could improve error recovery by detecting
602             // array<,  and marking the key type as missing.
603             let key_type = self.parse_type_specifier(false, true);
604             let kind = self.peek_token_kind();
605             if kind == TokenKind::GreaterThan {
606                 let right_angle = self.fetch_token();
607                 S!(
608                     make_vector_array_type_specifier,
609                     self,
610                     array_token,
611                     left_angle,
612                     key_type,
613                     right_angle
614                 )
615             } else if kind == TokenKind::Comma {
616                 let comma = self.fetch_token();
617                 let next_token_kind = self.peek_token_kind();
618                 let value_type = if next_token_kind == TokenKind::GreaterThan {
619                     S!(make_missing, self, self.pos())
620                 } else {
621                     self.parse_type_specifier(false, true)
622                 };
623                 let right_angle = self.require_right_angle();
624                 S!(
625                     make_map_array_type_specifier,
626                     self,
627                     array_token,
628                     left_angle,
629                     key_type,
630                     comma,
631                     value_type,
632                     right_angle,
633                 )
634             } else {
635                 // ERROR RECOVERY: TokenKind::Assume that the > is missing and keep going.
636                 let right_angle = S!(make_missing, self, self.pos());
637                 S!(
638                     make_vector_array_type_specifier,
639                     self,
640                     array_token,
641                     left_angle,
642                     key_type,
643                     right_angle
644                 )
645             }
646         }
647     }
649     fn parse_darray_type_specifier(&mut self) -> S::R {
650         // darray<type, type>
651         let array_token = self.assert_token(TokenKind::Darray);
652         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
653             S!(make_simple_type_specifier, self, array_token)
654         } else {
655             let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
656             let key_type = self.parse_type_specifier(false, true);
657             let comma = self.require_comma();
658             let value_type = self.parse_type_specifier(false, true);
659             let optional_comma = self.optional_token(TokenKind::Comma);
660             let right_angle = self.require_right_angle();
661             S!(
662                 make_darray_type_specifier,
663                 self,
664                 array_token,
665                 left_angle,
666                 key_type,
667                 comma,
668                 value_type,
669                 optional_comma,
670                 right_angle,
671             )
672         }
673     }
675     fn parse_varray_type_specifier(&mut self) -> S::R {
676         // varray<type>
677         let array_token = self.assert_token(TokenKind::Varray);
678         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
679             S!(make_simple_type_specifier, self, array_token)
680         } else {
681             let left_angle = self.assert_left_angle_in_type_list_with_possible_attribute();
682             let value_type = self.parse_type_specifier(false, true);
683             let optional_comma = self.optional_token(TokenKind::Comma);
684             let right_angle = self.require_right_angle();
685             S!(
686                 make_varray_type_specifier,
687                 self,
688                 array_token,
689                 left_angle,
690                 value_type,
691                 optional_comma,
692                 right_angle,
693             )
694         }
695     }
697     fn parse_vec_type_specifier(&mut self) -> S::R {
698         // vec < type-specifier >
699         // TODO: Should we allow a trailing comma?
700         // TODO: Add this to the specification
701         // ERROR RECOVERY: If there is no type argument list then just make
702         // this a simple type.  TODO: Should this be an error at parse time? what
703         // about at type checking time?
704         let keyword = self.assert_token(TokenKind::Vec);
705         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
706             S!(make_simple_type_specifier, self, keyword)
707         } else {
708             let left = self.assert_left_angle_in_type_list_with_possible_attribute();
709             let t = self.parse_type_specifier(false, true);
710             let optional_comma = self.optional_token(TokenKind::Comma);
711             let right = self.require_right_angle();
712             S!(
713                 make_vector_type_specifier,
714                 self,
715                 keyword,
716                 left,
717                 t,
718                 optional_comma,
719                 right
720             )
721         }
722     }
724     fn parse_keyset_type_specifier(&mut self) -> S::R {
725         // keyset < type-specifier >
726         // TODO: Should we allow a trailing comma?
727         // TODO: Add this to the specification
728         // ERROR RECOVERY: If there is no type argument list then just make
729         // this a simple type.  TODO: Should this be an error at parse time? what
730         // about at type checking time?
731         let keyword = self.assert_token(TokenKind::Keyset);
732         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
733             S!(make_simple_type_specifier, self, keyword)
734         } else {
735             let left = self.assert_left_angle_in_type_list_with_possible_attribute();
736             let t = self.parse_type_specifier(false, true);
737             let comma = self.optional_token(TokenKind::Comma);
738             let right = self.require_right_angle();
739             S!(
740                 make_keyset_type_specifier,
741                 self,
742                 keyword,
743                 left,
744                 t,
745                 comma,
746                 right
747             )
748         }
749     }
751     fn parse_tuple_type_explicit_specifier(&mut self) -> S::R {
752         // tuple < type-specifier-list >
753         // TODO: Add this to the specification
754         let keyword = self.assert_token(TokenKind::Tuple);
755         let left_angle = if self.peek_next_partial_token_is_triple_left_angle() {
756             self.assert_left_angle_in_type_list_with_possible_attribute()
757         } else {
758             self.require_left_angle()
759         };
760         let args = self.parse_type_list(TokenKind::GreaterThan);
761         let mut parser1 = self.clone();
762         let right_angle = parser1.next_token();
763         if right_angle.kind() == TokenKind::GreaterThan {
764             self.continue_from(parser1);
765             let token = S!(make_token, self, right_angle);
766             S!(
767                 make_tuple_type_explicit_specifier,
768                 self,
769                 keyword,
770                 left_angle,
771                 args,
772                 token
773             )
774         } else {
775             // ERROR RECOVERY: Don't eat the token that is in the place of the
776             // missing > or ,.  TokenKind::Assume that it is the > that is missing and
777             // try to parse whatever is coming after the type.
778             self.with_error(Errors::error1022);
779             let right_angle = S!(make_missing, self, self.pos());
780             S!(
781                 make_tuple_type_explicit_specifier,
782                 self,
783                 keyword,
784                 left_angle,
785                 args,
786                 right_angle
787             )
788         }
789     }
791     fn parse_dictionary_type_specifier(&mut self) -> S::R {
792         // dict < type-specifier , type-specifier >
793         //
794         // TODO: Add this to the specification
795         //
796         // Though we require there to be exactly two items, we actually parse
797         // an arbitrary comma-separated list here.
798         //
799         // TODO: Give an error in a later pass if there are not exactly two members.
800         //
801         // ERROR RECOVERY: If there is no type argument list then just make this
802         // a simple type.  TODO: Should this be an error at parse time?  what
803         // about at type checking time?
804         let keyword = self.assert_token(TokenKind::Dict);
805         if self.peek_token_kind_with_possible_attributized_type_list() != TokenKind::LessThan {
806             S!(make_simple_type_specifier, self, keyword)
807         } else {
808             // TODO: This allows "noreturn" as a type argument. Should we
809             // disallow that at parse time?
810             let left = self.assert_left_angle_in_type_list_with_possible_attribute();
811             let (arguments, _) = self.parse_comma_list_allow_trailing(
812                 TokenKind::GreaterThan,
813                 Errors::error1007,
814                 |x: &mut Self| x.parse_return_type(),
815             );
816             let right = self.require_right_angle();
817             S!(
818                 make_dictionary_type_specifier,
819                 self,
820                 keyword,
821                 left,
822                 arguments,
823                 right
824             )
825         }
826     }
828     fn parse_tuple_or_closure_type_specifier(&mut self) -> S::R {
829         let mut parser1 = self.clone();
830         let _ = parser1.assert_token(TokenKind::LeftParen);
831         let token = parser1.peek_token();
832         match token.kind() {
833             TokenKind::Function | TokenKind::Coroutine => self.parse_closure_type_specifier(),
834             _ => self.parse_tuple_type_specifier(),
835         }
836     }
838     fn parse_closure_type_specifier(&mut self) -> S::R {
839         // SPEC
840         //
841         // TODO: Update the specification with closure-param-type-specifier-list-opt.
842         // (This work is tracked by task T22582676.)
843         //
844         // TODO: Update grammar for inout parameters.
845         // (This work is tracked by task T22582715.)
846         //
847         // closure-type-specifier:
848         //   ( coroutine-opt function ( \
849         //   closure-param-type-specifier-list-opt \
850         //   ) : type-specifier )
851         //
852         // TODO: Error recovery is pretty weak here. We could be smarter.
853         let olp = self.fetch_token();
854         let coroutine = self.optional_token(TokenKind::Coroutine);
855         let fnc = self.fetch_token();
856         let ilp = self.require_left_paren();
857         let (pts, irp) = if self.peek_token_kind() == TokenKind::RightParen {
858             let missing = S!(make_missing, self, self.pos());
859             let token = self.next_token();
860             let token = S!(make_token, self, token);
861             (missing, token)
862         } else {
863             // TODO add second pass checking to ensure ellipsis is the last arg
864             let pts = self.parse_closure_param_list(TokenKind::RightParen);
865             let irp = self.require_right_paren();
866             (pts, irp)
867         };
868         let col = self.require_colon();
869         let ret = self.parse_type_specifier(false, true);
870         let orp = self.require_right_paren();
871         S!(
872             make_closure_type_specifier,
873             self,
874             olp,
875             coroutine,
876             fnc,
877             ilp,
878             pts,
879             irp,
880             col,
881             ret,
882             orp
883         )
884     }
886     fn parse_tuple_type_specifier(&mut self) -> S::R {
887         // SPEC
888         // tuple-type-specifier:
889         //   ( type-specifier  ,  type-specifier-list  )
890         // type-specifier-list:
891         //   type-specifiers  ,opt
892         //   type-specifiers
893         //   type-specifier
894         //   type-specifiers , type-specifier
896         // TODO: Here we parse a type list with one or more items, but the grammar
897         // actually requires a type list with two or more items. Give an error in
898         // a later pass if there is only one item here.
900         let left_paren = self.assert_token(TokenKind::LeftParen);
901         let args = self.parse_type_list(TokenKind::RightParen);
902         if self.peek_token_kind() == TokenKind::RightParen {
903             let right_paren = self.next_token();
904             let token = S!(make_token, self, right_paren);
905             S!(make_tuple_type_specifier, self, left_paren, args, token)
906         } else {
907             // ERROR RECOVERY: Don't eat the token that is in the place of the
908             // missing ) or ,.  Assume that it is the ) that is missing and
909             // try to parse whatever is coming after the type.
910             self.with_error(Errors::error1022);
911             let missing = S!(make_missing, self, self.pos());
912             S!(make_tuple_type_specifier, self, left_paren, args, missing)
913         }
914     }
916     fn parse_nullable_type_specifier(&mut self) -> S::R {
917         // SPEC:
918         // nullable-type-specifier:
919         //   ? type-specifier
920         //   mixed
921         //
922         // Note that we parse "mixed" as a simple type specifier, even though
923         // technically it is classified as a nullable type specifier by the grammar.
924         // Note that it is perfectly legal to have trivia between the ? and the
925         // underlying type.
926         let question = self.assert_token(TokenKind::Question);
927         let nullable_type = self.parse_type_specifier(false, true);
928         S!(make_nullable_type_specifier, self, question, nullable_type)
929     }
931     fn parse_like_type_specifier(&mut self) -> S::R {
932         // SPEC:
933         // like-type-specifier:
934         //   ~ type-specifier
935         //
936         // Note that it is perfectly legal to have trivia between the ~ and the
937         // underlying type.
938         let tilde = self.assert_token(TokenKind::Tilde);
939         let like_type = self.parse_type_specifier(false, true);
940         S!(make_like_type_specifier, self, tilde, like_type)
941     }
943     fn parse_soft_type_specifier(&mut self) -> S::R {
944         // SPEC (Draft)
945         // soft-type-specifier:
946         //   @ type-specifier
947         //
948         // TODO: The spec does not mention this type grammar.  Work out where and
949         // when it is legal, and what the exact semantics are, and put it in the spec.
950         // Add an error pass if necessary to identify illegal usages of this type.
951         //
952         // Note that it is legal for trivia to come between the @ and the type.
953         let soft_at = self.assert_token(TokenKind::At);
954         let soft_type = self.parse_type_specifier(false, true);
955         S!(make_soft_type_specifier, self, soft_at, soft_type)
956     }
958     fn parse_attributized_specifier(&mut self) -> S::R {
959         // SPEC
960         // attributized-specifier:
961         // attribute-specification-opt type-specifier
962         let attribute_spec_opt = self.with_decl_parser(|x: &mut DeclarationParser<'a, S, T>| {
963             x.parse_attribute_specification_opt()
964         });
965         let attributized_type = self.parse_type_specifier(false, true);
966         S!(
967             make_attributized_specifier,
968             self,
969             attribute_spec_opt,
970             attributized_type
971         )
972     }
974     fn parse_classname_type_specifier(&mut self) -> S::R {
975         // SPEC
976         // classname-type-specifier:
977         //   classname
978         //   classname  <  qualified-name generic-type-argument-list-opt >
979         //
980         // TODO: We parse any type as the class name type; we should write an
981         // error detection pass later that determines when this is a bad type.
982         //
983         // TODO: Is this grammar correct?  In particular, can the name have a
984         // scope resolution operator (::) in it?  Find out and update the spec if
985         // this is permitted.
987         // TODO ERROR RECOVERY is unsophisticated here.
988         let classname = self.fetch_token();
989         match self.peek_token_kind() {
990             TokenKind::LessThan => {
991                 let left_angle = self.require_left_angle();
992                 let classname_type = self.parse_type_specifier(false, true);
993                 let optional_comma = self.optional_token(TokenKind::Comma);
994                 let right_angle = self.require_right_angle();
995                 S!(
996                     make_classname_type_specifier,
997                     self,
998                     classname,
999                     left_angle,
1000                     classname_type,
1001                     optional_comma,
1002                     right_angle,
1003                 )
1004             }
1005             _ => {
1006                 let missing1 = S!(make_missing, self, self.pos());
1007                 let missing2 = S!(make_missing, self, self.pos());
1008                 let missing3 = S!(make_missing, self, self.pos());
1009                 let missing4 = S!(make_missing, self, self.pos());
1010                 S!(
1011                     make_classname_type_specifier,
1012                     self,
1013                     classname,
1014                     missing1,
1015                     missing2,
1016                     missing3,
1017                     missing4
1018                 )
1019             }
1020         }
1021     }
1023     fn parse_field_specifier(&mut self) -> S::R {
1024         // SPEC
1025         // field-specifier:
1026         //   ?-opt present-field-specifier
1027         // present-field-specifier:
1028         //   single-quoted-string-literal  =>  type-specifier
1029         //   qualified-name  =>  type-specifier
1030         //   scope-resolution-expression  =>  type-specifier
1032         // TODO: We require that it be either all literals or no literals in the
1033         // set of specifiers; make an error reporting pass that detects this.
1035         // ERROR RECOVERY: We allow any expression for the left-hand side.
1036         // TODO: Make an error-detecting pass that gives an error if the left-hand
1037         // side is not a literal or name.
1038         let question = if self.peek_token_kind() == TokenKind::Question {
1039             self.assert_token(TokenKind::Question)
1040         } else {
1041             S!(make_missing, self, self.pos())
1042         };
1043         let name = self.parse_expression();
1044         let arrow = self.require_arrow();
1045         let field_type = self.parse_type_specifier(false, true);
1046         S!(
1047             make_field_specifier,
1048             self,
1049             question,
1050             name,
1051             arrow,
1052             field_type
1053         )
1054     }
1056     fn parse_shape_specifier(&mut self) -> S::R {
1057         // SPEC
1058         // shape-specifier:
1059         //   shape ( field-specifier-list-opt )
1060         // field-specifier-list:
1061         //   field-specifiers  ,  ...
1062         //   field-specifiers  ,-opt
1063         // field-specifiers:
1064         //   field-specifier
1065         //   field-specifiers  ,  field-specifier
1066         //
1067         // TODO: ERROR RECOVERY is not very sophisticated here.
1068         let shape = self.fetch_token();
1069         let lparen = self.require_left_paren();
1070         let is_closing_token =
1071             |x: TokenKind| x == TokenKind::RightParen || x == TokenKind::DotDotDot;
1072         let fields = self.parse_comma_list_opt_allow_trailing_predicate(
1073             &is_closing_token,
1074             Errors::error1025,
1075             |x: &mut Self| x.parse_field_specifier(),
1076         );
1077         let ellipsis = if self.peek_token_kind() == TokenKind::DotDotDot {
1078             self.assert_token(TokenKind::DotDotDot)
1079         } else {
1080             S!(make_missing, self, self.pos())
1081         };
1082         let rparen = self.require_right_paren();
1083         S!(
1084             make_shape_type_specifier,
1085             self,
1086             shape,
1087             lparen,
1088             fields,
1089             ellipsis,
1090             rparen
1091         )
1092     }
1094     pub fn parse_type_constraint_opt(&mut self) -> S::R {
1095         // SPEC
1096         // type-constraint:
1097         //   as  type-specifier
1098         // TODO: Is this correct? Or do we need to allow "super" as well?
1099         // TODO: What about = ?
1100         if self.peek_token_kind() == TokenKind::As {
1101             let constraint_as = self.next_token();
1102             let constraint_as = S!(make_token, self, constraint_as);
1103             let constraint_type = self.parse_type_specifier(false, true);
1104             S!(make_type_constraint, self, constraint_as, constraint_type)
1105         } else {
1106             S!(make_missing, self, self.pos())
1107         }
1108     }
1110     pub fn parse_return_type(&mut self) -> S::R {
1111         if self.peek_token_kind() == TokenKind::Noreturn {
1112             let token = self.next_token();
1113             S!(make_token, self, token)
1114         } else {
1115             self.parse_type_specifier(false, true)
1116         }
1117     }