@@ -1538,7 +1538,7 @@ impl<'a> Parser<'a> {
1538
1538
generics. where_clause = self . parse_where_clause ( ) ?; // `where T: Ord`
1539
1539
1540
1540
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 `{ ... }`.
1542
1542
let fn_sig_span = sig_lo. to ( sig_hi) ;
1543
1543
Ok ( ( ident, FnSig { header, decl, span : fn_sig_span } , generics, body) )
1544
1544
}
@@ -1549,6 +1549,7 @@ impl<'a> Parser<'a> {
1549
1549
fn parse_fn_body (
1550
1550
& mut self ,
1551
1551
attrs : & mut Vec < Attribute > ,
1552
+ ident : & Ident ,
1552
1553
sig_hi : & mut Span ,
1553
1554
) -> PResult < ' a , Option < P < Block > > > {
1554
1555
let ( inner_attrs, body) = if self . eat ( & token:: Semi ) {
@@ -1573,9 +1574,21 @@ impl<'a> Parser<'a> {
1573
1574
. emit ( ) ;
1574
1575
( Vec :: new ( ) , Some ( self . mk_block_err ( span) ) )
1575
1576
} 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
+ }
1579
1592
} ;
1580
1593
attrs. extend ( inner_attrs) ;
1581
1594
Ok ( body)
@@ -1653,10 +1666,19 @@ impl<'a> Parser<'a> {
1653
1666
req_name : ReqName ,
1654
1667
ret_allow_plus : AllowPlus ,
1655
1668
) -> 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 } ) )
1660
1682
}
1661
1683
1662
1684
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
0 commit comments