Skip to content

Commit b05e9d2

Browse files
committed
parser: solidify fn parsing with parse_fn.
1 parent a833be2 commit b05e9d2

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

src/librustc_parse/parser/item.rs

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,11 @@ pub(super) struct ParamCfg {
15961596
pub is_name_required: fn(&token::Token) -> bool,
15971597
}
15981598

1599+
impl ParamCfg {
1600+
/// Configuration for a free function in the sense that it is not associated.
1601+
const FREE: Self = ParamCfg { is_name_required: |_| true };
1602+
}
1603+
15991604
/// Parsing of functions and methods.
16001605
impl<'a> Parser<'a> {
16011606
/// Parses an item-position function declaration.
@@ -1605,11 +1610,9 @@ impl<'a> Parser<'a> {
16051610
vis: Visibility,
16061611
mut attrs: Vec<Attribute>,
16071612
) -> PResult<'a, Option<P<Item>>> {
1608-
let cfg = ParamCfg { is_name_required: |_| true };
1609-
let header = self.parse_fn_front_matter()?;
1610-
let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
1611-
let body = self.parse_fn_body(&mut false, &mut attrs)?;
1612-
let kind = ItemKind::Fn(FnSig { decl, header }, generics, body);
1613+
let (ident, sig, generics, body) =
1614+
self.parse_fn(&mut false, &mut attrs, &ParamCfg::FREE)?;
1615+
let kind = ItemKind::Fn(sig, generics, body);
16131616
self.mk_item_with_info(attrs, lo, vis, (ident, kind, None))
16141617
}
16151618

@@ -1620,11 +1623,9 @@ impl<'a> Parser<'a> {
16201623
lo: Span,
16211624
mut attrs: Vec<Attribute>,
16221625
) -> PResult<'a, P<ForeignItem>> {
1623-
let cfg = ParamCfg { is_name_required: |_| true };
1624-
let header = self.parse_fn_front_matter()?;
1625-
let (ident, decl, generics) = self.parse_fn_sig(&cfg)?;
1626-
let body = self.parse_fn_body(&mut false, &mut attrs)?;
1627-
let kind = ForeignItemKind::Fn(FnSig { header, decl }, generics, body);
1626+
let (ident, sig, generics, body) =
1627+
self.parse_fn(&mut false, &mut attrs, &ParamCfg::FREE)?;
1628+
let kind = ForeignItemKind::Fn(sig, generics, body);
16281629
let span = lo.to(self.prev_span);
16291630
Ok(P(ast::ForeignItem { ident, attrs, kind, id: DUMMY_NODE_ID, span, vis, tokens: None }))
16301631
}
@@ -1635,10 +1636,25 @@ impl<'a> Parser<'a> {
16351636
attrs: &mut Vec<Attribute>,
16361637
is_name_required: fn(&token::Token) -> bool,
16371638
) -> PResult<'a, (Ident, AssocItemKind, Generics)> {
1638-
let header = self.parse_fn_front_matter()?;
1639-
let (ident, decl, generics) = self.parse_fn_sig(&&ParamCfg { is_name_required })?;
1640-
let body = self.parse_fn_body(at_end, attrs)?;
1641-
Ok((ident, AssocItemKind::Fn(FnSig { header, decl }, body), generics))
1639+
let cfg = ParamCfg { is_name_required };
1640+
let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, &cfg)?;
1641+
Ok((ident, AssocItemKind::Fn(sig, body), generics))
1642+
}
1643+
1644+
/// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
1645+
fn parse_fn(
1646+
&mut self,
1647+
at_end: &mut bool,
1648+
attrs: &mut Vec<Attribute>,
1649+
cfg: &ParamCfg,
1650+
) -> PResult<'a, (Ident, FnSig, Generics, Option<P<Block>>)> {
1651+
let header = self.parse_fn_front_matter()?; // `const ... fn`
1652+
let ident = self.parse_ident()?; // `foo`
1653+
let mut generics = self.parse_generics()?; // `<'a, T, ...>`
1654+
let decl = self.parse_fn_decl(cfg, AllowPlus::Yes)?; // `(p: u8, ...)`
1655+
generics.where_clause = self.parse_where_clause()?; // `where T: Ord`
1656+
let body = self.parse_fn_body(at_end, attrs)?; // `;` or `{ ... }`.
1657+
Ok((ident, FnSig { header, decl }, generics, body))
16421658
}
16431659

16441660
/// Parse the "body" of a function.
@@ -1722,15 +1738,6 @@ impl<'a> Parser<'a> {
17221738
Ok(FnHeader { constness, unsafety, asyncness, ext })
17231739
}
17241740

1725-
/// Parse the "signature", including the identifier, parameters, and generics of a function.
1726-
fn parse_fn_sig(&mut self, cfg: &ParamCfg) -> PResult<'a, (Ident, P<FnDecl>, Generics)> {
1727-
let ident = self.parse_ident()?;
1728-
let mut generics = self.parse_generics()?;
1729-
let decl = self.parse_fn_decl(cfg, AllowPlus::Yes)?;
1730-
generics.where_clause = self.parse_where_clause()?;
1731-
Ok((ident, decl, generics))
1732-
}
1733-
17341741
/// Parses the parameter list and result type of a function declaration.
17351742
pub(super) fn parse_fn_decl(
17361743
&mut self,

0 commit comments

Comments
 (0)