Skip to content

Commit 63eba73

Browse files
Support let-else statements (#162)
* Add tests for let-else statements * Allow let declaration to have else block * Regenerate parser * Use associativity to resolve let-else vs if conflicts Also rename 'let_else_block' field to 'alternative' to be more consistent with else blocks in if expressions Co-authored-by: Max Brunsfeld <[email protected]>
1 parent 47b061c commit 63eba73

File tree

5 files changed

+67821
-63290
lines changed

5 files changed

+67821
-63290
lines changed

corpus/declarations.txt

Lines changed: 141 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,94 @@ let u32: str = "";
431431
(primitive_type)
432432
(string_literal)))
433433

434+
================================================================================
435+
Let-else Statements
436+
================================================================================
437+
438+
let Foo::Bar {
439+
texts,
440+
values,
441+
} = foo().bar().await? else {
442+
return Err(index)
443+
};
444+
445+
let Some(x) = y else {
446+
let None = z else {
447+
foo();
448+
break;
449+
};
450+
continue;
451+
};
452+
453+
--------------------------------------------------------------------------------
454+
455+
(source_file
456+
(let_declaration
457+
pattern: (struct_pattern
458+
type: (scoped_type_identifier
459+
path: (identifier)
460+
name: (type_identifier))
461+
(field_pattern
462+
name: (shorthand_field_identifier))
463+
(field_pattern
464+
name: (shorthand_field_identifier)))
465+
value: (try_expression
466+
(await_expression
467+
(call_expression
468+
function: (field_expression
469+
value: (call_expression
470+
function: (identifier)
471+
arguments: (arguments))
472+
field: (field_identifier))
473+
arguments: (arguments))))
474+
alternative: (block
475+
(return_expression
476+
(call_expression
477+
function: (identifier)
478+
arguments: (arguments
479+
(identifier))))))
480+
(let_declaration
481+
pattern: (tuple_struct_pattern
482+
type: (identifier)
483+
(identifier))
484+
value: (identifier)
485+
alternative: (block
486+
(let_declaration
487+
pattern: (identifier)
488+
value: (identifier)
489+
alternative: (block
490+
(expression_statement
491+
(call_expression
492+
function: (identifier)
493+
arguments: (arguments)))
494+
(expression_statement
495+
(break_expression))))
496+
(expression_statement
497+
(continue_expression)))))
498+
499+
================================================================================
500+
Let declarations with if expressions as the value
501+
================================================================================
502+
503+
let a = if b {
504+
c
505+
} else {
506+
d
507+
};
508+
509+
--------------------------------------------------------------------------------
510+
511+
(source_file
512+
(let_declaration
513+
(identifier)
514+
(if_expression
515+
(identifier)
516+
(block
517+
(identifier))
518+
(else_clause
519+
(block
520+
(identifier))))))
521+
434522
================================================================================
435523
Structs
436524
================================================================================
@@ -1046,27 +1134,31 @@ foo(#[bar(some tokens are special in other contexts: $/';()*()+.)] x);
10461134
(call_expression
10471135
function: (identifier)
10481136
arguments: (arguments
1049-
(attribute_item (attr_item
1050-
(identifier)
1051-
arguments: (token_tree (identifier) (identifier))))
1137+
(attribute_item
1138+
(attr_item
1139+
(identifier)
1140+
arguments: (token_tree
1141+
(identifier)
1142+
(identifier))))
10521143
(identifier)
10531144
(identifier))))
10541145
(expression_statement
10551146
(call_expression
10561147
function: (identifier)
10571148
arguments: (arguments
1058-
(attribute_item (attr_item
1059-
(identifier)
1060-
arguments: (token_tree
1061-
(identifier)
1062-
(identifier)
1063-
(identifier)
1064-
(identifier)
1149+
(attribute_item
1150+
(attr_item
10651151
(identifier)
1066-
(identifier)
1067-
(identifier)
1068-
(token_tree)
1069-
(token_tree))))
1152+
arguments: (token_tree
1153+
(identifier)
1154+
(identifier)
1155+
(identifier)
1156+
(identifier)
1157+
(identifier)
1158+
(identifier)
1159+
(identifier)
1160+
(token_tree)
1161+
(token_tree))))
10701162
(identifier)))))
10711163

10721164
================================================================================
@@ -1090,36 +1182,51 @@ pub enum Error {
10901182
(source_file
10911183
(line_comment)
10921184
(use_declaration
1093-
(scoped_identifier (identifier) (identifier)))
1185+
(scoped_identifier
1186+
(identifier)
1187+
(identifier)))
10941188
(attribute_item
1095-
(meta_item (identifier)
1189+
(meta_item
1190+
(identifier)
10961191
(meta_arguments
1097-
(meta_item (identifier))
1098-
(meta_item (identifier)))))
1192+
(meta_item
1193+
(identifier))
1194+
(meta_item
1195+
(identifier)))))
10991196
(enum_item
11001197
(visibility_modifier)
11011198
(type_identifier)
11021199
(enum_variant_list
1103-
(attribute_item (attr_item
1104-
(identifier)
1105-
(token_tree
1106-
(string_literal)
1200+
(attribute_item
1201+
(attr_item
11071202
(identifier)
1108-
(token_tree (integer_literal)))))
1109-
(enum_variant (identifier)
1110-
(ordered_field_declaration_list (type_identifier)))
1111-
(attribute_item (attr_item
1203+
(token_tree
1204+
(string_literal)
1205+
(identifier)
1206+
(token_tree
1207+
(integer_literal)))))
1208+
(enum_variant
11121209
(identifier)
1113-
(token_tree
1114-
(string_literal)
1115-
(identifier)
1116-
(identifier)
1210+
(ordered_field_declaration_list
1211+
(type_identifier)))
1212+
(attribute_item
1213+
(attr_item
11171214
(identifier)
1118-
(identifier))))
1119-
(enum_variant (identifier)
1215+
(token_tree
1216+
(string_literal)
1217+
(identifier)
1218+
(identifier)
1219+
(identifier)
1220+
(identifier))))
1221+
(enum_variant
1222+
(identifier)
11201223
(field_declaration_list
1121-
(field_declaration (field_identifier) (primitive_type))
1122-
(field_declaration (field_identifier) (type_identifier)))))))
1224+
(field_declaration
1225+
(field_identifier)
1226+
(primitive_type))
1227+
(field_declaration
1228+
(field_identifier)
1229+
(type_identifier)))))))
11231230

11241231
================================================================================
11251232
Attributes and Expressions

grammar.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,10 @@ module.exports = grammar({
633633
'=',
634634
field('value', $._expression)
635635
)),
636+
optional(seq(
637+
'else',
638+
field('alternative', $.block)
639+
)),
636640
';'
637641
),
638642

@@ -1174,22 +1178,22 @@ module.exports = grammar({
11741178
$._expression
11751179
),
11761180

1177-
if_expression: $ => seq(
1181+
if_expression: $ => prec.right(seq(
11781182
'if',
11791183
field('condition', $._expression),
11801184
field('consequence', $.block),
11811185
optional(field("alternative", $.else_clause))
1182-
),
1186+
)),
11831187

1184-
if_let_expression: $ => seq(
1188+
if_let_expression: $ => prec.right(seq(
11851189
'if',
11861190
'let',
11871191
field('pattern', $._pattern),
11881192
'=',
11891193
field('value', $._expression),
11901194
field('consequence', $.block),
11911195
optional(field('alternative', $.else_clause))
1192-
),
1196+
)),
11931197

11941198
else_clause: $ => seq(
11951199
'else',

0 commit comments

Comments
 (0)