@@ -882,6 +882,12 @@ impl<'a> Parser<'a> {
882882 }
883883 }
884884
885+ fn look_ahead_type_ascription_as_field ( & mut self ) -> bool {
886+ self . look_ahead ( 1 , |t| t. is_ident ( ) )
887+ && self . look_ahead ( 2 , |t| t == & token:: Colon )
888+ && self . look_ahead ( 3 , |t| t. can_begin_expr ( ) )
889+ }
890+
885891 fn parse_dot_suffix_expr ( & mut self , lo : Span , base : P < Expr > ) -> PResult < ' a , P < Expr > > {
886892 match self . token . uninterpolate ( ) . kind {
887893 token:: Ident ( ..) => self . parse_dot_suffix ( base, lo) ,
@@ -1031,9 +1037,56 @@ impl<'a> Parser<'a> {
10311037
10321038 /// Parse a function call expression, `expr(...)`.
10331039 fn parse_fn_call_expr ( & mut self , lo : Span , fun : P < Expr > ) -> P < Expr > {
1034- let seq = self . parse_paren_expr_seq ( ) . map ( |args| {
1040+ let snapshot = if self . token . kind == token:: OpenDelim ( token:: Paren )
1041+ && self . look_ahead_type_ascription_as_field ( )
1042+ {
1043+ Some ( ( self . clone ( ) , fun. kind . clone ( ) ) )
1044+ } else {
1045+ None
1046+ } ;
1047+ let open_paren = self . token . span ;
1048+
1049+ let mut seq = self . parse_paren_expr_seq ( ) . map ( |args| {
10351050 self . mk_expr ( lo. to ( self . prev_token . span ) , self . mk_call ( fun, args) , AttrVec :: new ( ) )
10361051 } ) ;
1052+ match ( seq. as_mut ( ) , snapshot) {
1053+ ( Err ( ref mut err) , Some ( ( mut snapshot, ExprKind :: Path ( None , path) ) ) ) => {
1054+ let name = pprust:: path_to_string ( & path) ;
1055+ snapshot. bump ( ) ; // `(`
1056+ match snapshot. parse_struct_fields ( path. clone ( ) , false , token:: Paren ) {
1057+ Ok ( ( fields, ..) ) if snapshot. eat ( & token:: CloseDelim ( token:: Paren ) ) => {
1058+ // We have are certain we have `Enum::Foo(a: 3, b: 4)`, suggest
1059+ // `Enum::Foo { a: 3, b: 4 }` or `Enum::Foo(3, 4)`.
1060+ * self = snapshot;
1061+ let close_paren = self . prev_token . span ;
1062+ let span = lo. to ( self . prev_token . span ) ;
1063+ err. cancel ( ) ;
1064+ self . struct_span_err (
1065+ span,
1066+ "invalid `struct` delimiters or `fn` call arguments" ,
1067+ )
1068+ . multipart_suggestion (
1069+ & format ! ( "if `{}` is a struct, use braces as delimiters" , name) ,
1070+ vec ! [ ( open_paren, " { " . to_string( ) ) , ( close_paren, " }" . to_string( ) ) ] ,
1071+ Applicability :: MaybeIncorrect ,
1072+ )
1073+ . multipart_suggestion (
1074+ & format ! ( "if `{}` is a function, use the arguments directly" , name) ,
1075+ fields
1076+ . into_iter ( )
1077+ . map ( |field| ( field. span . until ( field. expr . span ) , String :: new ( ) ) )
1078+ . collect ( ) ,
1079+ Applicability :: MaybeIncorrect ,
1080+ )
1081+ . emit ( ) ;
1082+ return self . mk_expr_err ( span) ;
1083+ }
1084+ Ok ( _) => { }
1085+ Err ( mut err) => err. emit ( ) ,
1086+ }
1087+ }
1088+ _ => { }
1089+ }
10371090 self . recover_seq_parse_error ( token:: Paren , lo, seq)
10381091 }
10391092
@@ -2332,14 +2385,12 @@ impl<'a> Parser<'a> {
23322385 . emit ( ) ;
23332386 }
23342387
2335- /// Precondition: already parsed the '{'.
2336- pub ( super ) fn parse_struct_expr (
2388+ pub ( super ) fn parse_struct_fields (
23372389 & mut self ,
2338- qself : Option < ast:: QSelf > ,
23392390 pth : ast:: Path ,
2340- attrs : AttrVec ,
23412391 recover : bool ,
2342- ) -> PResult < ' a , P < Expr > > {
2392+ close_delim : token:: DelimToken ,
2393+ ) -> PResult < ' a , ( Vec < ExprField > , ast:: StructRest , bool ) > {
23432394 let mut fields = Vec :: new ( ) ;
23442395 let mut base = ast:: StructRest :: None ;
23452396 let mut recover_async = false ;
@@ -2351,11 +2402,11 @@ impl<'a> Parser<'a> {
23512402 e. note ( "for more on editions, read https://doc.rust-lang.org/edition-guide" ) ;
23522403 } ;
23532404
2354- while self . token != token:: CloseDelim ( token :: Brace ) {
2405+ while self . token != token:: CloseDelim ( close_delim ) {
23552406 if self . eat ( & token:: DotDot ) {
23562407 let exp_span = self . prev_token . span ;
23572408 // We permit `.. }` on the left-hand side of a destructuring assignment.
2358- if self . check ( & token:: CloseDelim ( token :: Brace ) ) {
2409+ if self . check ( & token:: CloseDelim ( close_delim ) ) {
23592410 self . sess . gated_spans . gate ( sym:: destructuring_assignment, self . prev_token . span ) ;
23602411 base = ast:: StructRest :: Rest ( self . prev_token . span . shrink_to_hi ( ) ) ;
23612412 break ;
@@ -2396,7 +2447,7 @@ impl<'a> Parser<'a> {
23962447 }
23972448 } ;
23982449
2399- match self . expect_one_of ( & [ token:: Comma ] , & [ token:: CloseDelim ( token :: Brace ) ] ) {
2450+ match self . expect_one_of ( & [ token:: Comma ] , & [ token:: CloseDelim ( close_delim ) ] ) {
24002451 Ok ( _) => {
24012452 if let Some ( f) = parsed_field. or ( recovery_field) {
24022453 // Only include the field if there's no parse error for the field name.
@@ -2427,8 +2478,21 @@ impl<'a> Parser<'a> {
24272478 }
24282479 }
24292480 }
2481+ Ok ( ( fields, base, recover_async) )
2482+ }
24302483
2431- let span = pth. span . to ( self . token . span ) ;
2484+ /// Precondition: already parsed the '{'.
2485+ pub ( super ) fn parse_struct_expr (
2486+ & mut self ,
2487+ qself : Option < ast:: QSelf > ,
2488+ pth : ast:: Path ,
2489+ attrs : AttrVec ,
2490+ recover : bool ,
2491+ ) -> PResult < ' a , P < Expr > > {
2492+ let lo = pth. span ;
2493+ let ( fields, base, recover_async) =
2494+ self . parse_struct_fields ( pth. clone ( ) , recover, token:: Brace ) ?;
2495+ let span = lo. to ( self . token . span ) ;
24322496 self . expect ( & token:: CloseDelim ( token:: Brace ) ) ?;
24332497 let expr = if recover_async {
24342498 ExprKind :: Err
0 commit comments