@@ -2200,7 +2200,9 @@ impl<'a> Parser<'a> {
22002200 }
22012201
22022202 fn is_array_like_block ( & mut self ) -> bool {
2203- self . look_ahead ( 1 , |t| matches ! ( t. kind, TokenKind :: Ident ( ..) | TokenKind :: Literal ( _) ) )
2203+ matches ! ( self . token. kind, TokenKind :: OpenDelim ( Delimiter :: Brace ) )
2204+ && self
2205+ . look_ahead ( 1 , |t| matches ! ( t. kind, TokenKind :: Ident ( ..) | TokenKind :: Literal ( _) ) )
22042206 && self . look_ahead ( 2 , |t| t == & token:: Comma )
22052207 && self . look_ahead ( 3 , |t| t. can_begin_expr ( ) )
22062208 }
@@ -2212,9 +2214,9 @@ impl<'a> Parser<'a> {
22122214 let mut snapshot = self . create_snapshot_for_diagnostic ( ) ;
22132215 match snapshot. parse_expr_array_or_repeat ( exp ! ( CloseBrace ) ) {
22142216 Ok ( arr) => {
2215- let guar = self . dcx ( ) . emit_err ( errors:: ArrayBracketsInsteadOfSpaces {
2217+ let guar = self . dcx ( ) . emit_err ( errors:: ArrayBracketsInsteadOfBraces {
22162218 span : arr. span ,
2217- sub : errors:: ArrayBracketsInsteadOfSpacesSugg {
2219+ sub : errors:: ArrayBracketsInsteadOfBracesSugg {
22182220 left : lo,
22192221 right : snapshot. prev_token . span ,
22202222 } ,
@@ -2337,7 +2339,8 @@ impl<'a> Parser<'a> {
23372339 let capture_clause = self . parse_capture_clause ( ) ?;
23382340 let ( fn_decl, fn_arg_span) = self . parse_fn_block_decl ( ) ?;
23392341 let decl_hi = self . prev_token . span ;
2340- let mut body = match fn_decl. output {
2342+ let mut body = match & fn_decl. output {
2343+ // No return type.
23412344 FnRetTy :: Default ( _) => {
23422345 let restrictions =
23432346 self . restrictions - Restrictions :: STMT_EXPR - Restrictions :: ALLOW_LET ;
@@ -2349,11 +2352,8 @@ impl<'a> Parser<'a> {
23492352 Err ( err) => self . recover_closure_body ( err, before, prev, token, lo, decl_hi) ?,
23502353 }
23512354 }
2352- _ => {
2353- // If an explicit return type is given, require a block to appear (RFC 968).
2354- let body_lo = self . token . span ;
2355- self . parse_expr_block ( None , body_lo, BlockCheckMode :: Default ) ?
2356- }
2355+ // Explicit return type (`->`) needs block `-> T { }`.
2356+ FnRetTy :: Ty ( ty) => self . parse_closure_block_body ( ty. span ) ?,
23572357 } ;
23582358
23592359 match coroutine_kind {
@@ -2405,6 +2405,49 @@ impl<'a> Parser<'a> {
24052405 Ok ( closure)
24062406 }
24072407
2408+ /// If an explicit return type is given, require a block to appear (RFC 968).
2409+ fn parse_closure_block_body ( & mut self , ret_span : Span ) -> PResult < ' a , P < Expr > > {
2410+ if self . may_recover ( )
2411+ && self . token . can_begin_expr ( )
2412+ && !matches ! ( self . token. kind, TokenKind :: OpenDelim ( Delimiter :: Brace ) )
2413+ && !self . token . is_whole_block ( )
2414+ {
2415+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
2416+ let restrictions =
2417+ self . restrictions - Restrictions :: STMT_EXPR - Restrictions :: ALLOW_LET ;
2418+ let tok = self . token . clone ( ) ;
2419+ match self . parse_expr_res ( restrictions, AttrWrapper :: empty ( ) ) {
2420+ Ok ( ( expr, _) ) => {
2421+ let descr = super :: token_descr ( & tok) ;
2422+ let mut diag = self
2423+ . dcx ( )
2424+ . struct_span_err ( tok. span , format ! ( "expected `{{`, found {descr}" ) ) ;
2425+ diag. span_label (
2426+ ret_span,
2427+ "explicit return type requires closure body to be enclosed in braces" ,
2428+ ) ;
2429+ diag. multipart_suggestion_verbose (
2430+ "wrap the expression in curly braces" ,
2431+ vec ! [
2432+ ( expr. span. shrink_to_lo( ) , "{ " . to_string( ) ) ,
2433+ ( expr. span. shrink_to_hi( ) , " }" . to_string( ) ) ,
2434+ ] ,
2435+ Applicability :: MachineApplicable ,
2436+ ) ;
2437+ diag. emit ( ) ;
2438+ return Ok ( expr) ;
2439+ }
2440+ Err ( diag) => {
2441+ diag. cancel ( ) ;
2442+ self . restore_snapshot ( snapshot) ;
2443+ }
2444+ }
2445+ }
2446+
2447+ let body_lo = self . token . span ;
2448+ self . parse_expr_block ( None , body_lo, BlockCheckMode :: Default )
2449+ }
2450+
24082451 /// Parses an optional `move` or `use` prefix to a closure-like construct.
24092452 fn parse_capture_clause ( & mut self ) -> PResult < ' a , CaptureBy > {
24102453 if self . eat_keyword ( exp ! ( Move ) ) {
0 commit comments