further deduplicate ast visitor code
This commit is contained in:
parent
52bf0cf795
commit
898b6a13f1
3 changed files with 285 additions and 430 deletions
|
|
@ -20,7 +20,7 @@ use thin_vec::ThinVec;
|
|||
use crate::ast::*;
|
||||
use crate::ptr::P;
|
||||
use crate::tokenstream::*;
|
||||
use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit};
|
||||
use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit, visit_opt, walk_list};
|
||||
|
||||
pub trait ExpectOne<A: Array> {
|
||||
fn expect_one(self, err: &'static str) -> A::Item;
|
||||
|
|
@ -33,18 +33,6 @@ impl<A: Array> ExpectOne<A> for SmallVec<A> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait WalkItemKind {
|
||||
type Ctxt;
|
||||
fn walk(
|
||||
&mut self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
visibility: &mut Visibility,
|
||||
ctxt: Self::Ctxt,
|
||||
visitor: &mut impl MutVisitor,
|
||||
);
|
||||
}
|
||||
|
||||
pub trait MutVisitor: Sized {
|
||||
// Methods in this trait have one of three forms:
|
||||
//
|
||||
|
|
@ -451,11 +439,6 @@ fn visit_thin_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut ThinVec<P<Expr>>) {
|
|||
exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
|
||||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
fn visit_bounds<T: MutVisitor>(vis: &mut T, bounds: &mut GenericBounds, ctxt: BoundKind) {
|
||||
visit_vec(bounds, |bound| vis.visit_param_bound(bound, ctxt));
|
||||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
|
||||
match args {
|
||||
|
|
@ -610,12 +593,6 @@ pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
|
|||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
|
||||
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
||||
visit_safety(vis, safety);
|
||||
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
|
||||
}
|
||||
|
||||
pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
|
||||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
|
||||
visitor.visit_id(id);
|
||||
|
|
@ -771,22 +748,6 @@ pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> Smal
|
|||
smallvec![param]
|
||||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
fn visit_defaultness<T: MutVisitor>(vis: &mut T, defaultness: &mut Defaultness) {
|
||||
match defaultness {
|
||||
Defaultness::Default(span) => vis.visit_span(span),
|
||||
Defaultness::Final => {}
|
||||
}
|
||||
}
|
||||
|
||||
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
|
||||
fn visit_polarity<T: MutVisitor>(vis: &mut T, polarity: &mut ImplPolarity) {
|
||||
match polarity {
|
||||
ImplPolarity::Positive => {}
|
||||
ImplPolarity::Negative(span) => vis.visit_span(span),
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_closure_binder<T: MutVisitor>(vis: &mut T, binder: &mut ClosureBinder) {
|
||||
match binder {
|
||||
ClosureBinder::NotPresent => {}
|
||||
|
|
@ -1080,169 +1041,15 @@ pub fn walk_item_kind<K: WalkItemKind>(
|
|||
kind.walk(span, id, visibility, ctxt, vis)
|
||||
}
|
||||
|
||||
impl WalkItemKind for ItemKind {
|
||||
type Ctxt = ();
|
||||
fn walk(
|
||||
&mut self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
visibility: &mut Visibility,
|
||||
_ctxt: Self::Ctxt,
|
||||
vis: &mut impl MutVisitor,
|
||||
) {
|
||||
match self {
|
||||
ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
|
||||
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
|
||||
ItemKind::Static(box StaticItem {
|
||||
ident,
|
||||
ty,
|
||||
safety: _,
|
||||
mutability: _,
|
||||
expr,
|
||||
define_opaque,
|
||||
}) => {
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_ty(ty);
|
||||
visit_opt(expr, |expr| vis.visit_expr(expr));
|
||||
walk_define_opaques(vis, define_opaque);
|
||||
}
|
||||
ItemKind::Const(item) => {
|
||||
walk_const_item(vis, item);
|
||||
}
|
||||
ItemKind::Fn(func) => {
|
||||
vis.visit_fn(FnKind::Fn(FnCtxt::Free, visibility, &mut *func), span, id);
|
||||
}
|
||||
ItemKind::Mod(safety, ident, mod_kind) => {
|
||||
visit_safety(vis, safety);
|
||||
vis.visit_ident(ident);
|
||||
match mod_kind {
|
||||
ModKind::Loaded(
|
||||
items,
|
||||
_inline,
|
||||
ModSpans { inner_span, inject_use_span },
|
||||
_,
|
||||
) => {
|
||||
items.flat_map_in_place(|item| vis.flat_map_item(item));
|
||||
vis.visit_span(inner_span);
|
||||
vis.visit_span(inject_use_span);
|
||||
}
|
||||
ModKind::Unloaded => {}
|
||||
}
|
||||
}
|
||||
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
||||
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
ident,
|
||||
generics,
|
||||
where_clauses,
|
||||
bounds,
|
||||
ty,
|
||||
}) => {
|
||||
visit_defaultness(vis, defaultness);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_generics(generics);
|
||||
visit_bounds(vis, bounds, BoundKind::Bound);
|
||||
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||
walk_ty_alias_where_clauses(vis, where_clauses);
|
||||
}
|
||||
ItemKind::Enum(ident, EnumDef { variants }, generics) => {
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_generics(generics);
|
||||
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
|
||||
}
|
||||
ItemKind::Struct(ident, variant_data, generics)
|
||||
| ItemKind::Union(ident, variant_data, generics) => {
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_generics(generics);
|
||||
vis.visit_variant_data(variant_data);
|
||||
}
|
||||
ItemKind::Impl(box Impl {
|
||||
defaultness,
|
||||
safety,
|
||||
generics,
|
||||
constness,
|
||||
polarity,
|
||||
of_trait,
|
||||
self_ty,
|
||||
items,
|
||||
}) => {
|
||||
visit_defaultness(vis, defaultness);
|
||||
visit_safety(vis, safety);
|
||||
vis.visit_generics(generics);
|
||||
visit_constness(vis, constness);
|
||||
visit_polarity(vis, polarity);
|
||||
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
|
||||
vis.visit_ty(self_ty);
|
||||
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: _, ident, generics, bounds, items }) => {
|
||||
visit_safety(vis, safety);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_generics(generics);
|
||||
visit_bounds(vis, bounds, BoundKind::Bound);
|
||||
items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait));
|
||||
}
|
||||
ItemKind::TraitAlias(ident, generics, bounds) => {
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_generics(generics);
|
||||
visit_bounds(vis, bounds, BoundKind::Bound);
|
||||
}
|
||||
ItemKind::MacCall(m) => vis.visit_mac_call(m),
|
||||
ItemKind::MacroDef(ident, def) => {
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_macro_def(def)
|
||||
}
|
||||
ItemKind::Delegation(box Delegation {
|
||||
id,
|
||||
qself,
|
||||
path,
|
||||
ident,
|
||||
rename,
|
||||
body,
|
||||
from_glob: _,
|
||||
}) => {
|
||||
vis.visit_id(id);
|
||||
vis.visit_qself(qself);
|
||||
vis.visit_path(path);
|
||||
vis.visit_ident(ident);
|
||||
if let Some(rename) = rename {
|
||||
vis.visit_ident(rename);
|
||||
}
|
||||
if let Some(body) = body {
|
||||
vis.visit_block(body);
|
||||
}
|
||||
}
|
||||
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
|
||||
vis.visit_qself(qself);
|
||||
vis.visit_path(prefix);
|
||||
if let Some(suffixes) = suffixes {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WalkItemKind for AssocItemKind {
|
||||
type Ctxt = AssocCtxt;
|
||||
fn walk(
|
||||
fn walk<V: MutVisitor>(
|
||||
&mut self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
visibility: &mut Visibility,
|
||||
ctxt: Self::Ctxt,
|
||||
visitor: &mut impl MutVisitor,
|
||||
visitor: &mut V,
|
||||
) {
|
||||
match self {
|
||||
AssocItemKind::Const(item) => {
|
||||
|
|
@ -1306,16 +1113,6 @@ impl WalkItemKind for AssocItemKind {
|
|||
}
|
||||
}
|
||||
|
||||
fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) {
|
||||
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
|
||||
visit_defaultness(vis, defaultness);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_generics(generics);
|
||||
vis.visit_ty(ty);
|
||||
visit_opt(expr, |expr| vis.visit_expr(expr));
|
||||
walk_define_opaques(vis, define_opaque);
|
||||
}
|
||||
|
||||
pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
|
||||
let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
|
||||
vis.visit_id(id);
|
||||
|
|
@ -1334,19 +1131,6 @@ pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P<AssocItem>, c
|
|||
walk_item_ctxt(visitor, item, ctxt)
|
||||
}
|
||||
|
||||
fn walk_item_ctxt<K: WalkItemKind>(
|
||||
visitor: &mut impl MutVisitor,
|
||||
item: &mut P<Item<K>>,
|
||||
ctxt: K::Ctxt,
|
||||
) {
|
||||
let Item { attrs, id, kind, vis, span, tokens: _ } = item.deref_mut();
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
visitor.visit_vis(vis);
|
||||
kind.walk(*span, *id, vis, ctxt, visitor);
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
|
||||
vis.visit_item(&mut item);
|
||||
smallvec![item]
|
||||
|
|
@ -1371,13 +1155,13 @@ pub fn walk_flat_map_assoc_item(
|
|||
|
||||
impl WalkItemKind for ForeignItemKind {
|
||||
type Ctxt = ();
|
||||
fn walk(
|
||||
fn walk<V: MutVisitor>(
|
||||
&mut self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
visibility: &mut Visibility,
|
||||
_ctxt: Self::Ctxt,
|
||||
visitor: &mut impl MutVisitor,
|
||||
visitor: &mut V,
|
||||
) {
|
||||
match self {
|
||||
ForeignItemKind::Static(box StaticItem {
|
||||
|
|
@ -1786,18 +1570,6 @@ fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
|
|||
}
|
||||
}
|
||||
|
||||
fn walk_define_opaques<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
define_opaque: &mut Option<ThinVec<(NodeId, Path)>>,
|
||||
) {
|
||||
if let Some(define_opaque) = define_opaque {
|
||||
for (id, path) in define_opaque {
|
||||
vis.visit_id(id);
|
||||
vis.visit_path(path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Some value for the AST node that is valid but possibly meaningless. Similar
|
||||
/// to `Default` but not intended for wide use. The value will never be used
|
||||
/// meaningfully, it exists just to support unwinding in `visit_clobber` in the
|
||||
|
|
|
|||
|
|
@ -112,18 +112,6 @@ pub enum LifetimeCtxt {
|
|||
GenericArg,
|
||||
}
|
||||
|
||||
pub trait WalkItemKind {
|
||||
type Ctxt;
|
||||
fn walk<'a, V: Visitor<'a>>(
|
||||
&'a self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
visibility: &'a Visibility,
|
||||
ctxt: Self::Ctxt,
|
||||
visitor: &mut V,
|
||||
) -> V::Result;
|
||||
}
|
||||
|
||||
/// Each method of the `Visitor` trait is a hook to be potentially
|
||||
/// overridden. Each method's default implementation recursively visits
|
||||
/// the substructure of the input via the corresponding `walk` method;
|
||||
|
|
@ -141,6 +129,9 @@ pub trait Visitor<'ast>: Sized {
|
|||
fn visit_ident(&mut self, _ident: &'ast Ident) -> Self::Result {
|
||||
Self::Result::output()
|
||||
}
|
||||
fn visit_foreign_mod(&mut self, nm: &'ast ForeignMod) -> Self::Result {
|
||||
walk_foreign_mod(self, nm)
|
||||
}
|
||||
fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result {
|
||||
walk_item(self, i)
|
||||
}
|
||||
|
|
@ -242,7 +233,7 @@ pub trait Visitor<'ast>: Sized {
|
|||
fn visit_mac_call(&mut self, mac: &'ast MacCall) -> Self::Result {
|
||||
walk_mac(self, mac)
|
||||
}
|
||||
fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) -> Self::Result {
|
||||
fn visit_macro_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) -> Self::Result {
|
||||
Self::Result::output()
|
||||
}
|
||||
fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result {
|
||||
|
|
@ -318,6 +309,18 @@ pub trait Visitor<'ast>: Sized {
|
|||
#[macro_export]
|
||||
macro_rules! common_visitor_and_walkers {
|
||||
($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => {
|
||||
pub trait WalkItemKind {
|
||||
type Ctxt;
|
||||
fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
&$($lt)? $($mut)? self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
visibility: &$($lt)? $($mut)? Visibility,
|
||||
ctxt: Self::Ctxt,
|
||||
visitor: &mut V,
|
||||
) $(-> <V as Visitor<$lt>>::Result)?;
|
||||
}
|
||||
|
||||
// this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
|
||||
$(${ignore($lt)}
|
||||
#[expect(unused, rustc::pass_by_value)]
|
||||
|
|
@ -325,7 +328,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
)?
|
||||
fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, span: &$($lt)? $($mut)? Span) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
$(
|
||||
let _ = stringify!($mut);
|
||||
${ignore($mut)}
|
||||
visitor.visit_span(span);
|
||||
)?
|
||||
$(${ignore($lt)}V::Result::output())?
|
||||
|
|
@ -338,7 +341,7 @@ macro_rules! common_visitor_and_walkers {
|
|||
)?
|
||||
fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, id: &$($lt)? $($mut)? NodeId) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
$(
|
||||
let _ = stringify!($mut);
|
||||
${ignore($mut)}
|
||||
visitor.visit_id(id);
|
||||
)?
|
||||
$(${ignore($lt)}V::Result::output())?
|
||||
|
|
@ -362,6 +365,27 @@ macro_rules! common_visitor_and_walkers {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
match defaultness {
|
||||
Defaultness::Default(span) => visit_span(vis, span),
|
||||
Defaultness::Final => {
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, polarity: &$($lt)? $($mut)? ImplPolarity) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
match polarity {
|
||||
ImplPolarity::Positive => { $(<V as Visitor<$lt>>::Result::output())? }
|
||||
ImplPolarity::Negative(span) => visit_span(vis, span),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
walk_list!(visitor, visit_param_bound, bounds, ctxt);
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
|
||||
pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
visitor.visit_ident(ident)
|
||||
}
|
||||
|
|
@ -379,6 +403,246 @@ macro_rules! common_visitor_and_walkers {
|
|||
try_visit!(visit_id(visitor, id));
|
||||
visitor.visit_ident(ident)
|
||||
}
|
||||
|
||||
fn walk_item_ctxt<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind>(
|
||||
visitor: &mut V,
|
||||
item: &$($mut P<Item<K>>)? $($lt Item<K>)?,
|
||||
ctxt: K::Ctxt,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let Item { attrs, id, kind, vis, span, tokens: _ } = &$($mut *)? *item;
|
||||
try_visit!(visit_id(visitor, id));
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
try_visit!(visitor.visit_vis(vis));
|
||||
try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
|
||||
visit_span(visitor, span)
|
||||
}
|
||||
|
||||
impl WalkItemKind for ItemKind {
|
||||
type Ctxt = ();
|
||||
fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
&$($lt)? $($mut)? self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
visibility: &$($lt)? $($mut)? Visibility,
|
||||
_ctxt: Self::Ctxt,
|
||||
vis: &mut V,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
match self {
|
||||
ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
|
||||
// FIXME(fee1-dead): look into this weird assymetry
|
||||
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree$(${ignore($lt)}, id, false)?),
|
||||
ItemKind::Static(box StaticItem {
|
||||
ident,
|
||||
ty,
|
||||
safety: _,
|
||||
mutability: _,
|
||||
expr,
|
||||
define_opaque,
|
||||
}) => {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_ty(ty));
|
||||
visit_opt!(vis, visit_expr, expr);
|
||||
walk_define_opaques(vis, define_opaque)
|
||||
}
|
||||
ItemKind::Const(item) => {
|
||||
walk_const_item(vis, item)
|
||||
}
|
||||
ItemKind::Fn(func) => {
|
||||
let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func);
|
||||
vis.visit_fn(kind, span, id)
|
||||
}
|
||||
ItemKind::Mod(safety, ident, mod_kind) => {
|
||||
try_visit!(visit_safety(vis, safety));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
match mod_kind {
|
||||
ModKind::Loaded(
|
||||
items,
|
||||
_inline,
|
||||
ModSpans { inner_span, inject_use_span },
|
||||
_,
|
||||
) => {
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| vis.flat_map_item(item));
|
||||
)?
|
||||
$(${ignore($lt)}
|
||||
walk_list!(vis, visit_item, items);
|
||||
)?
|
||||
try_visit!(visit_span(vis, inner_span));
|
||||
try_visit!(visit_span(vis, inject_use_span));
|
||||
}
|
||||
ModKind::Unloaded => {}
|
||||
}
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
||||
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
defaultness,
|
||||
ident,
|
||||
generics,
|
||||
$(${ignore($lt)} #[expect(unused)])?
|
||||
where_clauses,
|
||||
bounds,
|
||||
ty,
|
||||
}) => {
|
||||
try_visit!(visit_defaultness(vis, defaultness));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
|
||||
visit_opt!(vis, visit_ty, ty);
|
||||
$(${ignore($mut)}
|
||||
walk_ty_alias_where_clauses(vis, where_clauses);
|
||||
)?
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
ItemKind::Enum(ident, enum_definition, generics) => {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
$(${ignore($mut)}
|
||||
enum_definition.variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
|
||||
)?
|
||||
$(${ignore($lt)}vis.visit_enum_def(enum_definition))?
|
||||
}
|
||||
ItemKind::Struct(ident, variant_data, generics)
|
||||
| ItemKind::Union(ident, variant_data, generics) => {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
vis.visit_variant_data(variant_data)
|
||||
}
|
||||
ItemKind::Impl(box Impl {
|
||||
defaultness,
|
||||
safety,
|
||||
generics,
|
||||
constness,
|
||||
polarity,
|
||||
of_trait,
|
||||
self_ty,
|
||||
items,
|
||||
}) => {
|
||||
try_visit!(visit_defaultness(vis, defaultness));
|
||||
try_visit!(visit_safety(vis, safety));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
try_visit!(visit_constness(vis, constness));
|
||||
try_visit!(visit_polarity(vis, polarity));
|
||||
visit_opt!(vis, visit_trait_ref, of_trait);
|
||||
try_visit!(vis.visit_ty(self_ty));
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| {
|
||||
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
|
||||
});
|
||||
)?
|
||||
$(${ignore($lt)}
|
||||
walk_list!(
|
||||
vis,
|
||||
visit_assoc_item,
|
||||
items,
|
||||
AssocCtxt::Impl { of_trait: of_trait.is_some() }
|
||||
);
|
||||
<V as Visitor<$lt>>::Result::output()
|
||||
)?
|
||||
}
|
||||
ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
|
||||
try_visit!(visit_safety(vis, safety));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| {
|
||||
vis.flat_map_assoc_item(item, AssocCtxt::Trait)
|
||||
});
|
||||
)?
|
||||
$(${ignore($lt)}
|
||||
walk_list!(vis, visit_assoc_item, items, AssocCtxt::Trait);
|
||||
<V as Visitor<$lt>>::Result::output()
|
||||
)?
|
||||
}
|
||||
ItemKind::TraitAlias(ident, generics, bounds) => {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
visit_bounds(vis, bounds, BoundKind::Bound)
|
||||
}
|
||||
ItemKind::MacCall(m) => vis.visit_mac_call(m),
|
||||
ItemKind::MacroDef(ident, def) => {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
// FIXME(fee1-dead) assymetry
|
||||
vis.visit_macro_def(def$(${ignore($lt)}, id)?)
|
||||
}
|
||||
ItemKind::Delegation(box Delegation {
|
||||
id,
|
||||
qself,
|
||||
path,
|
||||
ident,
|
||||
rename,
|
||||
body,
|
||||
from_glob: _,
|
||||
}) => {
|
||||
try_visit!(visit_id(vis, id));
|
||||
try_visit!(vis.visit_qself(qself));
|
||||
try_visit!(vis.visit_path(path$(${ignore($lt)}, *id)?));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
if let Some(rename) = rename {
|
||||
try_visit!(vis.visit_ident(rename));
|
||||
}
|
||||
if let Some(body) = body {
|
||||
try_visit!(vis.visit_block(body));
|
||||
}
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
|
||||
try_visit!(vis.visit_qself(qself));
|
||||
try_visit!(vis.visit_path(prefix$(${ignore($lt)}, id)?));
|
||||
if let Some(suffixes) = suffixes {
|
||||
for (ident, rename) in suffixes {
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
if let Some(rename) = rename {
|
||||
try_visit!(vis.visit_ident(rename));
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(body) = body {
|
||||
try_visit!(vis.visit_block(body));
|
||||
}
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, item: &$($lt)? $($mut)? ConstItem) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
|
||||
try_visit!(visit_defaultness(vis, defaultness));
|
||||
try_visit!(vis.visit_ident(ident));
|
||||
try_visit!(vis.visit_generics(generics));
|
||||
try_visit!(vis.visit_ty(ty));
|
||||
visit_opt!(vis, visit_expr, expr);
|
||||
walk_define_opaques(vis, define_opaque)
|
||||
}
|
||||
|
||||
fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
|
||||
try_visit!(visit_safety(vis, safety));
|
||||
$(${ignore($mut)}
|
||||
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
|
||||
)?
|
||||
$(
|
||||
walk_list!(vis, visit_foreign_item, items);
|
||||
<V as Visitor<$lt>>::Result::output()
|
||||
)?
|
||||
}
|
||||
|
||||
fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>(
|
||||
visitor: &mut V,
|
||||
define_opaque: &$($lt)? $($mut)? Option<ThinVec<(NodeId, Path)>>,
|
||||
) $(-> <V as Visitor<$lt>>::Result)? {
|
||||
if let Some(define_opaque) = define_opaque {
|
||||
for (id, path) in define_opaque {
|
||||
try_visit!(visit_id(visitor, id));
|
||||
// FIXME(fee1-dead): look into this weird assymetry
|
||||
try_visit!(visitor.visit_path(path$(${ignore($lt)}, *id)?));
|
||||
}
|
||||
}
|
||||
$(<V as Visitor<$lt>>::Result::output())?
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -417,163 +681,6 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR
|
|||
visitor.visit_path(path, *ref_id)
|
||||
}
|
||||
|
||||
impl WalkItemKind for ItemKind {
|
||||
type Ctxt = ();
|
||||
fn walk<'a, V: Visitor<'a>>(
|
||||
&'a self,
|
||||
span: Span,
|
||||
id: NodeId,
|
||||
vis: &'a Visibility,
|
||||
_ctxt: Self::Ctxt,
|
||||
visitor: &mut V,
|
||||
) -> V::Result {
|
||||
match self {
|
||||
ItemKind::ExternCrate(_rename, ident) => try_visit!(visitor.visit_ident(ident)),
|
||||
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
|
||||
ItemKind::Static(box StaticItem {
|
||||
ident,
|
||||
ty,
|
||||
safety: _,
|
||||
mutability: _,
|
||||
expr,
|
||||
define_opaque,
|
||||
}) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_ty(ty));
|
||||
visit_opt!(visitor, visit_expr, expr);
|
||||
try_visit!(walk_define_opaques(visitor, define_opaque));
|
||||
}
|
||||
ItemKind::Const(box ConstItem {
|
||||
defaultness: _,
|
||||
ident,
|
||||
generics,
|
||||
ty,
|
||||
expr,
|
||||
define_opaque,
|
||||
}) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_generics(generics));
|
||||
try_visit!(visitor.visit_ty(ty));
|
||||
visit_opt!(visitor, visit_expr, expr);
|
||||
try_visit!(walk_define_opaques(visitor, define_opaque));
|
||||
}
|
||||
ItemKind::Fn(func) => {
|
||||
let kind = FnKind::Fn(FnCtxt::Free, vis, &*func);
|
||||
try_visit!(visitor.visit_fn(kind, span, id));
|
||||
}
|
||||
ItemKind::Mod(_unsafety, ident, mod_kind) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
match mod_kind {
|
||||
ModKind::Loaded(items, _inline, _inner_span, _) => {
|
||||
walk_list!(visitor, visit_item, items);
|
||||
}
|
||||
ModKind::Unloaded => {}
|
||||
}
|
||||
}
|
||||
ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
|
||||
walk_list!(visitor, visit_foreign_item, items);
|
||||
}
|
||||
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
generics,
|
||||
ident,
|
||||
bounds,
|
||||
ty,
|
||||
defaultness: _,
|
||||
where_clauses: _,
|
||||
}) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_generics(generics));
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||
visit_opt!(visitor, visit_ty, ty);
|
||||
}
|
||||
ItemKind::Enum(ident, enum_definition, generics) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_generics(generics));
|
||||
try_visit!(visitor.visit_enum_def(enum_definition));
|
||||
}
|
||||
ItemKind::Impl(box Impl {
|
||||
defaultness: _,
|
||||
safety: _,
|
||||
generics,
|
||||
constness: _,
|
||||
polarity: _,
|
||||
of_trait,
|
||||
self_ty,
|
||||
items,
|
||||
}) => {
|
||||
try_visit!(visitor.visit_generics(generics));
|
||||
visit_opt!(visitor, visit_trait_ref, of_trait);
|
||||
try_visit!(visitor.visit_ty(self_ty));
|
||||
walk_list!(
|
||||
visitor,
|
||||
visit_assoc_item,
|
||||
items,
|
||||
AssocCtxt::Impl { of_trait: of_trait.is_some() }
|
||||
);
|
||||
}
|
||||
ItemKind::Struct(ident, struct_definition, generics)
|
||||
| ItemKind::Union(ident, struct_definition, generics) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_generics(generics));
|
||||
try_visit!(visitor.visit_variant_data(struct_definition));
|
||||
}
|
||||
ItemKind::Trait(box Trait {
|
||||
safety: _,
|
||||
is_auto: _,
|
||||
ident,
|
||||
generics,
|
||||
bounds,
|
||||
items,
|
||||
}) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_generics(generics));
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
|
||||
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
|
||||
}
|
||||
ItemKind::TraitAlias(ident, generics, bounds) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_generics(generics));
|
||||
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
|
||||
}
|
||||
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
|
||||
ItemKind::MacroDef(ident, ts) => {
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
try_visit!(visitor.visit_mac_def(ts, id))
|
||||
}
|
||||
ItemKind::Delegation(box Delegation {
|
||||
id,
|
||||
qself,
|
||||
path,
|
||||
ident,
|
||||
rename,
|
||||
body,
|
||||
from_glob: _,
|
||||
}) => {
|
||||
try_visit!(visitor.visit_qself(qself));
|
||||
try_visit!(visitor.visit_path(path, *id));
|
||||
try_visit!(visitor.visit_ident(ident));
|
||||
visit_opt!(visitor, visit_ident, rename);
|
||||
visit_opt!(visitor, visit_block, body);
|
||||
}
|
||||
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
|
||||
try_visit!(visitor.visit_qself(qself));
|
||||
try_visit!(visitor.visit_path(prefix, id));
|
||||
if let Some(suffixes) = suffixes {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_enum_def<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
EnumDef { variants }: &'a EnumDef,
|
||||
|
|
@ -1121,18 +1228,6 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
|
|||
walk_item_ctxt(visitor, item, ctxt)
|
||||
}
|
||||
|
||||
fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
|
||||
visitor: &mut V,
|
||||
item: &'a Item<K>,
|
||||
ctxt: K::Ctxt,
|
||||
) -> V::Result {
|
||||
let Item { id, span, vis, attrs, kind, tokens: _ } = item;
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
try_visit!(visitor.visit_vis(vis));
|
||||
try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
pub fn walk_struct_def<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
struct_definition: &'a VariantData,
|
||||
|
|
@ -1455,15 +1550,3 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -
|
|||
}
|
||||
V::Result::output()
|
||||
}
|
||||
|
||||
fn walk_define_opaques<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
define_opaque: &'a Option<ThinVec<(NodeId, Path)>>,
|
||||
) -> V::Result {
|
||||
if let Some(define_opaque) = define_opaque {
|
||||
for (id, path) in define_opaque {
|
||||
try_visit!(visitor.visit_path(path, *id));
|
||||
}
|
||||
}
|
||||
V::Result::output()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
|
|||
ast_visit::walk_attribute(self, attr);
|
||||
}
|
||||
|
||||
fn visit_mac_def(&mut self, mac: &'ast ast::MacroDef, id: ast::NodeId) {
|
||||
fn visit_macro_def(&mut self, mac: &'ast ast::MacroDef, id: ast::NodeId) {
|
||||
lint_callback!(self, check_mac_def, mac);
|
||||
self.check_id(id);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue