diff options
Diffstat (limited to 'compiler/rustc_ast/src')
| -rw-r--r-- | compiler/rustc_ast/src/ast.rs | 90 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/ast_traits.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/mut_visit.rs | 656 | ||||
| -rw-r--r-- | compiler/rustc_ast/src/visit.rs | 1109 |
4 files changed, 718 insertions, 1143 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index a16219361c0..c9a8adec31a 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -32,7 +32,7 @@ use rustc_data_structures::tagged_ptr::Tag; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; pub use rustc_span::AttrId; use rustc_span::source_map::{Spanned, respan}; -use rustc_span::{ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, ErrorGuaranteed, Ident, Span, Symbol, kw, sym}; use thin_vec::{ThinVec, thin_vec}; pub use crate::format::*; @@ -99,8 +99,15 @@ pub struct Path { impl PartialEq<Symbol> for Path { #[inline] - fn eq(&self, symbol: &Symbol) -> bool { - matches!(&self.segments[..], [segment] if segment.ident.name == *symbol) + fn eq(&self, name: &Symbol) -> bool { + if let [segment] = self.segments.as_ref() + && segment.args.is_none() + && segment.ident.name == *name + { + true + } else { + false + } } } @@ -120,17 +127,6 @@ impl Path { Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None } } - pub fn is_ident(&self, name: Symbol) -> bool { - if let [segment] = self.segments.as_ref() - && segment.args.is_none() - && segment.ident.name == name - { - true - } else { - false - } - } - pub fn is_global(&self) -> bool { self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot) } @@ -1526,6 +1522,19 @@ impl Expr { | ExprKind::Struct(_) ) } + + /// Creates a dummy `P<Expr>`. + /// + /// Should only be used when it will be replaced afterwards or as a return value when an error was encountered. + pub fn dummy() -> P<Expr> { + P(Expr { + id: DUMMY_NODE_ID, + kind: ExprKind::Dummy, + span: DUMMY_SP, + attrs: ThinVec::new(), + tokens: None, + }) + } } #[derive(Clone, Encodable, Decodable, Debug)] @@ -2452,6 +2461,39 @@ impl TyKind { None } } + + /// Returns `true` if this type is considered a scalar primitive (e.g., + /// `i32`, `u8`, `bool`, etc). + /// + /// This check is based on **symbol equality** and does **not** remove any + /// path prefixes or references. If a type alias or shadowing is present + /// (e.g., `type i32 = CustomType;`), this method will still return `true` + /// for `i32`, even though it may not refer to the primitive type. + pub fn maybe_scalar(&self) -> bool { + let Some(ty_sym) = self.is_simple_path() else { + // unit type + return self.is_unit(); + }; + matches!( + ty_sym, + sym::i8 + | sym::i16 + | sym::i32 + | sym::i64 + | sym::i128 + | sym::u8 + | sym::u16 + | sym::u32 + | sym::u64 + | sym::u128 + | sym::f16 + | sym::f32 + | sym::f64 + | sym::f128 + | sym::char + | sym::bool + ) + } } /// A pattern type pattern. @@ -3417,9 +3459,9 @@ impl Item { ItemKind::Fn(i) => Some(&i.generics), ItemKind::TyAlias(i) => Some(&i.generics), ItemKind::TraitAlias(_, generics, _) - | ItemKind::Enum(_, _, generics) - | ItemKind::Struct(_, _, generics) - | ItemKind::Union(_, _, generics) => Some(&generics), + | ItemKind::Enum(_, generics, _) + | ItemKind::Struct(_, generics, _) + | ItemKind::Union(_, generics, _) => Some(&generics), ItemKind::Trait(i) => Some(&i.generics), ItemKind::Impl(i) => Some(&i.generics), } @@ -3663,15 +3705,15 @@ pub enum ItemKind { /// An enum definition (`enum`). /// /// E.g., `enum Foo<A, B> { C<A>, D<B> }`. - Enum(Ident, EnumDef, Generics), + Enum(Ident, Generics, EnumDef), /// A struct definition (`struct`). /// /// E.g., `struct Foo<A> { x: A }`. - Struct(Ident, VariantData, Generics), + Struct(Ident, Generics, VariantData), /// A union definition (`union`). /// /// E.g., `union Foo<A, B> { x: A, y: B }`. - Union(Ident, VariantData, Generics), + Union(Ident, Generics, VariantData), /// A trait declaration (`trait`). /// /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`. @@ -3688,10 +3730,8 @@ pub enum ItemKind { /// /// E.g., `foo!(..)`. MacCall(P<MacCall>), - /// A macro definition. MacroDef(Ident, MacroDef), - /// A single delegation item (`reuse`). /// /// E.g. `reuse <Type as Trait>::name { target_expr_template }`. @@ -3767,9 +3807,9 @@ impl ItemKind { Self::Fn(box Fn { generics, .. }) | Self::TyAlias(box TyAlias { generics, .. }) | Self::Const(box ConstItem { generics, .. }) - | Self::Enum(_, _, generics) - | Self::Struct(_, _, generics) - | Self::Union(_, _, generics) + | Self::Enum(_, generics, _) + | Self::Struct(_, generics, _) + | Self::Union(_, generics, _) | Self::Trait(box Trait { generics, .. }) | Self::TraitAlias(_, generics, _) | Self::Impl(box Impl { generics, .. }) => Some(generics), diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs index 21de7ff7719..797ab297319 100644 --- a/compiler/rustc_ast/src/ast_traits.rs +++ b/compiler/rustc_ast/src/ast_traits.rs @@ -304,6 +304,7 @@ impl HasAttrs for Stmt { } /// A newtype around an AST node that implements the traits above if the node implements them. +#[repr(transparent)] pub struct AstNodeWrapper<Wrapped, Tag> { pub wrapped: Wrapped, pub tag: PhantomData<Tag>, @@ -313,6 +314,11 @@ impl<Wrapped, Tag> AstNodeWrapper<Wrapped, Tag> { pub fn new(wrapped: Wrapped, _tag: Tag) -> AstNodeWrapper<Wrapped, Tag> { AstNodeWrapper { wrapped, tag: Default::default() } } + + pub fn from_mut(wrapped: &mut Wrapped, _tag: Tag) -> &mut AstNodeWrapper<Wrapped, Tag> { + // SAFETY: `AstNodeWrapper` is `repr(transparent)` w.r.t `Wrapped` + unsafe { &mut *<*mut Wrapped>::cast(wrapped) } + } } impl<Wrapped: HasNodeId, Tag> HasNodeId for AstNodeWrapper<Wrapped, Tag> { diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a90349f318c..08726ee6b41 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -12,7 +12,6 @@ use std::panic; use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_span::source_map::Spanned; use rustc_span::{Ident, Span}; use smallvec::{Array, SmallVec, smallvec}; use thin_vec::ThinVec; @@ -20,7 +19,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 +32,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: // @@ -52,12 +39,6 @@ pub trait MutVisitor: Sized { // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare // fn filter_map_t(&mut self, t: T) -> Option<T>; // rarest // - // Any additions to this trait should happen in form of a call to a public - // `noop_*` function that only calls out to the visitor again, not other - // `noop_*` functions. This is a necessary API workaround to the problem of - // not being able to call out to the super default method in an overridden - // default method. - // // When writing these methods, it is better to use destructuring like this: // // fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) { @@ -95,7 +76,7 @@ pub trait MutVisitor: Sized { walk_use_tree(self, use_tree); } - fn visit_foreign_item(&mut self, ni: &mut P<ForeignItem>) { + fn visit_foreign_item(&mut self, ni: &mut ForeignItem) { walk_item(self, ni); } @@ -103,7 +84,7 @@ pub trait MutVisitor: Sized { walk_flat_map_foreign_item(self, ni) } - fn visit_item(&mut self, i: &mut P<Item>) { + fn visit_item(&mut self, i: &mut Item) { walk_item(self, i); } @@ -123,7 +104,7 @@ pub trait MutVisitor: Sized { walk_flat_map_field_def(self, fd) } - fn visit_assoc_item(&mut self, i: &mut P<AssocItem>, ctxt: AssocCtxt) { + fn visit_assoc_item(&mut self, i: &mut AssocItem, ctxt: AssocCtxt) { walk_assoc_item(self, i, ctxt) } @@ -135,11 +116,11 @@ pub trait MutVisitor: Sized { walk_flat_map_assoc_item(self, i, ctxt) } - fn visit_contract(&mut self, c: &mut P<FnContract>) { + fn visit_contract(&mut self, c: &mut FnContract) { walk_contract(self, c); } - fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) { + fn visit_fn_decl(&mut self, d: &mut FnDecl) { walk_fn_decl(self, d); } @@ -156,7 +137,7 @@ pub trait MutVisitor: Sized { walk_closure_binder(self, b); } - fn visit_block(&mut self, b: &mut P<Block>) { + fn visit_block(&mut self, b: &mut Block) { walk_block(self, b); } @@ -191,7 +172,7 @@ pub trait MutVisitor: Sized { } fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> { - noop_filter_map_expr(self, e) + walk_filter_map_expr(self, e) } fn visit_generic_arg(&mut self, arg: &mut GenericArg) { @@ -202,7 +183,7 @@ pub trait MutVisitor: Sized { walk_ty(self, t); } - fn visit_ty_pat(&mut self, t: &mut P<TyPat>) { + fn visit_ty_pat(&mut self, t: &mut TyPat) { walk_ty_pat(self, t); } @@ -258,7 +239,7 @@ pub trait MutVisitor: Sized { walk_parenthesized_parameter_data(self, p); } - fn visit_local(&mut self, l: &mut P<Local>) { + fn visit_local(&mut self, l: &mut Local) { walk_local(self, l); } @@ -318,10 +299,6 @@ pub trait MutVisitor: Sized { walk_precise_capturing_arg(self, arg); } - fn visit_mt(&mut self, mt: &mut MutTy) { - walk_mt(self, mt); - } - fn visit_expr_field(&mut self, f: &mut ExprField) { walk_expr_field(self, f); } @@ -390,17 +367,6 @@ pub trait MutVisitor: Sized { super::common_visitor_and_walkers!((mut) MutVisitor); -/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful -/// when using a `flat_map_*` or `filter_map_*` method within a `visit_` -/// method. -// -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_clobber<T: DummyAstNode>(t: &mut T, f: impl FnOnce(T) -> T) { - let old_t = std::mem::replace(t, T::dummy()); - *t = f(old_t); -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F) where @@ -411,7 +377,6 @@ where } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F) where @@ -422,7 +387,6 @@ where } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F) where @@ -433,30 +397,21 @@ where } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_attrs<T: MutVisitor>(vis: &mut T, attrs: &mut AttrVec) { for attr in attrs.iter_mut() { vis.visit_attribute(attr); } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[allow(unused)] fn visit_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut Vec<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_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 { AttrArgs::Empty => {} @@ -468,7 +423,6 @@ fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) { } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_delim_args<T: MutVisitor>(vis: &mut T, args: &mut DelimArgs) { let DelimArgs { dspan, delim: _, tokens: _ } = args; let DelimSpan { open, close } = dspan; @@ -544,60 +498,8 @@ fn walk_assoc_item_constraint<T: MutVisitor>( vis.visit_span(span); } -pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) { - let Ty { id, kind, span, tokens: _ } = ty.deref_mut(); - vis.visit_id(id); - match kind { - TyKind::Err(_guar) => {} - TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Never | TyKind::CVarArgs => { - } - TyKind::Slice(ty) => vis.visit_ty(ty), - TyKind::Ptr(mt) => vis.visit_mt(mt), - TyKind::Ref(lt, mt) | TyKind::PinnedRef(lt, mt) => { - visit_opt(lt, |lt| vis.visit_lifetime(lt)); - vis.visit_mt(mt); - } - TyKind::BareFn(bft) => { - let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = bft.deref_mut(); - visit_safety(vis, safety); - generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_fn_decl(decl); - vis.visit_span(decl_span); - } - TyKind::UnsafeBinder(binder) => { - let UnsafeBinderTy { generic_params, inner_ty } = binder.deref_mut(); - generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_ty(inner_ty); - } - TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)), - TyKind::Paren(ty) => vis.visit_ty(ty), - TyKind::Pat(ty, pat) => { - vis.visit_ty(ty); - vis.visit_ty_pat(pat); - } - TyKind::Path(qself, path) => { - vis.visit_qself(qself); - vis.visit_path(path); - } - TyKind::Array(ty, length) => { - vis.visit_ty(ty); - vis.visit_anon_const(length); - } - TyKind::Typeof(expr) => vis.visit_anon_const(expr), - TyKind::TraitObject(bounds, _syntax) => { - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::TraitObject)) - } - TyKind::ImplTrait(id, bounds) => { - vis.visit_id(id); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Impl)); - } - TyKind::MacCall(mac) => vis.visit_mac_call(mac), - } - vis.visit_span(span); -} - -pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) { - let TyPat { id, kind, span, tokens: _ } = ty.deref_mut(); +pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut TyPat) { + let TyPat { id, kind, span, tokens: _ } = ty; vis.visit_id(id); match kind { TyPatKind::Range(start, end, _include_end) => { @@ -610,12 +512,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); @@ -639,13 +535,6 @@ fn walk_ident<T: MutVisitor>(vis: &mut T, Ident { name: _, span }: &mut Ident) { vis.visit_span(span); } -fn walk_path_segment<T: MutVisitor>(vis: &mut T, segment: &mut PathSegment) { - let PathSegment { ident, id, args } = segment; - vis.visit_id(id); - vis.visit_ident(ident); - visit_opt(args, |args| vis.visit_generic_args(args)); -} - fn walk_path<T: MutVisitor>(vis: &mut T, Path { segments, span, tokens: _ }: &mut Path) { for segment in segments { vis.visit_path_segment(segment); @@ -694,8 +583,8 @@ fn walk_parenthesized_parameter_data<T: MutVisitor>(vis: &mut T, args: &mut Pare vis.visit_span(inputs_span); } -fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut P<Local>) { - let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local.deref_mut(); +fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut Local) { + let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local; visit_opt(super_, |sp| vis.visit_span(sp)); vis.visit_id(id); visit_attrs(vis, attrs); @@ -771,22 +660,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 => {} @@ -796,18 +669,6 @@ fn walk_closure_binder<T: MutVisitor>(vis: &mut T, binder: &mut ClosureBinder) { } } -fn walk_coroutine_kind<T: MutVisitor>(vis: &mut T, coroutine_kind: &mut CoroutineKind) { - match coroutine_kind { - CoroutineKind::Async { span, closure_id, return_impl_trait_id } - | CoroutineKind::Gen { span, closure_id, return_impl_trait_id } - | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => { - vis.visit_id(closure_id); - vis.visit_id(return_impl_trait_id); - vis.visit_span(span); - } - } -} - fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) { match kind { FnKind::Fn( @@ -848,8 +709,8 @@ fn walk_fn<T: MutVisitor>(vis: &mut T, kind: FnKind<'_>) { } } -fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut P<FnContract>) { - let FnContract { requires, ensures } = contract.deref_mut(); +fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut FnContract) { + let FnContract { requires, ensures } = contract; if let Some(pred) = requires { vis.visit_expr(pred); } @@ -858,8 +719,8 @@ fn walk_contract<T: MutVisitor>(vis: &mut T, contract: &mut P<FnContract>) { } } -fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut P<FnDecl>) { - let FnDecl { inputs, output } = decl.deref_mut(); +fn walk_fn_decl<T: MutVisitor>(vis: &mut T, decl: &mut FnDecl) { + let FnDecl { inputs, output } = decl; inputs.flat_map_in_place(|param| vis.flat_map_param(param)); vis.visit_fn_ret_ty(output); } @@ -1058,17 +919,6 @@ pub fn walk_flat_map_expr_field<T: MutVisitor>( smallvec![f] } -fn walk_mt<T: MutVisitor>(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) { - vis.visit_ty(ty); -} - -pub fn walk_block<T: MutVisitor>(vis: &mut T, block: &mut P<Block>) { - let Block { id, stmts, rules: _, span, tokens: _ } = block.deref_mut(); - vis.visit_id(id); - stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); - vis.visit_span(span); -} - pub fn walk_item_kind<K: WalkItemKind>( kind: &mut K, span: Span, @@ -1080,242 +930,6 @@ 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( - &mut self, - span: Span, - id: NodeId, - visibility: &mut Visibility, - ctxt: Self::Ctxt, - visitor: &mut impl MutVisitor, - ) { - match self { - AssocItemKind::Const(item) => { - walk_const_item(visitor, item); - } - AssocItemKind::Fn(func) => { - visitor.visit_fn(FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &mut *func), span, id); - } - AssocItemKind::Type(box TyAlias { - defaultness, - ident, - generics, - where_clauses, - bounds, - ty, - }) => { - visit_defaultness(visitor, defaultness); - visitor.visit_ident(ident); - visitor.visit_generics(generics); - visit_bounds(visitor, bounds, BoundKind::Bound); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - walk_ty_alias_where_clauses(visitor, where_clauses); - } - AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), - AssocItemKind::Delegation(box Delegation { - id, - qself, - path, - ident, - rename, - body, - from_glob: _, - }) => { - visitor.visit_id(id); - visitor.visit_qself(qself); - visitor.visit_path(path); - visitor.visit_ident(ident); - if let Some(rename) = rename { - visitor.visit_ident(rename); - } - if let Some(body) = body { - visitor.visit_block(body); - } - } - AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { - visitor.visit_qself(qself); - visitor.visit_path(prefix); - if let Some(suffixes) = suffixes { - 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); - } - } - } - } -} - -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); @@ -1326,27 +940,6 @@ pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) { vis.visit_span(inject_use_span); } -pub fn walk_item(visitor: &mut impl MutVisitor, item: &mut P<Item<impl WalkItemKind<Ctxt = ()>>>) { - walk_item_ctxt(visitor, item, ()) -} - -pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P<AssocItem>, ctxt: AssocCtxt) { - 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] @@ -1369,104 +962,6 @@ pub fn walk_flat_map_assoc_item( smallvec![item] } -impl WalkItemKind for ForeignItemKind { - type Ctxt = (); - fn walk( - &mut self, - span: Span, - id: NodeId, - visibility: &mut Visibility, - _ctxt: Self::Ctxt, - visitor: &mut impl MutVisitor, - ) { - match self { - ForeignItemKind::Static(box StaticItem { - ident, - ty, - mutability: _, - expr, - safety: _, - define_opaque, - }) => { - visitor.visit_ident(ident); - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); - walk_define_opaques(visitor, define_opaque); - } - ForeignItemKind::Fn(func) => { - visitor.visit_fn(FnKind::Fn(FnCtxt::Foreign, visibility, &mut *func), span, id); - } - ForeignItemKind::TyAlias(box TyAlias { - defaultness, - ident, - generics, - where_clauses, - bounds, - ty, - }) => { - visit_defaultness(visitor, defaultness); - visitor.visit_ident(ident); - visitor.visit_generics(generics); - visit_bounds(visitor, bounds, BoundKind::Bound); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - walk_ty_alias_where_clauses(visitor, where_clauses); - } - ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), - } - } -} - -pub fn walk_pat<T: MutVisitor>(vis: &mut T, pat: &mut P<Pat>) { - let Pat { id, kind, span, tokens: _ } = pat.deref_mut(); - vis.visit_id(id); - match kind { - PatKind::Err(_guar) => {} - PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {} - PatKind::Ident(_binding_mode, ident, sub) => { - vis.visit_ident(ident); - visit_opt(sub, |sub| vis.visit_pat(sub)); - } - PatKind::Expr(e) => vis.visit_expr(e), - PatKind::TupleStruct(qself, path, elems) => { - vis.visit_qself(qself); - vis.visit_path(path); - visit_thin_vec(elems, |elem| vis.visit_pat(elem)); - } - PatKind::Path(qself, path) => { - vis.visit_qself(qself); - vis.visit_path(path); - } - PatKind::Struct(qself, path, fields, _etc) => { - vis.visit_qself(qself); - vis.visit_path(path); - fields.flat_map_in_place(|field| vis.flat_map_pat_field(field)); - } - PatKind::Box(inner) => vis.visit_pat(inner), - PatKind::Deref(inner) => vis.visit_pat(inner), - PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner), - PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => { - visit_opt(e1, |e| vis.visit_expr(e)); - visit_opt(e2, |e| vis.visit_expr(e)); - vis.visit_span(span); - } - PatKind::Guard(p, e) => { - vis.visit_pat(p); - vis.visit_expr(e); - } - PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { - visit_thin_vec(elems, |elem| vis.visit_pat(elem)) - } - PatKind::Paren(inner) => vis.visit_pat(inner), - PatKind::MacCall(mac) => vis.visit_mac_call(mac), - } - vis.visit_span(span); -} - -fn walk_anon_const<T: MutVisitor>(vis: &mut T, AnonConst { id, value }: &mut AnonConst) { - vis.visit_id(id); - vis.visit_expr(value); -} - fn walk_inline_asm<T: MutVisitor>(vis: &mut T, asm: &mut InlineAsm) { // FIXME: Visit spans inside all this currently ignored stuff. let InlineAsm { @@ -1716,11 +1211,9 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token vis.visit_span(span); } -pub fn noop_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> { - Some({ - vis.visit_expr(&mut e); - e - }) +pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> { + vis.visit_expr(&mut e); + Some(e) } pub fn walk_flat_map_stmt<T: MutVisitor>( @@ -1786,113 +1279,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 -/// case where its closure panics. -pub trait DummyAstNode { - fn dummy() -> Self; -} - -impl<T> DummyAstNode for Option<T> { - fn dummy() -> Self { - Default::default() - } -} - -impl<T: DummyAstNode + 'static> DummyAstNode for P<T> { - fn dummy() -> Self { - P(DummyAstNode::dummy()) - } -} - -impl DummyAstNode for Item { - fn dummy() -> Self { - Item { - attrs: Default::default(), - id: DUMMY_NODE_ID, - span: Default::default(), - vis: Visibility { - kind: VisibilityKind::Public, - span: Default::default(), - tokens: Default::default(), - }, - kind: ItemKind::ExternCrate(None, Ident::dummy()), - tokens: Default::default(), - } - } -} - -impl DummyAstNode for Expr { - fn dummy() -> Self { - Expr { - id: DUMMY_NODE_ID, - kind: ExprKind::Dummy, - span: Default::default(), - attrs: Default::default(), - tokens: Default::default(), - } - } -} - -impl DummyAstNode for Ty { - fn dummy() -> Self { - Ty { - id: DUMMY_NODE_ID, - kind: TyKind::Dummy, - span: Default::default(), - tokens: Default::default(), - } - } -} - -impl DummyAstNode for Pat { - fn dummy() -> Self { - Pat { - id: DUMMY_NODE_ID, - kind: PatKind::Wild, - span: Default::default(), - tokens: Default::default(), - } - } -} - -impl DummyAstNode for Stmt { - fn dummy() -> Self { - Stmt { id: DUMMY_NODE_ID, kind: StmtKind::Empty, span: Default::default() } - } -} - -impl DummyAstNode for Crate { - fn dummy() -> Self { - Crate { - attrs: Default::default(), - items: Default::default(), - spans: Default::default(), - id: DUMMY_NODE_ID, - is_placeholder: Default::default(), - } - } -} - -impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNodeWrapper<N, T> { - fn dummy() -> Self { - crate::ast_traits::AstNodeWrapper::new(N::dummy(), T::dummy()) - } -} - #[derive(Debug)] pub enum FnKind<'a> { /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index e43d7ae065d..908d9fd4bda 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -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) } @@ -219,7 +210,7 @@ pub trait Visitor<'ast>: Sized { walk_poly_trait_ref(self, t) } fn visit_variant_data(&mut self, s: &'ast VariantData) -> Self::Result { - walk_struct_def(self, s) + walk_variant_data(self, s) } fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result { walk_field_def(self, s) @@ -242,10 +233,13 @@ 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_id(&mut self, _id: NodeId) -> Self::Result { Self::Result::output() } - fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result { + fn visit_macro_def(&mut self, _mac: &'ast MacroDef) -> Self::Result { + Self::Result::output() + } + fn visit_path(&mut self, path: &'ast Path) -> Self::Result { walk_path(self, path) } fn visit_use_tree( @@ -304,8 +298,8 @@ pub trait Visitor<'ast>: Sized { fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result { Self::Result::output() } - fn visit_coroutine_kind(&mut self, _coroutine_kind: &'ast CoroutineKind) -> Self::Result { - Self::Result::output() + fn visit_coroutine_kind(&mut self, coroutine_kind: &'ast CoroutineKind) -> Self::Result { + walk_coroutine_kind(self, coroutine_kind) } fn visit_fn_decl(&mut self, fn_decl: &'ast FnDecl) -> Self::Result { walk_fn_decl(self, fn_decl) @@ -318,6 +312,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,23 +331,20 @@ 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())? } - // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier + /// helper since `Visitor` wants `NodeId` but `MutVisitor` wants `&mut NodeId` $(${ignore($lt)} - #[expect(unused, rustc::pass_by_value)] - #[inline] + #[expect(rustc::pass_by_value)] )? + #[inline] fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, id: &$($lt)? $($mut)? NodeId) $(-> <V as Visitor<$lt>>::Result)? { - $( - let _ = stringify!($mut); - visitor.visit_id(id); - )? - $(${ignore($lt)}V::Result::output())? + // deref `&NodeId` into `NodeId` only for `Visitor` + visitor.visit_id( $(${ignore($lt)} * )? id) } // this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier @@ -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) } @@ -369,9 +393,7 @@ macro_rules! common_visitor_and_walkers { pub fn walk_fn_header<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, header: &$($lt)? $($mut)? FnHeader) $(-> <V as Visitor<$lt>>::Result)? { let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; try_visit!(visit_constness(visitor, constness)); - if let Some(coroutine_kind) = coroutine_kind { - try_visit!(visitor.visit_coroutine_kind(coroutine_kind)); - } + visit_opt!(visitor, visit_coroutine_kind, coroutine_kind); visit_safety(visitor, safety) } @@ -379,6 +401,560 @@ 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)? $($lt)? Item<K>, + ctxt: K::Ctxt, + ) $(-> <V as Visitor<$lt>>::Result)? { + let Item { attrs, id, kind, vis, span, tokens: _ } = 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) + } + + pub fn walk_item<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind<Ctxt = ()>>( + visitor: &mut V, + item: &$($mut)? $($lt)? Item<K>, + ) $(-> <V as Visitor<$lt>>::Result)? { + walk_item_ctxt(visitor, item, ()) + } + + pub fn walk_assoc_item<$($lt,)? V: $Visitor$(<$lt>)?>( + visitor: &mut V, + item: &$($mut)? $($lt)? AssocItem, + ctxt: AssocCtxt, + ) $(-> <V as Visitor<$lt>>::Result)? { + walk_item_ctxt(visitor, item, ctxt) + } + + 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, generics, enum_definition) => { + 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, generics, variant_data) + | ItemKind::Union(ident, generics, variant_data) => { + 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)); + vis.visit_macro_def(def) + } + 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)); + try_visit!(vis.visit_ident(ident)); + visit_opt!(vis, visit_ident, rename); + visit_opt!(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)); + if let Some(suffixes) = suffixes { + for (ident, rename) in suffixes { + try_visit!(vis.visit_ident(ident)); + visit_opt!(vis, visit_ident, rename); + } + } + visit_opt!(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)); + try_visit!(visitor.visit_path(path)); + } + } + $(<V as Visitor<$lt>>::Result::output())? + } + + impl WalkItemKind for AssocItemKind { + type Ctxt = AssocCtxt; + 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 { + AssocItemKind::Const(item) => { + walk_const_item(vis, item) + } + AssocItemKind::Fn(func) => { + vis.visit_fn(FnKind::Fn(FnCtxt::Assoc(ctxt), visibility, &$($mut)? *func), span, id) + } + AssocItemKind::Type(box TyAlias { + generics, + ident, + bounds, + ty, + defaultness, + $(${ignore($lt)} #[expect(unused)])? + where_clauses, + }) => { + 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())? + } + AssocItemKind::MacCall(mac) => { + vis.visit_mac_call(mac) + } + AssocItemKind::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)); + try_visit!(vis.visit_ident(ident)); + visit_opt!(vis, visit_ident, rename); + visit_opt!(vis, visit_block, body); + $(<V as Visitor<$lt>>::Result::output())? + } + AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { + try_visit!(vis.visit_qself(qself)); + try_visit!(vis.visit_path(prefix)); + if let Some(suffixes) = suffixes { + for (ident, rename) in suffixes { + try_visit!(vis.visit_ident(ident)); + visit_opt!(vis, visit_ident, rename); + } + } + visit_opt!(vis, visit_block, body); + $(<V as Visitor<$lt>>::Result::output())? + } + } + } + } + + impl WalkItemKind for ForeignItemKind { + 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 { + ForeignItemKind::Static(box StaticItem { + ident, + ty, + mutability: _, + expr, + safety: _, + 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) + } + ForeignItemKind::Fn(func) => { + vis.visit_fn(FnKind::Fn(FnCtxt::Foreign, visibility, &$($mut)?*func), span, id) + } + ForeignItemKind::TyAlias(box TyAlias { + defaultness, + ident, + generics, + bounds, + ty, + $(${ignore($lt)} #[expect(unused)])? + where_clauses, + }) => { + 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())? + } + ForeignItemKind::MacCall(mac) => { + vis.visit_mac_call(mac) + } + } + } + } + + fn walk_coroutine_kind<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + coroutine_kind: &$($lt)? $($mut)? CoroutineKind, + ) $(-> <V as Visitor<$lt>>::Result)? { + match coroutine_kind { + CoroutineKind::Async { span, closure_id, return_impl_trait_id } + | CoroutineKind::Gen { span, closure_id, return_impl_trait_id } + | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => { + try_visit!(visit_id(vis, closure_id)); + try_visit!(visit_id(vis, return_impl_trait_id)); + visit_span(vis, span) + } + } + } + + pub fn walk_pat<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + pattern: &$($lt)? $($mut)? Pat + ) $(-> <V as Visitor<$lt>>::Result)? { + let Pat { id, kind, span, tokens: _ } = pattern; + try_visit!(visit_id(vis, id)); + match kind { + PatKind::Err(_guar) => {} + PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {} + PatKind::Ident(_bmode, ident, optional_subpattern) => { + try_visit!(vis.visit_ident(ident)); + visit_opt!(vis, visit_pat, optional_subpattern); + } + PatKind::Expr(expression) => try_visit!(vis.visit_expr(expression)), + PatKind::TupleStruct(opt_qself, path, elems) => { + try_visit!(vis.visit_qself(opt_qself)); + try_visit!(vis.visit_path(path)); + walk_list!(vis, visit_pat, elems); + } + PatKind::Path(opt_qself, path) => { + try_visit!(vis.visit_qself(opt_qself)); + try_visit!(vis.visit_path(path)) + } + PatKind::Struct(opt_qself, path, fields, _rest) => { + try_visit!(vis.visit_qself(opt_qself)); + try_visit!(vis.visit_path(path)); + + $( + ${ignore($lt)} + walk_list!(vis, visit_pat_field, fields); + )? + $( + ${ignore($mut)} + fields.flat_map_in_place(|field| vis.flat_map_pat_field(field)); + )? + } + PatKind::Box(subpattern) | PatKind::Deref(subpattern) | PatKind::Paren(subpattern) => { + try_visit!(vis.visit_pat(subpattern)); + } + PatKind::Ref(subpattern, _ /*mutbl*/) => { + try_visit!(vis.visit_pat(subpattern)); + } + PatKind::Range(lower_bound, upper_bound, _end) => { + visit_opt!(vis, visit_expr, lower_bound); + visit_opt!(vis, visit_expr, upper_bound); + try_visit!(visit_span(vis, span)); + } + PatKind::Guard(subpattern, guard_condition) => { + try_visit!(vis.visit_pat(subpattern)); + try_visit!(vis.visit_expr(guard_condition)); + } + PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { + walk_list!(vis, visit_pat, elems); + } + PatKind::MacCall(mac) => try_visit!(vis.visit_mac_call(mac)), + } + visit_span(vis, span) + } + + pub fn walk_anon_const<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + constant: &$($lt)? $($mut)? AnonConst, + ) $(-> <V as Visitor<$lt>>::Result)? { + let AnonConst { id, value } = constant; + try_visit!(visit_id(vis, id)); + vis.visit_expr(value) + } + + pub fn walk_path_segment<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + segment: &$($lt)? $($mut)? PathSegment, + ) $(-> <V as Visitor<$lt>>::Result)? { + let PathSegment { ident, id, args } = segment; + try_visit!(visit_id(vis, id)); + try_visit!(vis.visit_ident(ident)); + visit_opt!(vis, visit_generic_args, args); + $(<V as Visitor<$lt>>::Result::output())? + } + + pub fn walk_block<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + block: &$($lt)? $($mut)? Block + ) $(-> <V as Visitor<$lt>>::Result)? { + let Block { stmts, id, rules: _, span, tokens: _ } = block; + try_visit!(visit_id(vis, id)); + $( + ${ignore($lt)} + walk_list!(vis, visit_stmt, stmts); + )? + $( + ${ignore($mut)} + stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); + )? + visit_span(vis, span) + } + + + pub fn walk_ty<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, ty: &$($lt)? $($mut)? Ty + ) $(-> <V as Visitor<$lt>>::Result)? { + let Ty { id, kind, span, tokens: _ } = ty; + try_visit!(visit_id(vis, id)); + match kind { + TyKind::Err(_guar) => {} + TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Never | TyKind::CVarArgs => {} + TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(vis.visit_ty(ty)), + TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(vis.visit_ty(ty)), + TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) + | TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl: _ }) => { + // FIXME(fee1-dead) asymmetry + visit_opt!(vis, visit_lifetime, opt_lifetime$(${ignore($lt)}, LifetimeCtxt::Ref)?); + try_visit!(vis.visit_ty(ty)); + } + TyKind::Tup(tuple_element_types) => { + walk_list!(vis, visit_ty, tuple_element_types); + } + TyKind::BareFn(function_declaration) => { + let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = + &$($mut)? **function_declaration; + visit_safety(vis, safety); + $( + ${ignore($lt)} + walk_list!(vis, visit_generic_param, generic_params); + )? + $( + ${ignore($mut)} + generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + )? + + try_visit!(vis.visit_fn_decl(decl)); + try_visit!(visit_span(vis, decl_span)); + } + TyKind::UnsafeBinder(binder) => { + $( + ${ignore($lt)} + walk_list!(vis, visit_generic_param, &binder.generic_params); + )? + $( + ${ignore($mut)} + binder.generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + )? + try_visit!(vis.visit_ty(&$($mut)?binder.inner_ty)); + } + TyKind::Path(maybe_qself, path) => { + try_visit!(vis.visit_qself(maybe_qself)); + try_visit!(vis.visit_path(path)); + } + TyKind::Pat(ty, pat) => { + try_visit!(vis.visit_ty(ty)); + try_visit!(vis.visit_ty_pat(pat)); + } + TyKind::Array(ty, length) => { + try_visit!(vis.visit_ty(ty)); + try_visit!(vis.visit_anon_const(length)); + } + TyKind::TraitObject(bounds, _syntax) => { + walk_list!(vis, visit_param_bound, bounds, BoundKind::TraitObject); + } + TyKind::ImplTrait(id, bounds) => { + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_param_bound, bounds, BoundKind::Impl); + } + TyKind::Typeof(expression) => try_visit!(vis.visit_anon_const(expression)), + + TyKind::MacCall(mac) => try_visit!(vis.visit_mac_call(mac)), + } + visit_span(vis, span) + } }; } @@ -414,164 +990,8 @@ where pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitRef) -> V::Result { let TraitRef { path, ref_id } = trait_ref; - 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() - } + try_visit!(visitor.visit_path(path)); + visitor.visit_id(*ref_id) } pub fn walk_enum_def<'a, V: Visitor<'a>>( @@ -611,56 +1031,6 @@ pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result::output() } -pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { - let Ty { id, kind, span: _, tokens: _ } = typ; - match kind { - TyKind::Slice(ty) | TyKind::Paren(ty) => try_visit!(visitor.visit_ty(ty)), - TyKind::Ptr(MutTy { ty, mutbl: _ }) => try_visit!(visitor.visit_ty(ty)), - TyKind::Ref(opt_lifetime, MutTy { ty, mutbl: _ }) - | TyKind::PinnedRef(opt_lifetime, MutTy { ty, mutbl: _ }) => { - visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref); - try_visit!(visitor.visit_ty(ty)); - } - TyKind::Tup(tuple_element_types) => { - walk_list!(visitor, visit_ty, tuple_element_types); - } - TyKind::BareFn(function_declaration) => { - let BareFnTy { safety: _, ext: _, generic_params, decl, decl_span: _ } = - &**function_declaration; - walk_list!(visitor, visit_generic_param, generic_params); - try_visit!(visitor.visit_fn_decl(decl)); - } - TyKind::UnsafeBinder(binder) => { - walk_list!(visitor, visit_generic_param, &binder.generic_params); - try_visit!(visitor.visit_ty(&binder.inner_ty)); - } - TyKind::Path(maybe_qself, path) => { - try_visit!(visitor.visit_qself(maybe_qself)); - try_visit!(visitor.visit_path(path, *id)); - } - TyKind::Pat(ty, pat) => { - try_visit!(visitor.visit_ty(ty)); - try_visit!(visitor.visit_ty_pat(pat)); - } - TyKind::Array(ty, length) => { - try_visit!(visitor.visit_ty(ty)); - try_visit!(visitor.visit_anon_const(length)); - } - TyKind::TraitObject(bounds, _syntax) => { - walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject); - } - TyKind::ImplTrait(_id, bounds) => { - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); - } - TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)), - TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy => {} - TyKind::Err(_guar) => {} - TyKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - TyKind::Never | TyKind::CVarArgs => {} - } - V::Result::output() -} - pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result { let TyPat { id: _, kind, span: _, tokens: _ } = tp; match kind { @@ -694,7 +1064,8 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>( id: NodeId, ) -> V::Result { let UseTree { prefix, kind, span: _ } = use_tree; - try_visit!(visitor.visit_path(prefix, id)); + try_visit!(visitor.visit_id(id)); + try_visit!(visitor.visit_path(prefix)); match kind { UseTreeKind::Simple(rename) => { // The extra IDs are handled during AST lowering. @@ -710,16 +1081,6 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>( V::Result::output() } -pub fn walk_path_segment<'a, V: Visitor<'a>>( - visitor: &mut V, - segment: &'a PathSegment, -) -> V::Result { - let PathSegment { ident, id: _, args } = segment; - try_visit!(visitor.visit_ident(ident)); - visit_opt!(visitor, visit_generic_args, args); - V::Result::output() -} - pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) -> V::Result where V: Visitor<'a>, @@ -775,101 +1136,6 @@ pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( V::Result::output() } -pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) -> V::Result { - let Pat { id, kind, span: _, tokens: _ } = pattern; - match kind { - PatKind::TupleStruct(opt_qself, path, elems) => { - try_visit!(visitor.visit_qself(opt_qself)); - try_visit!(visitor.visit_path(path, *id)); - walk_list!(visitor, visit_pat, elems); - } - PatKind::Path(opt_qself, path) => { - try_visit!(visitor.visit_qself(opt_qself)); - try_visit!(visitor.visit_path(path, *id)) - } - PatKind::Struct(opt_qself, path, fields, _rest) => { - try_visit!(visitor.visit_qself(opt_qself)); - try_visit!(visitor.visit_path(path, *id)); - walk_list!(visitor, visit_pat_field, fields); - } - PatKind::Box(subpattern) | PatKind::Deref(subpattern) | PatKind::Paren(subpattern) => { - try_visit!(visitor.visit_pat(subpattern)); - } - PatKind::Ref(subpattern, _ /*mutbl*/) => { - try_visit!(visitor.visit_pat(subpattern)); - } - PatKind::Ident(_bmode, ident, optional_subpattern) => { - try_visit!(visitor.visit_ident(ident)); - visit_opt!(visitor, visit_pat, optional_subpattern); - } - PatKind::Expr(expression) => try_visit!(visitor.visit_expr(expression)), - PatKind::Range(lower_bound, upper_bound, _end) => { - visit_opt!(visitor, visit_expr, lower_bound); - visit_opt!(visitor, visit_expr, upper_bound); - } - PatKind::Guard(subpattern, guard_condition) => { - try_visit!(visitor.visit_pat(subpattern)); - try_visit!(visitor.visit_expr(guard_condition)); - } - PatKind::Missing | PatKind::Wild | PatKind::Rest | PatKind::Never => {} - PatKind::Err(_guar) => {} - PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { - walk_list!(visitor, visit_pat, elems); - } - PatKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - } - V::Result::output() -} - -impl WalkItemKind for ForeignItemKind { - 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 { - ForeignItemKind::Static(box StaticItem { - ident, - ty, - mutability: _, - expr, - safety: _, - 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)); - } - ForeignItemKind::Fn(func) => { - let kind = FnKind::Fn(FnCtxt::Foreign, vis, &*func); - try_visit!(visitor.visit_fn(kind, span, id)); - } - ForeignItemKind::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); - } - ForeignItemKind::MacCall(mac) => { - try_visit!(visitor.visit_mac_call(mac)); - } - } - V::Result::output() - } -} - pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) -> V::Result { match bound { GenericBound::Trait(trait_ref) => visitor.visit_poly_trait_ref(trait_ref), @@ -887,7 +1153,10 @@ pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( ) -> V::Result { match arg { PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg), - PreciseCapturingArg::Arg(path, id) => visitor.visit_path(path, *id), + PreciseCapturingArg::Arg(path, id) => { + try_visit!(visitor.visit_id(*id)); + visitor.visit_path(path) + } } } @@ -1028,116 +1297,9 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Resu V::Result::output() } -impl WalkItemKind for AssocItemKind { - type Ctxt = AssocCtxt; - 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 { - AssocItemKind::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)); - } - AssocItemKind::Fn(func) => { - let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), vis, &*func); - try_visit!(visitor.visit_fn(kind, span, id)); - } - AssocItemKind::Type(box TyAlias { - generics, - ident, - bounds, - ty, - defaultness: _, - where_clauses: _, - }) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ident(ident)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - } - AssocItemKind::MacCall(mac) => { - try_visit!(visitor.visit_mac_call(mac)); - } - AssocItemKind::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); - } - AssocItemKind::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_item<'a, V: Visitor<'a>>( - visitor: &mut V, - item: &'a Item<impl WalkItemKind<Ctxt = ()>>, -) -> V::Result { - walk_item_ctxt(visitor, item, ()) -} - -pub fn walk_assoc_item<'a, V: Visitor<'a>>( - visitor: &mut V, - item: &'a AssocItem, - ctxt: AssocCtxt, -) -> V::Result { - 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, -) -> V::Result { - walk_list!(visitor, visit_field_def, struct_definition.fields()); +pub fn walk_variant_data<'a, V: Visitor<'a>>(visitor: &mut V, data: &'a VariantData) -> V::Result { + visit_opt!(visitor, visit_id, data.ctor_node_id()); + walk_list!(visitor, visit_field_def, data.fields()); V::Result::output() } @@ -1152,12 +1314,6 @@ pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) V::Result::output() } -pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) -> V::Result { - let Block { stmts, id: _, rules: _, span: _, tokens: _ } = block; - walk_list!(visitor, visit_stmt, stmts); - V::Result::output() -} - pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result { let Stmt { id: _, kind, span: _ } = statement; match kind { @@ -1176,12 +1332,7 @@ pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V: pub fn walk_mac<'a, V: Visitor<'a>>(visitor: &mut V, mac: &'a MacCall) -> V::Result { let MacCall { path, args: _ } = mac; - visitor.visit_path(path, DUMMY_NODE_ID) -} - -pub fn walk_anon_const<'a, V: Visitor<'a>>(visitor: &mut V, constant: &'a AnonConst) -> V::Result { - let AnonConst { id: _, value } = constant; - visitor.visit_expr(value) + visitor.visit_path(path) } pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result { @@ -1221,7 +1372,8 @@ pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>( InlineAsmSym { id, qself, path }: &'a InlineAsmSym, ) -> V::Result { try_visit!(visitor.visit_qself(qself)); - visitor.visit_path(path, *id) + try_visit!(visitor.visit_id(*id)); + visitor.visit_path(path) } pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result { @@ -1253,7 +1405,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V ExprKind::Struct(se) => { let StructExpr { qself, path, fields, rest } = &**se; try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_path(path, *id)); + try_visit!(visitor.visit_id(*id)); + try_visit!(visitor.visit_path(path)); walk_list!(visitor, visit_expr_field, fields); match rest { StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)), @@ -1363,7 +1516,8 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V ExprKind::Underscore => {} ExprKind::Path(maybe_qself, path) => { try_visit!(visitor.visit_qself(maybe_qself)); - try_visit!(visitor.visit_path(path, *id)); + try_visit!(visitor.visit_id(*id)); + try_visit!(visitor.visit_path(path)); } ExprKind::Break(opt_label, opt_expr) => { visit_opt!(visitor, visit_label, opt_label); @@ -1426,7 +1580,8 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V:: let Visibility { kind, span: _, tokens: _ } = vis; match kind { VisibilityKind::Restricted { path, id, shorthand: _ } => { - try_visit!(visitor.visit_path(path, *id)); + try_visit!(visitor.visit_id(*id)); + try_visit!(visitor.visit_path(path)); } VisibilityKind::Public | VisibilityKind::Inherited => {} } @@ -1439,7 +1594,7 @@ pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) AttrKind::Normal(normal) => { let NormalAttr { item, tokens: _ } = &**normal; let AttrItem { unsafety: _, path, args, tokens: _ } = item; - try_visit!(visitor.visit_path(path, DUMMY_NODE_ID)); + try_visit!(visitor.visit_path(path)); try_visit!(walk_attr_args(visitor, args)); } AttrKind::DocComment(_kind, _sym) => {} @@ -1455,15 +1610,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() -} |
