Rollup merge of #138929 - oli-obk:assoc-ctxt-of-trait, r=compiler-errors
Visitors track whether an assoc item is in a trait impl or an inherent impl `AssocCtxt::Impl` now contains an `of_trait` field. This allows ast lowering and nameres to not have to track whether we're in a trait impl or an inherent impl.
This commit is contained in:
commit
1107fc7ad2
17 changed files with 185 additions and 96 deletions
|
@ -1318,7 +1318,9 @@ impl WalkItemKind for ItemKind {
|
||||||
visit_polarity(vis, polarity);
|
visit_polarity(vis, polarity);
|
||||||
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
|
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
|
||||||
vis.visit_ty(self_ty);
|
vis.visit_ty(self_ty);
|
||||||
items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Impl));
|
items.flat_map_in_place(|item| {
|
||||||
|
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
|
||||||
|
});
|
||||||
}
|
}
|
||||||
ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => {
|
ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => {
|
||||||
visit_safety(vis, safety);
|
visit_safety(vis, safety);
|
||||||
|
|
|
@ -23,7 +23,7 @@ use crate::ptr::P;
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
pub enum AssocCtxt {
|
pub enum AssocCtxt {
|
||||||
Trait,
|
Trait,
|
||||||
Impl,
|
Impl { of_trait: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||||
|
@ -422,7 +422,12 @@ impl WalkItemKind for ItemKind {
|
||||||
try_visit!(visitor.visit_generics(generics));
|
try_visit!(visitor.visit_generics(generics));
|
||||||
visit_opt!(visitor, visit_trait_ref, of_trait);
|
visit_opt!(visitor, visit_trait_ref, of_trait);
|
||||||
try_visit!(visitor.visit_ty(self_ty));
|
try_visit!(visitor.visit_ty(self_ty));
|
||||||
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl);
|
walk_list!(
|
||||||
|
visitor,
|
||||||
|
visit_assoc_item,
|
||||||
|
items,
|
||||||
|
AssocCtxt::Impl { of_trait: of_trait.is_some() }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
ItemKind::Struct(struct_definition, generics)
|
ItemKind::Struct(struct_definition, generics)
|
||||||
| ItemKind::Union(struct_definition, generics) => {
|
| ItemKind::Union(struct_definition, generics) => {
|
||||||
|
|
|
@ -61,8 +61,14 @@ pub(crate) struct DelegationResults<'hir> {
|
||||||
|
|
||||||
impl<'hir> LoweringContext<'_, 'hir> {
|
impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
/// Defines whether the delegatee is an associated function whose first parameter is `self`.
|
/// Defines whether the delegatee is an associated function whose first parameter is `self`.
|
||||||
pub(crate) fn delegatee_is_method(&self, item_id: NodeId, path_id: NodeId, span: Span) -> bool {
|
pub(crate) fn delegatee_is_method(
|
||||||
let sig_id = self.get_delegation_sig_id(item_id, path_id, span);
|
&self,
|
||||||
|
item_id: NodeId,
|
||||||
|
path_id: NodeId,
|
||||||
|
span: Span,
|
||||||
|
is_in_trait_impl: bool,
|
||||||
|
) -> bool {
|
||||||
|
let sig_id = self.get_delegation_sig_id(item_id, path_id, span, is_in_trait_impl);
|
||||||
let Ok(sig_id) = sig_id else {
|
let Ok(sig_id) = sig_id else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
@ -88,9 +94,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
&mut self,
|
&mut self,
|
||||||
delegation: &Delegation,
|
delegation: &Delegation,
|
||||||
item_id: NodeId,
|
item_id: NodeId,
|
||||||
|
is_in_trait_impl: bool,
|
||||||
) -> DelegationResults<'hir> {
|
) -> DelegationResults<'hir> {
|
||||||
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
|
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
|
||||||
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span);
|
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span, is_in_trait_impl);
|
||||||
match sig_id {
|
match sig_id {
|
||||||
Ok(sig_id) => {
|
Ok(sig_id) => {
|
||||||
let (param_count, c_variadic) = self.param_count(sig_id);
|
let (param_count, c_variadic) = self.param_count(sig_id);
|
||||||
|
@ -110,8 +117,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
item_id: NodeId,
|
item_id: NodeId,
|
||||||
path_id: NodeId,
|
path_id: NodeId,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
is_in_trait_impl: bool,
|
||||||
) -> Result<DefId, ErrorGuaranteed> {
|
) -> Result<DefId, ErrorGuaranteed> {
|
||||||
let sig_id = if self.is_in_trait_impl { item_id } else { path_id };
|
let sig_id = if is_in_trait_impl { item_id } else { path_id };
|
||||||
self.get_resolution_id(sig_id, span)
|
self.get_resolution_id(sig_id, span)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
|
||||||
use rustc_hir::{self as hir, HirId, PredicateOrigin};
|
use rustc_hir::{self as hir, HirId, PredicateOrigin};
|
||||||
use rustc_index::{IndexSlice, IndexVec};
|
use rustc_index::{IndexSlice, IndexVec};
|
||||||
use rustc_middle::span_bug;
|
|
||||||
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
|
use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
|
||||||
use rustc_span::edit_distance::find_best_match_for_name;
|
use rustc_span::edit_distance::find_best_match_for_name;
|
||||||
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
|
use rustc_span::{DUMMY_SP, DesugaringKind, Ident, Span, Symbol, kw, sym};
|
||||||
|
@ -104,10 +103,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
|
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
|
||||||
let def_id = self.resolver.node_id_to_def_id[&item.id];
|
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
|
||||||
let parent_id = self.tcx.local_parent(def_id);
|
|
||||||
let parent_hir = self.lower_node(parent_id).unwrap();
|
|
||||||
self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt, parent_hir))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_foreign_item(&mut self, item: &ForeignItem) {
|
fn lower_foreign_item(&mut self, item: &ForeignItem) {
|
||||||
|
@ -405,10 +401,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
(trait_ref, lowered_ty)
|
(trait_ref, lowered_ty)
|
||||||
});
|
});
|
||||||
|
|
||||||
self.is_in_trait_impl = trait_ref.is_some();
|
let new_impl_items = self.arena.alloc_from_iter(
|
||||||
let new_impl_items = self
|
impl_items
|
||||||
.arena
|
.iter()
|
||||||
.alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
|
.map(|item| self.lower_impl_item_ref(item, trait_ref.is_some())),
|
||||||
|
);
|
||||||
|
|
||||||
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
|
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
|
||||||
// to not cause an assertion failure inside the `lower_defaultness` function.
|
// to not cause an assertion failure inside the `lower_defaultness` function.
|
||||||
|
@ -485,7 +482,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
ItemKind::Delegation(box delegation) => {
|
ItemKind::Delegation(box delegation) => {
|
||||||
debug_assert_ne!(ident.name, kw::Empty);
|
debug_assert_ne!(ident.name, kw::Empty);
|
||||||
let ident = self.lower_ident(ident);
|
let ident = self.lower_ident(ident);
|
||||||
let delegation_results = self.lower_delegation(delegation, id);
|
let delegation_results = self.lower_delegation(delegation, id, false);
|
||||||
hir::ItemKind::Fn {
|
hir::ItemKind::Fn {
|
||||||
ident,
|
ident,
|
||||||
sig: delegation_results.sig,
|
sig: delegation_results.sig,
|
||||||
|
@ -628,29 +625,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_assoc_item(
|
fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) -> hir::OwnerNode<'hir> {
|
||||||
&mut self,
|
|
||||||
item: &AssocItem,
|
|
||||||
ctxt: AssocCtxt,
|
|
||||||
parent_hir: &'hir hir::OwnerInfo<'hir>,
|
|
||||||
) -> hir::OwnerNode<'hir> {
|
|
||||||
let parent_item = parent_hir.node().expect_item();
|
|
||||||
match parent_item.kind {
|
|
||||||
hir::ItemKind::Impl(impl_) => {
|
|
||||||
self.is_in_trait_impl = impl_.of_trait.is_some();
|
|
||||||
}
|
|
||||||
hir::ItemKind::Trait(..) => {}
|
|
||||||
kind => {
|
|
||||||
span_bug!(item.span, "assoc item has unexpected kind of parent: {}", kind.descr())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate with the lifetimes in `params` in-scope.
|
// Evaluate with the lifetimes in `params` in-scope.
|
||||||
// This is used to track which lifetimes have already been defined,
|
// This is used to track which lifetimes have already been defined,
|
||||||
// and which need to be replicated when lowering an async fn.
|
// and which need to be replicated when lowering an async fn.
|
||||||
match ctxt {
|
match ctxt {
|
||||||
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
|
AssocCtxt::Trait => hir::OwnerNode::TraitItem(self.lower_trait_item(item)),
|
||||||
AssocCtxt::Impl => hir::OwnerNode::ImplItem(self.lower_impl_item(item)),
|
AssocCtxt::Impl { of_trait } => {
|
||||||
|
hir::OwnerNode::ImplItem(self.lower_impl_item(item, of_trait))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -891,7 +874,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
(generics, kind, ty.is_some())
|
(generics, kind, ty.is_some())
|
||||||
}
|
}
|
||||||
AssocItemKind::Delegation(box delegation) => {
|
AssocItemKind::Delegation(box delegation) => {
|
||||||
let delegation_results = self.lower_delegation(delegation, i.id);
|
let delegation_results = self.lower_delegation(delegation, i.id, false);
|
||||||
let item_kind = hir::TraitItemKind::Fn(
|
let item_kind = hir::TraitItemKind::Fn(
|
||||||
delegation_results.sig,
|
delegation_results.sig,
|
||||||
hir::TraitFn::Provided(delegation_results.body_id),
|
hir::TraitFn::Provided(delegation_results.body_id),
|
||||||
|
@ -922,7 +905,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
|
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
|
||||||
}
|
}
|
||||||
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
||||||
has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
|
has_self: self.delegatee_is_method(i.id, delegation.id, i.span, false),
|
||||||
},
|
},
|
||||||
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
|
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
|
||||||
panic!("macros should have been expanded by now")
|
panic!("macros should have been expanded by now")
|
||||||
|
@ -942,7 +925,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
self.expr(span, hir::ExprKind::Err(guar))
|
self.expr(span, hir::ExprKind::Err(guar))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
|
fn lower_impl_item(
|
||||||
|
&mut self,
|
||||||
|
i: &AssocItem,
|
||||||
|
is_in_trait_impl: bool,
|
||||||
|
) -> &'hir hir::ImplItem<'hir> {
|
||||||
debug_assert_ne!(i.ident.name, kw::Empty);
|
debug_assert_ne!(i.ident.name, kw::Empty);
|
||||||
// Since `default impl` is not yet implemented, this is always true in impls.
|
// Since `default impl` is not yet implemented, this is always true in impls.
|
||||||
let has_value = true;
|
let has_value = true;
|
||||||
|
@ -978,7 +965,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
generics,
|
generics,
|
||||||
sig,
|
sig,
|
||||||
i.id,
|
i.id,
|
||||||
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
|
if is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
|
||||||
sig.header.coroutine_kind,
|
sig.header.coroutine_kind,
|
||||||
attrs,
|
attrs,
|
||||||
);
|
);
|
||||||
|
@ -1018,7 +1005,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
AssocItemKind::Delegation(box delegation) => {
|
AssocItemKind::Delegation(box delegation) => {
|
||||||
let delegation_results = self.lower_delegation(delegation, i.id);
|
let delegation_results = self.lower_delegation(delegation, i.id, is_in_trait_impl);
|
||||||
(
|
(
|
||||||
delegation_results.generics,
|
delegation_results.generics,
|
||||||
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
|
hir::ImplItemKind::Fn(delegation_results.sig, delegation_results.body_id),
|
||||||
|
@ -1041,7 +1028,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
self.arena.alloc(item)
|
self.arena.alloc(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
|
fn lower_impl_item_ref(&mut self, i: &AssocItem, is_in_trait_impl: bool) -> hir::ImplItemRef {
|
||||||
hir::ImplItemRef {
|
hir::ImplItemRef {
|
||||||
id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
|
id: hir::ImplItemId { owner_id: self.owner_id(i.id) },
|
||||||
ident: self.lower_ident(i.ident),
|
ident: self.lower_ident(i.ident),
|
||||||
|
@ -1053,7 +1040,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
|
hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
|
||||||
}
|
}
|
||||||
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
AssocItemKind::Delegation(box delegation) => hir::AssocItemKind::Fn {
|
||||||
has_self: self.delegatee_is_method(i.id, delegation.id, i.span),
|
has_self: self.delegatee_is_method(
|
||||||
|
i.id,
|
||||||
|
delegation.id,
|
||||||
|
i.span,
|
||||||
|
is_in_trait_impl,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
|
AssocItemKind::MacCall(..) | AssocItemKind::DelegationMac(..) => {
|
||||||
panic!("macros should have been expanded by now")
|
panic!("macros should have been expanded by now")
|
||||||
|
|
|
@ -121,7 +121,6 @@ struct LoweringContext<'a, 'hir> {
|
||||||
catch_scope: Option<HirId>,
|
catch_scope: Option<HirId>,
|
||||||
loop_scope: Option<HirId>,
|
loop_scope: Option<HirId>,
|
||||||
is_in_loop_condition: bool,
|
is_in_loop_condition: bool,
|
||||||
is_in_trait_impl: bool,
|
|
||||||
is_in_dyn_type: bool,
|
is_in_dyn_type: bool,
|
||||||
|
|
||||||
current_hir_id_owner: hir::OwnerId,
|
current_hir_id_owner: hir::OwnerId,
|
||||||
|
@ -173,7 +172,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
catch_scope: None,
|
catch_scope: None,
|
||||||
loop_scope: None,
|
loop_scope: None,
|
||||||
is_in_loop_condition: false,
|
is_in_loop_condition: false,
|
||||||
is_in_trait_impl: false,
|
|
||||||
is_in_dyn_type: false,
|
is_in_dyn_type: false,
|
||||||
coroutine_kind: None,
|
coroutine_kind: None,
|
||||||
task_context: None,
|
task_context: None,
|
||||||
|
|
|
@ -860,7 +860,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
this.visit_trait_ref(t);
|
this.visit_trait_ref(t);
|
||||||
this.visit_ty(self_ty);
|
this.visit_ty(self_ty);
|
||||||
|
|
||||||
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
|
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: true });
|
||||||
});
|
});
|
||||||
walk_list!(self, visit_attribute, &item.attrs);
|
walk_list!(self, visit_attribute, &item.attrs);
|
||||||
return; // Avoid visiting again.
|
return; // Avoid visiting again.
|
||||||
|
@ -913,7 +913,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
|this| this.visit_generics(generics),
|
|this| this.visit_generics(generics),
|
||||||
);
|
);
|
||||||
this.visit_ty(self_ty);
|
this.visit_ty(self_ty);
|
||||||
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
|
walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl { of_trait: false });
|
||||||
});
|
});
|
||||||
walk_list!(self, visit_attribute, &item.attrs);
|
walk_list!(self, visit_attribute, &item.attrs);
|
||||||
return; // Avoid visiting again.
|
return; // Avoid visiting again.
|
||||||
|
@ -1414,7 +1414,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||||
self.check_defaultness(item.span, item.kind.defaultness());
|
self.check_defaultness(item.span, item.kind.defaultness());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt == AssocCtxt::Impl {
|
if let AssocCtxt::Impl { .. } = ctxt {
|
||||||
match &item.kind {
|
match &item.kind {
|
||||||
AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
|
AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
|
||||||
self.dcx().emit_err(errors::AssocConstWithoutBody {
|
self.dcx().emit_err(errors::AssocConstWithoutBody {
|
||||||
|
|
|
@ -157,7 +157,7 @@ mod llvm_enzyme {
|
||||||
};
|
};
|
||||||
(sig.clone(), false)
|
(sig.clone(), false)
|
||||||
}
|
}
|
||||||
Annotatable::AssocItem(assoc_item, _) => {
|
Annotatable::AssocItem(assoc_item, Impl { of_trait: false }) => {
|
||||||
let sig = match &assoc_item.kind {
|
let sig = match &assoc_item.kind {
|
||||||
ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig,
|
ast::AssocItemKind::Fn(box ast::Fn { sig, .. }) => sig,
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -296,7 +296,7 @@ mod llvm_enzyme {
|
||||||
}
|
}
|
||||||
Annotatable::Item(iitem.clone())
|
Annotatable::Item(iitem.clone())
|
||||||
}
|
}
|
||||||
Annotatable::AssocItem(ref mut assoc_item, i @ Impl) => {
|
Annotatable::AssocItem(ref mut assoc_item, i @ Impl { of_trait: false }) => {
|
||||||
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
|
if !assoc_item.attrs.iter().any(|a| same_attribute(&a.kind, &attr.kind)) {
|
||||||
assoc_item.attrs.push(attr);
|
assoc_item.attrs.push(attr);
|
||||||
}
|
}
|
||||||
|
@ -327,7 +327,7 @@ mod llvm_enzyme {
|
||||||
kind: assoc_item,
|
kind: assoc_item,
|
||||||
tokens: None,
|
tokens: None,
|
||||||
});
|
});
|
||||||
Annotatable::AssocItem(d_fn, Impl)
|
Annotatable::AssocItem(d_fn, Impl { of_trait: false })
|
||||||
} else {
|
} else {
|
||||||
let mut d_fn =
|
let mut d_fn =
|
||||||
ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
|
ecx.item(span, d_ident, thin_vec![d_attr, inline_never], ItemKind::Fn(asdf));
|
||||||
|
|
|
@ -121,18 +121,11 @@ impl CfgEval<'_> {
|
||||||
let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
|
let item = parser.parse_item(ForceCollect::Yes)?.unwrap();
|
||||||
Annotatable::Item(self.flat_map_item(item).pop().unwrap())
|
Annotatable::Item(self.flat_map_item(item).pop().unwrap())
|
||||||
}
|
}
|
||||||
Annotatable::AssocItem(_, AssocCtxt::Trait) => {
|
Annotatable::AssocItem(_, ctxt) => {
|
||||||
let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap();
|
let item = parser.parse_trait_item(ForceCollect::Yes)?.unwrap().unwrap();
|
||||||
Annotatable::AssocItem(
|
Annotatable::AssocItem(
|
||||||
self.flat_map_assoc_item(item, AssocCtxt::Trait).pop().unwrap(),
|
self.flat_map_assoc_item(item, ctxt).pop().unwrap(),
|
||||||
AssocCtxt::Trait,
|
ctxt,
|
||||||
)
|
|
||||||
}
|
|
||||||
Annotatable::AssocItem(_, AssocCtxt::Impl) => {
|
|
||||||
let item = parser.parse_impl_item(ForceCollect::Yes)?.unwrap().unwrap();
|
|
||||||
Annotatable::AssocItem(
|
|
||||||
self.flat_map_assoc_item(item, AssocCtxt::Impl).pop().unwrap(),
|
|
||||||
AssocCtxt::Impl,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Annotatable::ForeignItem(_) => {
|
Annotatable::ForeignItem(_) => {
|
||||||
|
|
|
@ -153,7 +153,7 @@ impl Annotatable {
|
||||||
|
|
||||||
pub fn expect_impl_item(self) -> P<ast::AssocItem> {
|
pub fn expect_impl_item(self) -> P<ast::AssocItem> {
|
||||||
match self {
|
match self {
|
||||||
Annotatable::AssocItem(i, AssocCtxt::Impl) => i,
|
Annotatable::AssocItem(i, AssocCtxt::Impl { .. }) => i,
|
||||||
_ => panic!("expected Item"),
|
_ => panic!("expected Item"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,6 +403,11 @@ pub trait MacResult {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates zero or more impl items.
|
||||||
|
fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates zero or more trait items.
|
/// Creates zero or more trait items.
|
||||||
fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
||||||
None
|
None
|
||||||
|
@ -516,6 +521,10 @@ impl MacResult for MacEager {
|
||||||
self.impl_items
|
self.impl_items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_trait_impl_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
||||||
|
self.impl_items
|
||||||
|
}
|
||||||
|
|
||||||
fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
fn make_trait_items(self: Box<Self>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
||||||
self.trait_items
|
self.trait_items
|
||||||
}
|
}
|
||||||
|
@ -613,6 +622,10 @@ impl MacResult for DummyResult {
|
||||||
Some(SmallVec::new())
|
Some(SmallVec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_trait_impl_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
||||||
|
Some(SmallVec::new())
|
||||||
|
}
|
||||||
|
|
||||||
fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
fn make_trait_items(self: Box<DummyResult>) -> Option<SmallVec<[P<ast::AssocItem>; 1]>> {
|
||||||
Some(SmallVec::new())
|
Some(SmallVec::new())
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,9 +188,15 @@ ast_fragments! {
|
||||||
ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
|
ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
|
||||||
"impl item";
|
"impl item";
|
||||||
many fn flat_map_assoc_item;
|
many fn flat_map_assoc_item;
|
||||||
fn visit_assoc_item(AssocCtxt::Impl);
|
fn visit_assoc_item(AssocCtxt::Impl { of_trait: false });
|
||||||
fn make_impl_items;
|
fn make_impl_items;
|
||||||
}
|
}
|
||||||
|
TraitImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
|
||||||
|
"impl item";
|
||||||
|
many fn flat_map_assoc_item;
|
||||||
|
fn visit_assoc_item(AssocCtxt::Impl { of_trait: true });
|
||||||
|
fn make_trait_impl_items;
|
||||||
|
}
|
||||||
ForeignItems(SmallVec<[P<ast::ForeignItem>; 1]>) {
|
ForeignItems(SmallVec<[P<ast::ForeignItem>; 1]>) {
|
||||||
"foreign item";
|
"foreign item";
|
||||||
many fn flat_map_foreign_item;
|
many fn flat_map_foreign_item;
|
||||||
|
@ -257,6 +263,7 @@ impl AstFragmentKind {
|
||||||
AstFragmentKind::Items
|
AstFragmentKind::Items
|
||||||
| AstFragmentKind::TraitItems
|
| AstFragmentKind::TraitItems
|
||||||
| AstFragmentKind::ImplItems
|
| AstFragmentKind::ImplItems
|
||||||
|
| AstFragmentKind::TraitImplItems
|
||||||
| AstFragmentKind::ForeignItems
|
| AstFragmentKind::ForeignItems
|
||||||
| AstFragmentKind::Crate => SupportsMacroExpansion::Yes { supports_inner_attrs: true },
|
| AstFragmentKind::Crate => SupportsMacroExpansion::Yes { supports_inner_attrs: true },
|
||||||
AstFragmentKind::Arms
|
AstFragmentKind::Arms
|
||||||
|
@ -306,6 +313,9 @@ impl AstFragmentKind {
|
||||||
AstFragmentKind::ImplItems => {
|
AstFragmentKind::ImplItems => {
|
||||||
AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect())
|
AstFragment::ImplItems(items.map(Annotatable::expect_impl_item).collect())
|
||||||
}
|
}
|
||||||
|
AstFragmentKind::TraitImplItems => {
|
||||||
|
AstFragment::TraitImplItems(items.map(Annotatable::expect_impl_item).collect())
|
||||||
|
}
|
||||||
AstFragmentKind::TraitItems => {
|
AstFragmentKind::TraitItems => {
|
||||||
AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect())
|
AstFragment::TraitItems(items.map(Annotatable::expect_trait_item).collect())
|
||||||
}
|
}
|
||||||
|
@ -347,10 +357,10 @@ pub enum InvocationKind {
|
||||||
},
|
},
|
||||||
Attr {
|
Attr {
|
||||||
attr: ast::Attribute,
|
attr: ast::Attribute,
|
||||||
// Re-insertion position for inert attributes.
|
/// Re-insertion position for inert attributes.
|
||||||
pos: usize,
|
pos: usize,
|
||||||
item: Annotatable,
|
item: Annotatable,
|
||||||
// Required for resolving derive helper attributes.
|
/// Required for resolving derive helper attributes.
|
||||||
derives: Vec<ast::Path>,
|
derives: Vec<ast::Path>,
|
||||||
},
|
},
|
||||||
Derive {
|
Derive {
|
||||||
|
@ -360,6 +370,8 @@ pub enum InvocationKind {
|
||||||
},
|
},
|
||||||
GlobDelegation {
|
GlobDelegation {
|
||||||
item: P<ast::AssocItem>,
|
item: P<ast::AssocItem>,
|
||||||
|
/// Whether this is a trait impl or an inherent impl
|
||||||
|
of_trait: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +400,7 @@ impl Invocation {
|
||||||
InvocationKind::Bang { span, .. } => *span,
|
InvocationKind::Bang { span, .. } => *span,
|
||||||
InvocationKind::Attr { attr, .. } => attr.span,
|
InvocationKind::Attr { attr, .. } => attr.span,
|
||||||
InvocationKind::Derive { path, .. } => path.span,
|
InvocationKind::Derive { path, .. } => path.span,
|
||||||
InvocationKind::GlobDelegation { item } => item.span,
|
InvocationKind::GlobDelegation { item, .. } => item.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +409,7 @@ impl Invocation {
|
||||||
InvocationKind::Bang { span, .. } => span,
|
InvocationKind::Bang { span, .. } => span,
|
||||||
InvocationKind::Attr { attr, .. } => &mut attr.span,
|
InvocationKind::Attr { attr, .. } => &mut attr.span,
|
||||||
InvocationKind::Derive { path, .. } => &mut path.span,
|
InvocationKind::Derive { path, .. } => &mut path.span,
|
||||||
InvocationKind::GlobDelegation { item } => &mut item.span,
|
InvocationKind::GlobDelegation { item, .. } => &mut item.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -820,7 +832,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
InvocationKind::GlobDelegation { item } => {
|
InvocationKind::GlobDelegation { item, of_trait } => {
|
||||||
let AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
|
let AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
|
||||||
let suffixes = match ext {
|
let suffixes = match ext {
|
||||||
SyntaxExtensionKind::GlobDelegation(expander) => match expander.expand(self.cx)
|
SyntaxExtensionKind::GlobDelegation(expander) => match expander.expand(self.cx)
|
||||||
|
@ -829,7 +841,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
ExpandResult::Retry(()) => {
|
ExpandResult::Retry(()) => {
|
||||||
// Reassemble the original invocation for retrying.
|
// Reassemble the original invocation for retrying.
|
||||||
return ExpandResult::Retry(Invocation {
|
return ExpandResult::Retry(Invocation {
|
||||||
kind: InvocationKind::GlobDelegation { item },
|
kind: InvocationKind::GlobDelegation { item, of_trait },
|
||||||
..invoc
|
..invoc
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -847,7 +859,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||||
self.cx, deleg, &item, &suffixes, item.span, true,
|
self.cx, deleg, &item, &suffixes, item.span, true,
|
||||||
);
|
);
|
||||||
fragment_kind.expect_from_annotatables(
|
fragment_kind.expect_from_annotatables(
|
||||||
single_delegations.map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl)),
|
single_delegations
|
||||||
|
.map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl { of_trait })),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -973,6 +986,13 @@ pub fn parse_ast_fragment<'a>(
|
||||||
}
|
}
|
||||||
AstFragment::ImplItems(items)
|
AstFragment::ImplItems(items)
|
||||||
}
|
}
|
||||||
|
AstFragmentKind::TraitImplItems => {
|
||||||
|
let mut items = SmallVec::new();
|
||||||
|
while let Some(item) = this.parse_impl_item(ForceCollect::No)? {
|
||||||
|
items.extend(item);
|
||||||
|
}
|
||||||
|
AstFragment::TraitImplItems(items)
|
||||||
|
}
|
||||||
AstFragmentKind::ForeignItems => {
|
AstFragmentKind::ForeignItems => {
|
||||||
let mut items = SmallVec::new();
|
let mut items = SmallVec::new();
|
||||||
while let Some(item) = this.parse_foreign_item(ForceCollect::No)? {
|
while let Some(item) = this.parse_foreign_item(ForceCollect::No)? {
|
||||||
|
@ -1355,13 +1375,13 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
|
||||||
type ItemKind = AssocItemKind;
|
type ItemKind = AssocItemKind;
|
||||||
const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
|
const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
|
||||||
fn to_annotatable(self) -> Annotatable {
|
fn to_annotatable(self) -> Annotatable {
|
||||||
Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl)
|
Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: false })
|
||||||
}
|
}
|
||||||
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
|
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
|
||||||
fragment.make_impl_items()
|
fragment.make_impl_items()
|
||||||
}
|
}
|
||||||
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
|
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
|
||||||
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl)
|
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: false })
|
||||||
}
|
}
|
||||||
fn is_mac_call(&self) -> bool {
|
fn is_mac_call(&self) -> bool {
|
||||||
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
|
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
|
||||||
|
@ -1390,6 +1410,47 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TraitImplItemTag;
|
||||||
|
impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitImplItemTag> {
|
||||||
|
type OutputTy = SmallVec<[P<ast::AssocItem>; 1]>;
|
||||||
|
type ItemKind = AssocItemKind;
|
||||||
|
const KIND: AstFragmentKind = AstFragmentKind::TraitImplItems;
|
||||||
|
fn to_annotatable(self) -> Annotatable {
|
||||||
|
Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl { of_trait: true })
|
||||||
|
}
|
||||||
|
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
|
||||||
|
fragment.make_trait_impl_items()
|
||||||
|
}
|
||||||
|
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
|
||||||
|
walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl { of_trait: true })
|
||||||
|
}
|
||||||
|
fn is_mac_call(&self) -> bool {
|
||||||
|
matches!(self.wrapped.kind, AssocItemKind::MacCall(..))
|
||||||
|
}
|
||||||
|
fn take_mac_call(self) -> (P<ast::MacCall>, Self::AttrsTy, AddSemicolon) {
|
||||||
|
let item = self.wrapped.into_inner();
|
||||||
|
match item.kind {
|
||||||
|
AssocItemKind::MacCall(mac) => (mac, item.attrs, AddSemicolon::No),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn delegation(&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), TraitImplItemTag)
|
||||||
|
}
|
||||||
|
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> {
|
||||||
const KIND: AstFragmentKind = AstFragmentKind::ForeignItems;
|
const KIND: AstFragmentKind = AstFragmentKind::ForeignItems;
|
||||||
fn to_annotatable(self) -> Annotatable {
|
fn to_annotatable(self) -> Annotatable {
|
||||||
|
@ -1855,9 +1916,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
fn collect_glob_delegation(
|
fn collect_glob_delegation(
|
||||||
&mut self,
|
&mut self,
|
||||||
item: P<ast::AssocItem>,
|
item: P<ast::AssocItem>,
|
||||||
|
of_trait: bool,
|
||||||
kind: AstFragmentKind,
|
kind: AstFragmentKind,
|
||||||
) -> AstFragment {
|
) -> AstFragment {
|
||||||
self.collect(kind, InvocationKind::GlobDelegation { item })
|
self.collect(kind, InvocationKind::GlobDelegation { item, of_trait })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If `item` is an attribute invocation, remove the attribute and return it together with
|
/// If `item` is an attribute invocation, remove the attribute and return it together with
|
||||||
|
@ -2030,8 +2092,10 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
let Some(suffixes) = &deleg.suffixes else {
|
let Some(suffixes) = &deleg.suffixes else {
|
||||||
let traitless_qself =
|
let traitless_qself =
|
||||||
matches!(&deleg.qself, Some(qself) if qself.position == 0);
|
matches!(&deleg.qself, Some(qself) if qself.position == 0);
|
||||||
let item = match node.to_annotatable() {
|
let (item, of_trait) = match node.to_annotatable() {
|
||||||
Annotatable::AssocItem(item, AssocCtxt::Impl) => item,
|
Annotatable::AssocItem(item, AssocCtxt::Impl { of_trait }) => {
|
||||||
|
(item, of_trait)
|
||||||
|
}
|
||||||
ann @ (Annotatable::Item(_)
|
ann @ (Annotatable::Item(_)
|
||||||
| Annotatable::AssocItem(..)
|
| Annotatable::AssocItem(..)
|
||||||
| Annotatable::Stmt(_)) => {
|
| Annotatable::Stmt(_)) => {
|
||||||
|
@ -2046,7 +2110,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||||
self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
|
self.cx.dcx().emit_err(GlobDelegationTraitlessQpath { span });
|
||||||
return Default::default();
|
return Default::default();
|
||||||
}
|
}
|
||||||
return self.collect_glob_delegation(item, Node::KIND).make_ast::<Node>();
|
return self
|
||||||
|
.collect_glob_delegation(item, of_trait, Node::KIND)
|
||||||
|
.make_ast::<Node>();
|
||||||
};
|
};
|
||||||
|
|
||||||
let single_delegations = build_single_delegations::<Node>(
|
let single_delegations = build_single_delegations::<Node>(
|
||||||
|
@ -2126,7 +2192,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
|
||||||
) -> SmallVec<[P<ast::AssocItem>; 1]> {
|
) -> SmallVec<[P<ast::AssocItem>; 1]> {
|
||||||
match ctxt {
|
match ctxt {
|
||||||
AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
|
AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
|
||||||
AssocCtxt::Impl => self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)),
|
AssocCtxt::Impl { of_trait: false } => {
|
||||||
|
self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
|
||||||
|
}
|
||||||
|
AssocCtxt::Impl { of_trait: true } => {
|
||||||
|
self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,17 @@ pub(crate) fn placeholder(
|
||||||
kind: ast::AssocItemKind::MacCall(mac_placeholder()),
|
kind: ast::AssocItemKind::MacCall(mac_placeholder()),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
})]),
|
})]),
|
||||||
|
AstFragmentKind::TraitImplItems => {
|
||||||
|
AstFragment::TraitImplItems(smallvec![P(ast::AssocItem {
|
||||||
|
id,
|
||||||
|
span,
|
||||||
|
ident,
|
||||||
|
vis,
|
||||||
|
attrs,
|
||||||
|
kind: ast::AssocItemKind::MacCall(mac_placeholder()),
|
||||||
|
tokens: None,
|
||||||
|
})])
|
||||||
|
}
|
||||||
AstFragmentKind::ForeignItems => {
|
AstFragmentKind::ForeignItems => {
|
||||||
AstFragment::ForeignItems(smallvec![P(ast::ForeignItem {
|
AstFragment::ForeignItems(smallvec![P(ast::ForeignItem {
|
||||||
id,
|
id,
|
||||||
|
@ -308,7 +319,8 @@ impl MutVisitor for PlaceholderExpander {
|
||||||
let it = self.remove(item.id);
|
let it = self.remove(item.id);
|
||||||
match ctxt {
|
match ctxt {
|
||||||
AssocCtxt::Trait => it.make_trait_items(),
|
AssocCtxt::Trait => it.make_trait_items(),
|
||||||
AssocCtxt::Impl => it.make_impl_items(),
|
AssocCtxt::Impl { of_trait: false } => it.make_impl_items(),
|
||||||
|
AssocCtxt::Impl { of_trait: true } => it.make_trait_impl_items(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => walk_flat_map_assoc_item(self, item, ctxt),
|
_ => walk_flat_map_assoc_item(self, item, ctxt),
|
||||||
|
|
|
@ -241,7 +241,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
|
||||||
ast_visit::AssocCtxt::Trait => {
|
ast_visit::AssocCtxt::Trait => {
|
||||||
lint_callback!(cx, check_trait_item, item);
|
lint_callback!(cx, check_trait_item, item);
|
||||||
}
|
}
|
||||||
ast_visit::AssocCtxt::Impl => {
|
ast_visit::AssocCtxt::Impl { .. } => {
|
||||||
lint_callback!(cx, check_impl_item, item);
|
lint_callback!(cx, check_impl_item, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
|
||||||
ast_visit::AssocCtxt::Trait => {
|
ast_visit::AssocCtxt::Trait => {
|
||||||
lint_callback!(cx, check_trait_item_post, item);
|
lint_callback!(cx, check_trait_item_post, item);
|
||||||
}
|
}
|
||||||
ast_visit::AssocCtxt::Impl => {
|
ast_visit::AssocCtxt::Impl { .. } => {
|
||||||
lint_callback!(cx, check_impl_item_post, item);
|
lint_callback!(cx, check_impl_item_post, item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -884,10 +884,10 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// These items do not add names to modules.
|
// These items do not add names to modules.
|
||||||
ItemKind::Impl(box Impl { of_trait: Some(..), .. }) => {
|
ItemKind::Impl(box Impl { of_trait: Some(..), .. })
|
||||||
self.r.trait_impl_items.insert(local_def_id);
|
| ItemKind::Impl { .. }
|
||||||
}
|
| ItemKind::ForeignMod(..)
|
||||||
ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {}
|
| ItemKind::GlobalAsm(..) => {}
|
||||||
|
|
||||||
ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
|
ItemKind::MacroDef(..) | ItemKind::MacCall(_) | ItemKind::DelegationMac(..) => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
|
@ -1377,7 +1377,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
AssocCtxt::Trait => {
|
AssocCtxt::Trait => {
|
||||||
self.visit_invoc_in_module(item.id);
|
self.visit_invoc_in_module(item.id);
|
||||||
}
|
}
|
||||||
AssocCtxt::Impl => {
|
AssocCtxt::Impl { .. } => {
|
||||||
let invoc_id = item.id.placeholder_to_expn_id();
|
let invoc_id = item.id.placeholder_to_expn_id();
|
||||||
if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
|
if !self.r.glob_delegation_invoc_ids.contains(&invoc_id) {
|
||||||
self.r
|
self.r
|
||||||
|
@ -1397,9 +1397,8 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
|
||||||
let local_def_id = feed.key();
|
let local_def_id = feed.key();
|
||||||
let def_id = local_def_id.to_def_id();
|
let def_id = local_def_id.to_def_id();
|
||||||
|
|
||||||
if !(ctxt == AssocCtxt::Impl
|
if !(matches!(ctxt, AssocCtxt::Impl { of_trait: true })
|
||||||
&& matches!(item.vis.kind, ast::VisibilityKind::Inherited)
|
&& matches!(item.vis.kind, ast::VisibilityKind::Inherited))
|
||||||
&& self.r.trait_impl_items.contains(&self.r.tcx.local_parent(local_def_id)))
|
|
||||||
{
|
{
|
||||||
// Trait impl item visibility is inherited from its trait when not specified
|
// Trait impl item visibility is inherited from its trait when not specified
|
||||||
// explicitly. In that case we cannot determine it here in early resolve,
|
// explicitly. In that case we cannot determine it here in early resolve,
|
||||||
|
|
|
@ -3375,7 +3375,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
||||||
|i, s, c| MethodNotMemberOfTrait(i, s, c),
|
|i, s, c| MethodNotMemberOfTrait(i, s, c),
|
||||||
);
|
);
|
||||||
|
|
||||||
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
|
visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true })
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -3409,7 +3409,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
|
||||||
|i, s, c| TypeNotMemberOfTrait(i, s, c),
|
|i, s, c| TypeNotMemberOfTrait(i, s, c),
|
||||||
);
|
);
|
||||||
|
|
||||||
visit::walk_assoc_item(this, item, AssocCtxt::Impl)
|
visit::walk_assoc_item(this, item, AssocCtxt::Impl { of_trait: true })
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -1191,10 +1191,6 @@ pub struct Resolver<'ra, 'tcx> {
|
||||||
/// and how the `impl Trait` fragments were introduced.
|
/// and how the `impl Trait` fragments were introduced.
|
||||||
invocation_parents: FxHashMap<LocalExpnId, InvocationParent>,
|
invocation_parents: FxHashMap<LocalExpnId, InvocationParent>,
|
||||||
|
|
||||||
/// Some way to know that we are in a *trait* impl in `visit_assoc_item`.
|
|
||||||
/// FIXME: Replace with a more general AST map (together with some other fields).
|
|
||||||
trait_impl_items: FxHashSet<LocalDefId>,
|
|
||||||
|
|
||||||
legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
|
legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
|
||||||
/// Amount of lifetime parameters for each item in the crate.
|
/// Amount of lifetime parameters for each item in the crate.
|
||||||
item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
|
item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
|
||||||
|
@ -1558,7 +1554,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||||
def_id_to_node_id,
|
def_id_to_node_id,
|
||||||
placeholder_field_indices: Default::default(),
|
placeholder_field_indices: Default::default(),
|
||||||
invocation_parents,
|
invocation_parents,
|
||||||
trait_impl_items: Default::default(),
|
|
||||||
legacy_const_generic_args: Default::default(),
|
legacy_const_generic_args: Default::default(),
|
||||||
item_generics_num_lifetimes: Default::default(),
|
item_generics_num_lifetimes: Default::default(),
|
||||||
main_def: Default::default(),
|
main_def: Default::default(),
|
||||||
|
|
|
@ -264,7 +264,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
|
||||||
}
|
}
|
||||||
InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang),
|
InvocationKind::Bang { ref mac, .. } => (&mac.path, MacroKind::Bang),
|
||||||
InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive),
|
InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive),
|
||||||
InvocationKind::GlobDelegation { ref item } => {
|
InvocationKind::GlobDelegation { ref item, .. } => {
|
||||||
let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
|
let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
|
||||||
deleg_impl = Some(self.invocation_parent(invoc_id));
|
deleg_impl = Some(self.invocation_parent(invoc_id));
|
||||||
// It is sufficient to consider glob delegation a bang macro for now.
|
// It is sufficient to consider glob delegation a bang macro for now.
|
||||||
|
|
|
@ -624,7 +624,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
|
||||||
// TODO(calebcartwright): Not sure the skip spans are correct
|
// TODO(calebcartwright): Not sure the skip spans are correct
|
||||||
let (ai, skip_span, assoc_ctxt) = match visitor_kind {
|
let (ai, skip_span, assoc_ctxt) = match visitor_kind {
|
||||||
AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait),
|
AssocTraitItem(ai) => (*ai, ai.span(), visit::AssocCtxt::Trait),
|
||||||
AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl),
|
// There is no difference between trait and inherent assoc item formatting
|
||||||
|
AssocImplItem(ai) => (*ai, ai.span, visit::AssocCtxt::Impl { of_trait: false }),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
skip_out_of_file_lines_range_visitor!(self, ai.span);
|
skip_out_of_file_lines_range_visitor!(self, ai.span);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue