1
Fork 0

Merge impl and trait item mut visitor methods to mirror immut visitor

This commit is contained in:
Oli Scherer 2024-07-08 10:40:37 +00:00
parent aee3dc4c6c
commit 5241d8bb19
6 changed files with 62 additions and 65 deletions

View file

@ -37,8 +37,7 @@ use thin_vec::ThinVec;
#[derive(Debug, Clone)]
pub enum Annotatable {
Item(P<ast::Item>),
TraitItem(P<ast::AssocItem>),
ImplItem(P<ast::AssocItem>),
AssocItem(P<ast::AssocItem>, AssocCtxt),
ForeignItem(P<ast::ForeignItem>),
Stmt(P<ast::Stmt>),
Expr(P<ast::Expr>),
@ -56,8 +55,7 @@ impl Annotatable {
pub fn span(&self) -> Span {
match self {
Annotatable::Item(item) => item.span,
Annotatable::TraitItem(trait_item) => trait_item.span,
Annotatable::ImplItem(impl_item) => impl_item.span,
Annotatable::AssocItem(assoc_item, _) => assoc_item.span,
Annotatable::ForeignItem(foreign_item) => foreign_item.span,
Annotatable::Stmt(stmt) => stmt.span,
Annotatable::Expr(expr) => expr.span,
@ -75,8 +73,7 @@ impl Annotatable {
pub fn visit_attrs(&mut self, f: impl FnOnce(&mut AttrVec)) {
match self {
Annotatable::Item(item) => item.visit_attrs(f),
Annotatable::TraitItem(trait_item) => trait_item.visit_attrs(f),
Annotatable::ImplItem(impl_item) => impl_item.visit_attrs(f),
Annotatable::AssocItem(assoc_item, _) => assoc_item.visit_attrs(f),
Annotatable::ForeignItem(foreign_item) => foreign_item.visit_attrs(f),
Annotatable::Stmt(stmt) => stmt.visit_attrs(f),
Annotatable::Expr(expr) => expr.visit_attrs(f),
@ -94,8 +91,7 @@ impl Annotatable {
pub fn visit_with<'a, V: Visitor<'a>>(&'a self, visitor: &mut V) -> V::Result {
match self {
Annotatable::Item(item) => visitor.visit_item(item),
Annotatable::TraitItem(item) => visitor.visit_assoc_item(item, AssocCtxt::Trait),
Annotatable::ImplItem(item) => visitor.visit_assoc_item(item, AssocCtxt::Impl),
Annotatable::AssocItem(item, ctxt) => visitor.visit_assoc_item(item, *ctxt),
Annotatable::ForeignItem(foreign_item) => visitor.visit_foreign_item(foreign_item),
Annotatable::Stmt(stmt) => visitor.visit_stmt(stmt),
Annotatable::Expr(expr) => visitor.visit_expr(expr),
@ -113,9 +109,7 @@ impl Annotatable {
pub fn to_tokens(&self) -> TokenStream {
match self {
Annotatable::Item(node) => TokenStream::from_ast(node),
Annotatable::TraitItem(node) | Annotatable::ImplItem(node) => {
TokenStream::from_ast(node)
}
Annotatable::AssocItem(node, _) => TokenStream::from_ast(node),
Annotatable::ForeignItem(node) => TokenStream::from_ast(node),
Annotatable::Stmt(node) => {
assert!(!matches!(node.kind, ast::StmtKind::Empty));
@ -142,14 +136,14 @@ impl Annotatable {
pub fn expect_trait_item(self) -> P<ast::AssocItem> {
match self {
Annotatable::TraitItem(i) => i,
Annotatable::AssocItem(i, AssocCtxt::Trait) => i,
_ => panic!("expected Item"),
}
}
pub fn expect_impl_item(self) -> P<ast::AssocItem> {
match self {
Annotatable::ImplItem(i) => i,
Annotatable::AssocItem(i, AssocCtxt::Impl) => i,
_ => panic!("expected Item"),
}
}

View file

@ -140,7 +140,7 @@ macro_rules! ast_fragments {
AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr),
$($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)*
$($(AstFragment::$Kind(ast) =>
ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast)),)?)*
ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)*
}
}
@ -177,13 +177,13 @@ ast_fragments! {
}
TraitItems(SmallVec<[P<ast::AssocItem>; 1]>) {
"trait item";
many fn flat_map_trait_item;
many fn flat_map_assoc_item;
fn visit_assoc_item(AssocCtxt::Trait);
fn make_trait_items;
}
ImplItems(SmallVec<[P<ast::AssocItem>; 1]>) {
"impl item";
many fn flat_map_impl_item;
many fn flat_map_assoc_item;
fn visit_assoc_item(AssocCtxt::Impl);
fn make_impl_items;
}
@ -833,7 +833,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.cx, deleg, &item, &suffixes, item.span, true,
);
fragment_kind.expect_from_annotatables(
single_delegations.map(|item| Annotatable::ImplItem(P(item))),
single_delegations.map(|item| Annotatable::AssocItem(P(item), AssocCtxt::Impl)),
)
}
})
@ -843,8 +843,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
let kind = match item {
Annotatable::Item(_)
| Annotatable::TraitItem(_)
| Annotatable::ImplItem(_)
| Annotatable::AssocItem(..)
| Annotatable::ForeignItem(_)
| Annotatable::Crate(..) => return,
Annotatable::Stmt(stmt) => {
@ -1288,7 +1287,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, TraitItemTag>
type ItemKind = AssocItemKind;
const KIND: AstFragmentKind = AstFragmentKind::TraitItems;
fn to_annotatable(self) -> Annotatable {
Annotatable::TraitItem(self.wrapped)
Annotatable::AssocItem(self.wrapped, AssocCtxt::Trait)
}
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
fragment.make_trait_items()
@ -1329,7 +1328,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::AssocItem>, ImplItemTag>
type ItemKind = AssocItemKind;
const KIND: AstFragmentKind = AstFragmentKind::ImplItems;
fn to_annotatable(self) -> Annotatable {
Annotatable::ImplItem(self.wrapped)
Annotatable::AssocItem(self.wrapped, AssocCtxt::Impl)
}
fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
fragment.make_impl_items()
@ -1993,9 +1992,9 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
let traitless_qself =
matches!(&deleg.qself, Some(qself) if qself.position == 0);
let item = match node.to_annotatable() {
Annotatable::ImplItem(item) => item,
Annotatable::AssocItem(item, AssocCtxt::Impl) => item,
ann @ (Annotatable::Item(_)
| Annotatable::TraitItem(_)
| Annotatable::AssocItem(..)
| Annotatable::Stmt(_)) => {
let span = ann.span();
self.cx.dcx().emit_err(GlobDelegationOutsideImpls { span });
@ -2081,12 +2080,15 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
self.flat_map_node(node)
}
fn flat_map_trait_item(&mut self, node: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag))
}
fn flat_map_impl_item(&mut self, node: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag))
fn flat_map_assoc_item(
&mut self,
node: P<ast::AssocItem>,
ctxt: AssocCtxt,
) -> SmallVec<[P<ast::AssocItem>; 1]> {
match ctxt {
AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)),
AssocCtxt::Impl => self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)),
}
}
fn flat_map_foreign_item(

View file

@ -1,8 +1,8 @@
use crate::expand::{AstFragment, AstFragmentKind};
use rustc_ast as ast;
use rustc_ast::mut_visit::*;
use rustc_ast::ptr::P;
use rustc_ast::token::Delimiter;
use rustc_ast::{self as ast, visit::AssocCtxt};
use rustc_data_structures::fx::FxHashMap;
use rustc_span::symbol::Ident;
use rustc_span::DUMMY_SP;
@ -271,16 +271,19 @@ impl MutVisitor for PlaceholderExpander {
}
}
fn flat_map_trait_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
fn flat_map_assoc_item(
&mut self,
item: P<ast::AssocItem>,
ctxt: AssocCtxt,
) -> SmallVec<[P<ast::AssocItem>; 1]> {
match item.kind {
ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_trait_items(),
_ => noop_flat_map_item(item, self),
}
}
fn flat_map_impl_item(&mut self, item: P<ast::AssocItem>) -> SmallVec<[P<ast::AssocItem>; 1]> {
match item.kind {
ast::AssocItemKind::MacCall(_) => self.remove(item.id).make_impl_items(),
ast::AssocItemKind::MacCall(_) => {
let it = self.remove(item.id);
match ctxt {
AssocCtxt::Trait => it.make_trait_items(),
AssocCtxt::Impl => it.make_impl_items(),
}
}
_ => noop_flat_map_item(item, self),
}
}