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.
This commit is contained in:
commit
3cb0030fe9
@ -2961,6 +2961,7 @@ pub fn opt_generics(&self) -> Option<&Generics> {
|
|||||||
| ItemKind::GlobalAsm(_)
|
| ItemKind::GlobalAsm(_)
|
||||||
| ItemKind::MacCall(_)
|
| ItemKind::MacCall(_)
|
||||||
| ItemKind::Delegation(_)
|
| ItemKind::Delegation(_)
|
||||||
|
| ItemKind::DelegationMac(_)
|
||||||
| ItemKind::MacroDef(_) => None,
|
| ItemKind::MacroDef(_) => None,
|
||||||
ItemKind::Static(_) => None,
|
ItemKind::Static(_) => None,
|
||||||
ItemKind::Const(i) => Some(&i.generics),
|
ItemKind::Const(i) => Some(&i.generics),
|
||||||
@ -3123,8 +3124,16 @@ pub struct Delegation {
|
|||||||
/// Path resolution id.
|
/// Path resolution id.
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
pub qself: Option<P<QSelf>>,
|
pub qself: Option<P<QSelf>>,
|
||||||
pub rename: Option<Ident>,
|
|
||||||
pub path: Path,
|
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>>,
|
pub body: Option<P<Block>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3243,10 +3252,13 @@ pub enum ItemKind {
|
|||||||
/// A macro definition.
|
/// A macro definition.
|
||||||
MacroDef(MacroDef),
|
MacroDef(MacroDef),
|
||||||
|
|
||||||
/// A delegation item (`reuse`).
|
/// A single delegation item (`reuse`).
|
||||||
///
|
///
|
||||||
/// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
|
/// E.g. `reuse <Type as Trait>::name { target_expr_template }`.
|
||||||
Delegation(Box<Delegation>),
|
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 {
|
impl ItemKind {
|
||||||
@ -3255,7 +3267,7 @@ pub fn article(&self) -> &'static str {
|
|||||||
match self {
|
match self {
|
||||||
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
|
Use(..) | Static(..) | Const(..) | Fn(..) | Mod(..) | GlobalAsm(..) | TyAlias(..)
|
||||||
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
|
| Struct(..) | Union(..) | Trait(..) | TraitAlias(..) | MacroDef(..)
|
||||||
| Delegation(..) => "a",
|
| Delegation(..) | DelegationMac(..) => "a",
|
||||||
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
|
ExternCrate(..) | ForeignMod(..) | MacCall(..) | Enum(..) | Impl { .. } => "an",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3280,6 +3292,7 @@ pub fn descr(&self) -> &'static str {
|
|||||||
ItemKind::MacroDef(..) => "macro definition",
|
ItemKind::MacroDef(..) => "macro definition",
|
||||||
ItemKind::Impl { .. } => "implementation",
|
ItemKind::Impl { .. } => "implementation",
|
||||||
ItemKind::Delegation(..) => "delegated function",
|
ItemKind::Delegation(..) => "delegated function",
|
||||||
|
ItemKind::DelegationMac(..) => "delegation",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3323,6 +3336,8 @@ pub enum AssocItemKind {
|
|||||||
MacCall(P<MacCall>),
|
MacCall(P<MacCall>),
|
||||||
/// An associated delegation item.
|
/// An associated delegation item.
|
||||||
Delegation(Box<Delegation>),
|
Delegation(Box<Delegation>),
|
||||||
|
/// An associated delegation item list.
|
||||||
|
DelegationMac(Box<DelegationMac>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AssocItemKind {
|
impl AssocItemKind {
|
||||||
@ -3331,7 +3346,9 @@ pub fn defaultness(&self) -> Defaultness {
|
|||||||
Self::Const(box ConstItem { defaultness, .. })
|
Self::Const(box ConstItem { defaultness, .. })
|
||||||
| Self::Fn(box Fn { defaultness, .. })
|
| Self::Fn(box Fn { defaultness, .. })
|
||||||
| Self::Type(box TyAlias { defaultness, .. }) => 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 @@ fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
|
|||||||
AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
|
AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
|
||||||
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
|
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
|
||||||
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
|
AssocItemKind::Delegation(delegation) => ItemKind::Delegation(delegation),
|
||||||
|
AssocItemKind::DelegationMac(delegation) => ItemKind::DelegationMac(delegation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3358,6 +3376,7 @@ fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
|
|||||||
ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
|
ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
|
||||||
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
|
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
|
||||||
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
|
ItemKind::Delegation(d) => AssocItemKind::Delegation(d),
|
||||||
|
ItemKind::DelegationMac(d) => AssocItemKind::DelegationMac(d),
|
||||||
_ => return Err(item_kind),
|
_ => return Err(item_kind),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1170,6 +1170,19 @@ fn noop_visit(&mut self, vis: &mut impl MutVisitor) {
|
|||||||
vis.visit_block(body);
|
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 @@ fn noop_visit(&mut self, visitor: &mut impl MutVisitor) {
|
|||||||
visitor.visit_block(body);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,6 +403,19 @@ fn walk<'a, V: Visitor<'a>>(
|
|||||||
visit_opt!(visitor, visit_ident, *rename);
|
visit_opt!(visitor, visit_ident, *rename);
|
||||||
visit_opt!(visitor, visit_block, body);
|
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()
|
V::Result::output()
|
||||||
}
|
}
|
||||||
@ -815,6 +828,19 @@ fn walk<'a, V: Visitor<'a>>(
|
|||||||
visit_opt!(visitor, visit_ident, *rename);
|
visit_opt!(visitor, visit_ident, *rename);
|
||||||
visit_opt!(visitor, visit_block, body);
|
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()
|
V::Result::output()
|
||||||
}
|
}
|
||||||
|
@ -460,8 +460,8 @@ fn lower_item_kind(
|
|||||||
delegation_results.body_id,
|
delegation_results.body_id,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ItemKind::MacCall(..) => {
|
ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => {
|
||||||
panic!("`TyMac` should have been expanded by now")
|
panic!("macros should have been expanded by now")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -845,7 +845,9 @@ fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
|
|||||||
);
|
);
|
||||||
(delegation_results.generics, item_kind, true)
|
(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 {
|
let item = hir::TraitItem {
|
||||||
@ -869,7 +871,9 @@ fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
|
|||||||
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
||||||
has_self: self.delegation_has_self(i.id, delegation.id, i.span),
|
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) } };
|
let id = hir::TraitItemId { owner_id: hir::OwnerId { def_id: self.local_def_id(i.id) } };
|
||||||
hir::TraitItemRef {
|
hir::TraitItemRef {
|
||||||
@ -964,7 +968,9 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
|||||||
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
|
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 {
|
let item = hir::ImplItem {
|
||||||
@ -993,7 +999,9 @@ fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
|
|||||||
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
||||||
has_self: self.delegation_has_self(i.id, delegation.id, i.span),
|
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
|
trait_item_def_id: self
|
||||||
.resolver
|
.resolver
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
use ast::StaticItem;
|
use ast::StaticItem;
|
||||||
use itertools::{Itertools, Position};
|
use itertools::{Itertools, Position};
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
use rustc_ast::ptr::P;
|
||||||
use rustc_ast::ModKind;
|
use rustc_ast::ModKind;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
|
|
||||||
@ -374,9 +375,22 @@ pub(crate) fn print_item(&mut self, item: &ast::Item) {
|
|||||||
state.print_visibility(&item.vis)
|
state.print_visibility(&item.vis)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ast::ItemKind::Delegation(box delegation) => {
|
ast::ItemKind::Delegation(deleg) => self.print_delegation(
|
||||||
self.print_delegation(delegation, &item.vis, &item.attrs)
|
&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))
|
self.ann.post(self, AnnNode::Item(item))
|
||||||
}
|
}
|
||||||
@ -553,31 +567,63 @@ fn print_assoc_item(&mut self, item: &ast::AssocItem) {
|
|||||||
self.word(";");
|
self.word(";");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::AssocItemKind::Delegation(box delegation) => {
|
ast::AssocItemKind::Delegation(deleg) => self.print_delegation(
|
||||||
self.print_delegation(delegation, vis, &item.attrs)
|
&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))
|
self.ann.post(self, AnnNode::SubItem(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn print_delegation(
|
pub(crate) fn print_delegation(
|
||||||
&mut self,
|
&mut self,
|
||||||
delegation: &ast::Delegation,
|
|
||||||
vis: &ast::Visibility,
|
|
||||||
attrs: &[ast::Attribute],
|
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.head("");
|
||||||
}
|
}
|
||||||
self.print_visibility(vis);
|
self.print_visibility(vis);
|
||||||
self.word_space("reuse");
|
self.word_nbsp("reuse");
|
||||||
|
|
||||||
if let Some(qself) = &delegation.qself {
|
if let Some(qself) = qself {
|
||||||
self.print_qpath(&delegation.path, qself, false);
|
self.print_qpath(path, qself, false);
|
||||||
} else {
|
} else {
|
||||||
self.print_path(&delegation.path, false, 0);
|
self.print_path(path, false, 0);
|
||||||
}
|
}
|
||||||
if let Some(body) = &delegation.body {
|
if let Some(suffixes) = suffixes {
|
||||||
|
self.word("::");
|
||||||
|
self.word("{");
|
||||||
|
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) = body {
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
self.print_block_with_attrs(body, attrs);
|
self.print_block_with_attrs(body, attrs);
|
||||||
} else {
|
} else {
|
||||||
|
@ -30,6 +30,9 @@ expand_duplicate_matcher_binding = duplicate matcher binding
|
|||||||
.label = duplicate binding
|
.label = duplicate binding
|
||||||
.label2 = previous binding
|
.label2 = previous binding
|
||||||
|
|
||||||
|
expand_empty_delegation_list =
|
||||||
|
empty list delegation is not supported
|
||||||
|
|
||||||
expand_expected_paren_or_brace =
|
expand_expected_paren_or_brace =
|
||||||
expected `(` or `{"{"}`, found `{$token}`
|
expected `(` or `{"{"}`, found `{$token}`
|
||||||
|
|
||||||
|
@ -433,3 +433,10 @@ pub struct ExpectedParenOrBrace<'a> {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub token: Cow<'a, str>,
|
pub token: Cow<'a, str>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(expand_empty_delegation_list)]
|
||||||
|
pub(crate) struct EmptyDelegationList {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::base::*;
|
use crate::base::*;
|
||||||
use crate::config::StripUnconfigured;
|
use crate::config::StripUnconfigured;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
IncompleteParse, RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported,
|
EmptyDelegationList, IncompleteParse, RecursionLimitReached, RemoveExprNotSupported,
|
||||||
UnsupportedKeyValue, WrongFragmentKind,
|
RemoveNodeNotSupported, UnsupportedKeyValue, WrongFragmentKind,
|
||||||
};
|
};
|
||||||
use crate::mbe::diagnostics::annotate_err_with_kind;
|
use crate::mbe::diagnostics::annotate_err_with_kind;
|
||||||
use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
|
use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod};
|
||||||
@ -1041,6 +1041,7 @@ enum AddSemicolon {
|
|||||||
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
|
trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
|
||||||
type OutputTy = SmallVec<[Self; 1]>;
|
type OutputTy = SmallVec<[Self; 1]>;
|
||||||
type AttrsTy: Deref<Target = [ast::Attribute]> = ast::AttrVec;
|
type AttrsTy: Deref<Target = [ast::Attribute]> = ast::AttrVec;
|
||||||
|
type ItemKind = ItemKind;
|
||||||
const KIND: AstFragmentKind;
|
const KIND: AstFragmentKind;
|
||||||
fn to_annotatable(self) -> Annotatable;
|
fn to_annotatable(self) -> Annotatable;
|
||||||
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy;
|
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy;
|
||||||
@ -1059,6 +1060,18 @@ fn is_mac_call(&self) -> bool {
|
|||||||
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
|
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
fn delegation_list(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
fn delegation_item_kind(_deleg: Box<ast::Delegation>) -> Self::ItemKind {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn from_item(_item: ast::Item<Self::ItemKind>) -> Self {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn flatten_outputs(_outputs: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
fn pre_flat_map_node_collect_attr(_cfg: &StripUnconfigured<'_>, _attr: &ast::Attribute) {}
|
fn pre_flat_map_node_collect_attr(_cfg: &StripUnconfigured<'_>, _attr: &ast::Attribute) {}
|
||||||
fn post_flat_map_node_collect_bang(_output: &mut Self::OutputTy, _add_semicolon: AddSemicolon) {
|
fn post_flat_map_node_collect_bang(_output: &mut Self::OutputTy, _add_semicolon: AddSemicolon) {
|
||||||
}
|
}
|
||||||
@ -1106,6 +1119,21 @@ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn delegation_list(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
|
||||||
|
match &self.kind {
|
||||||
|
ItemKind::DelegationMac(deleg) => Some((deleg, self)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
|
||||||
|
ItemKind::Delegation(deleg)
|
||||||
|
}
|
||||||
|
fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
|
||||||
|
P(item)
|
||||||
|
}
|
||||||
|
fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
|
||||||
|
items.flatten().collect()
|
||||||
|
}
|
||||||
fn wrap_flat_map_node_noop_flat_map(
|
fn wrap_flat_map_node_noop_flat_map(
|
||||||
mut node: Self,
|
mut node: Self,
|
||||||
collector: &mut InvocationCollector<'_, '_>,
|
collector: &mut InvocationCollector<'_, '_>,
|
||||||
@ -1214,6 +1242,7 @@ fn collect_use_tree_leaves(ut: &ast::UseTree, idents: &mut Vec<Ident>) {
|
|||||||
struct TraitItemTag;
|
struct TraitItemTag;
|
||||||
impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag> {
|
impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag> {
|
||||||
type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
|
type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
|
||||||
|
type ItemKind = AssocItemKind;
|
||||||
const KIND: AstFragmentKind = AstFragmentKind::TraitItems;
|
const KIND: AstFragmentKind = AstFragmentKind::TraitItems;
|
||||||
fn to_annotatable(self) -> Annotatable {
|
fn to_annotatable(self) -> Annotatable {
|
||||||
Annotatable::TraitItem(self.wrapped)
|
Annotatable::TraitItem(self.wrapped)
|
||||||
@ -1234,11 +1263,27 @@ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn delegation_list(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
|
||||||
|
match &self.wrapped.kind {
|
||||||
|
AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
|
||||||
|
AssocItemKind::Delegation(deleg)
|
||||||
|
}
|
||||||
|
fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
|
||||||
|
AstNodeWrapper::new(P(item), TraitItemTag)
|
||||||
|
}
|
||||||
|
fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
|
||||||
|
items.flatten().collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ImplItemTag;
|
struct ImplItemTag;
|
||||||
impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag> {
|
impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag> {
|
||||||
type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
|
type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
|
||||||
|
type ItemKind = AssocItemKind;
|
||||||
const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
|
const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
|
||||||
fn to_annotatable(self) -> Annotatable {
|
fn to_annotatable(self) -> Annotatable {
|
||||||
Annotatable::ImplItem(self.wrapped)
|
Annotatable::ImplItem(self.wrapped)
|
||||||
@ -1259,6 +1304,21 @@ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn delegation_list(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
|
||||||
|
match &self.wrapped.kind {
|
||||||
|
AssocItemKind::DelegationMac(deleg) => Some((deleg, &self.wrapped)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
|
||||||
|
AssocItemKind::Delegation(deleg)
|
||||||
|
}
|
||||||
|
fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
|
||||||
|
AstNodeWrapper::new(P(item), ImplItemTag)
|
||||||
|
}
|
||||||
|
fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
|
||||||
|
items.flatten().collect()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InvocationCollectorNode for P<ast::ForeignItem> {
|
impl InvocationCollectorNode for P<ast::ForeignItem> {
|
||||||
@ -1420,6 +1480,24 @@ fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
|
|||||||
};
|
};
|
||||||
(mac, attrs, if add_semicolon { AddSemicolon::Yes } else { AddSemicolon::No })
|
(mac, attrs, if add_semicolon { AddSemicolon::Yes } else { AddSemicolon::No })
|
||||||
}
|
}
|
||||||
|
fn delegation_list(&self) -> Option<(&ast::DelegationMac, &ast::Item<Self::ItemKind>)> {
|
||||||
|
match &self.kind {
|
||||||
|
StmtKind::Item(item) => match &item.kind {
|
||||||
|
ItemKind::DelegationMac(deleg) => Some((deleg, item)),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn delegation_item_kind(deleg: Box<ast::Delegation>) -> Self::ItemKind {
|
||||||
|
ItemKind::Delegation(deleg)
|
||||||
|
}
|
||||||
|
fn from_item(item: ast::Item<Self::ItemKind>) -> Self {
|
||||||
|
ast::Stmt { id: ast::DUMMY_NODE_ID, span: item.span, kind: StmtKind::Item(P(item)) }
|
||||||
|
}
|
||||||
|
fn flatten_outputs(items: impl Iterator<Item = Self::OutputTy>) -> Self::OutputTy {
|
||||||
|
items.flatten().collect()
|
||||||
|
}
|
||||||
fn post_flat_map_node_collect_bang(stmts: &mut Self::OutputTy, add_semicolon: AddSemicolon) {
|
fn post_flat_map_node_collect_bang(stmts: &mut Self::OutputTy, add_semicolon: AddSemicolon) {
|
||||||
// If this is a macro invocation with a semicolon, then apply that
|
// If this is a macro invocation with a semicolon, then apply that
|
||||||
// semicolon to the final statement produced by expansion.
|
// semicolon to the final statement produced by expansion.
|
||||||
@ -1818,6 +1896,40 @@ fn flat_map_node<Node: InvocationCollectorNode<OutputTy: Default>>(
|
|||||||
Node::post_flat_map_node_collect_bang(&mut res, add_semicolon);
|
Node::post_flat_map_node_collect_bang(&mut res, add_semicolon);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
None if let Some((deleg, item)) = node.delegation_list() => {
|
||||||
|
if deleg.suffixes.is_empty() {
|
||||||
|
// Report an error for now, to avoid keeping stem for resolution and
|
||||||
|
// stability checks.
|
||||||
|
self.cx.dcx().emit_err(EmptyDelegationList { span: item.span });
|
||||||
|
}
|
||||||
|
|
||||||
|
Node::flatten_outputs(deleg.suffixes.iter().map(|&(ident, rename)| {
|
||||||
|
let mut path = deleg.prefix.clone();
|
||||||
|
path.segments.push(ast::PathSegment {
|
||||||
|
ident,
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
args: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut item = Node::from_item(ast::Item {
|
||||||
|
attrs: item.attrs.clone(),
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
span: ident.span,
|
||||||
|
vis: item.vis.clone(),
|
||||||
|
ident: rename.unwrap_or(ident),
|
||||||
|
kind: Node::delegation_item_kind(Box::new(ast::Delegation {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
qself: deleg.qself.clone(),
|
||||||
|
path,
|
||||||
|
rename,
|
||||||
|
body: deleg.body.clone(),
|
||||||
|
})),
|
||||||
|
tokens: None,
|
||||||
|
});
|
||||||
|
|
||||||
|
assign_id!(self, item.node_id_mut(), || item.noop_flat_map(self))
|
||||||
|
}))
|
||||||
|
}
|
||||||
None => {
|
None => {
|
||||||
match Node::wrap_flat_map_node_noop_flat_map(node, self, |mut node, this| {
|
match Node::wrap_flat_map_node_noop_flat_map(node, self, |mut node, this| {
|
||||||
assign_id!(this, node.node_id_mut(), || node.noop_flat_map(this))
|
assign_id!(this, node.node_id_mut(), || node.noop_flat_map(this))
|
||||||
@ -1866,6 +1978,7 @@ fn visit_node<Node: InvocationCollectorNode<OutputTy = Node> + DummyAstNode>(
|
|||||||
self.collect_bang(mac, Node::KIND).make_ast::<Node>()
|
self.collect_bang(mac, Node::KIND).make_ast::<Node>()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
None if node.delegation_list().is_some() => unreachable!(),
|
||||||
None => {
|
None => {
|
||||||
assign_id!(self, node.node_id_mut(), || node.noop_visit(self))
|
assign_id!(self, node.node_id_mut(), || node.noop_visit(self))
|
||||||
}
|
}
|
||||||
|
@ -685,20 +685,35 @@ fn parse_item_delegation(&mut self) -> PResult<'a, ItemInfo> {
|
|||||||
(None, self.parse_path(PathStyle::Expr)?)
|
(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 = if self.check(&token::OpenDelim(Delimiter::Brace)) {
|
|
||||||
Some(self.parse_block()?)
|
|
||||||
} else {
|
|
||||||
self.expect(&token::Semi)?;
|
|
||||||
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 (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 {
|
||||||
|
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);
|
let span = span.to(self.prev_token.span);
|
||||||
self.psess.gated_spans.gate(sym::fn_delegation, span);
|
self.psess.gated_spans.gate(sym::fn_delegation, span);
|
||||||
|
|
||||||
let ident = rename.unwrap_or_else(|| path.segments.last().unwrap().ident);
|
Ok((ident, item_kind))
|
||||||
let deleg = Delegation { id: DUMMY_NODE_ID, qself, path, rename, body };
|
|
||||||
Ok((ident, ItemKind::Delegation(Box::new(deleg))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_item_list<T>(
|
fn parse_item_list<T>(
|
||||||
|
@ -95,12 +95,15 @@ pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (P<QSelf>,
|
|||||||
debug!("parse_qpath: (decrement) count={:?}", self.unmatched_angle_bracket_count);
|
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)?;
|
self.expect(&token::PathSep)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let qself = P(QSelf { ty, path_span, position: path.segments.len() });
|
let qself = P(QSelf { ty, path_span, position: path.segments.len() });
|
||||||
|
if !is_import_coupler {
|
||||||
self.parse_path_segments(&mut path.segments, style, None)?;
|
self.parse_path_segments(&mut path.segments, style, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
qself,
|
qself,
|
||||||
|
@ -522,7 +522,8 @@ fn visit_item(&mut self, i: &'v ast::Item) {
|
|||||||
Impl,
|
Impl,
|
||||||
MacCall,
|
MacCall,
|
||||||
MacroDef,
|
MacroDef,
|
||||||
Delegation
|
Delegation,
|
||||||
|
DelegationMac
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
ast_visit::walk_item(self, i)
|
ast_visit::walk_item(self, i)
|
||||||
@ -650,7 +651,7 @@ fn visit_fn(&mut self, fk: ast_visit::FnKind<'v>, _: Span, _: NodeId) {
|
|||||||
fn visit_assoc_item(&mut self, i: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
|
fn visit_assoc_item(&mut self, i: &'v ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
|
||||||
record_variants!(
|
record_variants!(
|
||||||
(self, i, i.kind, Id::None, ast, AssocItem, AssocItemKind),
|
(self, i, i.kind, Id::None, ast, AssocItem, AssocItemKind),
|
||||||
[Const, Fn, Type, MacCall, Delegation]
|
[Const, Fn, Type, MacCall, Delegation, DelegationMac]
|
||||||
);
|
);
|
||||||
ast_visit::walk_assoc_item(self, i, ctxt);
|
ast_visit::walk_assoc_item(self, i, ctxt);
|
||||||
}
|
}
|
||||||
|
@ -285,7 +285,9 @@ fn visit_item(&mut self, i: &'ast ast::Item) {
|
|||||||
ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias,
|
ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias,
|
||||||
ast::ItemKind::Impl(_) => Target::Impl,
|
ast::ItemKind::Impl(_) => Target::Impl,
|
||||||
ast::ItemKind::MacroDef(_) => Target::MacroDef,
|
ast::ItemKind::MacroDef(_) => Target::MacroDef,
|
||||||
ast::ItemKind::MacCall(_) => unreachable!("macros should have been expanded"),
|
ast::ItemKind::MacCall(_) | ast::ItemKind::DelegationMac(_) => {
|
||||||
|
unreachable!("macros should have been expanded")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.check_for_lang(
|
self.check_for_lang(
|
||||||
@ -340,7 +342,9 @@ fn visit_assoc_item(&mut self, i: &'ast ast::AssocItem, ctxt: visit::AssocCtxt)
|
|||||||
}
|
}
|
||||||
ast::AssocItemKind::Const(ct) => (Target::AssocConst, Some(&ct.generics)),
|
ast::AssocItemKind::Const(ct) => (Target::AssocConst, Some(&ct.generics)),
|
||||||
ast::AssocItemKind::Type(ty) => (Target::AssocTy, Some(&ty.generics)),
|
ast::AssocItemKind::Type(ty) => (Target::AssocTy, Some(&ty.generics)),
|
||||||
ast::AssocItemKind::MacCall(_) => unreachable!("macros should have been expanded"),
|
ast::AssocItemKind::MacCall(_) | ast::AssocItemKind::DelegationMac(_) => {
|
||||||
|
unreachable!("macros should have been expanded")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.check_for_lang(
|
self.check_for_lang(
|
||||||
|
@ -825,7 +825,9 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
|
|||||||
}
|
}
|
||||||
ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
|
ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
|
||||||
|
|
||||||
ItemKind::MacroDef(..) | ItemKind::MacCall(_) => unreachable!(),
|
ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1381,7 +1383,7 @@ fn visit_assoc_item(&mut self, item: &'b AssocItem, ctxt: AssocCtxt) {
|
|||||||
| AssocItemKind::Delegation(..)
|
| AssocItemKind::Delegation(..)
|
||||||
| AssocItemKind::Fn(..) => ValueNS,
|
| AssocItemKind::Fn(..) => ValueNS,
|
||||||
AssocItemKind::Type(..) => TypeNS,
|
AssocItemKind::Type(..) => TypeNS,
|
||||||
AssocItemKind::MacCall(_) => bug!(), // handled above
|
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => bug!(), // handled above
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent = self.parent_scope.module;
|
let parent = self.parent_scope.module;
|
||||||
|
@ -139,6 +139,7 @@ fn visit_item(&mut self, i: &'a Item) {
|
|||||||
ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
|
ItemKind::GlobalAsm(..) => DefKind::GlobalAsm,
|
||||||
ItemKind::Use(..) => return visit::walk_item(self, i),
|
ItemKind::Use(..) => return visit::walk_item(self, i),
|
||||||
ItemKind::MacCall(..) => return self.visit_macro_invoc(i.id),
|
ItemKind::MacCall(..) => return self.visit_macro_invoc(i.id),
|
||||||
|
ItemKind::DelegationMac(..) => unreachable!(),
|
||||||
};
|
};
|
||||||
let def_id = self.create_def(i.id, i.ident.name, def_kind, i.span);
|
let def_id = self.create_def(i.id, i.ident.name, def_kind, i.span);
|
||||||
|
|
||||||
@ -278,6 +279,7 @@ fn visit_assoc_item(&mut self, i: &'a AssocItem, ctxt: visit::AssocCtxt) {
|
|||||||
AssocItemKind::Const(..) => DefKind::AssocConst,
|
AssocItemKind::Const(..) => DefKind::AssocConst,
|
||||||
AssocItemKind::Type(..) => DefKind::AssocTy,
|
AssocItemKind::Type(..) => DefKind::AssocTy,
|
||||||
AssocItemKind::MacCall(..) => return self.visit_macro_invoc(i.id),
|
AssocItemKind::MacCall(..) => return self.visit_macro_invoc(i.id),
|
||||||
|
AssocItemKind::DelegationMac(..) => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let def = self.create_def(i.id, i.ident.name, def_kind, i.span);
|
let def = self.create_def(i.id, i.ident.name, def_kind, i.span);
|
||||||
|
@ -236,7 +236,7 @@ fn visit_item(&mut self, item: &'ast ast::Item) {
|
|||||||
ast::ItemKind::Impl(..) => return,
|
ast::ItemKind::Impl(..) => return,
|
||||||
|
|
||||||
// Should be unreachable at this stage
|
// Should be unreachable at this stage
|
||||||
ast::ItemKind::MacCall(..) => panic!(
|
ast::ItemKind::MacCall(..) | ast::ItemKind::DelegationMac(..) => panic!(
|
||||||
"ast::ItemKind::MacCall encountered, this should not anymore appear at this stage"
|
"ast::ItemKind::MacCall encountered, this should not anymore appear at this stage"
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -2561,7 +2561,9 @@ fn resolve_item(&mut self, item: &'ast Item) {
|
|||||||
|
|
||||||
ItemKind::ExternCrate(..) => {}
|
ItemKind::ExternCrate(..) => {}
|
||||||
|
|
||||||
ItemKind::MacCall(_) => panic!("unexpanded macro in resolve!"),
|
ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
|
||||||
|
panic!("unexpanded macro in resolve!")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2849,7 +2851,7 @@ fn resolve_trait_items(&mut self, trait_items: &'ast [P<AssocItem>]) {
|
|||||||
.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
|
.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
|
||||||
walk_assoc_item(this, generics, LifetimeBinderKind::Item, item)
|
walk_assoc_item(this, generics, LifetimeBinderKind::Item, item)
|
||||||
}),
|
}),
|
||||||
AssocItemKind::MacCall(_) => {
|
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => {
|
||||||
panic!("unexpanded macro in resolve!")
|
panic!("unexpanded macro in resolve!")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -3116,7 +3118,7 @@ fn resolve_impl_item(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
AssocItemKind::MacCall(_) => {
|
AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => {
|
||||||
panic!("unexpanded macro in resolve!")
|
panic!("unexpanded macro in resolve!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3218,7 +3220,9 @@ fn check_trait_item<F>(
|
|||||||
AssocItemKind::Fn(..) => (E0324, "method"),
|
AssocItemKind::Fn(..) => (E0324, "method"),
|
||||||
AssocItemKind::Type(..) => (E0325, "type"),
|
AssocItemKind::Type(..) => (E0325, "type"),
|
||||||
AssocItemKind::Delegation(..) => (E0324, "method"),
|
AssocItemKind::Delegation(..) => (E0324, "method"),
|
||||||
AssocItemKind::MacCall(..) => span_bug!(span, "unexpanded macro"),
|
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
|
||||||
|
span_bug!(span, "unexpanded macro")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let trait_path = path_names_to_string(path);
|
let trait_path = path_names_to_string(path);
|
||||||
self.report_error(
|
self.report_error(
|
||||||
@ -4790,7 +4794,8 @@ fn visit_item(&mut self, item: &'ast Item) {
|
|||||||
| ItemKind::ExternCrate(..)
|
| ItemKind::ExternCrate(..)
|
||||||
| ItemKind::MacroDef(..)
|
| ItemKind::MacroDef(..)
|
||||||
| ItemKind::GlobalAsm(..)
|
| ItemKind::GlobalAsm(..)
|
||||||
| ItemKind::MacCall(..) => {}
|
| ItemKind::MacCall(..)
|
||||||
|
| ItemKind::DelegationMac(..) => {}
|
||||||
ItemKind::Delegation(..) => {
|
ItemKind::Delegation(..) => {
|
||||||
// Delegated functions have lifetimes, their count is not necessarily zero.
|
// Delegated functions have lifetimes, their count is not necessarily zero.
|
||||||
// But skipping the delegation items here doesn't mean that the count will be considered zero,
|
// But skipping the delegation items here doesn't mean that the count will be considered zero,
|
||||||
|
@ -2045,7 +2045,9 @@ fn extract_node_id(t: &Ty) -> Option<NodeId> {
|
|||||||
AssocSuggestion::MethodWithSelf { called }
|
AssocSuggestion::MethodWithSelf { called }
|
||||||
}
|
}
|
||||||
ast::AssocItemKind::Delegation(..) => AssocSuggestion::AssocFn { called },
|
ast::AssocItemKind::Delegation(..) => AssocSuggestion::AssocFn { called },
|
||||||
ast::AssocItemKind::MacCall(_) => continue,
|
ast::AssocItemKind::MacCall(_) | ast::AssocItemKind::DelegationMac(..) => {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -739,8 +739,8 @@ fn visit_impl_items(&mut self, items: &[ptr::P<ast::AssocItem>]) {
|
|||||||
(_, Const(..)) => Ordering::Greater,
|
(_, Const(..)) => Ordering::Greater,
|
||||||
(MacCall(..), _) => Ordering::Less,
|
(MacCall(..), _) => Ordering::Less,
|
||||||
(_, MacCall(..)) => Ordering::Greater,
|
(_, MacCall(..)) => Ordering::Greater,
|
||||||
(Delegation(..), _) => Ordering::Less,
|
(Delegation(..), _) | (DelegationMac(..), _) => Ordering::Less,
|
||||||
(_, Delegation(..)) => Ordering::Greater,
|
(_, Delegation(..)) | (_, DelegationMac(..)) => Ordering::Greater,
|
||||||
});
|
});
|
||||||
let mut prev_kind = None;
|
let mut prev_kind = None;
|
||||||
for (buf, item) in buffer {
|
for (buf, item) in buffer {
|
||||||
|
@ -586,7 +586,7 @@ pub(crate) fn visit_item(&mut self, item: &ast::Item) {
|
|||||||
);
|
);
|
||||||
self.push_rewrite(item.span, rewrite);
|
self.push_rewrite(item.span, rewrite);
|
||||||
}
|
}
|
||||||
ast::ItemKind::Delegation(..) => {
|
ast::ItemKind::Delegation(..) | ast::ItemKind::DelegationMac(..) => {
|
||||||
// TODO: rewrite delegation items once syntax is established.
|
// TODO: rewrite delegation items once syntax is established.
|
||||||
// For now, leave the contents of the Span unformatted.
|
// For now, leave the contents of the Span unformatted.
|
||||||
self.push_rewrite(item.span, None)
|
self.push_rewrite(item.span, None)
|
||||||
|
@ -36,4 +36,8 @@ impl Trait for S {
|
|||||||
//~^ ERROR cannot find function `foo` in this scope
|
//~^ ERROR cannot find function `foo` in this scope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod prefix {}
|
||||||
|
reuse unresolved_prefix::{a, b, c}; //~ ERROR use of undeclared crate or module `unresolved_prefix`
|
||||||
|
reuse prefix::{self, super, crate}; //~ ERROR `crate` in paths can only be used in start position
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -63,7 +63,19 @@ LL | type Type;
|
|||||||
LL | impl Trait for S {
|
LL | impl Trait for S {
|
||||||
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation
|
| ^^^^^^^^^^^^^^^^ missing `Type` in implementation
|
||||||
|
|
||||||
error: aborting due to 8 previous errors
|
error[E0433]: failed to resolve: use of undeclared crate or module `unresolved_prefix`
|
||||||
|
--> $DIR/bad-resolve.rs:40:7
|
||||||
|
|
|
||||||
|
LL | reuse unresolved_prefix::{a, b, c};
|
||||||
|
| ^^^^^^^^^^^^^^^^^ use of undeclared crate or module `unresolved_prefix`
|
||||||
|
|
||||||
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0575, E0576.
|
error[E0433]: failed to resolve: `crate` in paths can only be used in start position
|
||||||
|
--> $DIR/bad-resolve.rs:41:29
|
||||||
|
|
|
||||||
|
LL | reuse prefix::{self, super, crate};
|
||||||
|
| ^^^^^ `crate` in paths can only be used in start position
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0046, E0324, E0407, E0423, E0425, E0433, E0575, E0576.
|
||||||
For more information about an error, try `rustc --explain E0046`.
|
For more information about an error, try `rustc --explain E0046`.
|
||||||
|
32
tests/ui/delegation/body-identity-list.rs
Normal file
32
tests/ui/delegation/body-identity-list.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(fn_delegation)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
fn foo(&self) {}
|
||||||
|
fn bar(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u8 {}
|
||||||
|
|
||||||
|
struct S(u8);
|
||||||
|
|
||||||
|
mod to_import {
|
||||||
|
pub fn check(arg: &u8) -> &u8 { arg }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for S {
|
||||||
|
reuse Trait::{foo, bar} {
|
||||||
|
use to_import::check;
|
||||||
|
|
||||||
|
let _arr = Some(self.0).map(|x| [x * 2; 3]);
|
||||||
|
check(&self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = S(0);
|
||||||
|
s.foo();
|
||||||
|
s.bar();
|
||||||
|
}
|
8
tests/ui/delegation/empty-list.rs
Normal file
8
tests/ui/delegation/empty-list.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#![feature(fn_delegation)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
mod m {}
|
||||||
|
|
||||||
|
reuse m::{}; //~ ERROR empty list delegation is not supported
|
||||||
|
|
||||||
|
fn main() {}
|
8
tests/ui/delegation/empty-list.stderr
Normal file
8
tests/ui/delegation/empty-list.stderr
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
error: empty list delegation is not supported
|
||||||
|
--> $DIR/empty-list.rs:6:1
|
||||||
|
|
|
||||||
|
LL | reuse m::{};
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
8
tests/ui/delegation/inner-attr.rs
Normal file
8
tests/ui/delegation/inner-attr.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#![feature(fn_delegation)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
fn a() {}
|
||||||
|
|
||||||
|
reuse a as b { #![rustc_dummy] self } //~ ERROR an inner attribute is not permitted in this context
|
||||||
|
|
||||||
|
fn main() {}
|
18
tests/ui/delegation/inner-attr.stderr
Normal file
18
tests/ui/delegation/inner-attr.stderr
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
error: an inner attribute is not permitted in this context
|
||||||
|
--> $DIR/inner-attr.rs:6:16
|
||||||
|
|
|
||||||
|
LL | reuse a as b { #![rustc_dummy] self }
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
LL |
|
||||||
|
LL | fn main() {}
|
||||||
|
| ------------ the inner attribute doesn't annotate this function
|
||||||
|
|
|
||||||
|
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
|
||||||
|
help: to annotate the function, change the attribute from inner to outer style
|
||||||
|
|
|
||||||
|
LL - reuse a as b { #![rustc_dummy] self }
|
||||||
|
LL + reuse a as b { #[rustc_dummy] self }
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
46
tests/ui/delegation/list.rs
Normal file
46
tests/ui/delegation/list.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(fn_delegation)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
fn foo(&self) -> u8 { 0 }
|
||||||
|
fn bar(&self) -> u8 { 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u8 {}
|
||||||
|
|
||||||
|
struct S(u8);
|
||||||
|
struct Z(u8);
|
||||||
|
|
||||||
|
impl Trait for S {
|
||||||
|
reuse Trait::{foo, bar} { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for Z {
|
||||||
|
reuse <u8 as Trait>::{foo, bar} { &self.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Trait2 where Self: Trait {
|
||||||
|
reuse Trait::{foo, bar};
|
||||||
|
}
|
||||||
|
|
||||||
|
mod to_reuse {
|
||||||
|
pub fn a() {}
|
||||||
|
pub fn b() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
reuse to_reuse::{a, b};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = S(2);
|
||||||
|
s.foo();
|
||||||
|
s.bar();
|
||||||
|
|
||||||
|
let z = Z(3);
|
||||||
|
z.foo();
|
||||||
|
z.bar();
|
||||||
|
|
||||||
|
a();
|
||||||
|
b();
|
||||||
|
}
|
26
tests/ui/delegation/macro-inside-list.rs
Normal file
26
tests/ui/delegation/macro-inside-list.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(fn_delegation)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
fn foo(&self) -> u8 { 0 }
|
||||||
|
fn bar(&self) -> u8 { 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trait for u8 {}
|
||||||
|
|
||||||
|
struct S(u8);
|
||||||
|
|
||||||
|
// Macro expansion works inside delegation items.
|
||||||
|
macro_rules! u8 { () => { u8 } }
|
||||||
|
macro_rules! self_0 { () => { &self.0 } }
|
||||||
|
impl Trait for S {
|
||||||
|
reuse <u8!() as Trait>::{foo, bar} { self_0!() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = S(2);
|
||||||
|
s.foo();
|
||||||
|
s.bar();
|
||||||
|
}
|
@ -5,16 +5,23 @@
|
|||||||
|
|
||||||
mod to_reuse {
|
mod to_reuse {
|
||||||
pub fn a() {}
|
pub fn a() {}
|
||||||
|
pub fn b() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
reuse to_reuse::a as b;
|
reuse to_reuse::a as x;
|
||||||
|
reuse to_reuse::{a as y, b as z};
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
impl S {
|
impl S {
|
||||||
reuse to_reuse::a as b;
|
reuse to_reuse::a as x;
|
||||||
|
reuse to_reuse::{a as y, b as z};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
b();
|
x();
|
||||||
S::b();
|
y();
|
||||||
|
z();
|
||||||
|
S::x();
|
||||||
|
S::y();
|
||||||
|
S::z();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user