Grammar Diff (vN vs vN+1)


vN
vN+1
t1<<< =========================================================t1<<< =========================================================
2   Vitte — Active Frontend Grammar2   Vitte — Active Frontend Grammar
3   parser-aligned surface for docs/tests/frontend sync3   parser-aligned surface for docs/tests/frontend sync
4   canonical blocks: { }4   canonical blocks: { }
5   This file describes the syntax currently preserved by the5   This file describes the syntax currently preserved by the
6   active frontend AST builder. Ambitious future-only surfaces6   active frontend AST builder. Ambitious future-only surfaces
7   should not be specified here until they are actually built.7   should not be specified here until they are actually built.
8   ========================================================= >>>8   ========================================================= >>>
99
10program ::= WS? { toplevel WS? } EOF ;10program ::= WS? { toplevel WS? } EOF ;
1111
12<<< ================= Top-level ================= >>>12<<< ================= Top-level ================= >>>
1313
14toplevel ::= inner_attribute14toplevel ::= inner_attribute
15          | space_decl15          | space_decl
16          | use_decl16          | use_decl
17          | export_decl17          | export_decl
18          | const_decl18          | const_decl
19          | static_decl19          | static_decl
20          | region_decl20          | region_decl
21          | type_alias_decl21          | type_alias_decl
22          | opaque_type_decl22          | opaque_type_decl
23          | extern_type_decl23          | extern_type_decl
24          | form_decl24          | form_decl
25          | class_decl25          | class_decl
26          | union_decl26          | union_decl
27          | bits_decl27          | bits_decl
28          | pick_decl28          | pick_decl
29          | flags_decl29          | flags_decl
30          | trait_decl30          | trait_decl
31          | impl_decl31          | impl_decl
32          | extern_block32          | extern_block
33          | proc_decl33          | proc_decl
34          | intrinsic_decl34          | intrinsic_decl
35          | compiler_decl35          | compiler_decl
36          | query_decl36          | query_decl
37          | pass_decl37          | pass_decl
38          | backend_decl38          | backend_decl
39          | diagnostic_decl39          | diagnostic_decl
40          | macro_decl40          | macro_decl
41          | static_assert_decl41          | static_assert_decl
42          | test_decl42          | test_decl
43          | bench_decl43          | bench_decl
44          | entry_decl44          | entry_decl
45          ;45          ;
4646
47space_decl ::= "space" WS1 module_path ;47space_decl ::= "space" WS1 module_path ;
4848
49use_decl ::= "use" WS1 package_path [ use_group | use_glob ] [ WS1 "as" WS1 ident ] ;49use_decl ::= "use" WS1 package_path [ use_group | use_glob ] [ WS1 "as" WS1 ident ] ;
50use_glob ::= "." "*" ;50use_glob ::= "." "*" ;
51use_group ::= "." "{" WS? ( "*" | import_items [ WS? "," WS? "*" ]? ) WS? "}" ;51use_group ::= "." "{" WS? ( "*" | import_items [ WS? "," WS? "*" ]? ) WS? "}" ;
5252
53import_items ::= import_item { WS? "," WS? import_item } [ WS? "," ] ;53import_items ::= import_item { WS? "," WS? import_item } [ WS? "," ] ;
54import_item ::= ident [ WS1 "as" WS1 ident ] ;54import_item ::= ident [ WS1 "as" WS1 ident ] ;
5555
56export_decl ::= "export" WS1 ( "*" | ident_list | "{" WS? ident_list WS? "}" ) ;56export_decl ::= "export" WS1 ( "*" | ident_list | "{" WS? ident_list WS? "}" ) ;
5757
58const_decl ::= { attr_prefix WS? } "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;58const_decl ::= { attr_prefix WS? } "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;
59static_decl ::= { attr_prefix WS? } "static" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;59static_decl ::= { attr_prefix WS? } "static" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;
60region_decl ::= { attr_prefix WS? } "region" WS1 ident [ WS? ":" WS? region_kind ] [ WS? region_capabilities ] WS? meta_60region_decl ::= { attr_prefix WS? } "region" WS1 ident [ WS? ":" WS? region_kind ] [ WS? region_capabilities ] WS? meta_
>tail ;>tail ;
61region_kind ::= "stack" | "heap" | "arena" | "static" | "mmio" | "dma" | ident ;61region_kind ::= "stack" | "heap" | "arena" | "static" | "mmio" | "dma" | ident ;
62region_capabilities ::= "(" WS? ident_list? WS? ")" ;62region_capabilities ::= "(" WS? ident_list? WS? ")" ;
6363
64type_alias_decl ::= { attr_prefix WS? } "type" WS1 ident [ generic_params ] WS? "=" WS? type_expr ;64type_alias_decl ::= { attr_prefix WS? } "type" WS1 ident [ generic_params ] WS? "=" WS? type_expr ;
65opaque_type_decl ::= { attr_prefix WS? } "opaque" WS1 "type" WS1 ident [ generic_params ] [ WS? "=" WS? type_expr ] ;65opaque_type_decl ::= { attr_prefix WS? } "opaque" WS1 "type" WS1 ident [ generic_params ] [ WS? "=" WS? type_expr ] ;
66extern_type_decl ::= { attr_prefix WS? } "extern" WS1 "type" WS1 ident [ generic_params ] [ WS? ";" ] ;66extern_type_decl ::= { attr_prefix WS? } "extern" WS1 "type" WS1 ident [ generic_params ] [ WS? ";" ] ;
6767
68form_decl ::= { attr_prefix WS? } "form" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? form_items? WS? "68form_decl ::= { attr_prefix WS? } "form" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? form_items? WS? "
>}" ;>}" ;
69class_decl ::= { attr_prefix WS? } "class" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? class_items? WS69class_decl ::= { attr_prefix WS? } "class" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? class_items? WS
>? "}" ;>? "}" ;
70union_decl ::= { attr_prefix WS? } "union" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? field_list? WS?70union_decl ::= { attr_prefix WS? } "union" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS? field_list? WS?
> "}" ;> "}" ;
7171
72form_items ::= form_item { WS? ","? WS? form_item } [ WS? "," ] ;72form_items ::= form_item { WS? ","? WS? form_item } [ WS? "," ] ;
73form_item ::= field_item | const_decl | type_alias_decl | proc_decl ;73form_item ::= field_item | const_decl | type_alias_decl | proc_decl ;
7474
75class_items ::= class_item { WS? ","? WS? class_item } [ WS? "," ] ;75class_items ::= class_item { WS? ","? WS? class_item } [ WS? "," ] ;
76class_item ::= field_item | const_decl | type_alias_decl | proc_decl ;76class_item ::= field_item | const_decl | type_alias_decl | proc_decl ;
7777
78field_list ::= field_item { WS? "," WS? field_item } [ WS? "," ] ;78field_list ::= field_item { WS? "," WS? field_item } [ WS? "," ] ;
79field_item ::= { attr_prefix WS? } [ visibility WS1 ] ident WS? ":" WS? type_expr [ WS? "=" WS? expr ] ;79field_item ::= { attr_prefix WS? } [ visibility WS1 ] ident WS? ":" WS? type_expr [ WS? "=" WS? expr ] ;
8080
81bits_decl ::= { attr_prefix WS? } "bits" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? bitfield_list? WS? "}" ;81bits_decl ::= { attr_prefix WS? } "bits" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? bitfield_list? WS? "}" ;
82bitfield_list ::= bitfield_item { WS? "," WS? bitfield_item } [ WS? "," ] ;82bitfield_list ::= bitfield_item { WS? "," WS? bitfield_item } [ WS? "," ] ;
83bitfield_item ::= ident WS? ":" WS? expr WS? ".." WS? expr ;83bitfield_item ::= ident WS? ":" WS? expr WS? ".." WS? expr ;
8484
85pick_decl ::= { attr_prefix WS? } "pick" WS1 ident [ generic_params ] [ WS? ":" WS? type_expr ] [ WS? where_clause ] WS?85pick_decl ::= { attr_prefix WS? } "pick" WS1 ident [ generic_params ] [ WS? ":" WS? type_expr ] [ WS? where_clause ] WS?
> "{" WS? case_list? WS? "}" ;> "{" WS? case_list? WS? "}" ;
86case_list ::= case_item { WS? "," WS? case_item } [ WS? "," ] ;86case_list ::= case_item { WS? "," WS? case_item } [ WS? "," ] ;
87case_item ::= [ "case" WS1 ] ident [ "(" WS? case_payload? WS? ")" ] [ WS? "=" WS? expr ] ;87case_item ::= [ "case" WS1 ] ident [ "(" WS? case_payload? WS? ")" ] [ WS? "=" WS? expr ] ;
88case_payload ::= case_field { WS? "," WS? case_field } [ WS? "," ] ;88case_payload ::= case_field { WS? "," WS? case_field } [ WS? "," ] ;
89case_field ::= ident WS? ":" WS? type_expr | type_expr ;89case_field ::= ident WS? ":" WS? type_expr | type_expr ;
9090
91flags_decl ::= { attr_prefix WS? } "flags" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? flag_list? WS? "}" ;91flags_decl ::= { attr_prefix WS? } "flags" WS1 ident [ WS? ":" WS? type_expr ] WS? "{" WS? flag_list? WS? "}" ;
92flag_list ::= flag_item { WS? "," WS? flag_item } [ WS? "," ] ;92flag_list ::= flag_item { WS? "," WS? flag_item } [ WS? "," ] ;
93flag_item ::= ident [ WS? "=" WS? expr ] ;93flag_item ::= ident [ WS? "=" WS? expr ] ;
9494
95trait_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "trait" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS95trait_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "trait" WS1 ident [ generic_params ] [ WS? where_clause ] WS? "{" WS
>? trait_item* WS? "}" ;>? trait_item* WS? "}" ;
96trait_item ::= proc_signature | const_decl | associated_type_decl ;96trait_item ::= proc_signature | const_decl | associated_type_decl ;
9797
98associated_type_decl ::= "type" WS1 ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ] ;98associated_type_decl ::= "type" WS1 ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ] ;
9999
100impl_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "impl" WS1 impl_head [ WS? where_clause ] WS? "{" WS? impl_item* WS? 100impl_decl ::= { attr_prefix WS? } [ "unsafe" WS1 ] "impl" WS1 impl_head [ WS? where_clause ] WS? "{" WS? impl_item* WS? 
>"}" ;>"}" ;
101impl_head ::= type_expr | type_expr WS1 "for" WS1 type_expr ;101impl_head ::= type_expr | type_expr WS1 "for" WS1 type_expr ;
102impl_item ::= const_decl | type_alias_decl | associated_type_decl | proc_decl ;102impl_item ::= const_decl | type_alias_decl | associated_type_decl | proc_decl ;
103103
104proc_signature ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ]104proc_signature ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ]
105                   "(" WS? param_list? WS? ")"105                   "(" WS? param_list? WS? ")"
106                   [ WS? "->" WS? type_expr ]106                   [ WS? "->" WS? type_expr ]
107                   WS? proc_suffix*107                   WS? proc_suffix*
108                   WS? ";"108                   WS? ";"
109                   ;109                   ;
110110
111proc_decl ::= { attr_prefix WS? } [ visibility WS1 ] proc_modifier* [ extern_clause WS1 ] "proc" WS1 proc_name [ generic111proc_decl ::= { attr_prefix WS? } [ visibility WS1 ] proc_modifier* [ extern_clause WS1 ] "proc" WS1 proc_name [ generic
>_params ]>_params ]
112              "(" WS? param_list? WS? ")"112              "(" WS? param_list? WS? ")"
113              [ WS? "->" WS? type_expr ]113              [ WS? "->" WS? type_expr ]
114              WS? proc_suffix*114              WS? proc_suffix*
115              WS? ( block | ";" )115              WS? ( block | ";" )
116              ;116              ;
117117
118proc_name ::= ident | "operator" WS? operator_symbol ;118proc_name ::= ident | "operator" WS? operator_symbol ;
119operator_symbol ::= "+" | "-" | "*" | "/" | "%"119operator_symbol ::= "+" | "-" | "*" | "/" | "%"
120                  | "==" | "!=" | "<" | "<=" | ">" | ">="120                  | "==" | "!=" | "<" | "<=" | ">" | ">="
121                  | "[]" | "()" ;121                  | "[]" | "()" ;
122122
123proc_modifier ::= "async" WS1123proc_modifier ::= "async" WS1
124                | "unsafe" WS1124                | "unsafe" WS1
125                | "const" WS1125                | "const" WS1
126                | "inline" WS1126                | "inline" WS1
127                | "noinline" WS1127                | "noinline" WS1
128                | "naked" WS1128                | "naked" WS1
129                | "interrupt" WS1129                | "interrupt" WS1
130                ;130                ;
131131
132proc_suffix ::= effects_clause132proc_suffix ::= effects_clause
133              | requires_clause133              | requires_clause
134              | where_clause134              | where_clause
135              | "noexcept"135              | "noexcept"
136              ;136              ;
137137
138extern_block ::= { attr_prefix WS? } "extern" WS1 extern_abi WS? "{" WS? extern_item* WS? "}" ;138extern_block ::= { attr_prefix WS? } "extern" WS1 extern_abi WS? "{" WS? extern_item* WS? "}" ;
139extern_item ::= extern_proc_decl | extern_type_decl | const_decl ;139extern_item ::= extern_proc_decl | extern_type_decl | const_decl ;
140140
141extern_proc_decl ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ]141extern_proc_decl ::= { attr_prefix WS? } "proc" WS1 ident [ generic_params ]
142                     "(" WS? param_list? WS? ")"142                     "(" WS? param_list? WS? ")"
143                     [ WS? "->" WS? type_expr ]143                     [ WS? "->" WS? type_expr ]
144                     WS? proc_suffix*144                     WS? proc_suffix*
145                     WS? ";"145                     WS? ";"
146                     ;146                     ;
147147
148extern_clause ::= "extern" WS1 extern_abi ;148extern_clause ::= "extern" WS1 extern_abi ;
149extern_abi ::= callconv | string_lit ;149extern_abi ::= callconv | string_lit ;
150callconv ::= "C" | "sysv64" | "win64" | "interrupt" | "naked" ;150callconv ::= "C" | "sysv64" | "win64" | "interrupt" | "naked" ;
151151
152intrinsic_decl ::= { attr_prefix WS? } "intrinsic" WS1 ident [ generic_params ]152intrinsic_decl ::= { attr_prefix WS? } "intrinsic" WS1 ident [ generic_params ]
153                   "(" WS? param_list? WS? ")"153                   "(" WS? param_list? WS? ")"
154                   [ WS? "->" WS? type_expr ]154                   [ WS? "->" WS? type_expr ]
155                   WS? ";"155                   WS? ";"
156                   ;156                   ;
157157
158<<< macro / compiler / pass / backend / diagnostic / entry are currently158<<< macro / compiler / pass / backend / diagnostic / entry are currently
159    preserved as top-level meta items by the frontend. They accept either a159    preserved as top-level meta items by the frontend. They accept either a
160    trailing ";" form or a raw "{ ... }" body, but the body is not yet parsed160    trailing ";" form or a raw "{ ... }" body, but the body is not yet parsed
161    into a dedicated structured AST. Keep these rules narrow and parser-aligned. >>>161    into a dedicated structured AST. Keep these rules narrow and parser-aligned. >>>
162macro_decl ::= { attr_prefix WS? } "macro" WS1 ident [ "(" WS? macro_param_list? WS? ")" ] WS? meta_tail ;162macro_decl ::= { attr_prefix WS? } "macro" WS1 ident [ "(" WS? macro_param_list? WS? ")" ] WS? meta_tail ;
163macro_param_list ::= macro_param { WS? "," WS? macro_param } [ WS? "," ] ;163macro_param_list ::= macro_param { WS? "," WS? macro_param } [ WS? "," ] ;
164macro_param ::= ident [ WS? ":" WS? macro_kind ] ;164macro_param ::= ident [ WS? ":" WS? macro_kind ] ;
165macro_kind ::= "expr" | "stmt" | "type" | "ident" | "block" | "item" ;165macro_kind ::= "expr" | "stmt" | "type" | "ident" | "block" | "item" ;
166166
167static_assert_decl ::= "static_assert" WS? "(" WS? expr [ WS? "," WS? expr ] WS? ")" ;167static_assert_decl ::= "static_assert" WS? "(" WS? expr [ WS? "," WS? expr ] WS? ")" ;
168test_decl ::= { attr_prefix WS? } "test" WS1 string_lit WS? block ;168test_decl ::= { attr_prefix WS? } "test" WS1 string_lit WS? block ;
169bench_decl ::= { attr_prefix WS? } "bench" WS1 string_lit WS? block ;169bench_decl ::= { attr_prefix WS? } "bench" WS1 string_lit WS? block ;
170entry_decl ::= { attr_prefix WS? } "entry" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;170entry_decl ::= { attr_prefix WS? } "entry" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;
171171
172visibility ::= "pub" | "priv" | "pub" WS? "(" WS? visibility_scope WS? ")" ;172visibility ::= "pub" | "priv" | "pub" WS? "(" WS? visibility_scope WS? ")" ;
173visibility_scope ::= "package" | "module" | "super" ;173visibility_scope ::= "package" | "module" | "super" ;
174174
175generic_params ::= "[" WS? generic_param_list? WS? "]" ;175generic_params ::= "[" WS? generic_param_list? WS? "]" ;
176generic_param_list ::= generic_param { WS? "," WS? generic_param } [ WS? "," ] ;176generic_param_list ::= generic_param { WS? "," WS? generic_param } [ WS? "," ] ;
177generic_param ::= ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ]177generic_param ::= ident [ WS? ":" WS? trait_bound ] [ WS? "=" WS? type_expr ]
178                | "const" WS1 ident WS? ":" WS? type_expr178                | "const" WS1 ident WS? ":" WS? type_expr
179                | "comptime" WS1 ident WS? ":" WS? type_expr179                | "comptime" WS1 ident WS? ":" WS? type_expr
180                ;180                ;
181181
182where_clause ::= "where" WS1 where_bounds ;182where_clause ::= "where" WS1 where_bounds ;
183where_bounds ::= where_bound { WS? "," WS? where_bound } [ WS? "," ] ;183where_bounds ::= where_bound { WS? "," WS? where_bound } [ WS? "," ] ;
184where_bound ::= type_expr WS? ":" WS? trait_bound184where_bound ::= type_expr WS? ":" WS? trait_bound
185              | type_expr WS? "==" WS? type_expr185              | type_expr WS? "==" WS? type_expr
186              | expr WS? rel_op WS? expr186              | expr WS? rel_op WS? expr
187              ;187              ;
188188
189trait_bound ::= type_expr { WS? "+" WS? type_expr } ;189trait_bound ::= type_expr { WS? "+" WS? type_expr } ;
190190
191param_list ::= param { WS? "," WS? param } [ WS? "," ] ;191param_list ::= param { WS? "," WS? param } [ WS? "," ] ;
192param ::= self_param | normal_param | variadic_param ;192param ::= self_param | normal_param | variadic_param ;
193self_param ::= [ "&" WS? ] [ "mut" WS1 ] "self" ;193self_param ::= [ "&" WS? ] [ "mut" WS1 ] "self" ;
194normal_param ::= [ param_mode WS1 ] pattern [ WS? ":" WS? type_expr ] [ WS? "=" WS? expr ] ;194normal_param ::= [ param_mode WS1 ] pattern [ WS? ":" WS? type_expr ] [ WS? "=" WS? expr ] ;
195variadic_param ::= "..." | ident WS? ":" WS? "..." type_expr ;195variadic_param ::= "..." | ident WS? ":" WS? "..." type_expr ;
196param_mode ::= "mut" | "owned" | "borrow" | "move" ;196param_mode ::= "mut" | "owned" | "borrow" | "move" ;
197197
198effects_clause ::= "effects" WS? "(" WS? ident_list? WS? ")" ;198effects_clause ::= "effects" WS? "(" WS? ident_list? WS? ")" ;
199requires_clause ::= "requires" WS? "(" WS? capability_list? WS? ")" ;199requires_clause ::= "requires" WS? "(" WS? capability_list? WS? ")" ;
200capability_list ::= capability { WS? "," WS? capability } [ WS? "," ] ;200capability_list ::= capability { WS? "," WS? capability } [ WS? "," ] ;
201capability ::= ident { "." ident } ;201capability ::= ident { "." ident } ;
202202
203module_path ::= relative? package_parts ;203module_path ::= relative? package_parts ;
204package_path ::= relative? package_parts ;204package_path ::= relative? package_parts ;
205relative ::= { "." } ;205relative ::= { "." } ;
206package_parts ::= ident { ( "/" | "." | "::" ) ident } ;206package_parts ::= ident { ( "/" | "." | "::" ) ident } ;
207ident_list ::= ident { WS? "," WS? ident } [ WS? "," ] ;207ident_list ::= ident { WS? "," WS? ident } [ WS? "," ] ;
208208
209query_decl ::= { attr_prefix WS? } "query" WS1 ident209query_decl ::= { attr_prefix WS? } "query" WS1 ident
210               "(" WS? param_list? WS? ")"210               "(" WS? param_list? WS? ")"
211               WS? "->" WS? type_expr211               WS? "->" WS? type_expr
212               WS? query_body ;212               WS? query_body ;
213213
214query_body ::= block | ";" ;214query_body ::= block | ";" ;
215215
216<<< ================= Meta Declarations ================= >>>216<<< ================= Meta Declarations ================= >>>
217217
218compiler_decl ::= { attr_prefix WS? } "compiler" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;218compiler_decl ::= { attr_prefix WS? } "compiler" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;
219pass_decl ::= { attr_prefix WS? } "pass" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;219pass_decl ::= { attr_prefix WS? } "pass" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;
220backend_decl ::= { attr_prefix WS? } "backend" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;220backend_decl ::= { attr_prefix WS? } "backend" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;
221diagnostic_decl ::= { attr_prefix WS? } "diagnostic" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;221diagnostic_decl ::= { attr_prefix WS? } "diagnostic" WS1 ident_or_string [ WS? meta_args ] WS? meta_tail ;
222222
223ident_or_string ::= ident | string_lit ;223ident_or_string ::= ident | string_lit ;
224meta_args ::= "(" WS? meta_arg_list? WS? ")" ;224meta_args ::= "(" WS? meta_arg_list? WS? ")" ;
225meta_arg_list ::= meta_arg { WS? "," WS? meta_arg } [ WS? "," ] ;225meta_arg_list ::= meta_arg { WS? "," WS? meta_arg } [ WS? "," ] ;
226meta_arg ::= ident_or_string ;226meta_arg ::= ident_or_string ;
227meta_tail ::= block | ";" ;227meta_tail ::= block | ";" ;
228228
229<<< ================= Attributes ================= >>>229<<< ================= Attributes ================= >>>
230230
231attr_prefix ::= outer_attribute | doc_comment | docstring ;231attr_prefix ::= outer_attribute | doc_comment | docstring ;
232inner_attribute ::= "#![" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ;232inner_attribute ::= "#![" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ;
233outer_attribute ::= "#[" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ;233outer_attribute ::= "#[" attr_path [ "(" WS? attr_arg_list? WS? ")" ] "]" ;
234doc_comment ::= "///" { ~NEWLINE ANY } ;234doc_comment ::= "///" { ~NEWLINE ANY } ;
235docstring ::= raw_string_lit ;235docstring ::= raw_string_lit ;
236236
237attr_path ::= ident { "." ident } ;237attr_path ::= ident { "." ident } ;
238attr_arg_list ::= attr_arg { WS? "," WS? attr_arg } [ WS? "," ] ;238attr_arg_list ::= attr_arg { WS? "," WS? attr_arg } [ WS? "," ] ;
239attr_arg ::= ident239attr_arg ::= ident
240           | string_lit240           | string_lit
241           | int_lit241           | int_lit
242           | bool_lit242           | bool_lit
243           | ident WS? "=" WS? literal243           | ident WS? "=" WS? literal
244           ;244           ;
245245
246<<< ================= Blocks / Statements ================= >>>246<<< ================= Blocks / Statements ================= >>>
247247
248block ::= "{" WS? { stmt WS? } "}" ;248block ::= "{" WS? { stmt WS? } "}" ;
249249
250stmt ::= local_const_stmt stmt_end250stmt ::= local_const_stmt stmt_end
251       | let_stmt stmt_end251       | let_stmt stmt_end
252       | set_stmt stmt_end252       | set_stmt stmt_end
253       | give_stmt stmt_end253       | give_stmt stmt_end
254       | try_stmt stmt_end254       | try_stmt stmt_end
255       | defer_stmt255       | defer_stmt
256       | asm_stmt stmt_end256       | asm_stmt stmt_end
257       | unsafe_stmt257       | unsafe_stmt
258       | emit_stmt stmt_end258       | emit_stmt stmt_end
259       | assert_stmt stmt_end259       | assert_stmt stmt_end
260       | panic_stmt stmt_end260       | panic_stmt stmt_end
261       | unreachable_stmt stmt_end261       | unreachable_stmt stmt_end
262       | if_stmt262       | if_stmt
263       | while_stmt263       | while_stmt
264       | loop_stmt264       | loop_stmt
265       | for_stmt265       | for_stmt
266       | break_stmt stmt_end266       | break_stmt stmt_end
267       | continue_stmt stmt_end267       | continue_stmt stmt_end
268       | select_stmt268       | select_stmt
269       | match_stmt269       | match_stmt
270       | when_match_stmt270       | when_match_stmt
271       | with_stmt271       | with_stmt
272       | critical_stmt272       | critical_stmt
273       | expr_stmt stmt_end273       | expr_stmt stmt_end
274       ;274       ;
275275
276stmt_end ::= WS? ";" ;276stmt_end ::= WS? ";" ;
277277
278local_const_stmt ::= "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;278local_const_stmt ::= "const" WS1 ident [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;
279let_stmt ::= "let" WS1 [ "mut" WS1 ] pattern [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;279let_stmt ::= "let" WS1 [ "mut" WS1 ] pattern [ WS? ":" WS? type_expr ] WS? "=" WS? expr ;
280<<< assign_target stays intentionally syntactic here; projection validity and aliasing280<<< assign_target stays intentionally syntactic here; projection validity and aliasing
281    are enforced later by sema/typeck/borrowck on structured HIR/MIR places. >>>281    are enforced later by sema/typeck/borrowck on structured HIR/MIR places. >>>
282set_stmt ::= "set" WS1 assign_target WS? assign_op WS? expr ;282set_stmt ::= "set" WS1 assign_target WS? assign_op WS? expr ;
283assign_target ::= unary_expr ;283assign_target ::= unary_expr ;
284284
285give_stmt ::= "give" [ WS1 expr ] ;285give_stmt ::= "give" [ WS1 expr ] ;
286try_stmt ::= "try" WS1 expr ;286try_stmt ::= "try" WS1 expr ;
287defer_stmt ::= "defer" WS? block ;287defer_stmt ::= "defer" WS? block ;
288288
289asm_stmt ::= "asm" WS? "(" WS? asm_arg_list? WS? ")" ;289asm_stmt ::= "asm" WS? "(" WS? asm_arg_list? WS? ")" ;
290asm_arg_list ::= asm_arg { WS? "," WS? asm_arg } [ WS? "," ] ;290asm_arg_list ::= asm_arg { WS? "," WS? asm_arg } [ WS? "," ] ;
291asm_arg ::= string_lit | ident WS? "(" WS? arg_list? WS? ")" | ident WS? ":" WS? expr ;291asm_arg ::= string_lit | ident WS? "(" WS? arg_list? WS? ")" | ident WS? ":" WS? expr ;
292292
293unsafe_stmt ::= "unsafe" WS? block ;293unsafe_stmt ::= "unsafe" WS? block ;
294294
295emit_stmt ::= "emit" WS1 expr ;295emit_stmt ::= "emit" WS1 expr ;
296assert_stmt ::= "assert" WS1 expr [ WS? "," WS? expr ] ;296assert_stmt ::= "assert" WS1 expr [ WS? "," WS? expr ] ;
297panic_stmt ::= "panic" WS1 expr ;297panic_stmt ::= "panic" WS1 expr ;
298unreachable_stmt ::= "unreachable" ;298unreachable_stmt ::= "unreachable" ;
299299
300if_stmt ::= "if" WS1 expr WS? block300if_stmt ::= "if" WS1 expr WS? block
301            { WS? "elif" WS1 expr WS? block }301            { WS? "elif" WS1 expr WS? block }
302            [ WS? "else" WS? block ] ;302            [ WS? "else" WS? block ] ;
303303
304while_stmt ::= "while" WS1 expr WS? block ;304while_stmt ::= "while" WS1 expr WS? block ;
305loop_stmt ::= "loop" WS? block ;305loop_stmt ::= "loop" WS? block ;
306for_stmt ::= "for" WS1 pattern WS1 "in" WS1 expr WS? block ;306for_stmt ::= "for" WS1 pattern WS1 "in" WS1 expr WS? block ;
307307
308break_stmt ::= "break" [ WS1 expr ] ;308break_stmt ::= "break" [ WS1 expr ] ;
309continue_stmt ::= "continue" ;309continue_stmt ::= "continue" ;
310310
311select_stmt ::= "select" WS1 expr WS? "{" WS?311select_stmt ::= "select" WS1 expr WS? "{" WS?
312                { "when" WS1 pattern WS? block WS? }312                { "when" WS1 pattern WS? block WS? }
313                [ "else" WS? block ]313                [ "else" WS? block ]
314                WS? "}" ;314                WS? "}" ;
315315
316match_stmt ::= "match" WS1 expr WS?316match_stmt ::= "match" WS1 expr WS?
317               "{" WS?317               "{" WS?
318               { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? }318               { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? }
319               [ WS? "else" WS? match_arm_body ]319               [ WS? "else" WS? match_arm_body ]
320               WS? "}" ;320               WS? "}" ;
321321
322match_arm_body ::= block | "=>" WS? expr WS? ";" ;322match_arm_body ::= block | "=>" WS? expr WS? ";" ;
323323
324when_match_stmt ::= "when" WS1 expr WS1 "is" WS1 pattern WS? block ;324when_match_stmt ::= "when" WS1 expr WS1 "is" WS1 pattern WS? block ;
325with_stmt ::= "with" WS1 expr [ WS1 "as" WS1 pattern ] WS? block ;325with_stmt ::= "with" WS1 expr [ WS1 "as" WS1 pattern ] WS? block ;
326critical_stmt ::= "critical" WS? block ;326critical_stmt ::= "critical" WS? block ;
327expr_stmt ::= expr ;327expr_stmt ::= expr ;
328328
329<<< ================= Expressions ================= >>>329<<< ================= Expressions ================= >>>
330330
331expr ::= assign_expr ;331expr ::= assign_expr ;
332332
333assign_expr ::= ternary_expr [ WS? assign_op WS? assign_expr ] ;333assign_expr ::= ternary_expr [ WS? assign_op WS? assign_expr ] ;
334assign_op ::= "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" ;334assign_op ::= "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" ;
335335
336ternary_expr ::= coalesce_expr [ WS? "?" WS? expr WS? ":" WS? expr ] ;336ternary_expr ::= coalesce_expr [ WS? "?" WS? expr WS? ":" WS? expr ] ;
337coalesce_expr ::= range_expr { WS? "??" WS? range_expr } ;337coalesce_expr ::= range_expr { WS? "??" WS? range_expr } ;
338range_expr ::= or_expr [ WS? ( ".." | "..=" ) WS? or_expr ] ;338range_expr ::= or_expr [ WS? ( ".." | "..=" ) WS? or_expr ] ;
339339
340or_expr ::= and_expr { WS? ( "or" | "||" ) WS? and_expr } ;340or_expr ::= and_expr { WS? ( "or" | "||" ) WS? and_expr } ;
341and_expr ::= bit_or_expr { WS? ( "and" | "&&" ) WS? bit_or_expr } ;341and_expr ::= bit_or_expr { WS? ( "and" | "&&" ) WS? bit_or_expr } ;
342342
343bit_or_expr ::= bit_xor_expr { WS? "|" WS? bit_xor_expr } ;343bit_or_expr ::= bit_xor_expr { WS? "|" WS? bit_xor_expr } ;
344bit_xor_expr ::= bit_and_expr { WS? "^" WS? bit_and_expr } ;344bit_xor_expr ::= bit_and_expr { WS? "^" WS? bit_and_expr } ;
345bit_and_expr ::= eq_expr { WS? "&" WS? eq_expr } ;345bit_and_expr ::= eq_expr { WS? "&" WS? eq_expr } ;
346346
347eq_expr ::= rel_expr { WS? ( "==" | "!=" ) WS? rel_expr } ;347eq_expr ::= rel_expr { WS? ( "==" | "!=" ) WS? rel_expr } ;
348rel_expr ::= shift_expr { WS? rel_op WS? shift_expr } ;348rel_expr ::= shift_expr { WS? rel_op WS? shift_expr } ;
349rel_op ::= "<" | "<=" | ">" | ">=" | "in" | "not" WS1 "in" ;349rel_op ::= "<" | "<=" | ">" | ">=" | "in" | "not" WS1 "in" ;
350350
351shift_expr ::= add_expr { WS? ( "<<" | ">>" ) WS? add_expr } ;351shift_expr ::= add_expr { WS? ( "<<" | ">>" ) WS? add_expr } ;
352add_expr ::= mul_expr { WS? ( "+" | "-" ) WS? mul_expr } ;352add_expr ::= mul_expr { WS? ( "+" | "-" ) WS? mul_expr } ;
353mul_expr ::= cast_expr { WS? ( "*" | "/" | "%" ) WS? cast_expr } ;353mul_expr ::= cast_expr { WS? ( "*" | "/" | "%" ) WS? cast_expr } ;
354354
355cast_expr ::= unary_expr { WS? ( "as" WS? type_expr | "is" WS? pattern | "is" WS1 "not" WS1 pattern ) } ;355cast_expr ::= unary_expr { WS? ( "as" WS? type_expr | "is" WS? pattern | "is" WS1 "not" WS1 pattern ) } ;
356356
357<<< unary borrow and move syntax are accepted at parse time; whether a use is357<<< unary borrow and move syntax are accepted at parse time; whether a use is
358    actually a copy or a move is decided later from inferred types. >>>358    actually a copy or a move is decided later from inferred types. >>>
359unary_expr ::= ( "not" | "-" | "~" | "*" | "&" | "move" | "await" ) WS? unary_expr359unary_expr ::= ( "not" | "-" | "~" | "*" | "&" | "move" | "await" ) WS? unary_expr
360             | postfix_expr360             | postfix_expr
361             ;361             ;
362362
363<<< postfix chains define the full place surface used later by ownership and363<<< postfix chains define the full place surface used later by ownership and
364    borrow analysis: field projection, indexing, call, try and await suffixes. >>>364    borrow analysis: field projection, indexing, call, try and await suffixes. >>>
365postfix_expr ::= primary { call_suffix | member_suffix | index_suffix | try_suffix | await_suffix } ;365postfix_expr ::= primary { call_suffix | member_suffix | index_suffix | try_suffix | await_suffix } ;
366call_suffix ::= "(" WS? arg_list? WS? ")" ;366call_suffix ::= "(" WS? arg_list? WS? ")" ;
367member_suffix ::= "." ident ;367member_suffix ::= "." ident ;
368index_suffix ::= "[" WS? index_expr WS? "]" ;368index_suffix ::= "[" WS? index_expr WS? "]" ;
369try_suffix ::= "?" ;369try_suffix ::= "?" ;
370await_suffix ::= "." "await" ;370await_suffix ::= "." "await" ;
371371
372index_expr ::= expr | slice_expr ;372index_expr ::= expr | slice_expr ;
373slice_expr ::= [ expr ] ":" [ expr ] [ ":" expr ] ;373slice_expr ::= [ expr ] ":" [ expr ] [ ":" expr ] ;
374374
375primary ::= literal375primary ::= literal
376          | builtin_expr376          | builtin_expr
377          | path_expr377          | path_expr
378          | struct_lit378          | struct_lit
379          | list_lit379          | list_lit
380          | tuple_lit380          | tuple_lit
381          | set_lit381          | set_lit
382          | map_lit382          | map_lit
383          | bytes_lit383          | bytes_lit
384          | resource_lit384          | resource_lit
385          | if_expr385          | if_expr
386          | proc_expr386          | proc_expr
387          | match_expr387          | match_expr
388          | lambda_expr388          | lambda_expr
389          | unsafe_expr389          | unsafe_expr
390          | block390          | block
391          | "(" WS? expr WS? ")"391          | "(" WS? expr WS? ")"
392          ;392          ;
393393
394path_expr ::= ident { ( "." | "::" ) ident } ;394path_expr ::= ident { ( "." | "::" ) ident } ;
395395
396arg_list ::= arg { WS? "," WS? arg } [ WS? "," ] ;396arg_list ::= arg { WS? "," WS? arg } [ WS? "," ] ;
397arg ::= ident WS? ":" WS? expr | expr ;397arg ::= ident WS? ":" WS? expr | expr ;
398398
399tuple_lit ::= "(" WS? expr WS? "," WS? expr { WS? "," WS? expr } [ WS? "," ] WS? ")" ;399tuple_lit ::= "(" WS? expr WS? "," WS? expr { WS? "," WS? expr } [ WS? "," ] WS? ")" ;
400set_lit ::= "set" WS? "{" WS? arg_list? WS? "}" ;400set_lit ::= "set" WS? "{" WS? arg_list? WS? "}" ;
401401
402map_lit ::= "map" WS? "{" WS? map_items? WS? "}" ;402map_lit ::= "map" WS? "{" WS? map_items? WS? "}" ;
403map_items ::= map_item { WS? "," WS? map_item } [ WS? "," ] ;403map_items ::= map_item { WS? "," WS? map_item } [ WS? "," ] ;
404map_item ::= expr WS? ":" WS? expr ;404map_item ::= expr WS? ":" WS? expr ;
405405
406bytes_lit ::= "b" string_lit ;406bytes_lit ::= "b" string_lit ;
407407
408resource_lit ::= "resource" WS? "{" WS? resource_items? WS? "}" ;408resource_lit ::= "resource" WS? "{" WS? resource_items? WS? "}" ;
409resource_items ::= resource_item { WS? "," WS? resource_item } [ WS? "," ] ;409resource_items ::= resource_item { WS? "," WS? resource_item } [ WS? "," ] ;
410resource_item ::= ident WS? ":" WS? expr ;410resource_item ::= ident WS? ":" WS? expr ;
411411
412struct_lit ::= type_path WS? "{" WS? field_init_list? WS? "}" ;412struct_lit ::= type_path WS? "{" WS? field_init_list? WS? "}" ;
413type_path ::= ident { ( "." | "::" ) ident } ;413type_path ::= ident { ( "." | "::" ) ident } ;
414field_init_list ::= field_init { WS? "," WS? field_init } [ WS? "," ] ;414field_init_list ::= field_init { WS? "," WS? field_init } [ WS? "," ] ;
415field_init ::= ident WS? ":" WS? expr415field_init ::= ident WS? ":" WS? expr
416             | ident416             | ident
417             | ".." expr417             | ".." expr
418             ;418             ;
419419
420if_expr ::= "if" WS1 expr WS? block420if_expr ::= "if" WS1 expr WS? block
421            { WS? "elif" WS1 expr WS? block }421            { WS? "elif" WS1 expr WS? block }
422            [ WS? "else" WS? block ] ;422            [ WS? "else" WS? block ] ;
423423
424proc_expr ::= { attr_prefix WS? } proc_modifier* "proc" WS? "(" WS? param_list? WS? ")"424proc_expr ::= { attr_prefix WS? } proc_modifier* "proc" WS? "(" WS? param_list? WS? ")"
425              [ WS? "->" WS? type_expr ]425              [ WS? "->" WS? type_expr ]
426              WS? proc_suffix*426              WS? proc_suffix*
427              WS? block ;427              WS? block ;
428428
429match_expr ::= "match" WS1 expr WS?429match_expr ::= "match" WS1 expr WS?
430               "{" WS?430               "{" WS?
431               { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? }431               { "case" WS1 pattern [ WS1 "if" WS1 expr ] WS? match_arm_body WS? }
432               [ WS? "else" WS? match_arm_body ]432               [ WS? "else" WS? match_arm_body ]
433               WS? "}" ;433               WS? "}" ;
434434
435lambda_expr ::= "|" WS? param_list? WS? "|" WS? ( expr | block ) ;435lambda_expr ::= "|" WS? param_list? WS? "|" WS? ( expr | block ) ;
436unsafe_expr ::= "unsafe" WS? block ;436unsafe_expr ::= "unsafe" WS? block ;
437437
438builtin_expr ::= sizeof_expr | alignof_expr | offsetof_expr | typeof_expr | nameof_expr ;438builtin_expr ::= sizeof_expr | alignof_expr | offsetof_expr | typeof_expr | nameof_expr ;
439sizeof_expr ::= "sizeof" WS? "(" WS? ( type_expr | expr ) WS? ")" ;439sizeof_expr ::= "sizeof" WS? "(" WS? ( type_expr | expr ) WS? ")" ;
440alignof_expr ::= "alignof" WS? "(" WS? type_expr WS? ")" ;440alignof_expr ::= "alignof" WS? "(" WS? type_expr WS? ")" ;
441offsetof_expr ::= "offsetof" WS? "(" WS? type_expr WS? "," WS? ident WS? ")" ;441offsetof_expr ::= "offsetof" WS? "(" WS? type_expr WS? "," WS? ident WS? ")" ;
442typeof_expr ::= "typeof" WS? "(" WS? expr WS? ")" ;442typeof_expr ::= "typeof" WS? "(" WS? expr WS? ")" ;
443nameof_expr ::= "nameof" WS? "(" WS? path_expr WS? ")" ;443nameof_expr ::= "nameof" WS? "(" WS? path_expr WS? ")" ;
444444
445<<< ================= Patterns ================= >>>445<<< ================= Patterns ================= >>>
446446
447pattern ::= pattern_or ;447pattern ::= pattern_or ;
448pattern_or ::= pattern_atom { WS? "|" WS? pattern_atom } ;448pattern_or ::= pattern_atom { WS? "|" WS? pattern_atom } ;
449449
450pattern_atom ::= "_"450pattern_atom ::= "_"
451               | literal451               | literal
452               | "mut" WS1 pattern_bind452               | "mut" WS1 pattern_bind
453               | "ref" WS1 pattern_bind453               | "ref" WS1 pattern_bind
454               | pattern_bind454               | pattern_bind
455               | pattern_ctor455               | pattern_ctor
456               | pattern_struct456               | pattern_struct
457               | pattern_tuple457               | pattern_tuple
458               | pattern_list458               | pattern_list
459               | pattern_range459               | pattern_range
460               ;460               ;
461461
462pattern_bind ::= ident ;462pattern_bind ::= ident ;
463pattern_ctor ::= pattern_head [ "(" WS? pattern_args? WS? ")" ] ;463pattern_ctor ::= pattern_head [ "(" WS? pattern_args? WS? ")" ] ;
464pattern_head ::= ident { ( "." | "::" ) ident } ;464pattern_head ::= ident { ( "." | "::" ) ident } ;
465pattern_args ::= pattern { WS? "," WS? pattern } [ WS? "," ] ;465pattern_args ::= pattern { WS? "," WS? pattern } [ WS? "," ] ;
466466
467pattern_struct ::= pattern_head WS? "{" WS? pattern_fields? WS? "}" ;467pattern_struct ::= pattern_head WS? "{" WS? pattern_fields? WS? "}" ;
468pattern_fields ::= pattern_field { WS? "," WS? pattern_field } [ WS? "," ] ;468pattern_fields ::= pattern_field { WS? "," WS? pattern_field } [ WS? "," ] ;
469pattern_field ::= ident [ WS? ":" WS? pattern ] | ".." ;469pattern_field ::= ident [ WS? ":" WS? pattern ] | ".." ;
470470
471pattern_tuple ::= "(" WS? pattern WS? "," WS? pattern { WS? "," WS? pattern } [ WS? "," ] WS? ")" ;471pattern_tuple ::= "(" WS? pattern WS? "," WS? pattern { WS? "," WS? pattern } [ WS? "," ] WS? ")" ;
472pattern_list ::= "[" WS? pattern_args? WS? "]" ;472pattern_list ::= "[" WS? pattern_args? WS? "]" ;
473pattern_range ::= literal WS? ( ".." | "..=" ) WS? literal ;473pattern_range ::= literal WS? ( ".." | "..=" ) WS? literal ;
474474
475<<< ================= Types ================= >>>475<<< ================= Types ================= >>>
476476
477type_expr ::= type_union ;477type_expr ::= type_union ;
478478
479type_union ::= type_prefix { WS? "|" WS? type_prefix } ;479type_union ::= type_prefix { WS? "|" WS? type_prefix } ;
480480
481type_prefix ::= type_qualifier* type_atom ;481type_prefix ::= type_qualifier* type_atom ;
482type_qualifier ::= type_qual WS1 | addr_space WS1 ;482type_qualifier ::= type_qual WS1 | addr_space WS1 ;
483483
484type_qual ::= "const" | "volatile" | "atomic" | "mut" | "owned" | "borrow" ;484type_qual ::= "const" | "volatile" | "atomic" | "mut" | "owned" | "borrow" ;
485addr_space ::= "user" | "kernel" | "phys" | "mmio" | "dma" ;485addr_space ::= "user" | "kernel" | "phys" | "mmio" | "dma" ;
486486
487type_atom ::= reference_type487type_atom ::= reference_type
488            | pointer_type488            | pointer_type
489            | optional_type489            | optional_type
490            | fixed_array_type490            | fixed_array_type
491            | slice_type491            | slice_type
492            | tuple_type492            | tuple_type
493            | proc_type493            | proc_type
494            | dyn_type494            | dyn_type
495            | impl_trait_type495            | impl_trait_type
496            | type_primary496            | type_primary
497            ;497            ;
498498
499<<< shared and mutable references are part of the core surface grammar; lifetime,499<<< shared and mutable references are part of the core surface grammar; lifetime,
500    aliasing and region closure remain semantic checks outside the parser. >>>500    aliasing and region closure remain semantic checks outside the parser. >>>
501reference_type ::= "&" WS? [ lifetime WS? ] [ "mut" WS1 ] type_expr ;501reference_type ::= "&" WS? [ lifetime WS? ] [ "mut" WS1 ] type_expr ;
502pointer_type ::= "*" WS? [ "const" WS1 | "mut" WS1 | "volatile" WS1 | addr_space WS1 ] type_expr ;502pointer_type ::= "*" WS? [ "const" WS1 | "mut" WS1 | "volatile" WS1 | addr_space WS1 ] type_expr ;
503optional_type ::= "?" WS? type_expr ;503optional_type ::= "?" WS? type_expr ;
504504
505fixed_array_type ::= "[" WS? type_expr WS? ";" WS? expr WS? "]" ;505fixed_array_type ::= "[" WS? type_expr WS? ";" WS? expr WS? "]" ;
506slice_type ::= "[" WS? type_expr WS? "]" ;506slice_type ::= "[" WS? type_expr WS? "]" ;
507507
508tuple_type ::= "(" WS? type_expr WS? "," WS? type_expr { WS? "," WS? type_expr } [ WS? "," ] WS? ")" ;508tuple_type ::= "(" WS? type_expr WS? "," WS? type_expr { WS? "," WS? type_expr } [ WS? "," ] WS? ")" ;
509proc_type ::= "proc" WS? "(" WS? type_list? WS? ")" [ WS? "->" WS? type_expr ] ;509proc_type ::= "proc" WS? "(" WS? type_list? WS? ")" [ WS? "->" WS? type_expr ] ;
510510
511type_list ::= type_param { WS? "," WS? type_param } [ WS? "," ] ;511type_list ::= type_param { WS? "," WS? type_param } [ WS? "," ] ;
512type_param ::= ident WS? ":" WS? type_expr | type_expr ;512type_param ::= ident WS? ":" WS? type_expr | type_expr ;
513513
514dyn_type ::= "dyn" WS1 trait_bound ;514dyn_type ::= "dyn" WS1 trait_bound ;
515impl_trait_type ::= "impl" WS1 trait_bound ;515impl_trait_type ::= "impl" WS1 trait_bound ;
516516
517type_primary ::= type_path [ "[" WS? type_list? WS? "]" ]517type_primary ::= type_path [ "[" WS? type_list? WS? "]" ]
518               | primitive_type518               | primitive_type
519               | "Self"519               | "Self"
520               ;520               ;
521521
522lifetime ::= "'" ident ;522lifetime ::= "'" ident ;
523523
524primitive_type ::= "void"524primitive_type ::= "void"
525                 | "never"525                 | "never"
526                 | "unit"526                 | "unit"
527                 | "bool"527                 | "bool"
528                 | "char"528                 | "char"
529                 | "rune"529                 | "rune"
530                 | "str"530                 | "str"
531                 | "string"531                 | "string"
532                 | "bytes"532                 | "bytes"
533                 | "cstr"533                 | "cstr"
534                 | "int"534                 | "int"
535                 | "i8" | "i16" | "i32" | "i64" | "i128"535                 | "i8" | "i16" | "i32" | "i64" | "i128"
536                 | "u8" | "u16" | "u32" | "u64" | "u128"536                 | "u8" | "u16" | "u32" | "u64" | "u128"
537                 | "usize" | "isize"537                 | "usize" | "isize"
538                 | "intptr" | "uintptr"538                 | "intptr" | "uintptr"
539                 | "f16" | "f32" | "f64" | "f128"539                 | "f16" | "f32" | "f64" | "f128"
540                 | "c_char" | "c_int" | "c_uint" | "c_long" | "c_ulong" | "c_void"540                 | "c_char" | "c_int" | "c_uint" | "c_long" | "c_ulong" | "c_void"
541                 | "TokenId"541                 | "TokenId"
542                 | "NodeId"542                 | "NodeId"
543                 | "DefId"543                 | "DefId"
544                 | "HirId"544                 | "HirId"
545                 | "MirId"545                 | "MirId"
546                 | "TypeId"546                 | "TypeId"
547                 | "SymbolId"547                 | "SymbolId"
548                 | "ScopeId"548                 | "ScopeId"
549                 | "BlockId"549                 | "BlockId"
550                 | "ValueId"550                 | "ValueId"
551                 | "InstrId"551                 | "InstrId"
552                 ;552                 ;
553553
554<<< ================= Literals ================= >>>554<<< ================= Literals ================= >>>
555555
556literal ::= bool_lit556literal ::= bool_lit
557          | null_lit557          | null_lit
558          | int_lit558          | int_lit
559          | float_lit559          | float_lit
560          | char_lit560          | char_lit
561          | string_lit561          | string_lit
562          | list_lit562          | list_lit
563          ;563          ;
564564
565list_lit ::= "[" WS? ( list_comp | arg_list? ) WS? "]" ;565list_lit ::= "[" WS? ( list_comp | arg_list? ) WS? "]" ;
566list_comp ::= expr WS1 "for" WS1 pattern WS1 "in" WS1 expr [ WS1 "if" WS1 expr ] ;566list_comp ::= expr WS1 "for" WS1 pattern WS1 "in" WS1 expr [ WS1 "if" WS1 expr ] ;
567567
568bool_lit ::= "true" | "false" ;568bool_lit ::= "true" | "false" ;
569null_lit ::= "null" ;569null_lit ::= "null" ;
570570
571int_lit ::= [ "-" ] DIGIT { DIGIT | "_" } [ suffix ]571int_lit ::= [ "-" ] DIGIT { DIGIT | "_" } [ suffix ]
572          | [ "-" ] "0x" HEXDIGIT { HEXDIGIT | "_" } [ suffix ]572          | [ "-" ] "0x" HEXDIGIT { HEXDIGIT | "_" } [ suffix ]
573          | [ "-" ] "0b" BINDIGIT { BINDIGIT | "_" } [ suffix ]573          | [ "-" ] "0b" BINDIGIT { BINDIGIT | "_" } [ suffix ]
574          | [ "-" ] "0o" OCTDIGIT { OCTDIGIT | "_" } [ suffix ]574          | [ "-" ] "0o" OCTDIGIT { OCTDIGIT | "_" } [ suffix ]
575          ;575          ;
576576
577float_lit ::= [ "-" ] DIGIT { DIGIT | "_" } "." DIGIT { DIGIT | "_" } [ exponent ] [ suffix ] ;577float_lit ::= [ "-" ] DIGIT { DIGIT | "_" } "." DIGIT { DIGIT | "_" } [ exponent ] [ suffix ] ;
578exponent ::= ( "e" | "E" ) [ "+" | "-" ] DIGIT { DIGIT | "_" } ;578exponent ::= ( "e" | "E" ) [ "+" | "-" ] DIGIT { DIGIT | "_" } ;
579579
580char_lit ::= "'" char_char "'" ;580char_lit ::= "'" char_char "'" ;
581char_char ::= escape_seq | ~"'" ;581char_char ::= escape_seq | ~"'" ;
582582
583string_lit ::= "\"" { string_char } "\"" | raw_string_lit ;583string_lit ::= "\"" { string_char } "\"" | raw_string_lit ;
584string_char ::= escape_seq | ~"\"" ;584string_char ::= escape_seq | ~"\"" ;
585585
586escape_seq ::= "\\n"586escape_seq ::= "\\n"
587             | "\\r"587             | "\\r"
588             | "\\t"588             | "\\t"
589             | "\\0"589             | "\\0"
590             | "\\\""590             | "\\\""
591             | "\\'"591             | "\\'"
592             | "\\\\"592             | "\\\\"
593             | "\\x" HEXDIGIT HEXDIGIT593             | "\\x" HEXDIGIT HEXDIGIT
594             | "\\u{" HEXDIGIT { HEXDIGIT } "}"594             | "\\u{" HEXDIGIT { HEXDIGIT } "}"
595             ;595             ;
596596
597raw_string_lit ::= "\"\"\"" { raw_string_char } "\"\"\""597raw_string_lit ::= "\"\"\"" { raw_string_char } "\"\"\""
598                 | "r\"" { raw_string_char } "\""598                 | "r\"" { raw_string_char } "\""
599                 ;599                 ;
600raw_string_char ::= ~"\"\"\"" ;600raw_string_char ::= ~"\"\"\"" ;
601601
602<<< ================= Lexical ================= >>>602<<< ================= Lexical ================= >>>
603603
604line_comment ::= "#" { ~NEWLINE ANY }604line_comment ::= "#" { ~NEWLINE ANY }
605               | "//" { ~NEWLINE ANY }605               | "//" { ~NEWLINE ANY }
606               ;606               ;
607607
608block_comment ::= "/*" { ~"*/" ANY } "*/" ;608block_comment ::= "/*" { ~"*/" ANY } "*/" ;
609zone_comment ::= "<<<" { ~">>>" ANY } ">>>" ;609zone_comment ::= "<<<" { ~">>>" ANY } ">>>" ;
610610
611ident ::= ( LETTER | "_" ) { LETTER | DIGIT | "_" } ;611ident ::= ( LETTER | "_" ) { LETTER | DIGIT | "_" } ;
612suffix ::= LETTER { LETTER | DIGIT } ;612suffix ::= LETTER { LETTER | DIGIT } ;
613613
614WS ::= { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ;614WS ::= { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ;
615WS1 ::= ( " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment )615WS1 ::= ( " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment )
616        { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ;616        { " " | "\t" | NEWLINE | line_comment | block_comment | zone_comment } ;
617617
618NEWLINE ::= "\n" | "\r\n" ;618NEWLINE ::= "\n" | "\r\n" ;
619619
620LETTER ::= "a"..."z" | "A"..."Z" ;620LETTER ::= "a"..."z" | "A"..."Z" ;
621DIGIT ::= "0"..."9" ;621DIGIT ::= "0"..."9" ;
622BINDIGIT ::= "0" | "1" ;622BINDIGIT ::= "0" | "1" ;
623OCTDIGIT ::= "0"..."7" ;623OCTDIGIT ::= "0"..."7" ;
624HEXDIGIT ::= DIGIT | "a"..."f" | "A"..."F" ;624HEXDIGIT ::= DIGIT | "a"..."f" | "A"..."F" ;
625625
626EOF ::= !ANY ;626EOF ::= !ANY ;