@@ -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,12 +1549,12 @@ 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
- let ( inner_attrs, body) = if self . check ( & token:: Semi ) {
1555
+ let ( inner_attrs, body) = if self . eat ( & token:: Semi ) {
1555
1556
// 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 ;
1558
1558
( Vec :: new ( ) , None )
1559
1559
} else if self . check ( & token:: OpenDelim ( token:: Brace ) ) || self . token . is_whole_block ( ) {
1560
1560
self . parse_inner_attrs_and_block ( ) . map ( |( attrs, body) | ( attrs, Some ( body) ) ) ?
@@ -1574,7 +1574,21 @@ impl<'a> Parser<'a> {
1574
1574
. emit ( ) ;
1575
1575
( Vec :: new ( ) , Some ( self . mk_block_err ( span) ) )
1576
1576
} 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
+ }
1578
1592
} ;
1579
1593
attrs. extend ( inner_attrs) ;
1580
1594
Ok ( body)
@@ -1652,10 +1666,19 @@ impl<'a> Parser<'a> {
1652
1666
req_name : ReqName ,
1653
1667
ret_allow_plus : AllowPlus ,
1654
1668
) -> 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 } ) )
1659
1682
}
1660
1683
1661
1684
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
0 commit comments