1
Fork 0

delegation: Implement list delegation

```rust
reuse prefix::{a, b, c}
```
This commit is contained in:
Vadim Petrochenkov 2024-03-15 14:21:03 +03:00
parent 8387315ab3
commit c30b41012d
29 changed files with 511 additions and 60 deletions

View file

@ -2961,6 +2961,7 @@ impl Item {
| ItemKind::GlobalAsm(_)
| ItemKind::MacCall(_)
| ItemKind::Delegation(_)
| ItemKind::DelegationMac(_)
| ItemKind::MacroDef(_) => None,
ItemKind::Static(_) => None,
ItemKind::Const(i) => Some(&i.generics),
@ -3123,8 +3124,16 @@ pub struct Delegation {
/// Path resolution id.
pub id: NodeId,
pub qself: Option<P<QSelf>>,
pub rename: Option<Ident>,
pub path: Path,
pub rename: Option<Ident>,
pub body: Option<P<Block>>,
}
#[derive(Clone, Encodable, Decodable, Debug)]
pub struct DelegationMac {
pub qself: Option<P<QSelf>>,
pub prefix: Path,
pub suffixes: ThinVec<(Ident, Option<Ident>)>,
pub body: Option<P<Block>>,
}
@ -3243,10 +3252,13 @@ pub enum ItemKind {
/// A macro definition.
MacroDef(MacroDef),
/// A delegation item (`reuse`).
/// A single delegation item (`reuse`).
///
/// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
Delegation(Box<Delegation>),
/// A list delegation item (`reuse prefix::{a, b, c}`).
/// Treated similarly to a macro call and expanded early.
DelegationMac(Box<DelegationMac>),
}
impl ItemKind {
@ -3255,7 +3267,7 @@ impl ItemKind {
match self {
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
| Delegation(..) => "a",
| Delegation(..) | DelegationMac(..) => "a",
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
}
}
@ -3280,6 +3292,7 @@ impl ItemKind {
ItemKind::MacroDef(..) => "macro definition",
ItemKind::Impl { .. } => "implementation",
ItemKind::Delegation(..) => "delegated function",
ItemKind::DelegationMac(..) => "delegation",
}
}
@ -3323,6 +3336,8 @@ pub enum AssocItemKind {
MacCall(P<MacCall>),
/// An associated delegation item.
Delegation(Box<Delegation>),
/// An associated delegation item list.
DelegationMac(Box<DelegationMac>),
}
impl AssocItemKind {
@ -3331,7 +3346,9 @@ impl AssocItemKind {
Self::Const(box ConstItem { defaultness, .. })
| Self::Fn(box Fn { defaultness, .. })
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
Self::MacCall(..) | Self::Delegation(..) => Defaultness::Final,
Self::MacCall(..) | Self::Delegation(..) | Self::DelegationMac(..) => {
Defaultness::Final
}
}
}
}
@ -3344,6 +3361,7 @@ impl From<AssocItemKind> for ItemKind {
AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
}
}
}
@ -3358,6 +3376,7 @@ impl TryFrom<ItemKind> for AssocItemKind {
ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
_ => return Err(item_kind),
})
}

View file

@ -1170,6 +1170,19 @@ impl NoopVisitItemKind for ItemKind {
vis.visit_block(body);
}
}
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
vis.visit_qself(qself);
vis.visit_path(prefix);
for (ident, rename) in suffixes {
vis.visit_ident(ident);
if let Some(rename) = rename {
vis.visit_ident(rename);
}
}
if let Some(body) = body {
vis.visit_block(body);
}
}
}
}
}
@ -1213,6 +1226,19 @@ impl NoopVisitItemKind for AssocItemKind {
visitor.visit_block(body);
}
}
AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
visitor.visit_qself(qself);
visitor.visit_path(prefix);
for (ident, rename) in suffixes {
visitor.visit_ident(ident);
if let Some(rename) = rename {
visitor.visit_ident(rename);
}
}
if let Some(body) = body {
visitor.visit_block(body);
}
}
}
}
}

View file

@ -403,6 +403,19 @@ impl WalkItemKind for ItemKind {
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(prefix, item.id));
for (ident, rename) in suffixes {
visitor.visit_ident(*ident);
if let Some(rename) = rename {
visitor.visit_ident(*rename);
}
}
visit_opt!(visitor, visit_block, body);
}
}
V::Result::output()
}
@ -815,6 +828,19 @@ impl WalkItemKind for AssocItemKind {
visit_opt!(visitor, visit_ident, *rename);
visit_opt!(visitor, visit_block, body);
}
AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
if let Some(qself) = qself {
try_visit!(visitor.visit_ty(&qself.ty));
}
try_visit!(visitor.visit_path(prefix, item.id));
for (ident, rename) in suffixes {
visitor.visit_ident(*ident);
if let Some(rename) = rename {
visitor.visit_ident(*rename);
}
}
visit_opt!(visitor, visit_block, body);
}
}
V::Result::output()
}