about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-15 10:35:31 +0000
committerbors <bors@rust-lang.org>2024-05-15 10:35:31 +0000
commit3cb0030fe9de01eeacb7c03eeef0c51420798cfb (patch)
tree47262ea23428202480e68ed968b4611b9b6ae676 /compiler/rustc_parse/src
parenta71c3ffce9ca505af27f43cd3bad7606a72e3ec8 (diff)
parentc30b41012d474586d407392a6b154e7f19c38b2c (diff)
downloadrust-3cb0030fe9de01eeacb7c03eeef0c51420798cfb.tar.gz
rust-3cb0030fe9de01eeacb7c03eeef0c51420798cfb.zip
Auto merge of #123413 - petrochenkov:delegmulti2, r=fmease
delegation: Implement list delegation

```rust
reuse prefix::{a, b, c};
```

Using design described in https://github.com/rust-lang/rfcs/pull/3530#issuecomment-2020869823 (the lists are desugared at macro expansion time).
List delegations are expanded eagerly when encountered, similarly to `#[cfg]`s, and not enqueued for later resolution/expansion like regular macros or glob delegation (https://github.com/rust-lang/rust/pull/124135).

Part of https://github.com/rust-lang/rust/issues/118212.
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/parser/item.rs31
-rw-r--r--compiler/rustc_parse/src/parser/path.rs7
2 files changed, 28 insertions, 10 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 29957bd2f71..5a3bfb83725 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -685,20 +685,35 @@ impl<'a> Parser<'a> {
             (None, self.parse_path(PathStyle::Expr)?)
         };
 
-        let rename = if self.eat_keyword(kw::As) { Some(self.parse_ident()?) } else { None };
+        let rename = |this: &mut Self| {
+            Ok(if this.eat_keyword(kw::As) { Some(this.parse_ident()?) } else { None })
+        };
+        let body = |this: &mut Self| {
+            Ok(if this.check(&token::OpenDelim(Delimiter::Brace)) {
+                Some(this.parse_block()?)
+            } else {
+                this.expect(&token::Semi)?;
+                None
+            })
+        };
 
-        let body = if self.check(&token::OpenDelim(Delimiter::Brace)) {
-            Some(self.parse_block()?)
+        let (ident, item_kind) = if self.eat(&token::PathSep) {
+            let (suffixes, _) = self.parse_delim_comma_seq(Delimiter::Brace, |p| {
+                Ok((p.parse_path_segment_ident()?, rename(p)?))
+            })?;
+            let deleg = DelegationMac { qself, prefix: path, suffixes, body: body(self)? };
+            (Ident::empty(), ItemKind::DelegationMac(Box::new(deleg)))
         } else {
-            self.expect(&token::Semi)?;
-            None
+            let rename = rename(self)?;
+            let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
+            let deleg = Delegation { id: DUMMY_NODE_ID, qself, path, rename, body: body(self)? };
+            (ident, ItemKind::Delegation(Box::new(deleg)))
         };
+
         let span = span.to(self.prev_token.span);
         self.psess.gated_spans.gate(sym::fn_delegation, span);
 
-        let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
-        let deleg = Delegation { id: DUMMY_NODE_ID, qself, path, rename, body };
-        Ok((ident, ItemKind::Delegation(Box::new(deleg))))
+        Ok((ident, item_kind))
     }
 
     fn parse_item_list<T>(
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index c37d3f0441d..d845e8ab90d 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -95,12 +95,15 @@ impl<'a> Parser<'a> {
             debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count);
         }
 
-        if !self.recover_colon_before_qpath_proj() {
+        let is_import_coupler = self.is_import_coupler();
+        if !is_import_coupler && !self.recover_colon_before_qpath_proj() {
             self.expect(&token::PathSep)?;
         }
 
         let qself = P(QSelf { ty, path_span, position: path.segments.len() });
-        self.parse_path_segments(&mut path.segments, style, None)?;
+        if !is_import_coupler {
+            self.parse_path_segments(&mut path.segments, style, None)?;
+        }
 
         Ok((
             qself,