Skip to content

Commit

Permalink
delegation: Implement glob delegation
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed Apr 18, 2024
1 parent 7dda3b8 commit b6925fb
Show file tree
Hide file tree
Showing 25 changed files with 970 additions and 25 deletions.
8 changes: 8 additions & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3110,6 +3110,7 @@ pub struct Fn {
#[derive(Clone, Encodable, Decodable, Debug)]
pub enum DelegationKind {
Single,
Glob,
List(ThinVec<Ident>),
}

Expand All @@ -3121,6 +3122,13 @@ pub struct Delegation {
pub path: Path,
pub kind: DelegationKind,
pub body: Option<P<Block>>,
pub from_glob: bool,
}

impl Delegation {
pub fn is_glob(&self) -> bool {
matches!(self.kind, DelegationKind::Glob)
}
}

#[derive(Clone, Encodable, Decodable, Debug)]
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,12 +1149,12 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
}
ItemKind::MacCall(m) => vis.visit_mac_call(m),
ItemKind::MacroDef(def) => vis.visit_macro_def(def),
ItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
ItemKind::Delegation(box Delegation { id, qself, path, kind, body, from_glob: _ }) => {
vis.visit_id(id);
vis.visit_qself(qself);
vis.visit_path(path);
match kind {
DelegationKind::Single => {}
DelegationKind::Single | DelegationKind::Glob => {}
DelegationKind::List(suffixes) => {
for ident in suffixes {
vis.visit_ident(ident);
Expand Down Expand Up @@ -1203,12 +1203,12 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
visit_opt(ty, |ty| visitor.visit_ty(ty));
}
AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac),
AssocItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
AssocItemKind::Delegation(box Delegation { id, qself, path, kind, body, from_glob: _ }) => {
visitor.visit_id(id);
visitor.visit_qself(qself);
visitor.visit_path(path);
match kind {
DelegationKind::Single => {}
DelegationKind::Single | DelegationKind::Glob => {}
DelegationKind::List(suffixes) => {
for ident in suffixes {
visitor.visit_ident(ident);
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,13 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) -> V::Resu
}
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, item.id)),
ItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
ItemKind::Delegation(box Delegation { id, qself, path, kind, body, from_glob: _ }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, *id));
match kind {
DelegationKind::Single => {}
DelegationKind::Single | DelegationKind::Glob => {}
DelegationKind::List(suffixes) => {
for ident in suffixes {
visitor.visit_ident(*ident);
Expand Down Expand Up @@ -790,13 +790,13 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
AssocItemKind::MacCall(mac) => {
try_visit!(visitor.visit_mac_call(mac));
}
AssocItemKind::Delegation(box Delegation { id, qself, path, kind, body }) => {
AssocItemKind::Delegation(box Delegation { id, qself, path, kind, body, from_glob: _ }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(path, *id));
match kind {
DelegationKind::Single => {}
DelegationKind::Single | DelegationKind::Glob => {}
DelegationKind::List(suffixes) => {
for ident in suffixes {
visitor.visit_ident(*ident);
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,11 @@ pub enum SyntaxExtensionKind {
/// The produced AST fragment is appended to the input AST fragment.
Box<dyn MultiItemModifier + sync::DynSync + sync::DynSend>,
),
GlobDelegation(Box<dyn GlobDelegationExpander + sync::DynSync + sync::DynSend>),
}

pub trait GlobDelegationExpander {
fn expand(&self, ecx: &mut ExtCtxt<'_>) -> ExpandResult<Vec<Ident>, ()>;
}

/// A struct representing a macro definition in "lowered" form ready for expansion.
Expand Down Expand Up @@ -762,7 +767,9 @@ impl SyntaxExtension {
/// Returns which kind of macro calls this syntax extension.
pub fn macro_kind(&self) -> MacroKind {
match self.kind {
SyntaxExtensionKind::Bang(..) | SyntaxExtensionKind::LegacyBang(..) => MacroKind::Bang,
SyntaxExtensionKind::Bang(..)
| SyntaxExtensionKind::LegacyBang(..)
| SyntaxExtensionKind::GlobDelegation(..) => MacroKind::Bang,
SyntaxExtensionKind::Attr(..)
| SyntaxExtensionKind::LegacyAttr(..)
| SyntaxExtensionKind::NonMacroAttr => MacroKind::Attr,
Expand Down Expand Up @@ -1044,6 +1051,13 @@ pub trait ResolverExpand {

/// Tools registered with `#![register_tool]` and used by tool attributes and lints.
fn registered_tools(&self) -> &RegisteredTools;

fn glob_delegation_suffixes(
&mut self,
def_id: DefId,
parent_def_id: LocalDefId,
) -> Result<Vec<Ident>, Indeterminate>;
fn register_glob_delegation(&mut self, invoc_id: LocalExpnId);
}

pub trait LintStoreExpand {
Expand Down
Loading

0 comments on commit b6925fb

Please sign in to comment.