@@ -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,6 +1549,7 @@ 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 > > > {
15541555 let ( inner_attrs, body) = if self . eat ( & token:: Semi ) {
@@ -1573,9 +1574,21 @@ impl<'a> Parser<'a> {
15731574 . emit ( ) ;
15741575 ( Vec :: new ( ) , Some ( self . mk_block_err ( span) ) )
15751576 } else {
1576- return self
1577- . expected_one_of_not_found ( & [ ] , & [ token:: Semi , token:: OpenDelim ( token:: Brace ) ] )
1578- . map ( |_| None ) ;
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+ }
15791592 } ;
15801593 attrs. extend ( inner_attrs) ;
15811594 Ok ( body)
@@ -1653,10 +1666,19 @@ impl<'a> Parser<'a> {
16531666 req_name : ReqName ,
16541667 ret_allow_plus : AllowPlus ,
16551668 ) -> PResult < ' a , P < FnDecl > > {
1656- Ok ( P ( FnDecl {
1657- inputs : self . parse_fn_params ( req_name) ?,
1658- output : self . parse_ret_ty ( ret_allow_plus, RecoverQPath :: Yes ) ?,
1659- } ) )
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 } ) )
16601682 }
16611683
16621684 /// Parses the parameter list of a function, including the `(` and `)` delimiters.
0 commit comments