@@ -475,6 +475,7 @@ impl<'a> Parser<'a> {
475
475
}
476
476
477
477
fn error_block_no_opening_brace_msg ( & mut self , msg : Cow < ' static , str > ) -> Diag < ' a > {
478
+ let prev = self . prev_token . span ;
478
479
let sp = self . token . span ;
479
480
let mut e = self . dcx ( ) . struct_span_err ( sp, msg) ;
480
481
let do_not_suggest_help = self . token . is_keyword ( kw:: In ) || self . token == token:: Colon ;
@@ -514,8 +515,97 @@ impl<'a> Parser<'a> {
514
515
} else {
515
516
stmt. span
516
517
} ;
518
+ self . suggest_fixes_misparsed_for_loop_head (
519
+ & mut e,
520
+ prev. between ( sp) ,
521
+ stmt_span,
522
+ & stmt. kind ,
523
+ ) ;
524
+ }
525
+ Err ( e) => {
526
+ self . recover_stmt_ ( SemiColonMode :: Break , BlockMode :: Ignore ) ;
527
+ e. cancel ( ) ;
528
+ }
529
+ _ => { }
530
+ }
531
+ e. span_label ( sp, "expected `{`" ) ;
532
+ e
533
+ }
534
+
535
+ fn suggest_fixes_misparsed_for_loop_head (
536
+ & self ,
537
+ e : & mut Diag < ' _ > ,
538
+ between : Span ,
539
+ stmt_span : Span ,
540
+ stmt_kind : & StmtKind ,
541
+ ) {
542
+ match ( & self . token . kind , & stmt_kind) {
543
+ ( token:: OpenDelim ( Delimiter :: Brace ) , StmtKind :: Expr ( expr) )
544
+ if let ExprKind :: Call ( ..) = expr. kind =>
545
+ {
546
+ // for _ in x y() {}
547
+ e. span_suggestion_verbose (
548
+ between,
549
+ "you might have meant to write a method call" ,
550
+ "." . to_string ( ) ,
551
+ Applicability :: MaybeIncorrect ,
552
+ ) ;
553
+ }
554
+ ( token:: OpenDelim ( Delimiter :: Brace ) , StmtKind :: Expr ( expr) )
555
+ if let ExprKind :: Field ( ..) = expr. kind =>
556
+ {
557
+ // for _ in x y.z {}
558
+ e. span_suggestion_verbose (
559
+ between,
560
+ "you might have meant to write a field access" ,
561
+ "." . to_string ( ) ,
562
+ Applicability :: MaybeIncorrect ,
563
+ ) ;
564
+ }
565
+ ( token:: CloseDelim ( Delimiter :: Brace ) , StmtKind :: Expr ( expr) )
566
+ if let ExprKind :: Struct ( expr) = & expr. kind
567
+ && let None = expr. qself
568
+ && expr. path . segments . len ( ) == 1 =>
569
+ {
570
+ // This is specific to "mistyped `if` condition followed by empty body"
571
+ //
572
+ // for _ in x y {}
573
+ e. span_suggestion_verbose (
574
+ between,
575
+ "you might have meant to write a field access" ,
576
+ "." . to_string ( ) ,
577
+ Applicability :: MaybeIncorrect ,
578
+ ) ;
579
+ }
580
+ ( token:: OpenDelim ( Delimiter :: Brace ) , StmtKind :: Expr ( expr) )
581
+ if let ExprKind :: Lit ( lit) = expr. kind
582
+ && let None = lit. suffix
583
+ && let token:: LitKind :: Integer | token:: LitKind :: Float = lit. kind =>
584
+ {
585
+ // for _ in x 0 {}
586
+ // for _ in x 0.0 {}
587
+ e. span_suggestion_verbose (
588
+ between,
589
+ format ! ( "you might have meant to write a field access" ) ,
590
+ "." . to_string ( ) ,
591
+ Applicability :: MaybeIncorrect ,
592
+ ) ;
593
+ }
594
+ ( token:: OpenDelim ( Delimiter :: Brace ) , StmtKind :: Expr ( expr) )
595
+ if let ExprKind :: Loop ( ..)
596
+ | ExprKind :: If ( ..)
597
+ | ExprKind :: While ( ..)
598
+ | ExprKind :: Match ( ..)
599
+ | ExprKind :: ForLoop { .. }
600
+ | ExprKind :: TryBlock ( ..)
601
+ | ExprKind :: Ret ( ..)
602
+ | ExprKind :: Closure ( ..)
603
+ | ExprKind :: Struct ( ..)
604
+ | ExprKind :: Try ( ..) = expr. kind =>
605
+ {
606
+ // These are more likely to have been meant as a block body.
517
607
e. multipart_suggestion (
518
- "try placing this code inside a block" ,
608
+ "you might have meant to write this as part of a block" ,
519
609
vec ! [
520
610
( stmt_span. shrink_to_lo( ) , "{ " . to_string( ) ) ,
521
611
( stmt_span. shrink_to_hi( ) , " }" . to_string( ) ) ,
@@ -524,14 +614,19 @@ impl<'a> Parser<'a> {
524
614
Applicability :: MaybeIncorrect ,
525
615
) ;
526
616
}
527
- Err ( e) => {
528
- self . recover_stmt_ ( SemiColonMode :: Break , BlockMode :: Ignore ) ;
529
- e. cancel ( ) ;
617
+ ( token:: OpenDelim ( Delimiter :: Brace ) , _) => { }
618
+ ( _, _) => {
619
+ e. multipart_suggestion (
620
+ "you might have meant to write this as part of a block" ,
621
+ vec ! [
622
+ ( stmt_span. shrink_to_lo( ) , "{ " . to_string( ) ) ,
623
+ ( stmt_span. shrink_to_hi( ) , " }" . to_string( ) ) ,
624
+ ] ,
625
+ // Speculative; has been misleading in the past (#46836).
626
+ Applicability :: MaybeIncorrect ,
627
+ ) ;
530
628
}
531
- _ => { }
532
629
}
533
- e. span_label ( sp, "expected `{`" ) ;
534
- e
535
630
}
536
631
537
632
fn error_block_no_opening_brace < T > ( & mut self ) -> PResult < ' a , T > {
0 commit comments