diff options
Diffstat (limited to 'compiler/rustc_parse/src/parser/item.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index bcff820da79..3bd8ae02586 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -252,6 +252,8 @@ impl<'a> Parser<'a> { { // IMPL ITEM self.parse_item_impl(attrs, def_())? + } else if self.is_reuse_path_item() { + self.parse_item_delegation()? } else if self.check_keyword(kw::Mod) || self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Mod]) { @@ -349,11 +351,18 @@ impl<'a> Parser<'a> { /// When parsing a statement, would the start of a path be an item? pub(super) fn is_path_start_item(&mut self) -> bool { self.is_kw_followed_by_ident(kw::Union) // no: `union::b`, yes: `union U { .. }` + || self.is_reuse_path_item() || self.check_auto_or_unsafe_trait_item() // no: `auto::b`, yes: `auto trait X { .. }` || self.is_async_fn() // no(2015): `async::b`, yes: `async fn` || matches!(self.is_macro_rules_item(), IsMacroRulesItem::Yes{..}) // no: `macro_rules::b`, yes: `macro_rules! mac` } + fn is_reuse_path_item(&mut self) -> bool { + // no: `reuse ::path` for compatibility reasons with macro invocations + self.token.is_keyword(kw::Reuse) + && self.look_ahead(1, |t| t.is_path_start() && t.kind != token::ModSep) + } + /// Are we sure this could not possibly be a macro invocation? fn isnt_macro_invocation(&mut self) -> bool { self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::ModSep) @@ -655,6 +664,33 @@ impl<'a> Parser<'a> { Ok((Ident::empty(), item_kind)) } + fn parse_item_delegation(&mut self) -> PResult<'a, ItemInfo> { + let span = self.token.span; + self.expect_keyword(kw::Reuse)?; + + let (qself, path) = if self.eat_lt() { + let (qself, path) = self.parse_qpath(PathStyle::Expr)?; + (Some(qself), path) + } else { + (None, self.parse_path(PathStyle::Expr)?) + }; + + let body = if self.check(&token::OpenDelim(Delimiter::Brace)) { + Some(self.parse_block()?) + } else { + self.expect(&token::Semi)?; + None + }; + let span = span.to(self.prev_token.span); + self.sess.gated_spans.gate(sym::fn_delegation, span); + + let ident = path.segments.last().map(|seg| seg.ident).unwrap_or(Ident::empty()); + Ok(( + ident, + ItemKind::Delegation(Box::new(Delegation { id: DUMMY_NODE_ID, qself, path, body })), + )) + } + fn parse_item_list<T>( &mut self, attrs: &mut AttrVec, |
