@@ -1538,7 +1538,7 @@ impl<'a> Parser<'a> {
15381538 generics. where_clause = self . parse_where_clause ( ) ?; // `where T: Ord`
15391539
15401540 let mut sig_hi = self . prev_token . span ;
1541- let body = self . parse_fn_body ( attrs, & mut sig_hi) ?; // `;` or `{ ... }`.
1541+ let body = self . parse_fn_body ( attrs, & ident , & mut sig_hi) ?; // `;` or `{ ... }`.
15421542 let fn_sig_span = sig_lo. to ( sig_hi) ;
15431543 Ok ( ( ident, FnSig { header, decl, span : fn_sig_span } , generics, body) )
15441544 }
@@ -1549,12 +1549,12 @@ impl<'a> Parser<'a> {
15491549 fn parse_fn_body (
15501550 & mut self ,
15511551 attrs : & mut Vec < Attribute > ,
1552+ ident : & Ident ,
15521553 sig_hi : & mut Span ,
15531554 ) -> PResult < ' a , Option < P < Block > > > {
1554- let ( inner_attrs, body) = if self . check ( & token:: Semi ) {
1555+ let ( inner_attrs, body) = if self . eat ( & token:: Semi ) {
15551556 // Include the trailing semicolon in the span of the signature
1556- * sig_hi = self . token . span ;
1557- self . bump ( ) ; // `;`
1557+ * sig_hi = self . prev_token . span ;
15581558 ( Vec :: new ( ) , None )
15591559 } else if self . check ( & token:: OpenDelim ( token:: Brace ) ) || self . token . is_whole_block ( ) {
15601560 self . parse_inner_attrs_and_block ( ) . map ( |( attrs, body) | ( attrs, Some ( body) ) ) ?
@@ -1574,7 +1574,21 @@ impl<'a> Parser<'a> {
15741574 . emit ( ) ;
15751575 ( Vec :: new ( ) , Some ( self . mk_block_err ( span) ) )
15761576 } else {
1577- return self . expected_semi_or_open_brace ( ) ;
1577+ if let Err ( mut err) =
1578+ self . expected_one_of_not_found ( & [ ] , & [ token:: Semi , token:: OpenDelim ( token:: Brace ) ] )
1579+ {
1580+ if self . token . kind == token:: CloseDelim ( token:: Brace ) {
1581+ // The enclosing `mod`, `trait` or `impl` is being closed, so keep the `fn` in
1582+ // the AST for typechecking.
1583+ err. span_label ( ident. span , "while parsing this `fn`" ) ;
1584+ err. emit ( ) ;
1585+ ( Vec :: new ( ) , None )
1586+ } else {
1587+ return Err ( err) ;
1588+ }
1589+ } else {
1590+ unreachable ! ( )
1591+ }
15781592 } ;
15791593 attrs. extend ( inner_attrs) ;
15801594 Ok ( body)
@@ -1652,10 +1666,19 @@ impl<'a> Parser<'a> {
16521666 req_name : ReqName ,
16531667 ret_allow_plus : AllowPlus ,
16541668 ) -> PResult < ' a , P < FnDecl > > {
1655- Ok ( P ( FnDecl {
1656- inputs : self . parse_fn_params ( req_name) ?,
1657- output : self . parse_ret_ty ( ret_allow_plus, RecoverQPath :: Yes ) ?,
1658- } ) )
1669+ let inputs = self . parse_fn_params ( req_name) ?;
1670+ let output = self . parse_ret_ty ( ret_allow_plus, RecoverQPath :: Yes ) ?;
1671+
1672+ if let ast:: FnRetTy :: Ty ( ty) = & output {
1673+ if let TyKind :: Path ( _, Path { segments, .. } ) = & ty. kind {
1674+ if let [ .., last] = & segments[ ..] {
1675+ // Detect and recover `fn foo() -> Vec<i32>> {}`
1676+ self . check_trailing_angle_brackets ( last, & [ & token:: OpenDelim ( token:: Brace ) ] ) ;
1677+ }
1678+ }
1679+ }
1680+
1681+ Ok ( P ( FnDecl { inputs, output } ) )
16591682 }
16601683
16611684 /// Parses the parameter list of a function, including the `(` and `)` delimiters.
0 commit comments