@@ -12,9 +12,10 @@ use crate::errors::{
12
12
IncorrectAwait , IncorrectSemicolon , IncorrectUseOfAwait , ParenthesesInForHead ,
13
13
ParenthesesInForHeadSugg , PatternMethodParamWithoutBody , QuestionMarkInType ,
14
14
QuestionMarkInTypeSugg , SelfParamNotFirst , StructLiteralBodyWithoutPath ,
15
- StructLiteralBodyWithoutPathSugg , SuggEscapeToUseAsIdentifier , SuggRemoveComma ,
16
- UnexpectedConstInGenericParam , UnexpectedConstParamDeclaration ,
17
- UnexpectedConstParamDeclarationSugg , UnmatchedAngleBrackets , UseEqInstead ,
15
+ StructLiteralBodyWithoutPathSugg , StructLiteralNeedingParens , StructLiteralNeedingParensSugg ,
16
+ SuggEscapeToUseAsIdentifier , SuggRemoveComma , UnexpectedConstInGenericParam ,
17
+ UnexpectedConstParamDeclaration , UnexpectedConstParamDeclarationSugg , UnmatchedAngleBrackets ,
18
+ UseEqInstead ,
18
19
} ;
19
20
20
21
use crate :: lexer:: UnmatchedBrace ;
@@ -623,12 +624,15 @@ impl<'a> Parser<'a> {
623
624
& mut self ,
624
625
lo : Span ,
625
626
s : BlockCheckMode ,
627
+ maybe_struct_name : token:: Token ,
628
+ can_be_struct_literal : bool ,
626
629
) -> Option < PResult < ' a , P < Block > > > {
627
630
if self . token . is_ident ( ) && self . look_ahead ( 1 , |t| t == & token:: Colon ) {
628
631
// We might be having a struct literal where people forgot to include the path:
629
632
// fn foo() -> Foo {
630
633
// field: value,
631
634
// }
635
+ info ! ( ?maybe_struct_name, ?self . token) ;
632
636
let mut snapshot = self . create_snapshot_for_diagnostic ( ) ;
633
637
let path = Path {
634
638
segments : ThinVec :: new ( ) ,
@@ -648,21 +652,32 @@ impl<'a> Parser<'a> {
648
652
// field: value,
649
653
// } }
650
654
err. delay_as_bug ( ) ;
651
- self . sess . emit_err ( StructLiteralBodyWithoutPath {
652
- span : expr. span ,
653
- sugg : StructLiteralBodyWithoutPathSugg {
654
- before : expr. span . shrink_to_lo ( ) ,
655
- after : expr. span . shrink_to_hi ( ) ,
656
- } ,
657
- } ) ;
658
655
self . restore_snapshot ( snapshot) ;
659
656
let mut tail = self . mk_block (
660
657
vec ! [ self . mk_stmt_err( expr. span) ] ,
661
658
s,
662
659
lo. to ( self . prev_token . span ) ,
663
660
) ;
664
661
tail. could_be_bare_literal = true ;
665
- Ok ( tail)
662
+ if maybe_struct_name. is_ident ( ) && can_be_struct_literal {
663
+ // Account for `if Example { a: one(), }.is_pos() {}`.
664
+ Err ( self . sess . create_err ( StructLiteralNeedingParens {
665
+ span : maybe_struct_name. span . to ( expr. span ) ,
666
+ sugg : StructLiteralNeedingParensSugg {
667
+ before : maybe_struct_name. span . shrink_to_lo ( ) ,
668
+ after : expr. span . shrink_to_hi ( ) ,
669
+ } ,
670
+ } ) )
671
+ } else {
672
+ self . sess . emit_err ( StructLiteralBodyWithoutPath {
673
+ span : expr. span ,
674
+ sugg : StructLiteralBodyWithoutPathSugg {
675
+ before : expr. span . shrink_to_lo ( ) ,
676
+ after : expr. span . shrink_to_hi ( ) ,
677
+ } ,
678
+ } ) ;
679
+ Ok ( tail)
680
+ }
666
681
}
667
682
( Err ( err) , Ok ( tail) ) => {
668
683
// We have a block tail that contains a somehow valid type ascription expr.
0 commit comments