@@ -67,7 +67,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
67
67
preorder. skip_subtree ( ) ;
68
68
continue ;
69
69
}
70
-
71
70
// In some other situations, we can fix things by just appending some tokens.
72
71
let end_range = TextRange :: empty ( node. text_range ( ) . end ( ) ) ;
73
72
match_ast ! {
@@ -194,7 +193,75 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
194
193
}
195
194
} ,
196
195
// FIXME: foo::
197
- // FIXME: for, match etc.
196
+ ast:: MatchExpr ( it) => {
197
+ if it. expr( ) . is_none( ) {
198
+ let match_token = match it. match_token( ) {
199
+ Some ( t) => t,
200
+ None => continue
201
+ } ;
202
+ append. insert( match_token. into( ) , vec![
203
+ SyntheticToken {
204
+ kind: SyntaxKind :: IDENT ,
205
+ text: "__ra_fixup" . into( ) ,
206
+ range: end_range,
207
+ id: EMPTY_ID
208
+ } ,
209
+ ] ) ;
210
+ }
211
+ if it. match_arm_list( ) . is_none( ) {
212
+ // No match arms
213
+ append. insert( node. clone( ) . into( ) , vec![
214
+ SyntheticToken {
215
+ kind: SyntaxKind :: L_CURLY ,
216
+ text: "{" . into( ) ,
217
+ range: end_range,
218
+ id: EMPTY_ID ,
219
+ } ,
220
+ SyntheticToken {
221
+ kind: SyntaxKind :: R_CURLY ,
222
+ text: "}" . into( ) ,
223
+ range: end_range,
224
+ id: EMPTY_ID ,
225
+ } ,
226
+ ] ) ;
227
+ }
228
+ } ,
229
+ ast:: ForExpr ( it) => {
230
+ let for_token = match it. for_token( ) {
231
+ Some ( token) => token,
232
+ None => continue
233
+ } ;
234
+
235
+ let [ pat, in_token, iter] = [
236
+ ( SyntaxKind :: UNDERSCORE , "_" ) ,
237
+ ( SyntaxKind :: IN_KW , "in" ) ,
238
+ ( SyntaxKind :: IDENT , "__ra_fixup" )
239
+ ] . map( |( kind, text) | SyntheticToken { kind, text: text. into( ) , range: end_range, id: EMPTY_ID } ) ;
240
+
241
+ if it. pat( ) . is_none( ) && it. in_token( ) . is_none( ) && it. iterable( ) . is_none( ) {
242
+ append. insert( for_token. into( ) , vec![ pat, in_token, iter] ) ;
243
+ // does something funky -- see test case for_no_pat
244
+ } else if it. pat( ) . is_none( ) {
245
+ append. insert( for_token. into( ) , vec![ pat] ) ;
246
+ }
247
+
248
+ if it. loop_body( ) . is_none( ) {
249
+ append. insert( node. clone( ) . into( ) , vec![
250
+ SyntheticToken {
251
+ kind: SyntaxKind :: L_CURLY ,
252
+ text: "{" . into( ) ,
253
+ range: end_range,
254
+ id: EMPTY_ID ,
255
+ } ,
256
+ SyntheticToken {
257
+ kind: SyntaxKind :: R_CURLY ,
258
+ text: "}" . into( ) ,
259
+ range: end_range,
260
+ id: EMPTY_ID ,
261
+ } ,
262
+ ] ) ;
263
+ }
264
+ } ,
198
265
_ => ( ) ,
199
266
}
200
267
}
@@ -287,6 +354,111 @@ mod tests {
287
354
assert_eq ! ( tt. to_string( ) , original_as_tt. to_string( ) ) ;
288
355
}
289
356
357
+ #[ test]
358
+ fn just_for_token ( ) {
359
+ check (
360
+ r#"
361
+ fn foo() {
362
+ for
363
+ }
364
+ "# ,
365
+ expect ! [ [ r#"
366
+ fn foo () {for _ in __ra_fixup {}}
367
+ "# ] ] ,
368
+ )
369
+ }
370
+
371
+ #[ test]
372
+ fn for_no_iter_pattern ( ) {
373
+ check (
374
+ r#"
375
+ fn foo() {
376
+ for {}
377
+ }
378
+ "# ,
379
+ expect ! [ [ r#"
380
+ fn foo () {for _ in __ra_fixup {}}
381
+ "# ] ] ,
382
+ )
383
+ }
384
+
385
+ #[ test]
386
+ fn for_no_body ( ) {
387
+ check (
388
+ r#"
389
+ fn foo() {
390
+ for bar in qux
391
+ }
392
+ "# ,
393
+ expect ! [ [ r#"
394
+ fn foo () {for bar in qux {}}
395
+ "# ] ] ,
396
+ )
397
+ }
398
+
399
+ // FIXME: https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695
400
+ #[ test]
401
+ fn for_no_pat ( ) {
402
+ check (
403
+ r#"
404
+ fn foo() {
405
+ for in qux {
406
+
407
+ }
408
+ }
409
+ "# ,
410
+ expect ! [ [ r#"
411
+ fn foo () {__ra_fixup}
412
+ "# ] ] ,
413
+ )
414
+ }
415
+
416
+ #[ test]
417
+ fn match_no_expr_no_arms ( ) {
418
+ check (
419
+ r#"
420
+ fn foo() {
421
+ match
422
+ }
423
+ "# ,
424
+ expect ! [ [ r#"
425
+ fn foo () {match __ra_fixup {}}
426
+ "# ] ] ,
427
+ )
428
+ }
429
+
430
+ #[ test]
431
+ fn match_expr_no_arms ( ) {
432
+ check (
433
+ r#"
434
+ fn foo() {
435
+ match x {
436
+
437
+ }
438
+ }
439
+ "# ,
440
+ expect ! [ [ r#"
441
+ fn foo () {match x {}}
442
+ "# ] ] ,
443
+ )
444
+ }
445
+
446
+ #[ test]
447
+ fn match_no_expr ( ) {
448
+ check (
449
+ r#"
450
+ fn foo() {
451
+ match {
452
+ _ => {}
453
+ }
454
+ }
455
+ "# ,
456
+ expect ! [ [ r#"
457
+ fn foo () {match __ra_fixup {}}
458
+ "# ] ] ,
459
+ )
460
+ }
461
+
290
462
#[ test]
291
463
fn incomplete_field_expr_1 ( ) {
292
464
check (
0 commit comments