Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

delegation: Implement list delegation #123413

Merged
merged 1 commit into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 23 additions & 4 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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>>,
}

Expand Down Expand Up @@ -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 {
Expand All @@ -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",
}
}
Expand All @@ -3280,6 +3292,7 @@ impl ItemKind {
ItemKind::MacroDef(..) => "macro definition",
ItemKind::Impl { .. } => "implementation",
ItemKind::Delegation(..) => "delegated function",
ItemKind::DelegationMac(..) => "delegation",
}
}

Expand Down Expand Up @@ -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 {
Expand All @@ -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
}
}
}
}
Expand All @@ -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),
}
}
}
Expand All @@ -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),
})
}
Expand Down
26 changes: 26 additions & 0 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
}
}
Expand Down Expand Up @@ -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);
}
}
}
}
}
Expand Down
26 changes: 26 additions & 0 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down Expand Up @@ -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()
}
Expand Down
20 changes: 14 additions & 6 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
delegation_results.body_id,
)
}
ItemKind::MacCall(..) => {
panic!("`TyMac` should have been expanded by now")
ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
}
}
Expand Down Expand Up @@ -845,7 +845,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
(delegation_results.generics, item_kind, true)
}
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
};

let item = hir::TraitItem {
Expand All @@ -869,7 +871,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegation_has_self(i.id, delegation.id, i.span),
},
AssocItemKind::MacCall(..) => unimplemented!(),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
};
let id = hir::TraitItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } };
hir::TraitItemRef {
Expand Down Expand Up @@ -964,7 +968,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
)
}
AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
};

let item = hir::ImplItem {
Expand Down Expand Up @@ -993,7 +999,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
has_self: self.delegation_has_self(i.id, delegation.id, i.span),
},
AssocItemKind::MacCall(..) => unimplemented!(),
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
panic!("macros should have been expanded by now")
}
},
trait_item_def_id: self
.resolver
Expand Down
74 changes: 60 additions & 14 deletions compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
use ast::StaticItem;
use itertools::{Itertools, Position};
use rustc_ast as ast;
use rustc_ast::ptr::P;
use rustc_ast::ModKind;
use rustc_span::symbol::Ident;

Expand Down Expand Up @@ -374,9 +375,22 @@ impl<'a> State<'a> {
state.print_visibility(&item.vis)
});
}
ast::ItemKind::Delegation(box delegation) => {
self.print_delegation(delegation, &item.vis, &item.attrs)
}
ast::ItemKind::Delegation(deleg) => self.print_delegation(
&item.attrs,
&item.vis,
&deleg.qself,
&deleg.path,
None,
&deleg.body,
),
ast::ItemKind::DelegationMac(deleg) => self.print_delegation(
&item.attrs,
&item.vis,
&deleg.qself,
&deleg.prefix,
Some(&deleg.suffixes),
&deleg.body,
),
}
self.ann.post(self, AnnNode::Item(item))
}
Expand Down Expand Up @@ -553,31 +567,63 @@ impl<'a> State<'a> {
self.word(";");
}
}
ast::AssocItemKind::Delegation(box delegation) => {
self.print_delegation(delegation, vis, &item.attrs)
}
ast::AssocItemKind::Delegation(deleg) => self.print_delegation(
&item.attrs,
vis,
&deleg.qself,
&deleg.path,
None,
&deleg.body,
),
ast::AssocItemKind::DelegationMac(deleg) => self.print_delegation(
&item.attrs,
vis,
&deleg.qself,
&deleg.prefix,
Some(&deleg.suffixes),
&deleg.body,
),
}
self.ann.post(self, AnnNode::SubItem(id))
}

pub(crate) fn print_delegation(
&mut self,
delegation: &ast::Delegation,
vis: &ast::Visibility,
attrs: &[ast::Attribute],
vis: &ast::Visibility,
qself: &Option<P<ast::QSelf>>,
path: &ast::Path,
suffixes: Option<&[(Ident, Option<Ident>)]>,
body: &Option<P<ast::Block>>,
) {
if delegation.body.is_some() {
if body.is_some() {
self.head("");
}
self.print_visibility(vis);
self.word_space("reuse");
self.word_nbsp("reuse");

if let Some(qself) = &delegation.qself {
self.print_qpath(&delegation.path, qself, false);
if let Some(qself) = qself {
self.print_qpath(path, qself, false);
} else {
self.print_path(&delegation.path, false, 0);
self.print_path(path, false, 0);
}
if let Some(suffixes) = suffixes {
self.word("::");
self.word("{");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(minor, not blocking) could maybe use one of ibox, cbox

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll leave this for some later time.

for (i, (ident, rename)) in suffixes.iter().enumerate() {
self.print_ident(*ident);
if let Some(rename) = rename {
self.nbsp();
self.word_nbsp("as");
self.print_ident(*rename);
}
if i != suffixes.len() - 1 {
self.word_space(",");
}
}
self.word("}");
}
if let Some(body) = &delegation.body {
if let Some(body) = body {
self.nbsp();
self.print_block_with_attrs(body, attrs);
} else {
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_expand/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ expand_duplicate_matcher_binding = duplicate matcher binding
.label = duplicate binding
.label2 = previous binding

expand_empty_delegation_list =
empty list delegation is not supported

expand_expected_paren_or_brace =
expected `(` or `{"{"}`, found `{$token}`

Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_expand/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,10 @@ pub struct ExpectedParenOrBrace<'a> {
pub span: Span,
pub token: Cow<'a, str>,
}

#[derive(Diagnostic)]
#[diag(expand_empty_delegation_list)]
pub(crate) struct EmptyDelegationList {
#[primary_span]
pub span: Span,
}
Loading
Loading