Skip to content

Commit 4e6c21f

Browse files
committed
delegation: Implement glob delegation
1 parent 3cb0030 commit 4e6c21f

27 files changed

+1023
-73
lines changed

compiler/rustc_ast/src/ast.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -3127,13 +3127,15 @@ pub struct Delegation {
31273127
pub path: Path,
31283128
pub rename: Option<Ident>,
31293129
pub body: Option<P<Block>>,
3130+
pub from_glob: bool,
31303131
}
31313132

31323133
#[derive(Clone, Encodable, Decodable, Debug)]
31333134
pub struct DelegationMac {
31343135
pub qself: Option<P<QSelf>>,
31353136
pub prefix: Path,
3136-
pub suffixes: ThinVec<(Ident, Option<Ident>)>,
3137+
// Some for list delegation, and None for glob delegation.
3138+
pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
31373139
pub body: Option<P<Block>>,
31383140
}
31393141

@@ -3256,7 +3258,7 @@ pub enum ItemKind {
32563258
///
32573259
/// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
32583260
Delegation(Box<Delegation>),
3259-
/// A list delegation item (`reuse prefix::{a, b, c}`).
3261+
/// A list or glob delegation item (`reuse prefix::{a, b, c}`, `reuse prefix::*`).
32603262
/// Treated similarly to a macro call and expanded early.
32613263
DelegationMac(Box<DelegationMac>),
32623264
}
@@ -3336,7 +3338,7 @@ pub enum AssocItemKind {
33363338
MacCall(P<MacCall>),
33373339
/// An associated delegation item.
33383340
Delegation(Box<Delegation>),
3339-
/// An associated delegation item list.
3341+
/// An associated list or glob delegation item.
33403342
DelegationMac(Box<DelegationMac>),
33413343
}
33423344

compiler/rustc_ast/src/mut_visit.rs

+28-10
Original file line numberDiff line numberDiff line change
@@ -1159,7 +1159,14 @@ impl NoopVisitItemKind for ItemKind {
11591159
}
11601160
ItemKind::MacCall(m) => vis.visit_mac_call(m),
11611161
ItemKind::MacroDef(def) => vis.visit_macro_def(def),
1162-
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
1162+
ItemKind::Delegation(box Delegation {
1163+
id,
1164+
qself,
1165+
path,
1166+
rename,
1167+
body,
1168+
from_glob: _,
1169+
}) => {
11631170
vis.visit_id(id);
11641171
vis.visit_qself(qself);
11651172
vis.visit_path(path);
@@ -1173,10 +1180,12 @@ impl NoopVisitItemKind for ItemKind {
11731180
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
11741181
vis.visit_qself(qself);
11751182
vis.visit_path(prefix);
1176-
for (ident, rename) in suffixes {
1177-
vis.visit_ident(ident);
1178-
if let Some(rename) = rename {
1179-
vis.visit_ident(rename);
1183+
if let Some(suffixes) = suffixes {
1184+
for (ident, rename) in suffixes {
1185+
vis.visit_ident(ident);
1186+
if let Some(rename) = rename {
1187+
vis.visit_ident(rename);
1188+
}
11801189
}
11811190
}
11821191
if let Some(body) = body {
@@ -1215,7 +1224,14 @@ impl NoopVisitItemKind for AssocItemKind {
12151224
visit_opt(ty, |ty| visitor.visit_ty(ty));
12161225
}
12171226
AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
1218-
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
1227+
AssocItemKind::Delegation(box Delegation {
1228+
id,
1229+
qself,
1230+
path,
1231+
rename,
1232+
body,
1233+
from_glob: _,
1234+
}) => {
12191235
visitor.visit_id(id);
12201236
visitor.visit_qself(qself);
12211237
visitor.visit_path(path);
@@ -1229,10 +1245,12 @@ impl NoopVisitItemKind for AssocItemKind {
12291245
AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
12301246
visitor.visit_qself(qself);
12311247
visitor.visit_path(prefix);
1232-
for (ident, rename) in suffixes {
1233-
visitor.visit_ident(ident);
1234-
if let Some(rename) = rename {
1235-
visitor.visit_ident(rename);
1248+
if let Some(suffixes) = suffixes {
1249+
for (ident, rename) in suffixes {
1250+
visitor.visit_ident(ident);
1251+
if let Some(rename) = rename {
1252+
visitor.visit_ident(rename);
1253+
}
12361254
}
12371255
}
12381256
if let Some(body) = body {

compiler/rustc_ast/src/visit.rs

+28-10
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,14 @@ impl WalkItemKind for ItemKind {
395395
}
396396
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
397397
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
398-
ItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
398+
ItemKind::Delegation(box Delegation {
399+
id,
400+
qself,
401+
path,
402+
rename,
403+
body,
404+
from_glob: _,
405+
}) => {
399406
if let Some(qself) = qself {
400407
try_visit!(visitor.visit_ty(&qself.ty));
401408
}
@@ -408,10 +415,12 @@ impl WalkItemKind for ItemKind {
408415
try_visit!(visitor.visit_ty(&qself.ty));
409416
}
410417
try_visit!(visitor.visit_path(prefix, item.id));
411-
for (ident, rename) in suffixes {
412-
visitor.visit_ident(*ident);
413-
if let Some(rename) = rename {
414-
visitor.visit_ident(*rename);
418+
if let Some(suffixes) = suffixes {
419+
for (ident, rename) in suffixes {
420+
visitor.visit_ident(*ident);
421+
if let Some(rename) = rename {
422+
visitor.visit_ident(*rename);
423+
}
415424
}
416425
}
417426
visit_opt!(visitor, visit_block, body);
@@ -820,7 +829,14 @@ impl WalkItemKind for AssocItemKind {
820829
AssocItemKind::MacCall(mac) => {
821830
try_visit!(visitor.visit_mac_call(mac));
822831
}
823-
AssocItemKind::Delegation(box Delegation { id, qself, path, rename, body }) => {
832+
AssocItemKind::Delegation(box Delegation {
833+
id,
834+
qself,
835+
path,
836+
rename,
837+
body,
838+
from_glob: _,
839+
}) => {
824840
if let Some(qself) = qself {
825841
try_visit!(visitor.visit_ty(&qself.ty));
826842
}
@@ -833,10 +849,12 @@ impl WalkItemKind for AssocItemKind {
833849
try_visit!(visitor.visit_ty(&qself.ty));
834850
}
835851
try_visit!(visitor.visit_path(prefix, item.id));
836-
for (ident, rename) in suffixes {
837-
visitor.visit_ident(*ident);
838-
if let Some(rename) = rename {
839-
visitor.visit_ident(*rename);
852+
if let Some(suffixes) = suffixes {
853+
for (ident, rename) in suffixes {
854+
visitor.visit_ident(*ident);
855+
if let Some(rename) = rename {
856+
visitor.visit_ident(*rename);
857+
}
840858
}
841859
}
842860
visit_opt!(visitor, visit_block, body);

compiler/rustc_ast_pretty/src/pprust/state/item.rs

+32-19
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ use rustc_ast::ptr::P;
99
use rustc_ast::ModKind;
1010
use rustc_span::symbol::Ident;
1111

12+
enum DelegationKind<'a> {
13+
Single,
14+
List(&'a [(Ident, Option<Ident>)]),
15+
Glob,
16+
}
17+
1218
fn visibility_qualified(vis: &ast::Visibility, s: &str) -> String {
1319
format!("{}{}", State::to_string(|s| s.print_visibility(vis)), s)
1420
}
@@ -380,15 +386,15 @@ impl<'a> State<'a> {
380386
&item.vis,
381387
&deleg.qself,
382388
&deleg.path,
383-
None,
389+
DelegationKind::Single,
384390
&deleg.body,
385391
),
386392
ast::ItemKind::DelegationMac(deleg) => self.print_delegation(
387393
&item.attrs,
388394
&item.vis,
389395
&deleg.qself,
390396
&deleg.prefix,
391-
Some(&deleg.suffixes),
397+
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
392398
&deleg.body,
393399
),
394400
}
@@ -572,28 +578,28 @@ impl<'a> State<'a> {
572578
vis,
573579
&deleg.qself,
574580
&deleg.path,
575-
None,
581+
DelegationKind::Single,
576582
&deleg.body,
577583
),
578584
ast::AssocItemKind::DelegationMac(deleg) => self.print_delegation(
579585
&item.attrs,
580586
vis,
581587
&deleg.qself,
582588
&deleg.prefix,
583-
Some(&deleg.suffixes),
589+
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
584590
&deleg.body,
585591
),
586592
}
587593
self.ann.post(self, AnnNode::SubItem(id))
588594
}
589595

590-
pub(crate) fn print_delegation(
596+
fn print_delegation(
591597
&mut self,
592598
attrs: &[ast::Attribute],
593599
vis: &ast::Visibility,
594600
qself: &Option<P<ast::QSelf>>,
595601
path: &ast::Path,
596-
suffixes: Option<&[(Ident, Option<Ident>)]>,
602+
kind: DelegationKind<'_>,
597603
body: &Option<P<ast::Block>>,
598604
) {
599605
if body.is_some() {
@@ -607,21 +613,28 @@ impl<'a> State<'a> {
607613
} else {
608614
self.print_path(path, false, 0);
609615
}
610-
if let Some(suffixes) = suffixes {
611-
self.word("::");
612-
self.word("{");
613-
for (i, (ident, rename)) in suffixes.iter().enumerate() {
614-
self.print_ident(*ident);
615-
if let Some(rename) = rename {
616-
self.nbsp();
617-
self.word_nbsp("as");
618-
self.print_ident(*rename);
619-
}
620-
if i != suffixes.len() - 1 {
621-
self.word_space(",");
616+
match kind {
617+
DelegationKind::Single => {}
618+
DelegationKind::List(suffixes) => {
619+
self.word("::");
620+
self.word("{");
621+
for (i, (ident, rename)) in suffixes.iter().enumerate() {
622+
self.print_ident(*ident);
623+
if let Some(rename) = rename {
624+
self.nbsp();
625+
self.word_nbsp("as");
626+
self.print_ident(*rename);
627+
}
628+
if i != suffixes.len() - 1 {
629+
self.word_space(",");
630+
}
622631
}
632+
self.word("}");
633+
}
634+
DelegationKind::Glob => {
635+
self.word("::");
636+
self.word("*");
623637
}
624-
self.word("}");
625638
}
626639
if let Some(body) = body {
627640
self.nbsp();

compiler/rustc_expand/src/base.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,11 @@ pub enum SyntaxExtensionKind {
715715
/// The produced AST fragment is appended to the input AST fragment.
716716
Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
717717
),
718+
GlobDelegation(Box<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
719+
}
720+
721+
pub trait GlobDelegationExpander {
722+
fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<Ident>, ()>;
718723
}
719724

720725
/// A struct representing a macro definition in "lowered" form ready for expansion.
@@ -749,7 +754,9 @@ impl SyntaxExtension {
749754
/// Returns which kind of macro calls this syntax extension.
750755
pub fn macro_kind(&self) -> MacroKind {
751756
match self.kind {
752-
SyntaxExtensionKind::Bang(..) | SyntaxExtensionKind::LegacyBang(..) => MacroKind::Bang,
757+
SyntaxExtensionKind::Bang(..)
758+
| SyntaxExtensionKind::LegacyBang(..)
759+
| SyntaxExtensionKind::GlobDelegation(..) => MacroKind::Bang,
753760
SyntaxExtensionKind::Attr(..)
754761
| SyntaxExtensionKind::LegacyAttr(..)
755762
| SyntaxExtensionKind::NonMacroAttr => MacroKind::Attr,
@@ -1031,6 +1038,13 @@ pub trait ResolverExpand {
10311038

10321039
/// Tools registered with `#![register_tool]` and used by tool attributes and lints.
10331040
fn registered_tools(&self) -> &RegisteredTools;
1041+
1042+
fn glob_delegation_suffixes(
1043+
&mut self,
1044+
def_id: DefId,
1045+
parent_def_id: LocalDefId,
1046+
) -> Result<Vec<Ident>, Indeterminate>;
1047+
fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);
10341048
}
10351049

10361050
pub trait LintStoreExpand {

0 commit comments

Comments
 (0)