From 85e607148ee4de99982b13b9b3861e2a700f6b21 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 15:52:10 -0300 Subject: [PATCH 01/82] Merge visit and mut_visit in a single file --- compiler/rustc_ast/src/lib.rs | 4 +- compiler/rustc_ast/src/mut_visit.rs | 1792 --------------- compiler/rustc_ast/src/visit.rs | 1243 ----------- compiler/rustc_ast/src/visitors.rs | 3118 +++++++++++++++++++++++++++ 4 files changed, 3120 insertions(+), 3037 deletions(-) delete mode 100644 compiler/rustc_ast/src/mut_visit.rs delete mode 100644 compiler/rustc_ast/src/visit.rs create mode 100644 compiler/rustc_ast/src/visitors.rs diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index 7730d0b4b78df..b5c05e09abd1f 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -37,17 +37,17 @@ pub mod attr; pub mod entry; pub mod expand; pub mod format; -pub mod mut_visit; pub mod node_id; pub mod ptr; pub mod token; pub mod tokenstream; -pub mod visit; +pub mod visitors; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; pub use self::ast::*; pub use self::ast_traits::{AstDeref, AstNodeWrapper, HasAttrs, HasNodeId, HasTokens}; +pub use self::visitors::{mut_visit, visit}; /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs deleted file mode 100644 index 2afbd979c3023..0000000000000 --- a/compiler/rustc_ast/src/mut_visit.rs +++ /dev/null @@ -1,1792 +0,0 @@ -//! A `MutVisitor` represents an AST modification; it accepts an AST piece and -//! mutates it in place. So, for instance, macro expansion is a `MutVisitor` -//! that walks over an AST and modifies it. -//! -//! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on -//! an AST before macro expansion is probably a bad idea. For instance, -//! a `MutVisitor` renaming item names in a module will miss all of those -//! that are created by the expansion of a macro. - -use std::ops::DerefMut; -use std::panic; - -use rustc_data_structures::flat_map_in_place::FlatMapInPlace; -use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_data_structures::sync::Lrc; -use rustc_span::Span; -use rustc_span::source_map::Spanned; -use rustc_span::symbol::Ident; -use smallvec::{Array, SmallVec, smallvec}; -use thin_vec::ThinVec; - -use crate::ast::*; -use crate::ptr::P; -use crate::token::{self, Token}; -use crate::tokenstream::*; -use crate::visit::{AssocCtxt, BoundKind}; - -pub trait ExpectOne { - fn expect_one(self, err: &'static str) -> A::Item; -} - -impl ExpectOne for SmallVec { - fn expect_one(self, err: &'static str) -> A::Item { - assert!(self.len() == 1, "{}", err); - self.into_iter().next().unwrap() - } -} - -pub trait WalkItemKind { - fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor); -} - -pub trait MutVisitor: Sized { - /// Mutable token visiting only exists for the `macro_rules` token marker and should not be - /// used otherwise. Token visitor would be entirely separate from the regular visitor if - /// the marker didn't have to visit AST fragments in nonterminal tokens. - const VISIT_TOKENS: bool = false; - - // Methods in this trait have one of three forms: - // - // fn visit_t(&mut self, t: &mut T); // common - // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare - // fn filter_map_t(&mut self, t: T) -> Option; // 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) { - // visit_a(a); - // visit_b(b); - // } - // - // than to use field access like this: - // - // fn visit_abc(&mut self, abc: &mut ABC) { - // visit_a(&mut abc.a); - // visit_b(&mut abc.b); - // // ignore abc.c - // } - // - // As well as being more concise, the former is explicit about which fields - // are skipped. Furthermore, if a new field is added, the destructuring - // version will cause a compile error, which is good. In comparison, the - // field access version will continue working and it would be easy to - // forget to add handling for it. - - fn visit_crate(&mut self, c: &mut Crate) { - walk_crate(self, c) - } - - fn visit_meta_list_item(&mut self, list_item: &mut MetaItemInner) { - walk_meta_list_item(self, list_item); - } - - fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { - walk_meta_item(self, meta_item); - } - - fn visit_use_tree(&mut self, use_tree: &mut UseTree) { - walk_use_tree(self, use_tree); - } - - fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, ni) - } - - fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, i) - } - - fn visit_fn_header(&mut self, header: &mut FnHeader) { - walk_fn_header(self, header); - } - - fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { - walk_flat_map_field_def(self, fd) - } - - fn flat_map_assoc_item( - &mut self, - i: P, - _ctxt: AssocCtxt, - ) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, i) - } - - fn visit_fn_decl(&mut self, d: &mut P) { - walk_fn_decl(self, d); - } - - /// `Span` and `NodeId` are mutated at the caller site. - fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) { - walk_fn(self, fk) - } - - fn visit_coroutine_kind(&mut self, a: &mut CoroutineKind) { - walk_coroutine_kind(self, a); - } - - fn visit_closure_binder(&mut self, b: &mut ClosureBinder) { - walk_closure_binder(self, b); - } - - fn visit_block(&mut self, b: &mut P) { - walk_block(self, b); - } - - fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { - walk_flat_map_stmt(self, s) - } - - fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { - walk_flat_map_arm(self, arm) - } - - fn visit_pat(&mut self, p: &mut P) { - walk_pat(self, p); - } - - fn visit_anon_const(&mut self, c: &mut AnonConst) { - walk_anon_const(self, c); - } - - fn visit_expr(&mut self, e: &mut P) { - walk_expr(self, e); - } - - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. - /// It can be removed once that feature is stabilized. - fn visit_method_receiver_expr(&mut self, ex: &mut P) { - self.visit_expr(ex) - } - - fn filter_map_expr(&mut self, e: P) -> Option> { - noop_filter_map_expr(self, e) - } - - fn visit_generic_arg(&mut self, arg: &mut GenericArg) { - walk_generic_arg(self, arg); - } - - fn visit_ty(&mut self, t: &mut P) { - walk_ty(self, t); - } - - fn visit_lifetime(&mut self, l: &mut Lifetime) { - walk_lifetime(self, l); - } - - fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) { - walk_assoc_item_constraint(self, c); - } - - fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { - walk_foreign_mod(self, nm); - } - - fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { - walk_flat_map_variant(self, v) - } - - fn visit_ident(&mut self, i: &mut Ident) { - walk_ident(self, i); - } - - fn visit_path(&mut self, p: &mut Path) { - walk_path(self, p); - } - - fn visit_path_segment(&mut self, p: &mut PathSegment) { - walk_path_segment(self, p) - } - - fn visit_qself(&mut self, qs: &mut Option>) { - walk_qself(self, qs); - } - - fn visit_generic_args(&mut self, p: &mut GenericArgs) { - walk_generic_args(self, p); - } - - fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { - walk_angle_bracketed_parameter_data(self, p); - } - - fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { - walk_parenthesized_parameter_data(self, p); - } - - fn visit_local(&mut self, l: &mut P) { - walk_local(self, l); - } - - fn visit_mac_call(&mut self, mac: &mut MacCall) { - walk_mac(self, mac); - } - - fn visit_macro_def(&mut self, def: &mut MacroDef) { - walk_macro_def(self, def); - } - - fn visit_label(&mut self, label: &mut Label) { - walk_label(self, label); - } - - fn visit_attribute(&mut self, at: &mut Attribute) { - walk_attribute(self, at); - } - - fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { - walk_flat_map_param(self, param) - } - - fn visit_generics(&mut self, generics: &mut Generics) { - walk_generics(self, generics); - } - - fn visit_trait_ref(&mut self, tr: &mut TraitRef) { - walk_trait_ref(self, tr); - } - - fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { - walk_poly_trait_ref(self, p); - } - - fn visit_variant_data(&mut self, vdata: &mut VariantData) { - walk_variant_data(self, vdata); - } - - fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { - walk_flat_map_generic_param(self, param) - } - - fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) { - walk_param_bound(self, tpb); - } - - fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { - walk_precise_capturing_arg(self, arg); - } - - fn visit_mt(&mut self, mt: &mut MutTy) { - walk_mt(self, mt); - } - - fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { - walk_flat_map_expr_field(self, f) - } - - fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { - walk_where_clause(self, where_clause); - } - - fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { - walk_where_predicate(self, where_predicate); - } - - fn visit_vis(&mut self, vis: &mut Visibility) { - walk_vis(self, vis); - } - - fn visit_id(&mut self, _id: &mut NodeId) { - // Do nothing. - } - - fn visit_span(&mut self, _sp: &mut Span) { - // Do nothing. - } - - fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { - walk_flat_map_pat_field(self, fp) - } - - fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { - walk_inline_asm(self, asm) - } - - fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) { - walk_inline_asm_sym(self, sym) - } - - fn visit_format_args(&mut self, fmt: &mut FormatArgs) { - walk_format_args(self, fmt) - } - - fn visit_capture_by(&mut self, capture_by: &mut CaptureBy) { - walk_capture_by(self, capture_by) - } -} - -/// 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: &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(elems: &mut Vec, mut visit_elem: F) -where - F: FnMut(&mut T), -{ - for elem in elems { - visit_elem(elem); - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -#[inline] -fn visit_thin_vec(elems: &mut ThinVec, mut visit_elem: F) -where - F: FnMut(&mut T), -{ - for elem in elems { - visit_elem(elem); - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -#[inline] -fn visit_opt(opt: &mut Option, mut visit_elem: F) -where - F: FnMut(&mut T), -{ - if let Some(elem) = opt { - visit_elem(elem); - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_attrs(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(vis: &mut T, exprs: &mut Vec>) { - 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(vis: &mut T, exprs: &mut ThinVec>) { - 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(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(vis: &mut T, args: &mut AttrArgs) { - match args { - AttrArgs::Empty => {} - AttrArgs::Delimited(args) => visit_delim_args(vis, args), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { - vis.visit_expr(expr); - vis.visit_span(eq_span); - } - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when visiting mac args eq: {:?}", lit) - } - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_delim_args(vis: &mut T, args: &mut DelimArgs) { - let DelimArgs { dspan, delim: _, tokens } = args; - visit_tts(vis, tokens); - visit_delim_span(vis, dspan); -} - -pub fn visit_delim_span(vis: &mut T, DelimSpan { open, close }: &mut DelimSpan) { - vis.visit_span(open); - vis.visit_span(close); -} - -pub fn walk_flat_map_pat_field( - vis: &mut T, - mut fp: PatField, -) -> SmallVec<[PatField; 1]> { - let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - vis.visit_pat(pat); - vis.visit_span(span); - smallvec![fp] -} - -fn walk_use_tree(vis: &mut T, use_tree: &mut UseTree) { - let UseTree { prefix, kind, span } = use_tree; - vis.visit_path(prefix); - match kind { - UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)), - UseTreeKind::Nested { items, span } => { - for (tree, id) in items { - vis.visit_id(id); - vis.visit_use_tree(tree); - } - vis.visit_span(span); - } - UseTreeKind::Glob => {} - } - vis.visit_span(span); -} - -pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { - let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - visit_opt(guard, |guard| vis.visit_expr(guard)); - visit_opt(body, |body| vis.visit_expr(body)); - vis.visit_span(span); - smallvec![arm] -} - -fn walk_assoc_item_constraint( - vis: &mut T, - AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint, -) { - vis.visit_id(id); - vis.visit_ident(ident); - if let Some(gen_args) = gen_args { - vis.visit_generic_args(gen_args); - } - match kind { - AssocItemConstraintKind::Equality { term } => match term { - Term::Ty(ty) => vis.visit_ty(ty), - Term::Const(c) => vis.visit_anon_const(c), - }, - AssocItemConstraintKind::Bound { bounds } => visit_bounds(vis, bounds, BoundKind::Bound), - } - vis.visit_span(span); -} - -pub fn walk_ty(vis: &mut T, ty: &mut P) { - 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::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_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), - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); -} - -fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { - let ForeignMod { safety, abi: _, items } = foreign_mod; - visit_safety(vis, safety); - items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); -} - -pub fn walk_flat_map_variant( - visitor: &mut T, - mut variant: Variant, -) -> SmallVec<[Variant; 1]> { - let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant; - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visitor.visit_ident(ident); - visitor.visit_variant_data(data); - visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); - visitor.visit_span(span); - smallvec![variant] -} - -fn walk_ident(vis: &mut T, Ident { name: _, span }: &mut Ident) { - vis.visit_span(span); -} - -fn walk_path_segment(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(vis: &mut T, Path { segments, span, tokens }: &mut Path) { - for segment in segments { - vis.visit_path_segment(segment); - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); -} - -fn walk_qself(vis: &mut T, qself: &mut Option>) { - visit_opt(qself, |qself| { - let QSelf { ty, path_span, position: _ } = &mut **qself; - vis.visit_ty(ty); - vis.visit_span(path_span); - }) -} - -fn walk_generic_args(vis: &mut T, generic_args: &mut GenericArgs) { - match generic_args { - GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), - GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), - GenericArgs::ParenthesizedElided(span) => vis.visit_span(span), - } -} - -fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { - match arg { - GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), - GenericArg::Type(ty) => vis.visit_ty(ty), - GenericArg::Const(ct) => vis.visit_anon_const(ct), - } -} - -fn walk_angle_bracketed_parameter_data(vis: &mut T, data: &mut AngleBracketedArgs) { - let AngleBracketedArgs { args, span } = data; - visit_thin_vec(args, |arg| match arg { - AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), - AngleBracketedArg::Constraint(constraint) => vis.visit_assoc_item_constraint(constraint), - }); - vis.visit_span(span); -} - -fn walk_parenthesized_parameter_data(vis: &mut T, args: &mut ParenthesizedArgs) { - let ParenthesizedArgs { inputs, output, span, inputs_span } = args; - visit_thin_vec(inputs, |input| vis.visit_ty(input)); - walk_fn_ret_ty(vis, output); - vis.visit_span(span); - vis.visit_span(inputs_span); -} - -fn walk_local(vis: &mut T, local: &mut P) { - let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut(); - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - visit_opt(ty, |ty| vis.visit_ty(ty)); - match kind { - LocalKind::Decl => {} - LocalKind::Init(init) => { - vis.visit_expr(init); - } - LocalKind::InitElse(init, els) => { - vis.visit_expr(init); - vis.visit_block(els); - } - } - visit_lazy_tts(vis, tokens); - visit_opt(colon_sp, |sp| vis.visit_span(sp)); - vis.visit_span(span); -} - -fn walk_attribute(vis: &mut T, attr: &mut Attribute) { - let Attribute { kind, id: _, style: _, span } = attr; - match kind { - AttrKind::Normal(normal) => { - let NormalAttr { - item: AttrItem { unsafety: _, path, args, tokens }, - tokens: attr_tokens, - } = &mut **normal; - vis.visit_path(path); - visit_attr_args(vis, args); - visit_lazy_tts(vis, tokens); - visit_lazy_tts(vis, attr_tokens); - } - AttrKind::DocComment(_kind, _sym) => {} - } - vis.visit_span(span); -} - -fn walk_mac(vis: &mut T, mac: &mut MacCall) { - let MacCall { path, args } = mac; - vis.visit_path(path); - visit_delim_args(vis, args); -} - -fn walk_macro_def(vis: &mut T, macro_def: &mut MacroDef) { - let MacroDef { body, macro_rules: _ } = macro_def; - visit_delim_args(vis, body); -} - -fn walk_meta_list_item(vis: &mut T, li: &mut MetaItemInner) { - match li { - MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi), - MetaItemInner::Lit(_lit) => {} - } -} - -fn walk_meta_item(vis: &mut T, mi: &mut MetaItem) { - let MetaItem { unsafety: _, path: _, kind, span } = mi; - match kind { - MetaItemKind::Word => {} - MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)), - MetaItemKind::NameValue(_s) => {} - } - vis.visit_span(span); -} - -pub fn walk_flat_map_param(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> { - let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - vis.visit_ty(ty); - vis.visit_span(span); - smallvec![param] -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_attr_tt(vis: &mut T, tt: &mut AttrTokenTree) { - match tt { - AttrTokenTree::Token(token, _spacing) => { - visit_token(vis, token); - } - AttrTokenTree::Delimited(dspan, _spacing, _delim, tts) => { - visit_attr_tts(vis, tts); - visit_delim_span(vis, dspan); - } - AttrTokenTree::AttrsTarget(AttrsTarget { attrs, tokens }) => { - visit_attrs(vis, attrs); - visit_lazy_tts_opt_mut(vis, Some(tokens)); - } - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_tt(vis: &mut T, tt: &mut TokenTree) { - match tt { - TokenTree::Token(token, _spacing) => { - visit_token(vis, token); - } - TokenTree::Delimited(dspan, _spacing, _delim, tts) => { - visit_tts(vis, tts); - visit_delim_span(vis, dspan); - } - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_tts(vis: &mut T, TokenStream(tts): &mut TokenStream) { - if T::VISIT_TOKENS && !tts.is_empty() { - let tts = Lrc::make_mut(tts); - visit_vec(tts, |tree| visit_tt(vis, tree)); - } -} - -fn visit_attr_tts(vis: &mut T, AttrTokenStream(tts): &mut AttrTokenStream) { - if T::VISIT_TOKENS && !tts.is_empty() { - let tts = Lrc::make_mut(tts); - visit_vec(tts, |tree| visit_attr_tt(vis, tree)); - } -} - -fn visit_lazy_tts_opt_mut(vis: &mut T, lazy_tts: Option<&mut LazyAttrTokenStream>) { - if T::VISIT_TOKENS { - if let Some(lazy_tts) = lazy_tts { - let mut tts = lazy_tts.to_attr_token_stream(); - visit_attr_tts(vis, &mut tts); - *lazy_tts = LazyAttrTokenStream::new(tts); - } - } -} - -fn visit_lazy_tts(vis: &mut T, lazy_tts: &mut Option) { - visit_lazy_tts_opt_mut(vis, lazy_tts.as_mut()); -} - -/// Applies ident visitor if it's an ident; applies other visits to interpolated nodes. -/// In practice the ident part is not actually used by specific visitors right now, -/// but there's a test below checking that it works. -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_token(vis: &mut T, t: &mut Token) { - let Token { kind, span } = t; - match kind { - token::Ident(name, _is_raw) | token::Lifetime(name, _is_raw) => { - let mut ident = Ident::new(*name, *span); - vis.visit_ident(&mut ident); - *name = ident.name; - *span = ident.span; - return; // Avoid visiting the span for the second time. - } - token::NtIdent(ident, _is_raw) => { - vis.visit_ident(ident); - } - token::NtLifetime(ident, _is_raw) => { - vis.visit_ident(ident); - } - token::Interpolated(nt) => { - let nt = Lrc::make_mut(nt); - visit_nonterminal(vis, nt); - } - _ => {} - } - vis.visit_span(span); -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -/// Applies the visitor to elements of interpolated nodes. -// -// N.B., this can occur only when applying a visitor to partially expanded -// code, where parsed pieces have gotten implanted ito *other* macro -// invocations. This is relevant for macro hygiene, but possibly not elsewhere. -// -// One problem here occurs because the types for flat_map_item, flat_map_stmt, -// etc., allow the visitor to return *multiple* items; this is a problem for the -// nodes here, because they insist on having exactly one piece. One solution -// would be to mangle the MutVisitor trait to include one-to-many and -// one-to-one versions of these entry points, but that would probably confuse a -// lot of people and help very few. Instead, I'm just going to put in dynamic -// checks. I think the performance impact of this will be pretty much -// nonexistent. The danger is that someone will apply a `MutVisitor` to a -// partially expanded node, and will be confused by the fact that their -// `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt` -// nodes. Hopefully they'll wind up reading this comment, and doing something -// appropriate. -// -// BTW, design choice: I considered just changing the type of, e.g., `NtItem` to -// contain multiple items, but decided against it when I looked at -// `parse_item_or_view_item` and tried to figure out what I would do with -// multiple items there.... -fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { - match nt { - token::NtItem(item) => visit_clobber(item, |item| { - // This is probably okay, because the only visitors likely to - // peek inside interpolated nodes will be renamings/markings, - // which map single items to single items. - vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item") - }), - token::NtBlock(block) => vis.visit_block(block), - token::NtStmt(stmt) => visit_clobber(stmt, |stmt| { - // See reasoning above. - stmt.map(|stmt| { - vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item") - }) - }), - token::NtPat(pat) => vis.visit_pat(pat), - token::NtExpr(expr) => vis.visit_expr(expr), - token::NtTy(ty) => vis.visit_ty(ty), - token::NtLiteral(expr) => vis.visit_expr(expr), - token::NtMeta(item) => { - let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); - vis.visit_path(path); - visit_attr_args(vis, args); - visit_lazy_tts(vis, tokens); - } - token::NtPath(path) => vis.visit_path(path), - token::NtVis(visib) => vis.visit_vis(visib), - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_defaultness(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_safety(vis: &mut T, safety: &mut Safety) { - match safety { - Safety::Unsafe(span) => vis.visit_span(span), - Safety::Safe(span) => vis.visit_span(span), - Safety::Default => {} - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_polarity(vis: &mut T, polarity: &mut ImplPolarity) { - match polarity { - ImplPolarity::Positive => {} - ImplPolarity::Negative(span) => vis.visit_span(span), - } -} - -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -fn visit_constness(vis: &mut T, constness: &mut Const) { - match constness { - Const::Yes(span) => vis.visit_span(span), - Const::No => {} - } -} - -fn walk_closure_binder(vis: &mut T, binder: &mut ClosureBinder) { - match binder { - ClosureBinder::NotPresent => {} - ClosureBinder::For { span: _, generic_params } => { - generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - } - } -} - -fn walk_coroutine_kind(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(vis: &mut T, kind: FnKind<'_>) { - match kind { - FnKind::Fn(FnSig { header, decl, span }, generics, body) => { - // Identifier and visibility are visited as a part of the item. - vis.visit_fn_header(header); - vis.visit_generics(generics); - vis.visit_fn_decl(decl); - if let Some(body) = body { - vis.visit_block(body); - } - vis.visit_span(span); - } - FnKind::Closure(binder, decl, body) => { - vis.visit_closure_binder(binder); - vis.visit_fn_decl(decl); - vis.visit_expr(body); - } - } -} - -fn walk_fn_decl(vis: &mut T, decl: &mut P) { - let FnDecl { inputs, output } = decl.deref_mut(); - inputs.flat_map_in_place(|param| vis.flat_map_param(param)); - walk_fn_ret_ty(vis, output); -} - -fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { - match fn_ret_ty { - FnRetTy::Default(span) => vis.visit_span(span), - FnRetTy::Ty(ty) => vis.visit_ty(ty), - } -} - -fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { - match pb { - GenericBound::Trait(trait_ref) => vis.visit_poly_trait_ref(trait_ref), - GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime), - GenericBound::Use(args, span) => { - for arg in args { - vis.visit_precise_capturing_arg(arg); - } - vis.visit_span(span); - } - } -} - -fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCapturingArg) { - match arg { - PreciseCapturingArg::Lifetime(lt) => { - vis.visit_lifetime(lt); - } - PreciseCapturingArg::Arg(path, id) => { - vis.visit_id(id); - vis.visit_path(path); - } - } -} - -pub fn walk_flat_map_generic_param( - vis: &mut T, - mut param: GenericParam, -) -> SmallVec<[GenericParam; 1]> { - let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - match kind { - GenericParamKind::Lifetime => {} - GenericParamKind::Type { default } => { - visit_opt(default, |default| vis.visit_ty(default)); - } - GenericParamKind::Const { ty, kw_span: _, default } => { - vis.visit_ty(ty); - visit_opt(default, |default| vis.visit_anon_const(default)); - } - } - if let Some(colon_span) = colon_span { - vis.visit_span(colon_span); - } - smallvec![param] -} - -fn walk_label(vis: &mut T, Label { ident }: &mut Label) { - vis.visit_ident(ident); -} - -fn walk_lifetime(vis: &mut T, Lifetime { id, ident }: &mut Lifetime) { - vis.visit_id(id); - vis.visit_ident(ident); -} - -fn walk_generics(vis: &mut T, generics: &mut Generics) { - let Generics { params, where_clause, span } = generics; - params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_where_clause(where_clause); - vis.visit_span(span); -} - -fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWhereClauses) { - let TyAliasWhereClauses { before, after, split: _ } = tawcs; - let TyAliasWhereClause { has_where_token: _, span: span_before } = before; - let TyAliasWhereClause { has_where_token: _, span: span_after } = after; - vis.visit_span(span_before); - vis.visit_span(span_after); -} - -fn walk_where_clause(vis: &mut T, wc: &mut WhereClause) { - let WhereClause { has_where_token: _, predicates, span } = wc; - visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); - vis.visit_span(span); -} - -fn walk_where_predicate(vis: &mut T, pred: &mut WherePredicate) { - match pred { - WherePredicate::BoundPredicate(bp) => { - let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; - bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_ty(bounded_ty); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - vis.visit_span(span); - } - WherePredicate::RegionPredicate(rp) => { - let WhereRegionPredicate { span, lifetime, bounds } = rp; - vis.visit_lifetime(lifetime); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - vis.visit_span(span); - } - WherePredicate::EqPredicate(ep) => { - let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep; - vis.visit_ty(lhs_ty); - vis.visit_ty(rhs_ty); - vis.visit_span(span); - } - } -} - -fn walk_variant_data(vis: &mut T, vdata: &mut VariantData) { - match vdata { - VariantData::Struct { fields, recovered: _ } => { - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } - VariantData::Tuple(fields, id) => { - vis.visit_id(id); - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } - VariantData::Unit(id) => vis.visit_id(id), - } -} - -fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) { - vis.visit_id(ref_id); - vis.visit_path(path); -} - -fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { - let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span } = p; - bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_trait_ref(trait_ref); - vis.visit_span(span); -} - -pub fn walk_flat_map_field_def( - visitor: &mut T, - mut fd: FieldDef, -) -> SmallVec<[FieldDef; 1]> { - let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visit_opt(ident, |ident| visitor.visit_ident(ident)); - visitor.visit_ty(ty); - visitor.visit_span(span); - smallvec![fd] -} - -pub fn walk_flat_map_expr_field( - vis: &mut T, - mut f: ExprField, -) -> SmallVec<[ExprField; 1]> { - let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - vis.visit_expr(expr); - vis.visit_span(span); - smallvec![f] -} - -fn walk_mt(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) { - vis.visit_ty(ty); -} - -pub fn walk_block(vis: &mut T, block: &mut P) { - let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut(); - vis.visit_id(id); - stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); - visit_lazy_tts(vis, tokens); - vis.visit_span(span); -} - -pub fn walk_item_kind( - kind: &mut impl WalkItemKind, - span: Span, - id: NodeId, - vis: &mut impl MutVisitor, -) { - kind.walk(span, id, vis) -} - -impl WalkItemKind for ItemKind { - fn walk(&mut self, span: Span, id: NodeId, vis: &mut impl MutVisitor) { - match self { - ItemKind::ExternCrate(_orig_name) => {} - ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), - ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { - vis.visit_ty(ty); - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ItemKind::Const(item) => { - visit_const_item(item, vis); - } - ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(vis, defaultness); - vis.visit_fn(FnKind::Fn(sig, generics, body), span, id); - } - ItemKind::Mod(safety, mod_kind) => { - visit_safety(vis, safety); - 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, generics, where_clauses, bounds, ty }) => { - visit_defaultness(vis, defaultness); - 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(EnumDef { variants }, generics) => { - vis.visit_generics(generics); - variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); - } - ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { - 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)); - } - ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { - visit_safety(vis, safety); - 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(generics, bounds) => { - vis.visit_generics(generics); - visit_bounds(vis, bounds, BoundKind::Bound); - } - ItemKind::MacCall(m) => vis.visit_mac_call(m), - ItemKind::MacroDef(def) => vis.visit_macro_def(def), - ItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - vis.visit_id(id); - vis.visit_qself(qself); - vis.visit_path(path); - 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 { - fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) { - match self { - AssocItemKind::Const(item) => { - visit_const_item(item, visitor); - } - AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); - visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); - } - AssocItemKind::Type(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - }) => { - visit_defaultness(visitor, defaultness); - 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, - rename, - body, - from_glob: _, - }) => { - visitor.visit_id(id); - visitor.visit_qself(qself); - visitor.visit_path(path); - 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 visit_const_item( - ConstItem { defaultness, generics, ty, expr }: &mut ConstItem, - visitor: &mut T, -) { - visit_defaultness(visitor, defaultness); - visitor.visit_generics(generics); - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); -} - -fn walk_fn_header(vis: &mut T, header: &mut FnHeader) { - let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; - visit_constness(vis, constness); - coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); - visit_safety(vis, safety); -} - -pub fn walk_crate(vis: &mut T, krate: &mut Crate) { - let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; - vis.visit_id(id); - visit_attrs(vis, attrs); - items.flat_map_in_place(|item| vis.flat_map_item(item)); - let ModSpans { inner_span, inject_use_span } = spans; - vis.visit_span(inner_span); - vis.visit_span(inject_use_span); -} - -/// Mutates one item, returning the item again. -pub fn walk_flat_map_item( - visitor: &mut impl MutVisitor, - mut item: P>, -) -> SmallVec<[P>; 1]> { - let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visitor.visit_ident(ident); - kind.walk(*span, *id, visitor); - visit_lazy_tts(visitor, tokens); - visitor.visit_span(span); - smallvec![item] -} - -impl WalkItemKind for ForeignItemKind { - fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) { - match self { - ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); - } - ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); - visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); - } - ForeignItemKind::TyAlias(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - }) => { - visit_defaultness(visitor, defaultness); - 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(vis: &mut T, pat: &mut P) { - let Pat { id, kind, span, tokens } = pat.deref_mut(); - vis.visit_id(id); - match kind { - PatKind::Err(_guar) => {} - 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::Lit(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::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), - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); -} - -fn walk_anon_const(vis: &mut T, AnonConst { id, value }: &mut AnonConst) { - vis.visit_id(id); - vis.visit_expr(value); -} - -fn walk_inline_asm(vis: &mut T, asm: &mut InlineAsm) { - // FIXME: Visit spans inside all this currently ignored stuff. - let InlineAsm { - asm_macro: _, - template: _, - template_strs: _, - operands, - clobber_abis: _, - options: _, - line_spans: _, - } = asm; - for (op, span) in operands { - match op { - InlineAsmOperand::In { expr, reg: _ } - | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } - | InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr), - InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} - InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { - vis.visit_expr(in_expr); - if let Some(out_expr) = out_expr { - vis.visit_expr(out_expr); - } - } - InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const), - InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym), - InlineAsmOperand::Label { block } => vis.visit_block(block), - } - vis.visit_span(span); - } -} - -fn walk_inline_asm_sym( - vis: &mut T, - InlineAsmSym { id, qself, path }: &mut InlineAsmSym, -) { - vis.visit_id(id); - vis.visit_qself(qself); - vis.visit_path(path); -} - -fn walk_format_args(vis: &mut T, fmt: &mut FormatArgs) { - // FIXME: visit the template exhaustively. - let FormatArgs { span, template: _, arguments } = fmt; - for FormatArgument { kind, expr } in arguments.all_args_mut() { - match kind { - FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - vis.visit_ident(ident) - } - FormatArgumentKind::Normal => {} - } - vis.visit_expr(expr); - } - vis.visit_span(span); -} - -pub fn walk_expr(vis: &mut T, Expr { kind, id, span, attrs, tokens }: &mut Expr) { - vis.visit_id(id); - visit_attrs(vis, attrs); - match kind { - ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs), - ExprKind::ConstBlock(anon_const) => { - vis.visit_anon_const(anon_const); - } - ExprKind::Repeat(expr, count) => { - vis.visit_expr(expr); - vis.visit_anon_const(count); - } - ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs), - ExprKind::Call(f, args) => { - vis.visit_expr(f); - visit_thin_exprs(vis, args); - } - ExprKind::MethodCall(box MethodCall { - seg: PathSegment { ident, id, args: seg_args }, - receiver, - args: call_args, - span, - }) => { - vis.visit_method_receiver_expr(receiver); - vis.visit_id(id); - vis.visit_ident(ident); - visit_opt(seg_args, |args| vis.visit_generic_args(args)); - visit_thin_exprs(vis, call_args); - vis.visit_span(span); - } - ExprKind::Binary(_binop, lhs, rhs) => { - vis.visit_expr(lhs); - vis.visit_expr(rhs); - } - ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), - ExprKind::Cast(expr, ty) => { - vis.visit_expr(expr); - vis.visit_ty(ty); - } - ExprKind::Type(expr, ty) => { - vis.visit_expr(expr); - vis.visit_ty(ty); - } - ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs), - ExprKind::Let(pat, scrutinee, span, _recovered) => { - vis.visit_pat(pat); - vis.visit_expr(scrutinee); - vis.visit_span(span); - } - ExprKind::If(cond, tr, fl) => { - vis.visit_expr(cond); - vis.visit_block(tr); - visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl))); - } - ExprKind::While(cond, body, label) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_expr(cond); - vis.visit_block(body); - } - ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_pat(pat); - vis.visit_expr(iter); - vis.visit_block(body); - } - ExprKind::Loop(body, label, span) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_block(body); - vis.visit_span(span); - } - ExprKind::Match(expr, arms, _kind) => { - vis.visit_expr(expr); - arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); - } - ExprKind::Closure(box Closure { - binder, - capture_clause, - constness, - coroutine_kind, - movability: _, - fn_decl, - body, - fn_decl_span, - fn_arg_span, - }) => { - visit_constness(vis, constness); - coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); - vis.visit_capture_by(capture_clause); - vis.visit_fn(FnKind::Closure(binder, fn_decl, body), *span, *id); - vis.visit_span(fn_decl_span); - vis.visit_span(fn_arg_span); - } - ExprKind::Block(blk, label) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_block(blk); - } - ExprKind::Gen(_capture_by, body, _kind, decl_span) => { - vis.visit_block(body); - vis.visit_span(decl_span); - } - ExprKind::Await(expr, await_kw_span) => { - vis.visit_expr(expr); - vis.visit_span(await_kw_span); - } - ExprKind::Assign(el, er, span) => { - vis.visit_expr(el); - vis.visit_expr(er); - vis.visit_span(span); - } - ExprKind::AssignOp(_op, el, er) => { - vis.visit_expr(el); - vis.visit_expr(er); - } - ExprKind::Field(el, ident) => { - vis.visit_expr(el); - vis.visit_ident(ident); - } - ExprKind::Index(el, er, brackets_span) => { - vis.visit_expr(el); - vis.visit_expr(er); - vis.visit_span(brackets_span); - } - ExprKind::Range(e1, e2, _lim) => { - visit_opt(e1, |e1| vis.visit_expr(e1)); - visit_opt(e2, |e2| vis.visit_expr(e2)); - } - ExprKind::Underscore => {} - ExprKind::Path(qself, path) => { - vis.visit_qself(qself); - vis.visit_path(path); - } - ExprKind::Break(label, expr) => { - visit_opt(label, |label| vis.visit_label(label)); - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Continue(label) => { - visit_opt(label, |label| vis.visit_label(label)); - } - ExprKind::Ret(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Yeet(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Become(expr) => vis.visit_expr(expr), - ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), - ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), - ExprKind::OffsetOf(container, fields) => { - vis.visit_ty(container); - for field in fields.iter_mut() { - vis.visit_ident(field); - } - } - ExprKind::MacCall(mac) => vis.visit_mac_call(mac), - ExprKind::Struct(se) => { - let StructExpr { qself, path, fields, rest } = se.deref_mut(); - vis.visit_qself(qself); - vis.visit_path(path); - fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); - match rest { - StructRest::Base(expr) => vis.visit_expr(expr), - StructRest::Rest(_span) => {} - StructRest::None => {} - } - } - ExprKind::Paren(expr) => { - vis.visit_expr(expr); - } - ExprKind::Yield(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Try(expr) => vis.visit_expr(expr), - ExprKind::TryBlock(body) => vis.visit_block(body), - ExprKind::Lit(_token) => {} - ExprKind::IncludedBytes(_bytes) => {} - ExprKind::Err(_guar) => {} - ExprKind::Dummy => {} - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); -} - -pub fn noop_filter_map_expr(vis: &mut T, mut e: P) -> Option> { - Some({ - vis.visit_expr(&mut e); - e - }) -} - -pub fn walk_flat_map_stmt( - vis: &mut T, - Stmt { kind, mut span, mut id }: Stmt, -) -> SmallVec<[Stmt; 1]> { - vis.visit_id(&mut id); - let stmts: SmallVec<_> = walk_flat_map_stmt_kind(vis, kind) - .into_iter() - .map(|kind| Stmt { id, kind, span }) - .collect(); - if stmts.len() > 1 { - panic!( - "cloning statement `NodeId`s is prohibited by default, \ - the visitor should implement custom statement visiting" - ); - } - vis.visit_span(&mut span); - stmts -} - -fn walk_flat_map_stmt_kind(vis: &mut T, kind: StmtKind) -> SmallVec<[StmtKind; 1]> { - match kind { - StmtKind::Let(mut local) => smallvec![StmtKind::Let({ - vis.visit_local(&mut local); - local - })], - StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(), - StmtKind::Expr(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect(), - StmtKind::Semi(expr) => vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect(), - StmtKind::Empty => smallvec![StmtKind::Empty], - StmtKind::MacCall(mut mac) => { - let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); - visit_attrs(vis, attrs); - vis.visit_mac_call(mac_); - visit_lazy_tts(vis, tokens); - smallvec![StmtKind::MacCall(mac)] - } - } -} - -fn walk_vis(vis: &mut T, visibility: &mut Visibility) { - let Visibility { kind, span, tokens } = visibility; - match kind { - VisibilityKind::Public | VisibilityKind::Inherited => {} - VisibilityKind::Restricted { path, id, shorthand: _ } => { - vis.visit_id(id); - vis.visit_path(path); - } - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); -} - -fn walk_capture_by(vis: &mut T, capture_by: &mut CaptureBy) { - match capture_by { - CaptureBy::Ref => {} - CaptureBy::Value { move_kw } => { - vis.visit_span(move_kw); - } - } -} - -/// 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 DummyAstNode for Option { - fn dummy() -> Self { - Default::default() - } -} - -impl DummyAstNode for P { - 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(), - }, - ident: Ident::empty(), - kind: ItemKind::ExternCrate(None), - 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 DummyAstNode for crate::ast_traits::AstNodeWrapper { - 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()`. - Fn(&'a mut FnSig, &'a mut Generics, &'a mut Option>), - - /// E.g., `|x, y| body`. - Closure(&'a mut ClosureBinder, &'a mut P, &'a mut P), -} diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs deleted file mode 100644 index 207ec71065051..0000000000000 --- a/compiler/rustc_ast/src/visit.rs +++ /dev/null @@ -1,1243 +0,0 @@ -//! AST walker. Each overridden visit method has full control over what -//! happens with its node, it can do its own traversal of the node's children, -//! call `visit::walk_*` to apply the default traversal algorithm, or prevent -//! deeper traversal by doing nothing. -//! -//! Note: it is an important invariant that the default visitor walks the body -//! of a function in "execution order" (more concretely, reverse post-order -//! with respect to the CFG implied by the AST), meaning that if AST node A may -//! execute before AST node B, then A is visited first. The borrow checker in -//! particular relies on this property. -//! -//! Note: walking an AST before macro expansion is probably a bad idea. For -//! instance, a walker looking for item names in a module will miss all of -//! those that are created by the expansion of a macro. - -pub use rustc_ast_ir::visit::VisitorResult; -pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list}; -use rustc_span::Span; -use rustc_span::symbol::Ident; - -use crate::ast::*; -use crate::ptr::P; - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum AssocCtxt { - Trait, - Impl, -} - -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum FnCtxt { - Free, - Foreign, - Assoc(AssocCtxt), -} - -#[derive(Copy, Clone, Debug)] -pub enum BoundKind { - /// Trait bounds in generics bounds and type/trait alias. - /// E.g., ``, `type A: Bound`, or `where T: Bound`. - Bound, - - /// Trait bounds in `impl` type. - /// E.g., `type Foo = impl Bound1 + Bound2 + Bound3`. - Impl, - - /// Trait bounds in trait object type. - /// E.g., `dyn Bound1 + Bound2 + Bound3`. - TraitObject, - - /// Super traits of a trait. - /// E.g., `trait A: B` - SuperTraits, -} -impl BoundKind { - pub fn descr(self) -> &'static str { - match self { - BoundKind::Bound => "bounds", - BoundKind::Impl => "`impl Trait`", - BoundKind::TraitObject => "`dyn` trait object bounds", - BoundKind::SuperTraits => "supertrait bounds", - } - } -} - -#[derive(Copy, Clone, Debug)] -pub enum FnKind<'a> { - /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. - Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>), - - /// E.g., `|x, y| body`. - Closure(&'a ClosureBinder, &'a Option, &'a FnDecl, &'a Expr), -} - -impl<'a> FnKind<'a> { - pub fn header(&self) -> Option<&'a FnHeader> { - match *self { - FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header), - FnKind::Closure(..) => None, - } - } - - pub fn ident(&self) -> Option<&Ident> { - match self { - FnKind::Fn(_, ident, ..) => Some(ident), - _ => None, - } - } - - pub fn decl(&self) -> &'a FnDecl { - match self { - FnKind::Fn(_, _, sig, _, _, _) => &sig.decl, - FnKind::Closure(_, _, decl, _) => decl, - } - } - - pub fn ctxt(&self) -> Option { - match self { - FnKind::Fn(ctxt, ..) => Some(*ctxt), - FnKind::Closure(..) => None, - } - } -} - -#[derive(Copy, Clone, Debug)] -pub enum LifetimeCtxt { - /// Appears in a reference type. - Ref, - /// Appears as a bound on a type or another lifetime. - Bound, - /// Appears as a generic argument. - GenericArg, -} - -pub trait WalkItemKind: Sized { - fn walk<'a, V: Visitor<'a>>( - &'a self, - item: &'a Item, - ctxt: AssocCtxt, - 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; -/// e.g., the `visit_item` method by default calls `visit::walk_item`. -/// -/// If you want to ensure that your code handles every variant -/// explicitly, you need to override each method. (And you also need -/// to monitor future changes to `Visitor` in case a new method with a -/// new default implementation gets introduced.) -pub trait Visitor<'ast>: Sized { - /// The result type of the `visit_*` methods. Can be either `()`, - /// or `ControlFlow`. - type Result: VisitorResult = (); - - fn visit_ident(&mut self, _ident: Ident) -> Self::Result { - Self::Result::output() - } - fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result { - walk_item(self, i) - } - fn visit_item(&mut self, i: &'ast Item) -> Self::Result { - walk_item(self, i) - } - fn visit_local(&mut self, l: &'ast Local) -> Self::Result { - walk_local(self, l) - } - fn visit_block(&mut self, b: &'ast Block) -> Self::Result { - walk_block(self, b) - } - fn visit_stmt(&mut self, s: &'ast Stmt) -> Self::Result { - walk_stmt(self, s) - } - fn visit_param(&mut self, param: &'ast Param) -> Self::Result { - walk_param(self, param) - } - fn visit_arm(&mut self, a: &'ast Arm) -> Self::Result { - walk_arm(self, a) - } - fn visit_pat(&mut self, p: &'ast Pat) -> Self::Result { - walk_pat(self, p) - } - fn visit_anon_const(&mut self, c: &'ast AnonConst) -> Self::Result { - walk_anon_const(self, c) - } - fn visit_expr(&mut self, ex: &'ast Expr) -> Self::Result { - walk_expr(self, ex) - } - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. - /// It can be removed once that feature is stabilized. - fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { - self.visit_expr(ex) - } - fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { - Self::Result::output() - } - fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result { - walk_ty(self, t) - } - fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result { - walk_generic_param(self, param) - } - fn visit_generics(&mut self, g: &'ast Generics) -> Self::Result { - walk_generics(self, g) - } - fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result { - walk_closure_binder(self, b) - } - fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result { - walk_where_predicate(self, p) - } - fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { - walk_fn(self, fk) - } - fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) -> Self::Result { - walk_assoc_item(self, i, ctxt) - } - fn visit_trait_ref(&mut self, t: &'ast TraitRef) -> Self::Result { - walk_trait_ref(self, t) - } - fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) -> Self::Result { - walk_param_bound(self, bounds) - } - fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { - walk_precise_capturing_arg(self, arg); - } - fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result { - walk_poly_trait_ref(self, t) - } - fn visit_variant_data(&mut self, s: &'ast VariantData) -> Self::Result { - walk_struct_def(self, s) - } - fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result { - walk_field_def(self, s) - } - fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result { - walk_enum_def(self, enum_definition) - } - fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result { - walk_variant(self, v) - } - fn visit_variant_discr(&mut self, discr: &'ast AnonConst) -> Self::Result { - self.visit_anon_const(discr) - } - fn visit_label(&mut self, label: &'ast Label) -> Self::Result { - walk_label(self, label) - } - fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) -> Self::Result { - walk_lifetime(self, lifetime) - } - 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 { - Self::Result::output() - } - fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result { - walk_path(self, path) - } - fn visit_use_tree( - &mut self, - use_tree: &'ast UseTree, - id: NodeId, - _nested: bool, - ) -> Self::Result { - walk_use_tree(self, use_tree, id) - } - fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result { - walk_path_segment(self, path_segment) - } - fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) -> Self::Result { - walk_generic_args(self, generic_args) - } - fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result { - walk_generic_arg(self, generic_arg) - } - fn visit_assoc_item_constraint( - &mut self, - constraint: &'ast AssocItemConstraint, - ) -> Self::Result { - walk_assoc_item_constraint(self, constraint) - } - fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result { - walk_attribute(self, attr) - } - fn visit_vis(&mut self, vis: &'ast Visibility) -> Self::Result { - walk_vis(self, vis) - } - fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) -> Self::Result { - walk_fn_ret_ty(self, ret_ty) - } - fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { - Self::Result::output() - } - fn visit_expr_field(&mut self, f: &'ast ExprField) -> Self::Result { - walk_expr_field(self, f) - } - fn visit_pat_field(&mut self, fp: &'ast PatField) -> Self::Result { - walk_pat_field(self, fp) - } - fn visit_crate(&mut self, krate: &'ast Crate) -> Self::Result { - walk_crate(self, krate) - } - fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) -> Self::Result { - walk_inline_asm(self, asm) - } - fn visit_format_args(&mut self, fmt: &'ast FormatArgs) -> Self::Result { - walk_format_args(self, fmt) - } - fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) -> Self::Result { - walk_inline_asm_sym(self, sym) - } - fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result { - Self::Result::output() - } -} - -pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result { - let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate; - walk_list!(visitor, visit_attribute, attrs); - walk_list!(visitor, visit_item, items); - V::Result::output() -} - -pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result { - let Local { id: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - visit_opt!(visitor, visit_ty, ty); - if let Some((init, els)) = kind.init_else_opt() { - try_visit!(visitor.visit_expr(init)); - visit_opt!(visitor, visit_block, els); - } - V::Result::output() -} - -pub fn walk_label<'a, V: Visitor<'a>>(visitor: &mut V, Label { ident }: &'a Label) -> V::Result { - visitor.visit_ident(*ident) -} - -pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result { - let Lifetime { id: _, ident } = lifetime; - visitor.visit_ident(*ident) -} - -pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result -where - V: Visitor<'a>, -{ - let PolyTraitRef { bound_generic_params, modifiers: _, trait_ref, span: _ } = trait_ref; - walk_list!(visitor, visit_generic_param, bound_generic_params); - visitor.visit_trait_ref(trait_ref) -} - -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 { - fn walk<'a, V: Visitor<'a>>( - &'a self, - item: &'a Item, - _ctxt: AssocCtxt, - visitor: &mut V, - ) -> V::Result { - let Item { id, span, vis, ident, .. } = item; - match self { - ItemKind::ExternCrate(_rename) => {} - ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, *id, false)), - ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Free, *ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, *span, *id)); - } - ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { - ModKind::Loaded(items, _inline, _inner_span) => { - walk_list!(visitor, visit_item, items); - } - ModKind::Unloaded => {} - }, - ItemKind::ForeignMod(ForeignMod { 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, - bounds, - ty, - defaultness: _, - where_clauses: _, - }) => { - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - } - ItemKind::Enum(enum_definition, generics) => { - 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); - } - ItemKind::Struct(struct_definition, generics) - | ItemKind::Union(struct_definition, generics) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_variant_data(struct_definition)); - } - ItemKind::Trait(box Trait { safety: _, is_auto: _, generics, bounds, items }) => { - 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(generics, bounds) => { - 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(ts) => try_visit!(visitor.visit_mac_def(ts, *id)), - ItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - try_visit!(walk_qself(visitor, qself)); - try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); - visit_opt!(visitor, visit_block, body); - } - ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { - try_visit!(walk_qself(visitor, 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, -) -> V::Result { - walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) -} - -pub fn walk_enum_def<'a, V: Visitor<'a>>( - visitor: &mut V, - EnumDef { variants }: &'a EnumDef, -) -> V::Result { - walk_list!(visitor, visit_variant, variants); - V::Result::output() -} - -pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -> V::Result -where - V: Visitor<'a>, -{ - let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = variant; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(*ident)); - try_visit!(visitor.visit_variant_data(data)); - visit_opt!(visitor, visit_variant_discr, disr_expr); - V::Result::output() -} - -pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result { - let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = f; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); - try_visit!(visitor.visit_expr(expr)); - V::Result::output() -} - -pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result { - let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); - try_visit!(visitor.visit_pat(pat)); - 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!(walk_fn_decl(visitor, decl)); - } - TyKind::Path(maybe_qself, path) => { - try_visit!(walk_qself(visitor, maybe_qself)); - try_visit!(visitor.visit_path(path, *id)); - } - TyKind::Pat(ty, pat) => { - try_visit!(visitor.visit_ty(ty)); - try_visit!(visitor.visit_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() -} - -fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option>) -> V::Result { - if let Some(qself) = qself { - let QSelf { ty, path_span: _, position: _ } = &**qself; - try_visit!(visitor.visit_ty(ty)); - } - V::Result::output() -} - -pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result { - let Path { span: _, segments, tokens: _ } = path; - walk_list!(visitor, visit_path_segment, segments); - V::Result::output() -} - -pub fn walk_use_tree<'a, V: Visitor<'a>>( - visitor: &mut V, - use_tree: &'a UseTree, - id: NodeId, -) -> V::Result { - let UseTree { prefix, kind, span: _ } = use_tree; - try_visit!(visitor.visit_path(prefix, id)); - match kind { - UseTreeKind::Simple(rename) => { - // The extra IDs are handled during AST lowering. - visit_opt!(visitor, visit_ident, *rename); - } - UseTreeKind::Glob => {} - UseTreeKind::Nested { ref items, span: _ } => { - for &(ref nested_tree, nested_id) in items { - try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true)); - } - } - } - 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>, -{ - match generic_args { - GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, args }) => { - for arg in args { - match arg { - AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)), - AngleBracketedArg::Constraint(c) => { - try_visit!(visitor.visit_assoc_item_constraint(c)) - } - } - } - } - GenericArgs::Parenthesized(data) => { - let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data; - walk_list!(visitor, visit_ty, inputs); - try_visit!(visitor.visit_fn_ret_ty(output)); - } - GenericArgs::ParenthesizedElided(_span) => {} - } - V::Result::output() -} - -pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result -where - V: Visitor<'a>, -{ - match generic_arg { - GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg), - GenericArg::Type(ty) => visitor.visit_ty(ty), - GenericArg::Const(ct) => visitor.visit_anon_const(ct), - } -} - -pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( - visitor: &mut V, - constraint: &'a AssocItemConstraint, -) -> V::Result { - let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint; - try_visit!(visitor.visit_ident(*ident)); - visit_opt!(visitor, visit_generic_args, gen_args); - match kind { - AssocItemConstraintKind::Equality { term } => match term { - Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)), - Term::Const(c) => try_visit!(visitor.visit_anon_const(c)), - }, - AssocItemConstraintKind::Bound { bounds } => { - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - } - 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!(walk_qself(visitor, opt_qself)); - try_visit!(visitor.visit_path(path, *id)); - walk_list!(visitor, visit_pat, elems); - } - PatKind::Path(opt_qself, path) => { - try_visit!(walk_qself(visitor, opt_qself)); - try_visit!(visitor.visit_path(path, *id)) - } - PatKind::Struct(opt_qself, path, fields, _rest) => { - try_visit!(walk_qself(visitor, 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::Lit(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::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 { - fn walk<'a, V: Visitor<'a>>( - &'a self, - item: &'a Item, - _ctxt: AssocCtxt, - visitor: &mut V, - ) -> V::Result { - let &Item { id, span, ident, ref vis, .. } = item; - match self { - ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, span, id)); - } - ForeignItemKind::TyAlias(box TyAlias { - generics, - bounds, - ty, - defaultness: _, - where_clauses: _, - }) => { - 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), - GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound), - GenericBound::Use(args, _span) => { - walk_list!(visitor, visit_precise_capturing_arg, args); - V::Result::output() - } - } -} - -pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( - visitor: &mut V, - arg: &'a PreciseCapturingArg, -) { - match arg { - PreciseCapturingArg::Lifetime(lt) => { - visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg); - } - PreciseCapturingArg::Arg(path, id) => { - visitor.visit_path(path, *id); - } - } -} - -pub fn walk_generic_param<'a, V: Visitor<'a>>( - visitor: &mut V, - param: &'a GenericParam, -) -> V::Result { - let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } = - param; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - match kind { - GenericParamKind::Lifetime => (), - GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default), - GenericParamKind::Const { ty, default, kw_span: _ } => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_anon_const, default); - } - } - V::Result::output() -} - -pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result { - let Generics { params, where_clause, span: _ } = generics; - let WhereClause { has_where_token: _, predicates, span: _ } = where_clause; - walk_list!(visitor, visit_generic_param, params); - walk_list!(visitor, visit_where_predicate, predicates); - V::Result::output() -} - -pub fn walk_closure_binder<'a, V: Visitor<'a>>( - visitor: &mut V, - binder: &'a ClosureBinder, -) -> V::Result { - match binder { - ClosureBinder::NotPresent => {} - ClosureBinder::For { generic_params, span: _ } => { - walk_list!(visitor, visit_generic_param, generic_params) - } - } - V::Result::output() -} - -pub fn walk_where_predicate<'a, V: Visitor<'a>>( - visitor: &mut V, - predicate: &'a WherePredicate, -) -> V::Result { - match predicate { - WherePredicate::BoundPredicate(WhereBoundPredicate { - bounded_ty, - bounds, - bound_generic_params, - span: _, - }) => { - walk_list!(visitor, visit_generic_param, bound_generic_params); - try_visit!(visitor.visit_ty(bounded_ty)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => { - try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => { - try_visit!(visitor.visit_ty(lhs_ty)); - try_visit!(visitor.visit_ty(rhs_ty)); - } - } - V::Result::output() -} - -pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) -> V::Result { - match ret_ty { - FnRetTy::Default(_span) => {} - FnRetTy::Ty(output_ty) => try_visit!(visitor.visit_ty(output_ty)), - } - V::Result::output() -} - -pub fn walk_fn_decl<'a, V: Visitor<'a>>( - visitor: &mut V, - FnDecl { inputs, output }: &'a FnDecl, -) -> V::Result { - walk_list!(visitor, visit_param, inputs); - visitor.visit_fn_ret_ty(output) -} - -pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { - match kind { - FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => { - // Identifier and visibility are visited as a part of the item. - try_visit!(visitor.visit_fn_header(header)); - try_visit!(visitor.visit_generics(generics)); - try_visit!(walk_fn_decl(visitor, decl)); - visit_opt!(visitor, visit_block, body); - } - FnKind::Closure(binder, _coroutine_kind, decl, body) => { - try_visit!(visitor.visit_closure_binder(binder)); - try_visit!(walk_fn_decl(visitor, decl)); - try_visit!(visitor.visit_expr(body)); - } - } - V::Result::output() -} - -impl WalkItemKind for AssocItemKind { - fn walk<'a, V: Visitor<'a>>( - &'a self, - item: &'a Item, - ctxt: AssocCtxt, - visitor: &mut V, - ) -> V::Result { - let &Item { id, span, ident, ref vis, .. } = item; - match self { - AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = - FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, span, id)); - } - AssocItemKind::Type(box TyAlias { - generics, - bounds, - ty, - defaultness: _, - where_clauses: _, - }) => { - try_visit!(visitor.visit_generics(generics)); - 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, - rename, - body, - from_glob: _, - }) => { - try_visit!(walk_qself(visitor, qself)); - try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); - visit_opt!(visitor, visit_block, body); - } - AssocItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { - try_visit!(walk_qself(visitor, 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_assoc_item<'a, V: Visitor<'a>>( - visitor: &mut V, - item: &'a Item, - ctxt: AssocCtxt, -) -> V::Result { - let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(ident)); - try_visit!(kind.walk(item, 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()); - V::Result::output() -} - -pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result { - let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - visit_opt!(visitor, visit_ident, *ident); - try_visit!(visitor.visit_ty(ty)); - 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: _, could_be_bare_literal: _ } = 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 { - StmtKind::Let(local) => try_visit!(visitor.visit_local(local)), - StmtKind::Item(item) => try_visit!(visitor.visit_item(item)), - StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)), - StmtKind::Empty => {} - StmtKind::MacCall(mac) => { - let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_mac_call(mac)); - } - } - V::Result::output() -} - -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) -} - -pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result { - let InlineAsm { - asm_macro: _, - template: _, - template_strs: _, - operands, - clobber_abis: _, - options: _, - line_spans: _, - } = asm; - for (op, _span) in operands { - match op { - InlineAsmOperand::In { expr, reg: _ } - | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } - | InlineAsmOperand::InOut { expr, reg: _, late: _ } => { - try_visit!(visitor.visit_expr(expr)) - } - InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} - InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { - try_visit!(visitor.visit_expr(in_expr)); - visit_opt!(visitor, visit_expr, out_expr); - } - InlineAsmOperand::Const { anon_const } => { - try_visit!(visitor.visit_anon_const(anon_const)) - } - InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)), - InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)), - } - } - V::Result::output() -} - -pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>( - visitor: &mut V, - InlineAsmSym { id, qself, path }: &'a InlineAsmSym, -) -> V::Result { - try_visit!(walk_qself(visitor, qself)); - visitor.visit_path(path, *id) -} - -pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result { - let FormatArgs { span: _, template: _, arguments } = fmt; - for FormatArgument { kind, expr } in arguments.all_args() { - match kind { - FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - try_visit!(visitor.visit_ident(*ident)) - } - FormatArgumentKind::Normal => {} - } - try_visit!(visitor.visit_expr(expr)); - } - V::Result::output() -} - -pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result { - let Expr { id, kind, span, attrs, tokens: _ } = expression; - walk_list!(visitor, visit_attribute, attrs); - match kind { - ExprKind::Array(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)), - ExprKind::Repeat(element, count) => { - try_visit!(visitor.visit_expr(element)); - try_visit!(visitor.visit_anon_const(count)); - } - ExprKind::Struct(se) => { - let StructExpr { qself, path, fields, rest } = &**se; - try_visit!(walk_qself(visitor, qself)); - try_visit!(visitor.visit_path(path, *id)); - walk_list!(visitor, visit_expr_field, fields); - match rest { - StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)), - StructRest::Rest(_span) => {} - StructRest::None => {} - } - } - ExprKind::Tup(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::Call(callee_expression, arguments) => { - try_visit!(visitor.visit_expr(callee_expression)); - walk_list!(visitor, visit_expr, arguments); - } - ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => { - try_visit!(visitor.visit_expr(receiver)); - try_visit!(visitor.visit_path_segment(seg)); - walk_list!(visitor, visit_expr, args); - } - ExprKind::Binary(_op, left_expression, right_expression) => { - try_visit!(visitor.visit_expr(left_expression)); - try_visit!(visitor.visit_expr(right_expression)); - } - ExprKind::AddrOf(_kind, _mutbl, subexpression) => { - try_visit!(visitor.visit_expr(subexpression)); - } - ExprKind::Unary(_op, subexpression) => { - try_visit!(visitor.visit_expr(subexpression)); - } - ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => { - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ty(typ)); - } - ExprKind::Let(pat, expr, _span, _recovered) => { - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_expr(expr)); - } - ExprKind::If(head_expression, if_block, optional_else) => { - try_visit!(visitor.visit_expr(head_expression)); - try_visit!(visitor.visit_block(if_block)); - visit_opt!(visitor, visit_expr, optional_else); - } - ExprKind::While(subexpression, block, opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_block(block)); - } - ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { - visit_opt!(visitor, visit_label, label); - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_expr(iter)); - try_visit!(visitor.visit_block(body)); - } - ExprKind::Loop(block, opt_label, _span) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_block(block)); - } - ExprKind::Match(subexpression, arms, _kind) => { - try_visit!(visitor.visit_expr(subexpression)); - walk_list!(visitor, visit_arm, arms); - } - ExprKind::Closure(box Closure { - binder, - capture_clause, - coroutine_kind, - constness: _, - movability: _, - fn_decl, - body, - fn_decl_span: _, - fn_arg_span: _, - }) => { - try_visit!(visitor.visit_capture_by(capture_clause)); - try_visit!(visitor.visit_fn( - FnKind::Closure(binder, coroutine_kind, fn_decl, body), - *span, - *id - )) - } - ExprKind::Block(block, opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_block(block)); - } - ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)), - ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)), - ExprKind::Assign(lhs, rhs, _span) => { - try_visit!(visitor.visit_expr(lhs)); - try_visit!(visitor.visit_expr(rhs)); - } - ExprKind::AssignOp(_op, left_expression, right_expression) => { - try_visit!(visitor.visit_expr(left_expression)); - try_visit!(visitor.visit_expr(right_expression)); - } - ExprKind::Field(subexpression, ident) => { - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ident(*ident)); - } - ExprKind::Index(main_expression, index_expression, _span) => { - try_visit!(visitor.visit_expr(main_expression)); - try_visit!(visitor.visit_expr(index_expression)); - } - ExprKind::Range(start, end, _limit) => { - visit_opt!(visitor, visit_expr, start); - visit_opt!(visitor, visit_expr, end); - } - ExprKind::Underscore => {} - ExprKind::Path(maybe_qself, path) => { - try_visit!(walk_qself(visitor, maybe_qself)); - try_visit!(visitor.visit_path(path, *id)); - } - ExprKind::Break(opt_label, opt_expr) => { - visit_opt!(visitor, visit_label, opt_label); - visit_opt!(visitor, visit_expr, opt_expr); - } - ExprKind::Continue(opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - } - ExprKind::Ret(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Yeet(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Become(expr) => try_visit!(visitor.visit_expr(expr)), - ExprKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - ExprKind::Paren(subexpression) => try_visit!(visitor.visit_expr(subexpression)), - ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), - ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)), - ExprKind::OffsetOf(container, fields) => { - try_visit!(visitor.visit_ty(container)); - walk_list!(visitor, visit_ident, fields.iter().copied()); - } - ExprKind::Yield(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)), - ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)), - ExprKind::Lit(_token) => {} - ExprKind::IncludedBytes(_bytes) => {} - ExprKind::Err(_guar) => {} - ExprKind::Dummy => {} - } - - visitor.visit_expr_post(expression) -} - -pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result { - let Param { attrs, ty, pat, id: _, span: _, is_placeholder: _ } = param; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_ty(ty)); - V::Result::output() -} - -pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result { - let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - visit_opt!(visitor, visit_expr, guard); - visit_opt!(visitor, visit_expr, body); - V::Result::output() -} - -pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result { - let Visibility { kind, span: _, tokens: _ } = vis; - match kind { - VisibilityKind::Restricted { path, id, shorthand: _ } => { - try_visit!(visitor.visit_path(path, *id)); - } - VisibilityKind::Public | VisibilityKind::Inherited => {} - } - V::Result::output() -} - -pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result { - let Attribute { kind, id: _, style: _, span: _ } = attr; - match kind { - 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!(walk_attr_args(visitor, args)); - } - AttrKind::DocComment(_kind, _sym) => {} - } - V::Result::output() -} - -pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -> V::Result { - match args { - AttrArgs::Empty => {} - AttrArgs::Delimited(_args) => {} - AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => try_visit!(visitor.visit_expr(expr)), - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when walking mac args eq: {:?}", lit) - } - } - V::Result::output() -} diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs new file mode 100644 index 0000000000000..18bc0c83dfad3 --- /dev/null +++ b/compiler/rustc_ast/src/visitors.rs @@ -0,0 +1,3118 @@ +pub mod visit { + + //! AST walker. Each overridden visit method has full control over what + //! happens with its node, it can do its own traversal of the node's children, + //! call `visit::walk_*` to apply the default traversal algorithm, or prevent + //! deeper traversal by doing nothing. + //! + //! Note: it is an important invariant that the default visitor walks the body + //! of a function in "execution order" (more concretely, reverse post-order + //! with respect to the CFG implied by the AST), meaning that if AST node A may + //! execute before AST node B, then A is visited first. The borrow checker in + //! particular relies on this property. + //! + //! Note: walking an AST before macro expansion is probably a bad idea. For + //! instance, a walker looking for item names in a module will miss all of + //! those that are created by the expansion of a macro. + + pub use rustc_ast_ir::visit::VisitorResult; + pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list}; + use rustc_span::Span; + use rustc_span::symbol::Ident; + + use crate::ast::*; + use crate::ptr::P; + + #[derive(Copy, Clone, Debug, PartialEq)] + pub enum AssocCtxt { + Trait, + Impl, + } + + #[derive(Copy, Clone, Debug, PartialEq)] + pub enum FnCtxt { + Free, + Foreign, + Assoc(AssocCtxt), + } + + #[derive(Copy, Clone, Debug)] + pub enum BoundKind { + /// Trait bounds in generics bounds and type/trait alias. + /// E.g., ``, `type A: Bound`, or `where T: Bound`. + Bound, + + /// Trait bounds in `impl` type. + /// E.g., `type Foo = impl Bound1 + Bound2 + Bound3`. + Impl, + + /// Trait bounds in trait object type. + /// E.g., `dyn Bound1 + Bound2 + Bound3`. + TraitObject, + + /// Super traits of a trait. + /// E.g., `trait A: B` + SuperTraits, + } + impl BoundKind { + pub fn descr(self) -> &'static str { + match self { + BoundKind::Bound => "bounds", + BoundKind::Impl => "`impl Trait`", + BoundKind::TraitObject => "`dyn` trait object bounds", + BoundKind::SuperTraits => "supertrait bounds", + } + } + } + + #[derive(Copy, Clone, Debug)] + pub enum FnKind<'a> { + /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. + Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>), + + /// E.g., `|x, y| body`. + Closure(&'a ClosureBinder, &'a Option, &'a FnDecl, &'a Expr), + } + + impl<'a> FnKind<'a> { + pub fn header(&self) -> Option<&'a FnHeader> { + match *self { + FnKind::Fn(_, _, sig, _, _, _) => Some(&sig.header), + FnKind::Closure(..) => None, + } + } + + pub fn ident(&self) -> Option<&Ident> { + match self { + FnKind::Fn(_, ident, ..) => Some(ident), + _ => None, + } + } + + pub fn decl(&self) -> &'a FnDecl { + match self { + FnKind::Fn(_, _, sig, _, _, _) => &sig.decl, + FnKind::Closure(_, _, decl, _) => decl, + } + } + + pub fn ctxt(&self) -> Option { + match self { + FnKind::Fn(ctxt, ..) => Some(*ctxt), + FnKind::Closure(..) => None, + } + } + } + + #[derive(Copy, Clone, Debug)] + pub enum LifetimeCtxt { + /// Appears in a reference type. + Ref, + /// Appears as a bound on a type or another lifetime. + Bound, + /// Appears as a generic argument. + GenericArg, + } + + pub trait WalkItemKind: Sized { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + ctxt: AssocCtxt, + 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; + /// e.g., the `visit_item` method by default calls `visit::walk_item`. + /// + /// If you want to ensure that your code handles every variant + /// explicitly, you need to override each method. (And you also need + /// to monitor future changes to `Visitor` in case a new method with a + /// new default implementation gets introduced.) + pub trait Visitor<'ast>: Sized { + /// The result type of the `visit_*` methods. Can be either `()`, + /// or `ControlFlow`. + type Result: VisitorResult = (); + + fn visit_ident(&mut self, _ident: Ident) -> Self::Result { + Self::Result::output() + } + fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result { + walk_item(self, i) + } + fn visit_item(&mut self, i: &'ast Item) -> Self::Result { + walk_item(self, i) + } + fn visit_local(&mut self, l: &'ast Local) -> Self::Result { + walk_local(self, l) + } + fn visit_block(&mut self, b: &'ast Block) -> Self::Result { + walk_block(self, b) + } + fn visit_stmt(&mut self, s: &'ast Stmt) -> Self::Result { + walk_stmt(self, s) + } + fn visit_param(&mut self, param: &'ast Param) -> Self::Result { + walk_param(self, param) + } + fn visit_arm(&mut self, a: &'ast Arm) -> Self::Result { + walk_arm(self, a) + } + fn visit_pat(&mut self, p: &'ast Pat) -> Self::Result { + walk_pat(self, p) + } + fn visit_anon_const(&mut self, c: &'ast AnonConst) -> Self::Result { + walk_anon_const(self, c) + } + fn visit_expr(&mut self, ex: &'ast Expr) -> Self::Result { + walk_expr(self, ex) + } + /// This method is a hack to workaround unstable of `stmt_expr_attributes`. + /// It can be removed once that feature is stabilized. + fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { + self.visit_expr(ex) + } + fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { + Self::Result::output() + } + fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result { + walk_ty(self, t) + } + fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result { + walk_generic_param(self, param) + } + fn visit_generics(&mut self, g: &'ast Generics) -> Self::Result { + walk_generics(self, g) + } + fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result { + walk_closure_binder(self, b) + } + fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result { + walk_where_predicate(self, p) + } + fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { + walk_fn(self, fk) + } + fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) -> Self::Result { + walk_assoc_item(self, i, ctxt) + } + fn visit_trait_ref(&mut self, t: &'ast TraitRef) -> Self::Result { + walk_trait_ref(self, t) + } + fn visit_param_bound( + &mut self, + bounds: &'ast GenericBound, + _ctxt: BoundKind, + ) -> Self::Result { + walk_param_bound(self, bounds) + } + fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { + walk_precise_capturing_arg(self, arg); + } + fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result { + walk_poly_trait_ref(self, t) + } + fn visit_variant_data(&mut self, s: &'ast VariantData) -> Self::Result { + walk_struct_def(self, s) + } + fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result { + walk_field_def(self, s) + } + fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result { + walk_enum_def(self, enum_definition) + } + fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result { + walk_variant(self, v) + } + fn visit_variant_discr(&mut self, discr: &'ast AnonConst) -> Self::Result { + self.visit_anon_const(discr) + } + fn visit_label(&mut self, label: &'ast Label) -> Self::Result { + walk_label(self, label) + } + fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) -> Self::Result { + walk_lifetime(self, lifetime) + } + 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 { + Self::Result::output() + } + fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result { + walk_path(self, path) + } + fn visit_use_tree( + &mut self, + use_tree: &'ast UseTree, + id: NodeId, + _nested: bool, + ) -> Self::Result { + walk_use_tree(self, use_tree, id) + } + fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result { + walk_path_segment(self, path_segment) + } + fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) -> Self::Result { + walk_generic_args(self, generic_args) + } + fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result { + walk_generic_arg(self, generic_arg) + } + fn visit_assoc_item_constraint( + &mut self, + constraint: &'ast AssocItemConstraint, + ) -> Self::Result { + walk_assoc_item_constraint(self, constraint) + } + fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result { + walk_attribute(self, attr) + } + fn visit_vis(&mut self, vis: &'ast Visibility) -> Self::Result { + walk_vis(self, vis) + } + fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) -> Self::Result { + walk_fn_ret_ty(self, ret_ty) + } + fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { + Self::Result::output() + } + fn visit_expr_field(&mut self, f: &'ast ExprField) -> Self::Result { + walk_expr_field(self, f) + } + fn visit_pat_field(&mut self, fp: &'ast PatField) -> Self::Result { + walk_pat_field(self, fp) + } + fn visit_crate(&mut self, krate: &'ast Crate) -> Self::Result { + walk_crate(self, krate) + } + fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) -> Self::Result { + walk_inline_asm(self, asm) + } + fn visit_format_args(&mut self, fmt: &'ast FormatArgs) -> Self::Result { + walk_format_args(self, fmt) + } + fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) -> Self::Result { + walk_inline_asm_sym(self, sym) + } + fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result { + Self::Result::output() + } + } + + pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result { + let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate; + walk_list!(visitor, visit_attribute, attrs); + walk_list!(visitor, visit_item, items); + V::Result::output() + } + + pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result { + let Local { id: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_pat(pat)); + visit_opt!(visitor, visit_ty, ty); + if let Some((init, els)) = kind.init_else_opt() { + try_visit!(visitor.visit_expr(init)); + visit_opt!(visitor, visit_block, els); + } + V::Result::output() + } + + pub fn walk_label<'a, V: Visitor<'a>>( + visitor: &mut V, + Label { ident }: &'a Label, + ) -> V::Result { + visitor.visit_ident(*ident) + } + + pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result { + let Lifetime { id: _, ident } = lifetime; + visitor.visit_ident(*ident) + } + + pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result + where + V: Visitor<'a>, + { + let PolyTraitRef { bound_generic_params, trait_ref, span: _, modifiers: _ } = trait_ref; + walk_list!(visitor, visit_generic_param, bound_generic_params); + visitor.visit_trait_ref(trait_ref) + } + + 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 { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + _ctxt: AssocCtxt, + visitor: &mut V, + ) -> V::Result { + let Item { id, span, vis, ident, .. } = item; + match self { + ItemKind::ExternCrate(_rename) => {} + ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, *id, false)), + ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + let kind = + FnKind::Fn(FnCtxt::Free, *ident, sig, vis, generics, body.as_deref()); + try_visit!(visitor.visit_fn(kind, *span, *id)); + } + ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { + ModKind::Loaded(items, _inline, _inner_span) => { + walk_list!(visitor, visit_item, items); + } + ModKind::Unloaded => {} + }, + ItemKind::ForeignMod(ForeignMod { 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, + bounds, + ty, + defaultness: _, + where_clauses: _, + }) => { + try_visit!(visitor.visit_generics(generics)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + visit_opt!(visitor, visit_ty, ty); + } + ItemKind::Enum(enum_definition, generics) => { + 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); + } + ItemKind::Struct(struct_definition, generics) + | ItemKind::Union(struct_definition, generics) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_variant_data(struct_definition)); + } + ItemKind::Trait(box Trait { safety: _, is_auto: _, generics, bounds, items }) => { + 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(generics, bounds) => { + 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(ts) => try_visit!(visitor.visit_mac_def(ts, *id)), + ItemKind::Delegation(box Delegation { + id, + qself, + path, + rename, + body, + from_glob: _, + }) => { + try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_path(path, *id)); + visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_block, body); + } + ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { + try_visit!(walk_qself(visitor, 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, + ) -> V::Result { + walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) + } + + pub fn walk_enum_def<'a, V: Visitor<'a>>( + visitor: &mut V, + EnumDef { variants }: &'a EnumDef, + ) -> V::Result { + walk_list!(visitor, visit_variant, variants); + V::Result::output() + } + + pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -> V::Result + where + V: Visitor<'a>, + { + let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = + variant; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_vis(vis)); + try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_variant_data(data)); + visit_opt!(visitor, visit_variant_discr, disr_expr); + V::Result::output() + } + + pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result { + let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = + f; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_expr(expr)); + V::Result::output() + } + + pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result { + let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_pat(pat)); + 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!(walk_fn_decl(visitor, decl)); + } + TyKind::Path(maybe_qself, path) => { + try_visit!(walk_qself(visitor, maybe_qself)); + try_visit!(visitor.visit_path(path, *id)); + } + TyKind::Pat(ty, pat) => { + try_visit!(visitor.visit_ty(ty)); + try_visit!(visitor.visit_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() + } + + fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option>) -> V::Result { + if let Some(qself) = qself { + let QSelf { ty, path_span: _, position: _ } = &**qself; + try_visit!(visitor.visit_ty(ty)); + } + V::Result::output() + } + + pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result { + let Path { span: _, segments, tokens: _ } = path; + walk_list!(visitor, visit_path_segment, segments); + V::Result::output() + } + + pub fn walk_use_tree<'a, V: Visitor<'a>>( + visitor: &mut V, + use_tree: &'a UseTree, + id: NodeId, + ) -> V::Result { + let UseTree { prefix, kind, span: _ } = use_tree; + try_visit!(visitor.visit_path(prefix, id)); + match kind { + UseTreeKind::Simple(rename) => { + // The extra IDs are handled during AST lowering. + visit_opt!(visitor, visit_ident, *rename); + } + UseTreeKind::Glob => {} + UseTreeKind::Nested { ref items, span: _ } => { + for &(ref nested_tree, nested_id) in items { + try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true)); + } + } + } + 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>, + { + match generic_args { + GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, args }) => { + for arg in args { + match arg { + AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)), + AngleBracketedArg::Constraint(c) => { + try_visit!(visitor.visit_assoc_item_constraint(c)) + } + } + } + } + GenericArgs::Parenthesized(data) => { + let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data; + walk_list!(visitor, visit_ty, inputs); + try_visit!(visitor.visit_fn_ret_ty(output)); + } + GenericArgs::ParenthesizedElided(_span) => {} + } + V::Result::output() + } + + pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result + where + V: Visitor<'a>, + { + match generic_arg { + GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg), + GenericArg::Type(ty) => visitor.visit_ty(ty), + GenericArg::Const(ct) => visitor.visit_anon_const(ct), + } + } + + pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( + visitor: &mut V, + constraint: &'a AssocItemConstraint, + ) -> V::Result { + let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint; + try_visit!(visitor.visit_ident(*ident)); + visit_opt!(visitor, visit_generic_args, gen_args); + match kind { + AssocItemConstraintKind::Equality { term } => match term { + Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)), + Term::Const(c) => try_visit!(visitor.visit_anon_const(c)), + }, + AssocItemConstraintKind::Bound { bounds } => { + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + } + } + 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!(walk_qself(visitor, opt_qself)); + try_visit!(visitor.visit_path(path, *id)); + walk_list!(visitor, visit_pat, elems); + } + PatKind::Path(opt_qself, path) => { + try_visit!(walk_qself(visitor, opt_qself)); + try_visit!(visitor.visit_path(path, *id)) + } + PatKind::Struct(opt_qself, path, fields, _rest) => { + try_visit!(walk_qself(visitor, 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::Lit(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::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 { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + _ctxt: AssocCtxt, + visitor: &mut V, + ) -> V::Result { + let &Item { id, span, ident, ref vis, .. } = item; + match self { + ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + let kind = + FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); + try_visit!(visitor.visit_fn(kind, span, id)); + } + ForeignItemKind::TyAlias(box TyAlias { + generics, + bounds, + ty, + defaultness: _, + where_clauses: _, + }) => { + 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(typ) => visitor.visit_poly_trait_ref(typ), + GenericBound::Outlives(lifetime) => { + visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound) + } + GenericBound::Use(args, _span) => { + walk_list!(visitor, visit_precise_capturing_arg, args); + V::Result::output() + } + } + } + + pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( + visitor: &mut V, + arg: &'a PreciseCapturingArg, + ) { + match arg { + PreciseCapturingArg::Lifetime(lt) => { + visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg); + } + PreciseCapturingArg::Arg(path, id) => { + visitor.visit_path(path, *id); + } + } + } + + pub fn walk_generic_param<'a, V: Visitor<'a>>( + visitor: &mut V, + param: &'a GenericParam, + ) -> V::Result { + let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } = + param; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_ident(*ident)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + match kind { + GenericParamKind::Lifetime => (), + GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default), + GenericParamKind::Const { ty, default, kw_span: _ } => { + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_anon_const, default); + } + } + V::Result::output() + } + + pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result { + let Generics { params, where_clause, span: _ } = generics; + let WhereClause { has_where_token: _, predicates, span: _ } = where_clause; + walk_list!(visitor, visit_generic_param, params); + walk_list!(visitor, visit_where_predicate, predicates); + V::Result::output() + } + + pub fn walk_closure_binder<'a, V: Visitor<'a>>( + visitor: &mut V, + binder: &'a ClosureBinder, + ) -> V::Result { + match binder { + ClosureBinder::NotPresent => {} + ClosureBinder::For { generic_params, span: _ } => { + walk_list!(visitor, visit_generic_param, generic_params) + } + } + V::Result::output() + } + + pub fn walk_where_predicate<'a, V: Visitor<'a>>( + visitor: &mut V, + predicate: &'a WherePredicate, + ) -> V::Result { + match predicate { + WherePredicate::BoundPredicate(WhereBoundPredicate { + bounded_ty, + bounds, + bound_generic_params, + span: _, + }) => { + walk_list!(visitor, visit_generic_param, bound_generic_params); + try_visit!(visitor.visit_ty(bounded_ty)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + } + WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => { + try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + } + WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => { + try_visit!(visitor.visit_ty(lhs_ty)); + try_visit!(visitor.visit_ty(rhs_ty)); + } + } + V::Result::output() + } + + pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) -> V::Result { + match ret_ty { + FnRetTy::Default(_span) => {} + FnRetTy::Ty(output_ty) => try_visit!(visitor.visit_ty(output_ty)), + } + V::Result::output() + } + + pub fn walk_fn_decl<'a, V: Visitor<'a>>( + visitor: &mut V, + FnDecl { inputs, output }: &'a FnDecl, + ) -> V::Result { + walk_list!(visitor, visit_param, inputs); + visitor.visit_fn_ret_ty(output) + } + + pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { + match kind { + FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => { + // Identifier and visibility are visited as a part of the item. + try_visit!(visitor.visit_fn_header(header)); + try_visit!(visitor.visit_generics(generics)); + try_visit!(walk_fn_decl(visitor, decl)); + visit_opt!(visitor, visit_block, body); + } + FnKind::Closure(binder, _coroutine_kind, decl, body) => { + try_visit!(visitor.visit_closure_binder(binder)); + try_visit!(walk_fn_decl(visitor, decl)); + try_visit!(visitor.visit_expr(body)); + } + } + V::Result::output() + } + + impl WalkItemKind for AssocItemKind { + fn walk<'a, V: Visitor<'a>>( + &'a self, + item: &'a Item, + ctxt: AssocCtxt, + visitor: &mut V, + ) -> V::Result { + let &Item { id, span, ident, ref vis, .. } = item; + match self { + AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + let kind = + FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); + try_visit!(visitor.visit_fn(kind, span, id)); + } + AssocItemKind::Type(box TyAlias { + generics, + bounds, + ty, + defaultness: _, + where_clauses: _, + }) => { + try_visit!(visitor.visit_generics(generics)); + 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, + rename, + body, + from_glob: _, + }) => { + try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_path(path, *id)); + visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_block, body); + } + AssocItemKind::DelegationMac(box DelegationMac { + qself, + prefix, + suffixes, + body, + }) => { + try_visit!(walk_qself(visitor, 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_assoc_item<'a, V: Visitor<'a>>( + visitor: &mut V, + item: &'a Item, + ctxt: AssocCtxt, + ) -> V::Result { + let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_vis(vis)); + try_visit!(visitor.visit_ident(ident)); + try_visit!(kind.walk(item, 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()); + V::Result::output() + } + + pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result { + let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_vis(vis)); + visit_opt!(visitor, visit_ident, *ident); + try_visit!(visitor.visit_ty(ty)); + 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: _, could_be_bare_literal: _ } = 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 { + StmtKind::Let(local) => try_visit!(visitor.visit_local(local)), + StmtKind::Item(item) => try_visit!(visitor.visit_item(item)), + StmtKind::Expr(expr) | StmtKind::Semi(expr) => try_visit!(visitor.visit_expr(expr)), + StmtKind::Empty => {} + StmtKind::MacCall(mac) => { + let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_mac_call(mac)); + } + } + V::Result::output() + } + + 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) + } + + pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result { + let InlineAsm { + asm_macro: _, + template: _, + template_strs: _, + operands, + clobber_abis: _, + options: _, + line_spans: _, + } = asm; + for (op, _span) in operands { + match op { + InlineAsmOperand::In { expr, reg: _ } + | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } + | InlineAsmOperand::InOut { expr, reg: _, late: _ } => { + try_visit!(visitor.visit_expr(expr)) + } + InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} + InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { + try_visit!(visitor.visit_expr(in_expr)); + visit_opt!(visitor, visit_expr, out_expr); + } + InlineAsmOperand::Const { anon_const } => { + try_visit!(visitor.visit_anon_const(anon_const)) + } + InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)), + InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)), + } + } + V::Result::output() + } + + pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>( + visitor: &mut V, + InlineAsmSym { id, qself, path }: &'a InlineAsmSym, + ) -> V::Result { + try_visit!(walk_qself(visitor, qself)); + visitor.visit_path(path, *id) + } + + pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result { + let FormatArgs { span: _, template: _, arguments } = fmt; + for FormatArgument { kind, expr } in arguments.all_args() { + match kind { + FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { + try_visit!(visitor.visit_ident(*ident)) + } + FormatArgumentKind::Normal => {} + } + try_visit!(visitor.visit_expr(expr)); + } + V::Result::output() + } + + pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result { + let Expr { id, kind, span, attrs, tokens: _ } = expression; + walk_list!(visitor, visit_attribute, attrs); + match kind { + ExprKind::Array(subexpressions) => { + walk_list!(visitor, visit_expr, subexpressions); + } + ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)), + ExprKind::Repeat(element, count) => { + try_visit!(visitor.visit_expr(element)); + try_visit!(visitor.visit_anon_const(count)); + } + ExprKind::Struct(se) => { + let StructExpr { qself, path, fields, rest } = &**se; + try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_path(path, *id)); + walk_list!(visitor, visit_expr_field, fields); + match rest { + StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)), + StructRest::Rest(_span) => {} + StructRest::None => {} + } + } + ExprKind::Tup(subexpressions) => { + walk_list!(visitor, visit_expr, subexpressions); + } + ExprKind::Call(callee_expression, arguments) => { + try_visit!(visitor.visit_expr(callee_expression)); + walk_list!(visitor, visit_expr, arguments); + } + ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => { + try_visit!(visitor.visit_expr(receiver)); + try_visit!(visitor.visit_path_segment(seg)); + walk_list!(visitor, visit_expr, args); + } + ExprKind::Binary(_op, left_expression, right_expression) => { + try_visit!(visitor.visit_expr(left_expression)); + try_visit!(visitor.visit_expr(right_expression)); + } + ExprKind::AddrOf(_kind, _mutbl, subexpression) => { + try_visit!(visitor.visit_expr(subexpression)); + } + ExprKind::Unary(_op, subexpression) => { + try_visit!(visitor.visit_expr(subexpression)); + } + ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => { + try_visit!(visitor.visit_expr(subexpression)); + try_visit!(visitor.visit_ty(typ)); + } + ExprKind::Let(pat, expr, _span, _recovered) => { + try_visit!(visitor.visit_pat(pat)); + try_visit!(visitor.visit_expr(expr)); + } + ExprKind::If(head_expression, if_block, optional_else) => { + try_visit!(visitor.visit_expr(head_expression)); + try_visit!(visitor.visit_block(if_block)); + visit_opt!(visitor, visit_expr, optional_else); + } + ExprKind::While(subexpression, block, opt_label) => { + visit_opt!(visitor, visit_label, opt_label); + try_visit!(visitor.visit_expr(subexpression)); + try_visit!(visitor.visit_block(block)); + } + ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { + visit_opt!(visitor, visit_label, label); + try_visit!(visitor.visit_pat(pat)); + try_visit!(visitor.visit_expr(iter)); + try_visit!(visitor.visit_block(body)); + } + ExprKind::Loop(block, opt_label, _span) => { + visit_opt!(visitor, visit_label, opt_label); + try_visit!(visitor.visit_block(block)); + } + ExprKind::Match(subexpression, arms, _kind) => { + try_visit!(visitor.visit_expr(subexpression)); + walk_list!(visitor, visit_arm, arms); + } + ExprKind::Closure(box Closure { + binder, + capture_clause, + coroutine_kind, + constness: _, + movability: _, + fn_decl, + body, + fn_decl_span: _, + fn_arg_span: _, + }) => { + try_visit!(visitor.visit_capture_by(capture_clause)); + try_visit!(visitor.visit_fn( + FnKind::Closure(binder, coroutine_kind, fn_decl, body), + *span, + *id + )) + } + ExprKind::Block(block, opt_label) => { + visit_opt!(visitor, visit_label, opt_label); + try_visit!(visitor.visit_block(block)); + } + ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)), + ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)), + ExprKind::Assign(lhs, rhs, _span) => { + try_visit!(visitor.visit_expr(lhs)); + try_visit!(visitor.visit_expr(rhs)); + } + ExprKind::AssignOp(_op, left_expression, right_expression) => { + try_visit!(visitor.visit_expr(left_expression)); + try_visit!(visitor.visit_expr(right_expression)); + } + ExprKind::Field(subexpression, ident) => { + try_visit!(visitor.visit_expr(subexpression)); + try_visit!(visitor.visit_ident(*ident)); + } + ExprKind::Index(main_expression, index_expression, _span) => { + try_visit!(visitor.visit_expr(main_expression)); + try_visit!(visitor.visit_expr(index_expression)); + } + ExprKind::Range(start, end, _limit) => { + visit_opt!(visitor, visit_expr, start); + visit_opt!(visitor, visit_expr, end); + } + ExprKind::Underscore => {} + ExprKind::Path(maybe_qself, path) => { + try_visit!(walk_qself(visitor, maybe_qself)); + try_visit!(visitor.visit_path(path, *id)); + } + ExprKind::Break(opt_label, opt_expr) => { + visit_opt!(visitor, visit_label, opt_label); + visit_opt!(visitor, visit_expr, opt_expr); + } + ExprKind::Continue(opt_label) => { + visit_opt!(visitor, visit_label, opt_label); + } + ExprKind::Ret(optional_expression) => { + visit_opt!(visitor, visit_expr, optional_expression); + } + ExprKind::Yeet(optional_expression) => { + visit_opt!(visitor, visit_expr, optional_expression); + } + ExprKind::Become(expr) => try_visit!(visitor.visit_expr(expr)), + ExprKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), + ExprKind::Paren(subexpression) => try_visit!(visitor.visit_expr(subexpression)), + ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), + ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)), + ExprKind::OffsetOf(container, fields) => { + try_visit!(visitor.visit_ty(container)); + walk_list!(visitor, visit_ident, fields.iter().copied()); + } + ExprKind::Yield(optional_expression) => { + visit_opt!(visitor, visit_expr, optional_expression); + } + ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)), + ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)), + ExprKind::Lit(_token) => {} + ExprKind::IncludedBytes(_bytes) => {} + ExprKind::Err(_guar) => {} + ExprKind::Dummy => {} + } + + visitor.visit_expr_post(expression) + } + + pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result { + let Param { attrs, ty, pat, id: _, span: _, is_placeholder: _ } = param; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_pat(pat)); + try_visit!(visitor.visit_ty(ty)); + V::Result::output() + } + + pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result { + let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_pat(pat)); + visit_opt!(visitor, visit_expr, guard); + visit_opt!(visitor, visit_expr, body); + V::Result::output() + } + + pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result { + let Visibility { kind, span: _, tokens: _ } = vis; + match kind { + VisibilityKind::Restricted { path, id, shorthand: _ } => { + try_visit!(visitor.visit_path(path, *id)); + } + VisibilityKind::Public | VisibilityKind::Inherited => {} + } + V::Result::output() + } + + pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result { + let Attribute { kind, id: _, style: _, span: _ } = attr; + match kind { + 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!(walk_attr_args(visitor, args)); + } + AttrKind::DocComment(_kind, _sym) => {} + } + V::Result::output() + } + + pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -> V::Result { + match args { + AttrArgs::Empty => {} + AttrArgs::Delimited(_args) => {} + AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => try_visit!(visitor.visit_expr(expr)), + AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { + unreachable!("in literal form when walking mac args eq: {:?}", lit) + } + } + V::Result::output() + } +} + +pub mod mut_visit { + //! A `MutVisitor` represents an AST modification; it accepts an AST piece and + //! mutates it in place. So, for instance, macro expansion is a `MutVisitor` + //! that walks over an AST and modifies it. + //! + //! Note: using a `MutVisitor` (other than the `MacroExpander` `MutVisitor`) on + //! an AST before macro expansion is probably a bad idea. For instance, + //! a `MutVisitor` renaming item names in a module will miss all of those + //! that are created by the expansion of a macro. + + use std::ops::DerefMut; + use std::panic; + + use rustc_data_structures::flat_map_in_place::FlatMapInPlace; + use rustc_data_structures::stack::ensure_sufficient_stack; + use rustc_data_structures::sync::Lrc; + use rustc_span::Span; + use rustc_span::source_map::Spanned; + use rustc_span::symbol::Ident; + use smallvec::{Array, SmallVec, smallvec}; + use thin_vec::ThinVec; + + use crate::ast::*; + use crate::ptr::P; + use crate::token::{self, Token}; + use crate::tokenstream::*; + use crate::visit::{AssocCtxt, BoundKind}; + + pub trait ExpectOne { + fn expect_one(self, err: &'static str) -> A::Item; + } + + impl ExpectOne for SmallVec { + fn expect_one(self, err: &'static str) -> A::Item { + assert!(self.len() == 1, "{}", err); + self.into_iter().next().unwrap() + } + } + + pub trait WalkItemKind { + fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor); + } + + pub trait MutVisitor: Sized { + /// Mutable token visiting only exists for the `macro_rules` token marker and should not be + /// used otherwise. Token visitor would be entirely separate from the regular visitor if + /// the marker didn't have to visit AST fragments in nonterminal tokens. + const VISIT_TOKENS: bool = false; + + // Methods in this trait have one of three forms: + // + // fn visit_t(&mut self, t: &mut T); // common + // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare + // fn filter_map_t(&mut self, t: T) -> Option; // 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) { + // visit_a(a); + // visit_b(b); + // } + // + // than to use field access like this: + // + // fn visit_abc(&mut self, abc: &mut ABC) { + // visit_a(&mut abc.a); + // visit_b(&mut abc.b); + // // ignore abc.c + // } + // + // As well as being more concise, the former is explicit about which fields + // are skipped. Furthermore, if a new field is added, the destructuring + // version will cause a compile error, which is good. In comparison, the + // field access version will continue working and it would be easy to + // forget to add handling for it. + + fn visit_crate(&mut self, c: &mut Crate) { + walk_crate(self, c) + } + + fn visit_meta_list_item(&mut self, list_item: &mut MetaItemInner) { + walk_meta_list_item(self, list_item); + } + + fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { + walk_meta_item(self, meta_item); + } + + fn visit_use_tree(&mut self, use_tree: &mut UseTree) { + walk_use_tree(self, use_tree); + } + + fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { + walk_flat_map_item(self, ni) + } + + fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { + walk_flat_map_item(self, i) + } + + fn visit_fn_header(&mut self, header: &mut FnHeader) { + walk_fn_header(self, header); + } + + fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { + walk_flat_map_field_def(self, fd) + } + + fn flat_map_assoc_item( + &mut self, + i: P, + _ctxt: AssocCtxt, + ) -> SmallVec<[P; 1]> { + walk_flat_map_item(self, i) + } + + fn visit_fn_decl(&mut self, d: &mut P) { + walk_fn_decl(self, d); + } + + /// `Span` and `NodeId` are mutated at the caller site. + fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) { + walk_fn(self, fk) + } + + fn visit_coroutine_kind(&mut self, a: &mut CoroutineKind) { + walk_coroutine_kind(self, a); + } + + fn visit_closure_binder(&mut self, b: &mut ClosureBinder) { + walk_closure_binder(self, b); + } + + fn visit_block(&mut self, b: &mut P) { + walk_block(self, b); + } + + fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { + walk_flat_map_stmt(self, s) + } + + fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { + walk_flat_map_arm(self, arm) + } + + fn visit_pat(&mut self, p: &mut P) { + walk_pat(self, p); + } + + fn visit_anon_const(&mut self, c: &mut AnonConst) { + walk_anon_const(self, c); + } + + fn visit_expr(&mut self, e: &mut P) { + walk_expr(self, e); + } + + /// This method is a hack to workaround unstable of `stmt_expr_attributes`. + /// It can be removed once that feature is stabilized. + fn visit_method_receiver_expr(&mut self, ex: &mut P) { + self.visit_expr(ex) + } + + fn filter_map_expr(&mut self, e: P) -> Option> { + noop_filter_map_expr(self, e) + } + + fn visit_generic_arg(&mut self, arg: &mut GenericArg) { + walk_generic_arg(self, arg); + } + + fn visit_ty(&mut self, t: &mut P) { + walk_ty(self, t); + } + + fn visit_lifetime(&mut self, l: &mut Lifetime) { + walk_lifetime(self, l); + } + + fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) { + walk_assoc_item_constraint(self, c); + } + + fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { + walk_foreign_mod(self, nm); + } + + fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { + walk_flat_map_variant(self, v) + } + + fn visit_ident(&mut self, i: &mut Ident) { + walk_ident(self, i); + } + + fn visit_path(&mut self, p: &mut Path) { + walk_path(self, p); + } + + fn visit_path_segment(&mut self, p: &mut PathSegment) { + walk_path_segment(self, p) + } + + fn visit_qself(&mut self, qs: &mut Option>) { + walk_qself(self, qs); + } + + fn visit_generic_args(&mut self, p: &mut GenericArgs) { + walk_generic_args(self, p); + } + + fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { + walk_angle_bracketed_parameter_data(self, p); + } + + fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { + walk_parenthesized_parameter_data(self, p); + } + + fn visit_local(&mut self, l: &mut P) { + walk_local(self, l); + } + + fn visit_mac_call(&mut self, mac: &mut MacCall) { + walk_mac(self, mac); + } + + fn visit_macro_def(&mut self, def: &mut MacroDef) { + walk_macro_def(self, def); + } + + fn visit_label(&mut self, label: &mut Label) { + walk_label(self, label); + } + + fn visit_attribute(&mut self, at: &mut Attribute) { + walk_attribute(self, at); + } + + fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { + walk_flat_map_param(self, param) + } + + fn visit_generics(&mut self, generics: &mut Generics) { + walk_generics(self, generics); + } + + fn visit_trait_ref(&mut self, tr: &mut TraitRef) { + walk_trait_ref(self, tr); + } + + fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { + walk_poly_trait_ref(self, p); + } + + fn visit_variant_data(&mut self, vdata: &mut VariantData) { + walk_variant_data(self, vdata); + } + + fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { + walk_flat_map_generic_param(self, param) + } + + fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) { + walk_param_bound(self, tpb); + } + + fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { + walk_precise_capturing_arg(self, arg); + } + + fn visit_mt(&mut self, mt: &mut MutTy) { + walk_mt(self, mt); + } + + fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { + walk_flat_map_expr_field(self, f) + } + + fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { + walk_where_clause(self, where_clause); + } + + fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { + walk_where_predicate(self, where_predicate); + } + + fn visit_vis(&mut self, vis: &mut Visibility) { + walk_vis(self, vis); + } + + fn visit_id(&mut self, _id: &mut NodeId) { + // Do nothing. + } + + fn visit_span(&mut self, _sp: &mut Span) { + // Do nothing. + } + + fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { + walk_flat_map_pat_field(self, fp) + } + + fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { + walk_inline_asm(self, asm) + } + + fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) { + walk_inline_asm_sym(self, sym) + } + + fn visit_format_args(&mut self, fmt: &mut FormatArgs) { + walk_format_args(self, fmt) + } + + fn visit_capture_by(&mut self, capture_by: &mut CaptureBy) { + walk_capture_by(self, capture_by) + } + } + + /// 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: &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(elems: &mut Vec, mut visit_elem: F) + where + F: FnMut(&mut T), + { + for elem in elems { + visit_elem(elem); + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + #[inline] + fn visit_thin_vec(elems: &mut ThinVec, mut visit_elem: F) + where + F: FnMut(&mut T), + { + for elem in elems { + visit_elem(elem); + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + #[inline] + fn visit_opt(opt: &mut Option, mut visit_elem: F) + where + F: FnMut(&mut T), + { + if let Some(elem) = opt { + visit_elem(elem); + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_attrs(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(vis: &mut T, exprs: &mut Vec>) { + 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(vis: &mut T, exprs: &mut ThinVec>) { + 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(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(vis: &mut T, args: &mut AttrArgs) { + match args { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => visit_delim_args(vis, args), + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { + vis.visit_expr(expr); + vis.visit_span(eq_span); + } + AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { + unreachable!("in literal form when visiting mac args eq: {:?}", lit) + } + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_delim_args(vis: &mut T, args: &mut DelimArgs) { + let DelimArgs { dspan, delim: _, tokens } = args; + visit_tts(vis, tokens); + visit_delim_span(vis, dspan); + } + + pub fn visit_delim_span(vis: &mut T, DelimSpan { open, close }: &mut DelimSpan) { + vis.visit_span(open); + vis.visit_span(close); + } + + pub fn walk_flat_map_pat_field( + vis: &mut T, + mut fp: PatField, + ) -> SmallVec<[PatField; 1]> { + let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; + vis.visit_id(id); + visit_attrs(vis, attrs); + vis.visit_ident(ident); + vis.visit_pat(pat); + vis.visit_span(span); + smallvec![fp] + } + + fn walk_use_tree(vis: &mut T, use_tree: &mut UseTree) { + let UseTree { prefix, kind, span } = use_tree; + vis.visit_path(prefix); + match kind { + UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)), + UseTreeKind::Nested { items, span } => { + for (tree, id) in items { + vis.visit_id(id); + vis.visit_use_tree(tree); + } + vis.visit_span(span); + } + UseTreeKind::Glob => {} + } + vis.visit_span(span); + } + + pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { + let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; + vis.visit_id(id); + visit_attrs(vis, attrs); + vis.visit_pat(pat); + visit_opt(guard, |guard| vis.visit_expr(guard)); + visit_opt(body, |body| vis.visit_expr(body)); + vis.visit_span(span); + smallvec![arm] + } + + fn walk_assoc_item_constraint( + vis: &mut T, + AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint, + ) { + vis.visit_id(id); + vis.visit_ident(ident); + if let Some(gen_args) = gen_args { + vis.visit_generic_args(gen_args); + } + match kind { + AssocItemConstraintKind::Equality { term } => match term { + Term::Ty(ty) => vis.visit_ty(ty), + Term::Const(c) => vis.visit_anon_const(c), + }, + AssocItemConstraintKind::Bound { bounds } => { + visit_bounds(vis, bounds, BoundKind::Bound) + } + } + vis.visit_span(span); + } + + pub fn walk_ty(vis: &mut T, ty: &mut P) { + 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::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_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), + } + visit_lazy_tts(vis, tokens); + vis.visit_span(span); + } + + fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { + let ForeignMod { safety, abi: _, items } = foreign_mod; + visit_safety(vis, safety); + items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); + } + + pub fn walk_flat_map_variant( + visitor: &mut T, + mut variant: Variant, + ) -> SmallVec<[Variant; 1]> { + let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = + &mut variant; + visitor.visit_id(id); + visit_attrs(visitor, attrs); + visitor.visit_vis(vis); + visitor.visit_ident(ident); + visitor.visit_variant_data(data); + visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); + visitor.visit_span(span); + smallvec![variant] + } + + fn walk_ident(vis: &mut T, Ident { name: _, span }: &mut Ident) { + vis.visit_span(span); + } + + fn walk_path_segment(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(vis: &mut T, Path { segments, span, tokens }: &mut Path) { + for segment in segments { + vis.visit_path_segment(segment); + } + visit_lazy_tts(vis, tokens); + vis.visit_span(span); + } + + fn walk_qself(vis: &mut T, qself: &mut Option>) { + visit_opt(qself, |qself| { + let QSelf { ty, path_span, position: _ } = &mut **qself; + vis.visit_ty(ty); + vis.visit_span(path_span); + }) + } + + fn walk_generic_args(vis: &mut T, generic_args: &mut GenericArgs) { + match generic_args { + GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), + GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), + GenericArgs::ParenthesizedElided(span) => vis.visit_span(span), + } + } + + fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { + match arg { + GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), + GenericArg::Type(ty) => vis.visit_ty(ty), + GenericArg::Const(ct) => vis.visit_anon_const(ct), + } + } + + fn walk_angle_bracketed_parameter_data( + vis: &mut T, + data: &mut AngleBracketedArgs, + ) { + let AngleBracketedArgs { args, span } = data; + visit_thin_vec(args, |arg| match arg { + AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), + AngleBracketedArg::Constraint(constraint) => { + vis.visit_assoc_item_constraint(constraint) + } + }); + vis.visit_span(span); + } + + fn walk_parenthesized_parameter_data(vis: &mut T, args: &mut ParenthesizedArgs) { + let ParenthesizedArgs { inputs, output, span, inputs_span } = args; + visit_thin_vec(inputs, |input| vis.visit_ty(input)); + walk_fn_ret_ty(vis, output); + vis.visit_span(span); + vis.visit_span(inputs_span); + } + + fn walk_local(vis: &mut T, local: &mut P) { + let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut(); + vis.visit_id(id); + visit_attrs(vis, attrs); + vis.visit_pat(pat); + visit_opt(ty, |ty| vis.visit_ty(ty)); + match kind { + LocalKind::Decl => {} + LocalKind::Init(init) => { + vis.visit_expr(init); + } + LocalKind::InitElse(init, els) => { + vis.visit_expr(init); + vis.visit_block(els); + } + } + visit_lazy_tts(vis, tokens); + visit_opt(colon_sp, |sp| vis.visit_span(sp)); + vis.visit_span(span); + } + + fn walk_attribute(vis: &mut T, attr: &mut Attribute) { + let Attribute { kind, id: _, style: _, span } = attr; + match kind { + AttrKind::Normal(normal) => { + let NormalAttr { + item: AttrItem { unsafety: _, path, args, tokens }, + tokens: attr_tokens, + } = &mut **normal; + vis.visit_path(path); + visit_attr_args(vis, args); + visit_lazy_tts(vis, tokens); + visit_lazy_tts(vis, attr_tokens); + } + AttrKind::DocComment(_kind, _sym) => {} + } + vis.visit_span(span); + } + + fn walk_mac(vis: &mut T, mac: &mut MacCall) { + let MacCall { path, args } = mac; + vis.visit_path(path); + visit_delim_args(vis, args); + } + + fn walk_macro_def(vis: &mut T, macro_def: &mut MacroDef) { + let MacroDef { body, macro_rules: _ } = macro_def; + visit_delim_args(vis, body); + } + + fn walk_meta_list_item(vis: &mut T, li: &mut MetaItemInner) { + match li { + MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi), + MetaItemInner::Lit(_lit) => {} + } + } + + fn walk_meta_item(vis: &mut T, mi: &mut MetaItem) { + let MetaItem { unsafety: _, path: _, kind, span } = mi; + match kind { + MetaItemKind::Word => {} + MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)), + MetaItemKind::NameValue(_s) => {} + } + vis.visit_span(span); + } + + pub fn walk_flat_map_param( + vis: &mut T, + mut param: Param, + ) -> SmallVec<[Param; 1]> { + let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; + vis.visit_id(id); + visit_attrs(vis, attrs); + vis.visit_pat(pat); + vis.visit_ty(ty); + vis.visit_span(span); + smallvec![param] + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_attr_tt(vis: &mut T, tt: &mut AttrTokenTree) { + match tt { + AttrTokenTree::Token(token, _spacing) => { + visit_token(vis, token); + } + AttrTokenTree::Delimited(dspan, _spacing, _delim, tts) => { + visit_attr_tts(vis, tts); + visit_delim_span(vis, dspan); + } + AttrTokenTree::AttrsTarget(AttrsTarget { attrs, tokens }) => { + visit_attrs(vis, attrs); + visit_lazy_tts_opt_mut(vis, Some(tokens)); + } + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_tt(vis: &mut T, tt: &mut TokenTree) { + match tt { + TokenTree::Token(token, _spacing) => { + visit_token(vis, token); + } + TokenTree::Delimited(dspan, _spacing, _delim, tts) => { + visit_tts(vis, tts); + visit_delim_span(vis, dspan); + } + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_tts(vis: &mut T, TokenStream(tts): &mut TokenStream) { + if T::VISIT_TOKENS && !tts.is_empty() { + let tts = Lrc::make_mut(tts); + visit_vec(tts, |tree| visit_tt(vis, tree)); + } + } + + fn visit_attr_tts(vis: &mut T, AttrTokenStream(tts): &mut AttrTokenStream) { + if T::VISIT_TOKENS && !tts.is_empty() { + let tts = Lrc::make_mut(tts); + visit_vec(tts, |tree| visit_attr_tt(vis, tree)); + } + } + + fn visit_lazy_tts_opt_mut( + vis: &mut T, + lazy_tts: Option<&mut LazyAttrTokenStream>, + ) { + if T::VISIT_TOKENS { + if let Some(lazy_tts) = lazy_tts { + let mut tts = lazy_tts.to_attr_token_stream(); + visit_attr_tts(vis, &mut tts); + *lazy_tts = LazyAttrTokenStream::new(tts); + } + } + } + + fn visit_lazy_tts(vis: &mut T, lazy_tts: &mut Option) { + visit_lazy_tts_opt_mut(vis, lazy_tts.as_mut()); + } + + /// Applies ident visitor if it's an ident; applies other visits to interpolated nodes. + /// In practice the ident part is not actually used by specific visitors right now, + /// but there's a test below checking that it works. + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + pub fn visit_token(vis: &mut T, t: &mut Token) { + let Token { kind, span } = t; + match kind { + token::Ident(name, _is_raw) | token::Lifetime(name, _is_raw) => { + let mut ident = Ident::new(*name, *span); + vis.visit_ident(&mut ident); + *name = ident.name; + *span = ident.span; + return; // Avoid visiting the span for the second time. + } + token::NtIdent(ident, _is_raw) => { + vis.visit_ident(ident); + } + token::NtLifetime(ident, _is_raw) => { + vis.visit_ident(ident); + } + token::Interpolated(nt) => { + let nt = Lrc::make_mut(nt); + visit_nonterminal(vis, nt); + } + _ => {} + } + vis.visit_span(span); + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + /// Applies the visitor to elements of interpolated nodes. + // + // N.B., this can occur only when applying a visitor to partially expanded + // code, where parsed pieces have gotten implanted ito *other* macro + // invocations. This is relevant for macro hygiene, but possibly not elsewhere. + // + // One problem here occurs because the types for flat_map_item, flat_map_stmt, + // etc., allow the visitor to return *multiple* items; this is a problem for the + // nodes here, because they insist on having exactly one piece. One solution + // would be to mangle the MutVisitor trait to include one-to-many and + // one-to-one versions of these entry points, but that would probably confuse a + // lot of people and help very few. Instead, I'm just going to put in dynamic + // checks. I think the performance impact of this will be pretty much + // nonexistent. The danger is that someone will apply a `MutVisitor` to a + // partially expanded node, and will be confused by the fact that their + // `flat_map_item` or `flat_map_stmt` isn't getting called on `NtItem` or `NtStmt` + // nodes. Hopefully they'll wind up reading this comment, and doing something + // appropriate. + // + // BTW, design choice: I considered just changing the type of, e.g., `NtItem` to + // contain multiple items, but decided against it when I looked at + // `parse_item_or_view_item` and tried to figure out what I would do with + // multiple items there.... + fn visit_nonterminal(vis: &mut T, nt: &mut token::Nonterminal) { + match nt { + token::NtItem(item) => visit_clobber(item, |item| { + // This is probably okay, because the only visitors likely to + // peek inside interpolated nodes will be renamings/markings, + // which map single items to single items. + vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item") + }), + token::NtBlock(block) => vis.visit_block(block), + token::NtStmt(stmt) => visit_clobber(stmt, |stmt| { + // See reasoning above. + stmt.map(|stmt| { + vis.flat_map_stmt(stmt) + .expect_one("expected visitor to produce exactly one item") + }) + }), + token::NtPat(pat) => vis.visit_pat(pat), + token::NtExpr(expr) => vis.visit_expr(expr), + token::NtTy(ty) => vis.visit_ty(ty), + token::NtLiteral(expr) => vis.visit_expr(expr), + token::NtMeta(item) => { + let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); + vis.visit_path(path); + visit_attr_args(vis, args); + visit_lazy_tts(vis, tokens); + } + token::NtPath(path) => vis.visit_path(path), + token::NtVis(visib) => vis.visit_vis(visib), + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_defaultness(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_safety(vis: &mut T, safety: &mut Safety) { + match safety { + Safety::Unsafe(span) => vis.visit_span(span), + Safety::Safe(span) => vis.visit_span(span), + Safety::Default => {} + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_polarity(vis: &mut T, polarity: &mut ImplPolarity) { + match polarity { + ImplPolarity::Positive => {} + ImplPolarity::Negative(span) => vis.visit_span(span), + } + } + + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. + fn visit_constness(vis: &mut T, constness: &mut Const) { + match constness { + Const::Yes(span) => vis.visit_span(span), + Const::No => {} + } + } + + fn walk_closure_binder(vis: &mut T, binder: &mut ClosureBinder) { + match binder { + ClosureBinder::NotPresent => {} + ClosureBinder::For { span: _, generic_params } => { + generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + } + } + } + + fn walk_coroutine_kind(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(vis: &mut T, kind: FnKind<'_>) { + match kind { + FnKind::Fn(FnSig { header, decl, span }, generics, body) => { + // Identifier and visibility are visited as a part of the item. + vis.visit_fn_header(header); + vis.visit_generics(generics); + vis.visit_fn_decl(decl); + if let Some(body) = body { + vis.visit_block(body); + } + vis.visit_span(span); + } + FnKind::Closure(binder, decl, body) => { + vis.visit_closure_binder(binder); + vis.visit_fn_decl(decl); + vis.visit_expr(body); + } + } + } + + fn walk_fn_decl(vis: &mut T, decl: &mut P) { + let FnDecl { inputs, output } = decl.deref_mut(); + inputs.flat_map_in_place(|param| vis.flat_map_param(param)); + walk_fn_ret_ty(vis, output); + } + + fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { + match fn_ret_ty { + FnRetTy::Default(span) => vis.visit_span(span), + FnRetTy::Ty(ty) => vis.visit_ty(ty), + } + } + + fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { + match pb { + GenericBound::Trait(ty) => vis.visit_poly_trait_ref(ty), + GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime), + GenericBound::Use(args, span) => { + for arg in args { + vis.visit_precise_capturing_arg(arg); + } + vis.visit_span(span); + } + } + } + + fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCapturingArg) { + match arg { + PreciseCapturingArg::Lifetime(lt) => { + vis.visit_lifetime(lt); + } + PreciseCapturingArg::Arg(path, id) => { + vis.visit_id(id); + vis.visit_path(path); + } + } + } + + pub fn walk_flat_map_generic_param( + vis: &mut T, + mut param: GenericParam, + ) -> SmallVec<[GenericParam; 1]> { + let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = + &mut param; + vis.visit_id(id); + visit_attrs(vis, attrs); + vis.visit_ident(ident); + visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); + match kind { + GenericParamKind::Lifetime => {} + GenericParamKind::Type { default } => { + visit_opt(default, |default| vis.visit_ty(default)); + } + GenericParamKind::Const { ty, kw_span: _, default } => { + vis.visit_ty(ty); + visit_opt(default, |default| vis.visit_anon_const(default)); + } + } + if let Some(colon_span) = colon_span { + vis.visit_span(colon_span); + } + smallvec![param] + } + + fn walk_label(vis: &mut T, Label { ident }: &mut Label) { + vis.visit_ident(ident); + } + + fn walk_lifetime(vis: &mut T, Lifetime { id, ident }: &mut Lifetime) { + vis.visit_id(id); + vis.visit_ident(ident); + } + + fn walk_generics(vis: &mut T, generics: &mut Generics) { + let Generics { params, where_clause, span } = generics; + params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + vis.visit_where_clause(where_clause); + vis.visit_span(span); + } + + fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWhereClauses) { + let TyAliasWhereClauses { before, after, split: _ } = tawcs; + let TyAliasWhereClause { has_where_token: _, span: span_before } = before; + let TyAliasWhereClause { has_where_token: _, span: span_after } = after; + vis.visit_span(span_before); + vis.visit_span(span_after); + } + + fn walk_where_clause(vis: &mut T, wc: &mut WhereClause) { + let WhereClause { has_where_token: _, predicates, span } = wc; + visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); + vis.visit_span(span); + } + + fn walk_where_predicate(vis: &mut T, pred: &mut WherePredicate) { + match pred { + WherePredicate::BoundPredicate(bp) => { + let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; + bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + vis.visit_ty(bounded_ty); + visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); + vis.visit_span(span); + } + WherePredicate::RegionPredicate(rp) => { + let WhereRegionPredicate { span, lifetime, bounds } = rp; + vis.visit_lifetime(lifetime); + visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); + vis.visit_span(span); + } + WherePredicate::EqPredicate(ep) => { + let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep; + vis.visit_ty(lhs_ty); + vis.visit_ty(rhs_ty); + vis.visit_span(span); + } + } + } + + fn walk_variant_data(vis: &mut T, vdata: &mut VariantData) { + match vdata { + VariantData::Struct { fields, recovered: _ } => { + fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); + } + VariantData::Tuple(fields, id) => { + vis.visit_id(id); + fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); + } + VariantData::Unit(id) => vis.visit_id(id), + } + } + + fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) { + vis.visit_id(ref_id); + vis.visit_path(path); + } + + fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { + let PolyTraitRef { bound_generic_params, trait_ref, span, modifiers: _ } = p; + bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + vis.visit_trait_ref(trait_ref); + vis.visit_span(span); + } + + pub fn walk_flat_map_field_def( + visitor: &mut T, + mut fd: FieldDef, + ) -> SmallVec<[FieldDef; 1]> { + let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; + visitor.visit_id(id); + visit_attrs(visitor, attrs); + visitor.visit_vis(vis); + visit_opt(ident, |ident| visitor.visit_ident(ident)); + visitor.visit_ty(ty); + visitor.visit_span(span); + smallvec![fd] + } + + pub fn walk_flat_map_expr_field( + vis: &mut T, + mut f: ExprField, + ) -> SmallVec<[ExprField; 1]> { + let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; + vis.visit_id(id); + visit_attrs(vis, attrs); + vis.visit_ident(ident); + vis.visit_expr(expr); + vis.visit_span(span); + smallvec![f] + } + + fn walk_mt(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) { + vis.visit_ty(ty); + } + + pub fn walk_block(vis: &mut T, block: &mut P) { + let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = + block.deref_mut(); + vis.visit_id(id); + stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); + visit_lazy_tts(vis, tokens); + vis.visit_span(span); + } + + pub fn walk_item_kind( + kind: &mut impl WalkItemKind, + span: Span, + id: NodeId, + vis: &mut impl MutVisitor, + ) { + kind.walk(span, id, vis) + } + + impl WalkItemKind for ItemKind { + fn walk(&mut self, span: Span, id: NodeId, vis: &mut impl MutVisitor) { + match self { + ItemKind::ExternCrate(_orig_name) => {} + ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), + ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { + vis.visit_ty(ty); + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ItemKind::Const(item) => { + visit_const_item(item, vis); + } + ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + visit_defaultness(vis, defaultness); + vis.visit_fn(FnKind::Fn(sig, generics, body), span, id); + } + ItemKind::Mod(safety, mod_kind) => { + visit_safety(vis, safety); + 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, + generics, + where_clauses, + bounds, + ty, + }) => { + visit_defaultness(vis, defaultness); + 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(EnumDef { variants }, generics) => { + vis.visit_generics(generics); + variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); + } + ItemKind::Struct(variant_data, generics) + | ItemKind::Union(variant_data, generics) => { + 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)); + } + ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { + visit_safety(vis, safety); + 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(generics, bounds) => { + vis.visit_generics(generics); + visit_bounds(vis, bounds, BoundKind::Bound); + } + ItemKind::MacCall(m) => vis.visit_mac_call(m), + ItemKind::MacroDef(def) => vis.visit_macro_def(def), + ItemKind::Delegation(box Delegation { + id, + qself, + path, + rename, + body, + from_glob: _, + }) => { + vis.visit_id(id); + vis.visit_qself(qself); + vis.visit_path(path); + 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 { + fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) { + match self { + AssocItemKind::Const(item) => { + visit_const_item(item, visitor); + } + AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + visit_defaultness(visitor, defaultness); + visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); + } + AssocItemKind::Type(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + }) => { + visit_defaultness(visitor, defaultness); + 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, + rename, + body, + from_glob: _, + }) => { + visitor.visit_id(id); + visitor.visit_qself(qself); + visitor.visit_path(path); + 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 visit_const_item( + ConstItem { defaultness, generics, ty, expr }: &mut ConstItem, + visitor: &mut T, + ) { + visit_defaultness(visitor, defaultness); + visitor.visit_generics(generics); + visitor.visit_ty(ty); + visit_opt(expr, |expr| visitor.visit_expr(expr)); + } + + fn walk_fn_header(vis: &mut T, header: &mut FnHeader) { + let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; + visit_constness(vis, constness); + coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); + visit_safety(vis, safety); + } + + pub fn walk_crate(vis: &mut T, krate: &mut Crate) { + let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; + vis.visit_id(id); + visit_attrs(vis, attrs); + items.flat_map_in_place(|item| vis.flat_map_item(item)); + let ModSpans { inner_span, inject_use_span } = spans; + vis.visit_span(inner_span); + vis.visit_span(inject_use_span); + } + + /// Mutates one item, returning the item again. + pub fn walk_flat_map_item( + visitor: &mut impl MutVisitor, + mut item: P>, + ) -> SmallVec<[P>; 1]> { + let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); + visitor.visit_id(id); + visit_attrs(visitor, attrs); + visitor.visit_vis(vis); + visitor.visit_ident(ident); + kind.walk(*span, *id, visitor); + visit_lazy_tts(visitor, tokens); + visitor.visit_span(span); + smallvec![item] + } + + impl WalkItemKind for ForeignItemKind { + fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) { + match self { + ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { + visitor.visit_ty(ty); + visit_opt(expr, |expr| visitor.visit_expr(expr)); + } + ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + visit_defaultness(visitor, defaultness); + visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); + } + ForeignItemKind::TyAlias(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + }) => { + visit_defaultness(visitor, defaultness); + 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(vis: &mut T, pat: &mut P) { + let Pat { id, kind, span, tokens } = pat.deref_mut(); + vis.visit_id(id); + match kind { + PatKind::Err(_guar) => {} + 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::Lit(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::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), + } + visit_lazy_tts(vis, tokens); + vis.visit_span(span); + } + + fn walk_anon_const(vis: &mut T, AnonConst { id, value }: &mut AnonConst) { + vis.visit_id(id); + vis.visit_expr(value); + } + + fn walk_inline_asm(vis: &mut T, asm: &mut InlineAsm) { + // FIXME: Visit spans inside all this currently ignored stuff. + let InlineAsm { + asm_macro: _, + template: _, + template_strs: _, + operands, + clobber_abis: _, + options: _, + line_spans: _, + } = asm; + for (op, span) in operands { + match op { + InlineAsmOperand::In { expr, reg: _ } + | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } + | InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr), + InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} + InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { + vis.visit_expr(in_expr); + if let Some(out_expr) = out_expr { + vis.visit_expr(out_expr); + } + } + InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const), + InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym), + InlineAsmOperand::Label { block } => vis.visit_block(block), + } + vis.visit_span(span); + } + } + + fn walk_inline_asm_sym( + vis: &mut T, + InlineAsmSym { id, qself, path }: &mut InlineAsmSym, + ) { + vis.visit_id(id); + vis.visit_qself(qself); + vis.visit_path(path); + } + + fn walk_format_args(vis: &mut T, fmt: &mut FormatArgs) { + // FIXME: visit the template exhaustively. + let FormatArgs { span, template: _, arguments } = fmt; + for FormatArgument { kind, expr } in arguments.all_args_mut() { + match kind { + FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { + vis.visit_ident(ident) + } + FormatArgumentKind::Normal => {} + } + vis.visit_expr(expr); + } + vis.visit_span(span); + } + + pub fn walk_expr( + vis: &mut T, + Expr { kind, id, span, attrs, tokens }: &mut Expr, + ) { + vis.visit_id(id); + visit_attrs(vis, attrs); + match kind { + ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs), + ExprKind::ConstBlock(anon_const) => { + vis.visit_anon_const(anon_const); + } + ExprKind::Repeat(expr, count) => { + vis.visit_expr(expr); + vis.visit_anon_const(count); + } + ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs), + ExprKind::Call(f, args) => { + vis.visit_expr(f); + visit_thin_exprs(vis, args); + } + ExprKind::MethodCall(box MethodCall { + seg: PathSegment { ident, id, args: seg_args }, + receiver, + args: call_args, + span, + }) => { + vis.visit_method_receiver_expr(receiver); + vis.visit_id(id); + vis.visit_ident(ident); + visit_opt(seg_args, |args| vis.visit_generic_args(args)); + visit_thin_exprs(vis, call_args); + vis.visit_span(span); + } + ExprKind::Binary(_binop, lhs, rhs) => { + vis.visit_expr(lhs); + vis.visit_expr(rhs); + } + ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), + ExprKind::Cast(expr, ty) => { + vis.visit_expr(expr); + vis.visit_ty(ty); + } + ExprKind::Type(expr, ty) => { + vis.visit_expr(expr); + vis.visit_ty(ty); + } + ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs), + ExprKind::Let(pat, scrutinee, span, _recovered) => { + vis.visit_pat(pat); + vis.visit_expr(scrutinee); + vis.visit_span(span); + } + ExprKind::If(cond, tr, fl) => { + vis.visit_expr(cond); + vis.visit_block(tr); + visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl))); + } + ExprKind::While(cond, body, label) => { + visit_opt(label, |label| vis.visit_label(label)); + vis.visit_expr(cond); + vis.visit_block(body); + } + ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { + visit_opt(label, |label| vis.visit_label(label)); + vis.visit_pat(pat); + vis.visit_expr(iter); + vis.visit_block(body); + } + ExprKind::Loop(body, label, span) => { + visit_opt(label, |label| vis.visit_label(label)); + vis.visit_block(body); + vis.visit_span(span); + } + ExprKind::Match(expr, arms, _kind) => { + vis.visit_expr(expr); + arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); + } + ExprKind::Closure(box Closure { + binder, + capture_clause, + constness, + coroutine_kind, + movability: _, + fn_decl, + body, + fn_decl_span, + fn_arg_span, + }) => { + visit_constness(vis, constness); + coroutine_kind + .as_mut() + .map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); + vis.visit_capture_by(capture_clause); + vis.visit_fn(FnKind::Closure(binder, fn_decl, body), *span, *id); + vis.visit_span(fn_decl_span); + vis.visit_span(fn_arg_span); + } + ExprKind::Block(blk, label) => { + visit_opt(label, |label| vis.visit_label(label)); + vis.visit_block(blk); + } + ExprKind::Gen(_capture_by, body, _kind, decl_span) => { + vis.visit_block(body); + vis.visit_span(decl_span); + } + ExprKind::Await(expr, await_kw_span) => { + vis.visit_expr(expr); + vis.visit_span(await_kw_span); + } + ExprKind::Assign(el, er, span) => { + vis.visit_expr(el); + vis.visit_expr(er); + vis.visit_span(span); + } + ExprKind::AssignOp(_op, el, er) => { + vis.visit_expr(el); + vis.visit_expr(er); + } + ExprKind::Field(el, ident) => { + vis.visit_expr(el); + vis.visit_ident(ident); + } + ExprKind::Index(el, er, brackets_span) => { + vis.visit_expr(el); + vis.visit_expr(er); + vis.visit_span(brackets_span); + } + ExprKind::Range(e1, e2, _lim) => { + visit_opt(e1, |e1| vis.visit_expr(e1)); + visit_opt(e2, |e2| vis.visit_expr(e2)); + } + ExprKind::Underscore => {} + ExprKind::Path(qself, path) => { + vis.visit_qself(qself); + vis.visit_path(path); + } + ExprKind::Break(label, expr) => { + visit_opt(label, |label| vis.visit_label(label)); + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Continue(label) => { + visit_opt(label, |label| vis.visit_label(label)); + } + ExprKind::Ret(expr) => { + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Yeet(expr) => { + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Become(expr) => vis.visit_expr(expr), + ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), + ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), + ExprKind::OffsetOf(container, fields) => { + vis.visit_ty(container); + for field in fields.iter_mut() { + vis.visit_ident(field); + } + } + ExprKind::MacCall(mac) => vis.visit_mac_call(mac), + ExprKind::Struct(se) => { + let StructExpr { qself, path, fields, rest } = se.deref_mut(); + vis.visit_qself(qself); + vis.visit_path(path); + fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); + match rest { + StructRest::Base(expr) => vis.visit_expr(expr), + StructRest::Rest(_span) => {} + StructRest::None => {} + } + } + ExprKind::Paren(expr) => { + vis.visit_expr(expr); + } + ExprKind::Yield(expr) => { + visit_opt(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Try(expr) => vis.visit_expr(expr), + ExprKind::TryBlock(body) => vis.visit_block(body), + ExprKind::Lit(_token) => {} + ExprKind::IncludedBytes(_bytes) => {} + ExprKind::Err(_guar) => {} + ExprKind::Dummy => {} + } + visit_lazy_tts(vis, tokens); + vis.visit_span(span); + } + + pub fn noop_filter_map_expr(vis: &mut T, mut e: P) -> Option> { + Some({ + vis.visit_expr(&mut e); + e + }) + } + + pub fn walk_flat_map_stmt( + vis: &mut T, + Stmt { kind, mut span, mut id }: Stmt, + ) -> SmallVec<[Stmt; 1]> { + vis.visit_id(&mut id); + let stmts: SmallVec<_> = walk_flat_map_stmt_kind(vis, kind) + .into_iter() + .map(|kind| Stmt { id, kind, span }) + .collect(); + if stmts.len() > 1 { + panic!( + "cloning statement `NodeId`s is prohibited by default, \ + the visitor should implement custom statement visiting" + ); + } + vis.visit_span(&mut span); + stmts + } + + fn walk_flat_map_stmt_kind( + vis: &mut T, + kind: StmtKind, + ) -> SmallVec<[StmtKind; 1]> { + match kind { + StmtKind::Let(mut local) => smallvec![StmtKind::Let({ + vis.visit_local(&mut local); + local + })], + StmtKind::Item(item) => { + vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect() + } + StmtKind::Expr(expr) => { + vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect() + } + StmtKind::Semi(expr) => { + vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect() + } + StmtKind::Empty => smallvec![StmtKind::Empty], + StmtKind::MacCall(mut mac) => { + let MacCallStmt { mac: mac_, style: _, attrs, tokens } = mac.deref_mut(); + visit_attrs(vis, attrs); + vis.visit_mac_call(mac_); + visit_lazy_tts(vis, tokens); + smallvec![StmtKind::MacCall(mac)] + } + } + } + + fn walk_vis(vis: &mut T, visibility: &mut Visibility) { + let Visibility { kind, span, tokens } = visibility; + match kind { + VisibilityKind::Public | VisibilityKind::Inherited => {} + VisibilityKind::Restricted { path, id, shorthand: _ } => { + vis.visit_id(id); + vis.visit_path(path); + } + } + visit_lazy_tts(vis, tokens); + vis.visit_span(span); + } + + fn walk_capture_by(vis: &mut T, capture_by: &mut CaptureBy) { + match capture_by { + CaptureBy::Ref => {} + CaptureBy::Value { move_kw } => { + vis.visit_span(move_kw); + } + } + } + + /// 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 DummyAstNode for Option { + fn dummy() -> Self { + Default::default() + } + } + + impl DummyAstNode for P { + 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(), + }, + ident: Ident::empty(), + kind: ItemKind::ExternCrate(None), + 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 DummyAstNode for crate::ast_traits::AstNodeWrapper { + 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()`. + Fn(&'a mut FnSig, &'a mut Generics, &'a mut Option>), + + /// E.g., `|x, y| body`. + Closure(&'a mut ClosureBinder, &'a mut P, &'a mut P), + } +} From ad4a2f3dd68a33cc05b1a3c3e3aad79be01b962d Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 15:57:45 -0300 Subject: [PATCH 02/82] Pull uses out of modules --- compiler/rustc_ast/src/visitors.rs | 40 ++++++++++++++---------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 18bc0c83dfad3..be80034140cef 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -1,5 +1,21 @@ -pub mod visit { +use std::ops::DerefMut; +use std::panic; + +use rustc_data_structures::flat_map_in_place::FlatMapInPlace; +use rustc_data_structures::stack::ensure_sufficient_stack; +use rustc_data_structures::sync::Lrc; +use rustc_span::Span; +use rustc_span::source_map::Spanned; +use rustc_span::symbol::Ident; +use smallvec::{Array, SmallVec, smallvec}; +use thin_vec::ThinVec; + +use crate::ast::*; +use crate::ptr::P; +use crate::token::{self, Token}; +use crate::tokenstream::*; +pub mod visit { //! AST walker. Each overridden visit method has full control over what //! happens with its node, it can do its own traversal of the node's children, //! call `visit::walk_*` to apply the default traversal algorithm, or prevent @@ -17,11 +33,8 @@ pub mod visit { pub use rustc_ast_ir::visit::VisitorResult; pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list}; - use rustc_span::Span; - use rustc_span::symbol::Ident; - use crate::ast::*; - use crate::ptr::P; + use super::*; #[derive(Copy, Clone, Debug, PartialEq)] pub enum AssocCtxt { @@ -1282,22 +1295,7 @@ pub mod mut_visit { //! a `MutVisitor` renaming item names in a module will miss all of those //! that are created by the expansion of a macro. - use std::ops::DerefMut; - use std::panic; - - use rustc_data_structures::flat_map_in_place::FlatMapInPlace; - use rustc_data_structures::stack::ensure_sufficient_stack; - use rustc_data_structures::sync::Lrc; - use rustc_span::Span; - use rustc_span::source_map::Spanned; - use rustc_span::symbol::Ident; - use smallvec::{Array, SmallVec, smallvec}; - use thin_vec::ThinVec; - - use crate::ast::*; - use crate::ptr::P; - use crate::token::{self, Token}; - use crate::tokenstream::*; + use super::*; use crate::visit::{AssocCtxt, BoundKind}; pub trait ExpectOne { From ce290fa3fb9d456171fa261ac9d452411f14d157 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 16:23:13 -0300 Subject: [PATCH 03/82] Add macro_if! --- compiler/rustc_ast/src/visitors.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index be80034140cef..1296bfe8622a4 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -15,6 +15,16 @@ use crate::ptr::P; use crate::token::{self, Token}; use crate::tokenstream::*; +#[allow(unused)] +macro_rules! macro_if { + ($_: tt { $($if: tt)* } $(else {$($else: tt)*})?) => { + $($if)* + }; + ({ $($if: tt)* } $(else {$($else: tt)*})?) => { + $($($else)*)? + }; +} + pub mod visit { //! AST walker. Each overridden visit method has full control over what //! happens with its node, it can do its own traversal of the node's children, From eaaee58691fb39ee17769885726ab93f23abea38 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 16:39:31 -0300 Subject: [PATCH 04/82] Add make_ast_visitor! --- compiler/rustc_ast/src/visitors.rs | 931 +++++++++++++++-------------- 1 file changed, 469 insertions(+), 462 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 1296bfe8622a4..4a7063ff636ed 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -15,7 +15,6 @@ use crate::ptr::P; use crate::token::{self, Token}; use crate::tokenstream::*; -#[allow(unused)] macro_rules! macro_if { ($_: tt { $($if: tt)* } $(else {$($else: tt)*})?) => { $($if)* @@ -25,6 +24,473 @@ macro_rules! macro_if { }; } +macro_rules! make_ast_visitor { + ($trait: ident $(<$lt: lifetime>)? $(, $mut: ident)?) => { + /// Each method of the traits `Visitor` and `MutVisitor` 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; e.g., the `visit_item` method by default calls `walk_item`. + /// + /// If you want to ensure that your code handles every variant explicitly, + /// you need to override each method. (And you also need to monitor + /// future changes to this trait in case a new method with a new default + /// implementation gets introduced.) + pub trait $trait$(<$lt>)?: Sized { + macro_if!{$($mut)? { + /// Mutable token visiting only exists for the `macro_rules` token marker and should not be + /// used otherwise. Token visitor would be entirely separate from the regular visitor if + /// the marker didn't have to visit AST fragments in nonterminal tokens. + const VISIT_TOKENS: bool = false; + + // Methods in this trait have one of three forms: + // + // fn visit_t(&mut self, t: &mut T); // common + // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare + // fn filter_map_t(&mut self, t: T) -> Option; // 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) { + // visit_a(a); + // visit_b(b); + // } + // + // than to use field access like this: + // + // fn visit_abc(&mut self, abc: &mut ABC) { + // visit_a(&mut abc.a); + // visit_b(&mut abc.b); + // // ignore abc.c + // } + // + // As well as being more concise, the former is explicit about which fields + // are skipped. Furthermore, if a new field is added, the destructuring + // version will cause a compile error, which is good. In comparison, the + // field access version will continue working and it would be easy to + // forget to add handling for it. + + fn visit_crate(&mut self, c: &mut Crate) { + walk_crate(self, c) + } + + fn visit_meta_list_item(&mut self, list_item: &mut MetaItemInner) { + walk_meta_list_item(self, list_item); + } + + fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { + walk_meta_item(self, meta_item); + } + + fn visit_use_tree(&mut self, use_tree: &mut UseTree) { + walk_use_tree(self, use_tree); + } + + fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { + walk_flat_map_item(self, ni) + } + + fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { + walk_flat_map_item(self, i) + } + + fn visit_fn_header(&mut self, header: &mut FnHeader) { + walk_fn_header(self, header); + } + + fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { + walk_flat_map_field_def(self, fd) + } + + fn flat_map_assoc_item( + &mut self, + i: P, + _ctxt: AssocCtxt, + ) -> SmallVec<[P; 1]> { + walk_flat_map_item(self, i) + } + + fn visit_fn_decl(&mut self, d: &mut P) { + walk_fn_decl(self, d); + } + + /// `Span` and `NodeId` are mutated at the caller site. + fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) { + walk_fn(self, fk) + } + + fn visit_coroutine_kind(&mut self, a: &mut CoroutineKind) { + walk_coroutine_kind(self, a); + } + + fn visit_closure_binder(&mut self, b: &mut ClosureBinder) { + walk_closure_binder(self, b); + } + + fn visit_block(&mut self, b: &mut P) { + walk_block(self, b); + } + + fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { + walk_flat_map_stmt(self, s) + } + + fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { + walk_flat_map_arm(self, arm) + } + + fn visit_pat(&mut self, p: &mut P) { + walk_pat(self, p); + } + + fn visit_anon_const(&mut self, c: &mut AnonConst) { + walk_anon_const(self, c); + } + + fn visit_expr(&mut self, e: &mut P) { + walk_expr(self, e); + } + + /// This method is a hack to workaround unstable of `stmt_expr_attributes`. + /// It can be removed once that feature is stabilized. + fn visit_method_receiver_expr(&mut self, ex: &mut P) { + self.visit_expr(ex) + } + + fn filter_map_expr(&mut self, e: P) -> Option> { + noop_filter_map_expr(self, e) + } + + fn visit_generic_arg(&mut self, arg: &mut GenericArg) { + walk_generic_arg(self, arg); + } + + fn visit_ty(&mut self, t: &mut P) { + walk_ty(self, t); + } + + fn visit_lifetime(&mut self, l: &mut Lifetime) { + walk_lifetime(self, l); + } + + fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) { + walk_assoc_item_constraint(self, c); + } + + fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { + walk_foreign_mod(self, nm); + } + + fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { + walk_flat_map_variant(self, v) + } + + fn visit_ident(&mut self, i: &mut Ident) { + walk_ident(self, i); + } + + fn visit_path(&mut self, p: &mut Path) { + walk_path(self, p); + } + + fn visit_path_segment(&mut self, p: &mut PathSegment) { + walk_path_segment(self, p) + } + + fn visit_qself(&mut self, qs: &mut Option>) { + walk_qself(self, qs); + } + + fn visit_generic_args(&mut self, p: &mut GenericArgs) { + walk_generic_args(self, p); + } + + fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { + walk_angle_bracketed_parameter_data(self, p); + } + + fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { + walk_parenthesized_parameter_data(self, p); + } + + fn visit_local(&mut self, l: &mut P) { + walk_local(self, l); + } + + fn visit_mac_call(&mut self, mac: &mut MacCall) { + walk_mac(self, mac); + } + + fn visit_macro_def(&mut self, def: &mut MacroDef) { + walk_macro_def(self, def); + } + + fn visit_label(&mut self, label: &mut Label) { + walk_label(self, label); + } + + fn visit_attribute(&mut self, at: &mut Attribute) { + walk_attribute(self, at); + } + + fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { + walk_flat_map_param(self, param) + } + + fn visit_generics(&mut self, generics: &mut Generics) { + walk_generics(self, generics); + } + + fn visit_trait_ref(&mut self, tr: &mut TraitRef) { + walk_trait_ref(self, tr); + } + + fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { + walk_poly_trait_ref(self, p); + } + + fn visit_variant_data(&mut self, vdata: &mut VariantData) { + walk_variant_data(self, vdata); + } + + fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { + walk_flat_map_generic_param(self, param) + } + + fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) { + walk_param_bound(self, tpb); + } + + fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { + walk_precise_capturing_arg(self, arg); + } + + fn visit_mt(&mut self, mt: &mut MutTy) { + walk_mt(self, mt); + } + + fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { + walk_flat_map_expr_field(self, f) + } + + fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { + walk_where_clause(self, where_clause); + } + + fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { + walk_where_predicate(self, where_predicate); + } + + fn visit_vis(&mut self, vis: &mut Visibility) { + walk_vis(self, vis); + } + + fn visit_id(&mut self, _id: &mut NodeId) { + // Do nothing. + } + + fn visit_span(&mut self, _sp: &mut Span) { + // Do nothing. + } + + fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { + walk_flat_map_pat_field(self, fp) + } + + fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { + walk_inline_asm(self, asm) + } + + fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) { + walk_inline_asm_sym(self, sym) + } + + fn visit_format_args(&mut self, fmt: &mut FormatArgs) { + walk_format_args(self, fmt) + } + + fn visit_capture_by(&mut self, capture_by: &mut CaptureBy) { + walk_capture_by(self, capture_by) + } + } else { + /// The result type of the `visit_*` methods. Can be either `()`, + /// or `ControlFlow`. + type Result: VisitorResult = (); + + fn visit_ident(&mut self, _ident: Ident) -> Self::Result { + Self::Result::output() + } + fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result { + walk_item(self, i) + } + fn visit_item(&mut self, i: &'ast Item) -> Self::Result { + walk_item(self, i) + } + fn visit_local(&mut self, l: &'ast Local) -> Self::Result { + walk_local(self, l) + } + fn visit_block(&mut self, b: &'ast Block) -> Self::Result { + walk_block(self, b) + } + fn visit_stmt(&mut self, s: &'ast Stmt) -> Self::Result { + walk_stmt(self, s) + } + fn visit_param(&mut self, param: &'ast Param) -> Self::Result { + walk_param(self, param) + } + fn visit_arm(&mut self, a: &'ast Arm) -> Self::Result { + walk_arm(self, a) + } + fn visit_pat(&mut self, p: &'ast Pat) -> Self::Result { + walk_pat(self, p) + } + fn visit_anon_const(&mut self, c: &'ast AnonConst) -> Self::Result { + walk_anon_const(self, c) + } + fn visit_expr(&mut self, ex: &'ast Expr) -> Self::Result { + walk_expr(self, ex) + } + /// This method is a hack to workaround unstable of `stmt_expr_attributes`. + /// It can be removed once that feature is stabilized. + fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { + self.visit_expr(ex) + } + fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { + Self::Result::output() + } + fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result { + walk_ty(self, t) + } + fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result { + walk_generic_param(self, param) + } + fn visit_generics(&mut self, g: &'ast Generics) -> Self::Result { + walk_generics(self, g) + } + fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result { + walk_closure_binder(self, b) + } + fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result { + walk_where_predicate(self, p) + } + fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { + walk_fn(self, fk) + } + fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) -> Self::Result { + walk_assoc_item(self, i, ctxt) + } + fn visit_trait_ref(&mut self, t: &'ast TraitRef) -> Self::Result { + walk_trait_ref(self, t) + } + fn visit_param_bound( + &mut self, + bounds: &'ast GenericBound, + _ctxt: BoundKind, + ) -> Self::Result { + walk_param_bound(self, bounds) + } + fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { + walk_precise_capturing_arg(self, arg); + } + fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result { + walk_poly_trait_ref(self, t) + } + fn visit_variant_data(&mut self, s: &'ast VariantData) -> Self::Result { + walk_struct_def(self, s) + } + fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result { + walk_field_def(self, s) + } + fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result { + walk_enum_def(self, enum_definition) + } + fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result { + walk_variant(self, v) + } + fn visit_variant_discr(&mut self, discr: &'ast AnonConst) -> Self::Result { + self.visit_anon_const(discr) + } + fn visit_label(&mut self, label: &'ast Label) -> Self::Result { + walk_label(self, label) + } + fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) -> Self::Result { + walk_lifetime(self, lifetime) + } + 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 { + Self::Result::output() + } + fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result { + walk_path(self, path) + } + fn visit_use_tree( + &mut self, + use_tree: &'ast UseTree, + id: NodeId, + _nested: bool, + ) -> Self::Result { + walk_use_tree(self, use_tree, id) + } + fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result { + walk_path_segment(self, path_segment) + } + fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) -> Self::Result { + walk_generic_args(self, generic_args) + } + fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result { + walk_generic_arg(self, generic_arg) + } + fn visit_assoc_item_constraint( + &mut self, + constraint: &'ast AssocItemConstraint, + ) -> Self::Result { + walk_assoc_item_constraint(self, constraint) + } + fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result { + walk_attribute(self, attr) + } + fn visit_vis(&mut self, vis: &'ast Visibility) -> Self::Result { + walk_vis(self, vis) + } + fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) -> Self::Result { + walk_fn_ret_ty(self, ret_ty) + } + fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { + Self::Result::output() + } + fn visit_expr_field(&mut self, f: &'ast ExprField) -> Self::Result { + walk_expr_field(self, f) + } + fn visit_pat_field(&mut self, fp: &'ast PatField) -> Self::Result { + walk_pat_field(self, fp) + } + fn visit_crate(&mut self, krate: &'ast Crate) -> Self::Result { + walk_crate(self, krate) + } + fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) -> Self::Result { + walk_inline_asm(self, asm) + } + fn visit_format_args(&mut self, fmt: &'ast FormatArgs) -> Self::Result { + walk_format_args(self, fmt) + } + fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) -> Self::Result { + walk_inline_asm_sym(self, sym) + } + fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result { + Self::Result::output() + } + }} + } + } +} + pub mod visit { //! AST walker. Each overridden visit method has full control over what //! happens with its node, it can do its own traversal of the node's children, @@ -146,185 +612,7 @@ pub mod visit { ) -> 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; - /// e.g., the `visit_item` method by default calls `visit::walk_item`. - /// - /// If you want to ensure that your code handles every variant - /// explicitly, you need to override each method. (And you also need - /// to monitor future changes to `Visitor` in case a new method with a - /// new default implementation gets introduced.) - pub trait Visitor<'ast>: Sized { - /// The result type of the `visit_*` methods. Can be either `()`, - /// or `ControlFlow`. - type Result: VisitorResult = (); - - fn visit_ident(&mut self, _ident: Ident) -> Self::Result { - Self::Result::output() - } - fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result { - walk_item(self, i) - } - fn visit_item(&mut self, i: &'ast Item) -> Self::Result { - walk_item(self, i) - } - fn visit_local(&mut self, l: &'ast Local) -> Self::Result { - walk_local(self, l) - } - fn visit_block(&mut self, b: &'ast Block) -> Self::Result { - walk_block(self, b) - } - fn visit_stmt(&mut self, s: &'ast Stmt) -> Self::Result { - walk_stmt(self, s) - } - fn visit_param(&mut self, param: &'ast Param) -> Self::Result { - walk_param(self, param) - } - fn visit_arm(&mut self, a: &'ast Arm) -> Self::Result { - walk_arm(self, a) - } - fn visit_pat(&mut self, p: &'ast Pat) -> Self::Result { - walk_pat(self, p) - } - fn visit_anon_const(&mut self, c: &'ast AnonConst) -> Self::Result { - walk_anon_const(self, c) - } - fn visit_expr(&mut self, ex: &'ast Expr) -> Self::Result { - walk_expr(self, ex) - } - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. - /// It can be removed once that feature is stabilized. - fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { - self.visit_expr(ex) - } - fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { - Self::Result::output() - } - fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result { - walk_ty(self, t) - } - fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result { - walk_generic_param(self, param) - } - fn visit_generics(&mut self, g: &'ast Generics) -> Self::Result { - walk_generics(self, g) - } - fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result { - walk_closure_binder(self, b) - } - fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result { - walk_where_predicate(self, p) - } - fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { - walk_fn(self, fk) - } - fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) -> Self::Result { - walk_assoc_item(self, i, ctxt) - } - fn visit_trait_ref(&mut self, t: &'ast TraitRef) -> Self::Result { - walk_trait_ref(self, t) - } - fn visit_param_bound( - &mut self, - bounds: &'ast GenericBound, - _ctxt: BoundKind, - ) -> Self::Result { - walk_param_bound(self, bounds) - } - fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { - walk_precise_capturing_arg(self, arg); - } - fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result { - walk_poly_trait_ref(self, t) - } - fn visit_variant_data(&mut self, s: &'ast VariantData) -> Self::Result { - walk_struct_def(self, s) - } - fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result { - walk_field_def(self, s) - } - fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result { - walk_enum_def(self, enum_definition) - } - fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result { - walk_variant(self, v) - } - fn visit_variant_discr(&mut self, discr: &'ast AnonConst) -> Self::Result { - self.visit_anon_const(discr) - } - fn visit_label(&mut self, label: &'ast Label) -> Self::Result { - walk_label(self, label) - } - fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) -> Self::Result { - walk_lifetime(self, lifetime) - } - 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 { - Self::Result::output() - } - fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result { - walk_path(self, path) - } - fn visit_use_tree( - &mut self, - use_tree: &'ast UseTree, - id: NodeId, - _nested: bool, - ) -> Self::Result { - walk_use_tree(self, use_tree, id) - } - fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result { - walk_path_segment(self, path_segment) - } - fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) -> Self::Result { - walk_generic_args(self, generic_args) - } - fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result { - walk_generic_arg(self, generic_arg) - } - fn visit_assoc_item_constraint( - &mut self, - constraint: &'ast AssocItemConstraint, - ) -> Self::Result { - walk_assoc_item_constraint(self, constraint) - } - fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result { - walk_attribute(self, attr) - } - fn visit_vis(&mut self, vis: &'ast Visibility) -> Self::Result { - walk_vis(self, vis) - } - fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) -> Self::Result { - walk_fn_ret_ty(self, ret_ty) - } - fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { - Self::Result::output() - } - fn visit_expr_field(&mut self, f: &'ast ExprField) -> Self::Result { - walk_expr_field(self, f) - } - fn visit_pat_field(&mut self, fp: &'ast PatField) -> Self::Result { - walk_pat_field(self, fp) - } - fn visit_crate(&mut self, krate: &'ast Crate) -> Self::Result { - walk_crate(self, krate) - } - fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) -> Self::Result { - walk_inline_asm(self, asm) - } - fn visit_format_args(&mut self, fmt: &'ast FormatArgs) -> Self::Result { - walk_format_args(self, fmt) - } - fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) -> Self::Result { - walk_inline_asm_sym(self, sym) - } - fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result { - Self::Result::output() - } - } + make_ast_visitor!(Visitor<'ast>); pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result { let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate; @@ -1323,288 +1611,7 @@ pub mod mut_visit { fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor); } - pub trait MutVisitor: Sized { - /// Mutable token visiting only exists for the `macro_rules` token marker and should not be - /// used otherwise. Token visitor would be entirely separate from the regular visitor if - /// the marker didn't have to visit AST fragments in nonterminal tokens. - const VISIT_TOKENS: bool = false; - - // Methods in this trait have one of three forms: - // - // fn visit_t(&mut self, t: &mut T); // common - // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare - // fn filter_map_t(&mut self, t: T) -> Option; // 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) { - // visit_a(a); - // visit_b(b); - // } - // - // than to use field access like this: - // - // fn visit_abc(&mut self, abc: &mut ABC) { - // visit_a(&mut abc.a); - // visit_b(&mut abc.b); - // // ignore abc.c - // } - // - // As well as being more concise, the former is explicit about which fields - // are skipped. Furthermore, if a new field is added, the destructuring - // version will cause a compile error, which is good. In comparison, the - // field access version will continue working and it would be easy to - // forget to add handling for it. - - fn visit_crate(&mut self, c: &mut Crate) { - walk_crate(self, c) - } - - fn visit_meta_list_item(&mut self, list_item: &mut MetaItemInner) { - walk_meta_list_item(self, list_item); - } - - fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { - walk_meta_item(self, meta_item); - } - - fn visit_use_tree(&mut self, use_tree: &mut UseTree) { - walk_use_tree(self, use_tree); - } - - fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, ni) - } - - fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, i) - } - - fn visit_fn_header(&mut self, header: &mut FnHeader) { - walk_fn_header(self, header); - } - - fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { - walk_flat_map_field_def(self, fd) - } - - fn flat_map_assoc_item( - &mut self, - i: P, - _ctxt: AssocCtxt, - ) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, i) - } - - fn visit_fn_decl(&mut self, d: &mut P) { - walk_fn_decl(self, d); - } - - /// `Span` and `NodeId` are mutated at the caller site. - fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) { - walk_fn(self, fk) - } - - fn visit_coroutine_kind(&mut self, a: &mut CoroutineKind) { - walk_coroutine_kind(self, a); - } - - fn visit_closure_binder(&mut self, b: &mut ClosureBinder) { - walk_closure_binder(self, b); - } - - fn visit_block(&mut self, b: &mut P) { - walk_block(self, b); - } - - fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { - walk_flat_map_stmt(self, s) - } - - fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { - walk_flat_map_arm(self, arm) - } - - fn visit_pat(&mut self, p: &mut P) { - walk_pat(self, p); - } - - fn visit_anon_const(&mut self, c: &mut AnonConst) { - walk_anon_const(self, c); - } - - fn visit_expr(&mut self, e: &mut P) { - walk_expr(self, e); - } - - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. - /// It can be removed once that feature is stabilized. - fn visit_method_receiver_expr(&mut self, ex: &mut P) { - self.visit_expr(ex) - } - - fn filter_map_expr(&mut self, e: P) -> Option> { - noop_filter_map_expr(self, e) - } - - fn visit_generic_arg(&mut self, arg: &mut GenericArg) { - walk_generic_arg(self, arg); - } - - fn visit_ty(&mut self, t: &mut P) { - walk_ty(self, t); - } - - fn visit_lifetime(&mut self, l: &mut Lifetime) { - walk_lifetime(self, l); - } - - fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) { - walk_assoc_item_constraint(self, c); - } - - fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { - walk_foreign_mod(self, nm); - } - - fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { - walk_flat_map_variant(self, v) - } - - fn visit_ident(&mut self, i: &mut Ident) { - walk_ident(self, i); - } - - fn visit_path(&mut self, p: &mut Path) { - walk_path(self, p); - } - - fn visit_path_segment(&mut self, p: &mut PathSegment) { - walk_path_segment(self, p) - } - - fn visit_qself(&mut self, qs: &mut Option>) { - walk_qself(self, qs); - } - - fn visit_generic_args(&mut self, p: &mut GenericArgs) { - walk_generic_args(self, p); - } - - fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { - walk_angle_bracketed_parameter_data(self, p); - } - - fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { - walk_parenthesized_parameter_data(self, p); - } - - fn visit_local(&mut self, l: &mut P) { - walk_local(self, l); - } - - fn visit_mac_call(&mut self, mac: &mut MacCall) { - walk_mac(self, mac); - } - - fn visit_macro_def(&mut self, def: &mut MacroDef) { - walk_macro_def(self, def); - } - - fn visit_label(&mut self, label: &mut Label) { - walk_label(self, label); - } - - fn visit_attribute(&mut self, at: &mut Attribute) { - walk_attribute(self, at); - } - - fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { - walk_flat_map_param(self, param) - } - - fn visit_generics(&mut self, generics: &mut Generics) { - walk_generics(self, generics); - } - - fn visit_trait_ref(&mut self, tr: &mut TraitRef) { - walk_trait_ref(self, tr); - } - - fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { - walk_poly_trait_ref(self, p); - } - - fn visit_variant_data(&mut self, vdata: &mut VariantData) { - walk_variant_data(self, vdata); - } - - fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { - walk_flat_map_generic_param(self, param) - } - - fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) { - walk_param_bound(self, tpb); - } - - fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { - walk_precise_capturing_arg(self, arg); - } - - fn visit_mt(&mut self, mt: &mut MutTy) { - walk_mt(self, mt); - } - - fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { - walk_flat_map_expr_field(self, f) - } - - fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { - walk_where_clause(self, where_clause); - } - - fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { - walk_where_predicate(self, where_predicate); - } - - fn visit_vis(&mut self, vis: &mut Visibility) { - walk_vis(self, vis); - } - - fn visit_id(&mut self, _id: &mut NodeId) { - // Do nothing. - } - - fn visit_span(&mut self, _sp: &mut Span) { - // Do nothing. - } - - fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { - walk_flat_map_pat_field(self, fp) - } - - fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { - walk_inline_asm(self, asm) - } - - fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) { - walk_inline_asm_sym(self, sym) - } - - fn visit_format_args(&mut self, fmt: &mut FormatArgs) { - walk_format_args(self, fmt) - } - - fn visit_capture_by(&mut self, capture_by: &mut CaptureBy) { - walk_capture_by(self, capture_by) - } - } + make_ast_visitor!(MutVisitor, mut); /// 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_` From d8c70a204706f441b7d7d2a5898efba1163a868d Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 16:52:42 -0300 Subject: [PATCH 05/82] Add ref_t!, result!, make_visit! and P! --- compiler/rustc_ast/src/lib.rs | 1 + compiler/rustc_ast/src/visitors.rs | 43 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs index b5c05e09abd1f..d9f885d9aaee5 100644 --- a/compiler/rustc_ast/src/lib.rs +++ b/compiler/rustc_ast/src/lib.rs @@ -15,6 +15,7 @@ #![feature(box_patterns)] #![feature(if_let_guard)] #![feature(let_chains)] +#![feature(macro_metavar_expr)] #![feature(negative_impls)] #![feature(never_type)] #![feature(rustdoc_internals)] diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 4a7063ff636ed..7f3687451058a 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -26,6 +26,49 @@ macro_rules! macro_if { macro_rules! make_ast_visitor { ($trait: ident $(<$lt: lifetime>)? $(, $mut: ident)?) => { + #[allow(unused)] + macro_rules! ref_t { + ($t: ty) => { & $($lt)? $($mut)? $t }; + } + + #[allow(unused)] + macro_rules! result { + ($V: ty) => { + macro_if!($($mut)? { () } else { <$V>::Result }) + }; + () => { + result!(Self) + }; + } + + #[allow(unused)] + macro_rules! make_visit { + ( + $ty: ty + $$(, $$($arg: ident)? $$(_ $ignored_arg: ident)?: $arg_ty: ty)*; + $visit: ident, $walk: ident + ) => { + fn $visit( + &mut self, + node: ref_t!($ty) + $$(, $$($arg)? $$(#[allow(unused)] $ignored_arg)?: $arg_ty)* + ) -> result!() { + $walk(self, node $$($$(, $arg)?)*) + } + }; + } + + #[allow(unused)] + macro_rules! P { + ($t: ty) => { + macro_if!{$($mut)? { + P<$t> + } else { + $t + }} + }; + } + /// Each method of the traits `Visitor` and `MutVisitor` trait is a hook /// to be potentially overridden. Each method's default implementation /// recursively visits the substructure of the input via the corresponding From 4882464d24e02b562cbfc59a12d5e9650be6b919 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 18:14:59 -0300 Subject: [PATCH 06/82] Use make_visit! on every possible visit_ --- compiler/rustc_ast/src/visitors.rs | 397 +++++++---------------------- 1 file changed, 87 insertions(+), 310 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 7f3687451058a..638774e01edcf 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -26,12 +26,10 @@ macro_rules! macro_if { macro_rules! make_ast_visitor { ($trait: ident $(<$lt: lifetime>)? $(, $mut: ident)?) => { - #[allow(unused)] macro_rules! ref_t { ($t: ty) => { & $($lt)? $($mut)? $t }; } - #[allow(unused)] macro_rules! result { ($V: ty) => { macro_if!($($mut)? { () } else { <$V>::Result }) @@ -41,7 +39,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! make_visit { ( $ty: ty @@ -58,7 +55,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! P { ($t: ty) => { macro_if!{$($mut)? { @@ -118,21 +114,50 @@ macro_rules! make_ast_visitor { // field access version will continue working and it would be easy to // forget to add handling for it. - fn visit_crate(&mut self, c: &mut Crate) { - walk_crate(self, c) - } - - fn visit_meta_list_item(&mut self, list_item: &mut MetaItemInner) { - walk_meta_list_item(self, list_item); - } - - fn visit_meta_item(&mut self, meta_item: &mut MetaItem) { - walk_meta_item(self, meta_item); - } - - fn visit_use_tree(&mut self, use_tree: &mut UseTree) { - walk_use_tree(self, use_tree); - } + make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} + make_visit!{AnonConst; visit_anon_const, walk_anon_const} + make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} + make_visit!{Attribute; visit_attribute, walk_attribute} + make_visit!{CaptureBy; visit_capture_by, walk_capture_by} + make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} + make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} + make_visit!{Crate; visit_crate, walk_crate} + make_visit!{FnHeader; visit_fn_header, walk_fn_header} + make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} + make_visit!{FormatArgs; visit_format_args, walk_format_args} + make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} + make_visit!{GenericArgs; visit_generic_args, walk_generic_args} + make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} + make_visit!{Generics; visit_generics, walk_generics} + make_visit!{Ident; visit_ident, walk_ident} + make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} + make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} + make_visit!{Label; visit_label, walk_label} + make_visit!{Lifetime; visit_lifetime, walk_lifetime} + make_visit!{MacCall; visit_mac_call, walk_mac} + make_visit!{MacroDef; visit_macro_def, walk_macro_def} + make_visit!{MetaItem; visit_meta_item, walk_meta_item} + make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} + make_visit!{MutTy; visit_mt, walk_mt} + make_visit!{Option>; visit_qself, walk_qself} + make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} + make_visit!{Path; visit_path, walk_path} + make_visit!{PathSegment; visit_path_segment, walk_path_segment} + make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} + make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} + make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} + make_visit!{UseTree; visit_use_tree, walk_use_tree} + make_visit!{VariantData; visit_variant_data, walk_variant_data} + make_visit!{Visibility; visit_vis, walk_vis} + make_visit!{WhereClause; visit_where_clause, walk_where_clause} + make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} + + make_visit!{P!(Block); visit_block, walk_block} + make_visit!{P!(Expr); visit_expr, walk_expr} + make_visit!{P!(FnDecl); visit_fn_decl, walk_fn_decl} + make_visit!{P!(Local); visit_local, walk_local} + make_visit!{P!(Pat); visit_pat, walk_pat} + make_visit!{P!(Ty); visit_ty, walk_ty} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { walk_flat_map_item(self, ni) @@ -142,10 +167,6 @@ macro_rules! make_ast_visitor { walk_flat_map_item(self, i) } - fn visit_fn_header(&mut self, header: &mut FnHeader) { - walk_fn_header(self, header); - } - fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { walk_flat_map_field_def(self, fd) } @@ -158,27 +179,11 @@ macro_rules! make_ast_visitor { walk_flat_map_item(self, i) } - fn visit_fn_decl(&mut self, d: &mut P) { - walk_fn_decl(self, d); - } - /// `Span` and `NodeId` are mutated at the caller site. fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) { walk_fn(self, fk) } - fn visit_coroutine_kind(&mut self, a: &mut CoroutineKind) { - walk_coroutine_kind(self, a); - } - - fn visit_closure_binder(&mut self, b: &mut ClosureBinder) { - walk_closure_binder(self, b); - } - - fn visit_block(&mut self, b: &mut P) { - walk_block(self, b); - } - fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { walk_flat_map_stmt(self, s) } @@ -187,18 +192,6 @@ macro_rules! make_ast_visitor { walk_flat_map_arm(self, arm) } - fn visit_pat(&mut self, p: &mut P) { - walk_pat(self, p); - } - - fn visit_anon_const(&mut self, c: &mut AnonConst) { - walk_anon_const(self, c); - } - - fn visit_expr(&mut self, e: &mut P) { - walk_expr(self, e); - } - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. /// It can be removed once that feature is stabilized. fn visit_method_receiver_expr(&mut self, ex: &mut P) { @@ -209,130 +202,22 @@ macro_rules! make_ast_visitor { noop_filter_map_expr(self, e) } - fn visit_generic_arg(&mut self, arg: &mut GenericArg) { - walk_generic_arg(self, arg); - } - - fn visit_ty(&mut self, t: &mut P) { - walk_ty(self, t); - } - - fn visit_lifetime(&mut self, l: &mut Lifetime) { - walk_lifetime(self, l); - } - - fn visit_assoc_item_constraint(&mut self, c: &mut AssocItemConstraint) { - walk_assoc_item_constraint(self, c); - } - - fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) { - walk_foreign_mod(self, nm); - } - fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { walk_flat_map_variant(self, v) } - fn visit_ident(&mut self, i: &mut Ident) { - walk_ident(self, i); - } - - fn visit_path(&mut self, p: &mut Path) { - walk_path(self, p); - } - - fn visit_path_segment(&mut self, p: &mut PathSegment) { - walk_path_segment(self, p) - } - - fn visit_qself(&mut self, qs: &mut Option>) { - walk_qself(self, qs); - } - - fn visit_generic_args(&mut self, p: &mut GenericArgs) { - walk_generic_args(self, p); - } - - fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) { - walk_angle_bracketed_parameter_data(self, p); - } - - fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) { - walk_parenthesized_parameter_data(self, p); - } - - fn visit_local(&mut self, l: &mut P) { - walk_local(self, l); - } - - fn visit_mac_call(&mut self, mac: &mut MacCall) { - walk_mac(self, mac); - } - - fn visit_macro_def(&mut self, def: &mut MacroDef) { - walk_macro_def(self, def); - } - - fn visit_label(&mut self, label: &mut Label) { - walk_label(self, label); - } - - fn visit_attribute(&mut self, at: &mut Attribute) { - walk_attribute(self, at); - } - fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { walk_flat_map_param(self, param) } - fn visit_generics(&mut self, generics: &mut Generics) { - walk_generics(self, generics); - } - - fn visit_trait_ref(&mut self, tr: &mut TraitRef) { - walk_trait_ref(self, tr); - } - - fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) { - walk_poly_trait_ref(self, p); - } - - fn visit_variant_data(&mut self, vdata: &mut VariantData) { - walk_variant_data(self, vdata); - } - fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { walk_flat_map_generic_param(self, param) } - fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) { - walk_param_bound(self, tpb); - } - - fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { - walk_precise_capturing_arg(self, arg); - } - - fn visit_mt(&mut self, mt: &mut MutTy) { - walk_mt(self, mt); - } - fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { walk_flat_map_expr_field(self, f) } - fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { - walk_where_clause(self, where_clause); - } - - fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) { - walk_where_predicate(self, where_predicate); - } - - fn visit_vis(&mut self, vis: &mut Visibility) { - walk_vis(self, vis); - } - fn visit_id(&mut self, _id: &mut NodeId) { // Do nothing. } @@ -344,60 +229,57 @@ macro_rules! make_ast_visitor { fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { walk_flat_map_pat_field(self, fp) } - - fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { - walk_inline_asm(self, asm) - } - - fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) { - walk_inline_asm_sym(self, sym) - } - - fn visit_format_args(&mut self, fmt: &mut FormatArgs) { - walk_format_args(self, fmt) - } - - fn visit_capture_by(&mut self, capture_by: &mut CaptureBy) { - walk_capture_by(self, capture_by) - } } else { /// The result type of the `visit_*` methods. Can be either `()`, /// or `ControlFlow`. type Result: VisitorResult = (); + make_visit!{AnonConst; visit_anon_const, walk_anon_const} + make_visit!{Arm; visit_arm, walk_arm} + make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} + make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} + make_visit!{Attribute; visit_attribute, walk_attribute} + make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} + make_visit!{Crate; visit_crate, walk_crate} + make_visit!{EnumDef; visit_enum_def, walk_enum_def} + make_visit!{ExprField; visit_expr_field, walk_expr_field} + make_visit!{FieldDef; visit_field_def, walk_field_def} + make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} + make_visit!{ForeignItem; visit_foreign_item, walk_item} + make_visit!{FormatArgs; visit_format_args, walk_format_args} + make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} + make_visit!{GenericArgs; visit_generic_args, walk_generic_args} + make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} + make_visit!{GenericParam; visit_generic_param, walk_generic_param} + make_visit!{Generics; visit_generics, walk_generics} + make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} + make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} + make_visit!{Item; visit_item, walk_item} + make_visit!{Label; visit_label, walk_label} + make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} + make_visit!{MacCall; visit_mac_call, walk_mac} + make_visit!{Param; visit_param, walk_param} + make_visit!{PatField; visit_pat_field, walk_pat_field} + make_visit!{Path, _ id: NodeId; visit_path, walk_path} + make_visit!{PathSegment; visit_path_segment, walk_path_segment} + make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} + make_visit!{Stmt; visit_stmt, walk_stmt} + make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} + make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} + make_visit!{Variant; visit_variant, walk_variant} + make_visit!{VariantData; visit_variant_data, walk_struct_def} + make_visit!{Visibility; visit_vis, walk_vis} + make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} + + make_visit!{P!(Block); visit_block, walk_block} + make_visit!{P!(Expr); visit_expr, walk_expr} + make_visit!{P!(Local); visit_local, walk_local} + make_visit!{P!(Pat); visit_pat, walk_pat} + make_visit!{P!(Ty); visit_ty, walk_ty} + fn visit_ident(&mut self, _ident: Ident) -> Self::Result { Self::Result::output() } - fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result { - walk_item(self, i) - } - fn visit_item(&mut self, i: &'ast Item) -> Self::Result { - walk_item(self, i) - } - fn visit_local(&mut self, l: &'ast Local) -> Self::Result { - walk_local(self, l) - } - fn visit_block(&mut self, b: &'ast Block) -> Self::Result { - walk_block(self, b) - } - fn visit_stmt(&mut self, s: &'ast Stmt) -> Self::Result { - walk_stmt(self, s) - } - fn visit_param(&mut self, param: &'ast Param) -> Self::Result { - walk_param(self, param) - } - fn visit_arm(&mut self, a: &'ast Arm) -> Self::Result { - walk_arm(self, a) - } - fn visit_pat(&mut self, p: &'ast Pat) -> Self::Result { - walk_pat(self, p) - } - fn visit_anon_const(&mut self, c: &'ast AnonConst) -> Self::Result { - walk_anon_const(self, c) - } - fn visit_expr(&mut self, ex: &'ast Expr) -> Self::Result { - walk_expr(self, ex) - } /// This method is a hack to workaround unstable of `stmt_expr_attributes`. /// It can be removed once that feature is stabilized. fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { @@ -406,126 +288,21 @@ macro_rules! make_ast_visitor { fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { Self::Result::output() } - fn visit_ty(&mut self, t: &'ast Ty) -> Self::Result { - walk_ty(self, t) - } - fn visit_generic_param(&mut self, param: &'ast GenericParam) -> Self::Result { - walk_generic_param(self, param) - } - fn visit_generics(&mut self, g: &'ast Generics) -> Self::Result { - walk_generics(self, g) - } - fn visit_closure_binder(&mut self, b: &'ast ClosureBinder) -> Self::Result { - walk_closure_binder(self, b) - } - fn visit_where_predicate(&mut self, p: &'ast WherePredicate) -> Self::Result { - walk_where_predicate(self, p) - } fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { walk_fn(self, fk) } - fn visit_assoc_item(&mut self, i: &'ast AssocItem, ctxt: AssocCtxt) -> Self::Result { - walk_assoc_item(self, i, ctxt) - } - fn visit_trait_ref(&mut self, t: &'ast TraitRef) -> Self::Result { - walk_trait_ref(self, t) - } - fn visit_param_bound( - &mut self, - bounds: &'ast GenericBound, - _ctxt: BoundKind, - ) -> Self::Result { - walk_param_bound(self, bounds) - } fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { walk_precise_capturing_arg(self, arg); } - fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result { - walk_poly_trait_ref(self, t) - } - fn visit_variant_data(&mut self, s: &'ast VariantData) -> Self::Result { - walk_struct_def(self, s) - } - fn visit_field_def(&mut self, s: &'ast FieldDef) -> Self::Result { - walk_field_def(self, s) - } - fn visit_enum_def(&mut self, enum_definition: &'ast EnumDef) -> Self::Result { - walk_enum_def(self, enum_definition) - } - fn visit_variant(&mut self, v: &'ast Variant) -> Self::Result { - walk_variant(self, v) - } fn visit_variant_discr(&mut self, discr: &'ast AnonConst) -> Self::Result { self.visit_anon_const(discr) } - fn visit_label(&mut self, label: &'ast Label) -> Self::Result { - walk_label(self, label) - } - fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, _: LifetimeCtxt) -> Self::Result { - walk_lifetime(self, lifetime) - } - 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 { Self::Result::output() } - fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result { - walk_path(self, path) - } - fn visit_use_tree( - &mut self, - use_tree: &'ast UseTree, - id: NodeId, - _nested: bool, - ) -> Self::Result { - walk_use_tree(self, use_tree, id) - } - fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result { - walk_path_segment(self, path_segment) - } - fn visit_generic_args(&mut self, generic_args: &'ast GenericArgs) -> Self::Result { - walk_generic_args(self, generic_args) - } - fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) -> Self::Result { - walk_generic_arg(self, generic_arg) - } - fn visit_assoc_item_constraint( - &mut self, - constraint: &'ast AssocItemConstraint, - ) -> Self::Result { - walk_assoc_item_constraint(self, constraint) - } - fn visit_attribute(&mut self, attr: &'ast Attribute) -> Self::Result { - walk_attribute(self, attr) - } - fn visit_vis(&mut self, vis: &'ast Visibility) -> Self::Result { - walk_vis(self, vis) - } - fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) -> Self::Result { - walk_fn_ret_ty(self, ret_ty) - } fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { Self::Result::output() } - fn visit_expr_field(&mut self, f: &'ast ExprField) -> Self::Result { - walk_expr_field(self, f) - } - fn visit_pat_field(&mut self, fp: &'ast PatField) -> Self::Result { - walk_pat_field(self, fp) - } - fn visit_crate(&mut self, krate: &'ast Crate) -> Self::Result { - walk_crate(self, krate) - } - fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) -> Self::Result { - walk_inline_asm(self, asm) - } - fn visit_format_args(&mut self, fmt: &'ast FormatArgs) -> Self::Result { - walk_format_args(self, fmt) - } - fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) -> Self::Result { - walk_inline_asm_sym(self, sym) - } fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result { Self::Result::output() } From c7398d1aff8dd54047b6090f1291cf8b207f5fcc Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 18:26:36 -0300 Subject: [PATCH 07/82] Unify make_visit!s --- compiler/rustc_ast/src/visitors.rs | 75 +++++++++++------------------- 1 file changed, 26 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 638774e01edcf..6460882329555 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -115,26 +115,12 @@ macro_rules! make_ast_visitor { // forget to add handling for it. make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} - make_visit!{AnonConst; visit_anon_const, walk_anon_const} - make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} - make_visit!{Attribute; visit_attribute, walk_attribute} make_visit!{CaptureBy; visit_capture_by, walk_capture_by} - make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} - make_visit!{Crate; visit_crate, walk_crate} make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} - make_visit!{FormatArgs; visit_format_args, walk_format_args} - make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} - make_visit!{GenericArgs; visit_generic_args, walk_generic_args} - make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} - make_visit!{Generics; visit_generics, walk_generics} make_visit!{Ident; visit_ident, walk_ident} - make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} - make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} - make_visit!{Label; visit_label, walk_label} make_visit!{Lifetime; visit_lifetime, walk_lifetime} - make_visit!{MacCall; visit_mac_call, walk_mac} make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} @@ -142,22 +128,12 @@ macro_rules! make_ast_visitor { make_visit!{Option>; visit_qself, walk_qself} make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} make_visit!{Path; visit_path, walk_path} - make_visit!{PathSegment; visit_path_segment, walk_path_segment} - make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} - make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} make_visit!{UseTree; visit_use_tree, walk_use_tree} make_visit!{VariantData; visit_variant_data, walk_variant_data} - make_visit!{Visibility; visit_vis, walk_vis} make_visit!{WhereClause; visit_where_clause, walk_where_clause} - make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} - make_visit!{P!(Block); visit_block, walk_block} - make_visit!{P!(Expr); visit_expr, walk_expr} make_visit!{P!(FnDecl); visit_fn_decl, walk_fn_decl} - make_visit!{P!(Local); visit_local, walk_local} - make_visit!{P!(Pat); visit_pat, walk_pat} - make_visit!{P!(Ty); visit_ty, walk_ty} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { walk_flat_map_item(self, ni) @@ -234,48 +210,23 @@ macro_rules! make_ast_visitor { /// or `ControlFlow`. type Result: VisitorResult = (); - make_visit!{AnonConst; visit_anon_const, walk_anon_const} make_visit!{Arm; visit_arm, walk_arm} make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} - make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} - make_visit!{Attribute; visit_attribute, walk_attribute} - make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} - make_visit!{Crate; visit_crate, walk_crate} make_visit!{EnumDef; visit_enum_def, walk_enum_def} make_visit!{ExprField; visit_expr_field, walk_expr_field} make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{ForeignItem; visit_foreign_item, walk_item} - make_visit!{FormatArgs; visit_format_args, walk_format_args} - make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} - make_visit!{GenericArgs; visit_generic_args, walk_generic_args} - make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} make_visit!{GenericParam; visit_generic_param, walk_generic_param} - make_visit!{Generics; visit_generics, walk_generics} - make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} - make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} make_visit!{Item; visit_item, walk_item} - make_visit!{Label; visit_label, walk_label} make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} - make_visit!{MacCall; visit_mac_call, walk_mac} make_visit!{Param; visit_param, walk_param} make_visit!{PatField; visit_pat_field, walk_pat_field} make_visit!{Path, _ id: NodeId; visit_path, walk_path} - make_visit!{PathSegment; visit_path_segment, walk_path_segment} - make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{Stmt; visit_stmt, walk_stmt} - make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} make_visit!{Variant; visit_variant, walk_variant} make_visit!{VariantData; visit_variant_data, walk_struct_def} - make_visit!{Visibility; visit_vis, walk_vis} - make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} - - make_visit!{P!(Block); visit_block, walk_block} - make_visit!{P!(Expr); visit_expr, walk_expr} - make_visit!{P!(Local); visit_local, walk_local} - make_visit!{P!(Pat); visit_pat, walk_pat} - make_visit!{P!(Ty); visit_ty, walk_ty} fn visit_ident(&mut self, _ident: Ident) -> Self::Result { Self::Result::output() @@ -307,6 +258,32 @@ macro_rules! make_ast_visitor { Self::Result::output() } }} + + make_visit!{AnonConst; visit_anon_const, walk_anon_const} + make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} + make_visit!{Attribute; visit_attribute, walk_attribute} + make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} + make_visit!{Crate; visit_crate, walk_crate} + make_visit!{FormatArgs; visit_format_args, walk_format_args} + make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} + make_visit!{GenericArgs; visit_generic_args, walk_generic_args} + make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} + make_visit!{Generics; visit_generics, walk_generics} + make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} + make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} + make_visit!{Label; visit_label, walk_label} + make_visit!{MacCall; visit_mac_call, walk_mac} + make_visit!{PathSegment; visit_path_segment, walk_path_segment} + make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} + make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} + make_visit!{Visibility; visit_vis, walk_vis} + make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} + + make_visit!{P!(Block); visit_block, walk_block} + make_visit!{P!(Expr); visit_expr, walk_expr} + make_visit!{P!(Local); visit_local, walk_local} + make_visit!{P!(Pat); visit_pat, walk_pat} + make_visit!{P!(Ty); visit_ty, walk_ty} } } } From 87cc131a730ecdc6381a940f6759e23c5b8faf1c Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 19:43:21 -0300 Subject: [PATCH 08/82] Add visits for nodes that already had walks (QSelf,FnRetTy,FnDecl) --- compiler/rustc_ast/src/visitors.rs | 39 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 6460882329555..1fe57dc345e52 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -125,7 +125,6 @@ macro_rules! make_ast_visitor { make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} make_visit!{MutTy; visit_mt, walk_mt} - make_visit!{Option>; visit_qself, walk_qself} make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} make_visit!{Path; visit_path, walk_path} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} @@ -133,8 +132,6 @@ macro_rules! make_ast_visitor { make_visit!{VariantData; visit_variant_data, walk_variant_data} make_visit!{WhereClause; visit_where_clause, walk_where_clause} - make_visit!{P!(FnDecl); visit_fn_decl, walk_fn_decl} - fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { walk_flat_map_item(self, ni) } @@ -215,7 +212,6 @@ macro_rules! make_ast_visitor { make_visit!{EnumDef; visit_enum_def, walk_enum_def} make_visit!{ExprField; visit_expr_field, walk_expr_field} make_visit!{FieldDef; visit_field_def, walk_field_def} - make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{ForeignItem; visit_foreign_item, walk_item} make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Item; visit_item, walk_item} @@ -264,6 +260,7 @@ macro_rules! make_ast_visitor { make_visit!{Attribute; visit_attribute, walk_attribute} make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} make_visit!{Crate; visit_crate, walk_crate} + make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{FormatArgs; visit_format_args, walk_format_args} make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} make_visit!{GenericArgs; visit_generic_args, walk_generic_args} @@ -273,6 +270,7 @@ macro_rules! make_ast_visitor { make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} make_visit!{Label; visit_label, walk_label} make_visit!{MacCall; visit_mac_call, walk_mac} + make_visit!{Option>; visit_qself, walk_qself} make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} @@ -281,6 +279,7 @@ macro_rules! make_ast_visitor { make_visit!{P!(Block); visit_block, walk_block} make_visit!{P!(Expr); visit_expr, walk_expr} + make_visit!{P!(FnDecl); visit_fn_decl, walk_fn_decl} make_visit!{P!(Local); visit_local, walk_local} make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} @@ -548,13 +547,13 @@ pub mod visit { body, from_glob: _, }) => { - try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_path(path, *id)); visit_opt!(visitor, visit_ident, *rename); visit_opt!(visitor, visit_block, body); } ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { - try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_path(prefix, *id)); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { @@ -634,10 +633,10 @@ pub mod visit { let BareFnTy { safety: _, ext: _, generic_params, decl, decl_span: _ } = &**function_declaration; walk_list!(visitor, visit_generic_param, generic_params); - try_visit!(walk_fn_decl(visitor, decl)); + try_visit!(visitor.visit_fn_decl(decl)); } TyKind::Path(maybe_qself, path) => { - try_visit!(walk_qself(visitor, maybe_qself)); + try_visit!(visitor.visit_qself(maybe_qself)); try_visit!(visitor.visit_path(path, *id)); } TyKind::Pat(ty, pat) => { @@ -768,16 +767,16 @@ pub mod visit { let Pat { id, kind, span: _, tokens: _ } = pattern; match kind { PatKind::TupleStruct(opt_qself, path, elems) => { - try_visit!(walk_qself(visitor, opt_qself)); + 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!(walk_qself(visitor, opt_qself)); + try_visit!(visitor.visit_qself(opt_qself)); try_visit!(visitor.visit_path(path, *id)) } PatKind::Struct(opt_qself, path, fields, _rest) => { - try_visit!(walk_qself(visitor, opt_qself)); + try_visit!(visitor.visit_qself(opt_qself)); try_visit!(visitor.visit_path(path, *id)); walk_list!(visitor, visit_pat_field, fields); } @@ -963,12 +962,12 @@ pub mod visit { // Identifier and visibility are visited as a part of the item. try_visit!(visitor.visit_fn_header(header)); try_visit!(visitor.visit_generics(generics)); - try_visit!(walk_fn_decl(visitor, decl)); + try_visit!(visitor.visit_fn_decl(decl)); visit_opt!(visitor, visit_block, body); } FnKind::Closure(binder, _coroutine_kind, decl, body) => { try_visit!(visitor.visit_closure_binder(binder)); - try_visit!(walk_fn_decl(visitor, decl)); + try_visit!(visitor.visit_fn_decl(decl)); try_visit!(visitor.visit_expr(body)); } } @@ -1016,7 +1015,7 @@ pub mod visit { body, from_glob: _, }) => { - try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_path(path, *id)); visit_opt!(visitor, visit_ident, *rename); visit_opt!(visitor, visit_block, body); @@ -1027,7 +1026,7 @@ pub mod visit { suffixes, body, }) => { - try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_path(prefix, id)); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { @@ -1145,7 +1144,7 @@ pub mod visit { visitor: &mut V, InlineAsmSym { id, qself, path }: &'a InlineAsmSym, ) -> V::Result { - try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_qself(qself)); visitor.visit_path(path, *id) } @@ -1177,7 +1176,7 @@ pub mod visit { } ExprKind::Struct(se) => { let StructExpr { qself, path, fields, rest } = &**se; - try_visit!(walk_qself(visitor, qself)); + try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_path(path, *id)); walk_list!(visitor, visit_expr_field, fields); match rest { @@ -1286,7 +1285,7 @@ pub mod visit { } ExprKind::Underscore => {} ExprKind::Path(maybe_qself, path) => { - try_visit!(walk_qself(visitor, maybe_qself)); + try_visit!(visitor.visit_qself(maybe_qself)); try_visit!(visitor.visit_path(path, *id)); } ExprKind::Break(opt_label, opt_expr) => { @@ -1698,7 +1697,7 @@ pub mod mut_visit { fn walk_parenthesized_parameter_data(vis: &mut T, args: &mut ParenthesizedArgs) { let ParenthesizedArgs { inputs, output, span, inputs_span } = args; visit_thin_vec(inputs, |input| vis.visit_ty(input)); - walk_fn_ret_ty(vis, output); + vis.visit_fn_ret_ty(output); vis.visit_span(span); vis.visit_span(inputs_span); } @@ -2006,7 +2005,7 @@ pub mod mut_visit { fn walk_fn_decl(vis: &mut T, decl: &mut P) { let FnDecl { inputs, output } = decl.deref_mut(); inputs.flat_map_in_place(|param| vis.flat_map_param(param)); - walk_fn_ret_ty(vis, output); + vis.visit_fn_ret_ty(output); } fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { From c73930b7822f7a9f3382be01ad4947ccb4e8126e Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 18:55:33 -0300 Subject: [PATCH 09/82] Add return_result!, defer_P!, visit_{id,span}!, try_v! and visit_{o,list}! --- compiler/rustc_ast/src/visitors.rs | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 1fe57dc345e52..e632f7c1303dd 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -39,6 +39,13 @@ macro_rules! make_ast_visitor { }; } + #[allow(unused)] + macro_rules! return_result { + ($V: ty) => { + macro_if!($($mut)? { () } else { <$V>::Result::output() }) + }; + } + macro_rules! make_visit { ( $ty: ty @@ -65,6 +72,73 @@ macro_rules! make_ast_visitor { }; } + #[allow(unused)] + macro_rules! deref_P { + ($p: expr) => { + macro_if!{$($mut)? { + $p.deref_mut() + } else { + $p + }} + }; + } + + #[allow(unused)] + macro_rules! visit_id { + ($vis: ident, $id: ident) => { + macro_if!{ $($mut)? { + $vis.visit_id($id) + } else { + // assign to _ to prevent unused_variable warnings + {let _ = (&$vis, &$id);} + }} + }; + } + + #[allow(unused)] + macro_rules! visit_span { + ($vis: ident, $span: ident) => { + macro_if!{ $($mut)? { + $vis.visit_span($span) + } else { + // assign to _ to prevent unused_variable warnings + {let _ = (&$vis, &$span);} + }} + }; + } + + #[allow(unused)] + macro_rules! try_v { + ($visit: expr) => { + macro_if!{$($mut)? { $visit } else { try_visit!($visit) }} + }; + } + + #[allow(unused)] + macro_rules! visit_o { + ($opt: expr, $fn: expr) => { + if let Some(elem) = $opt { + try_v!($fn(elem)) + } + }; + } + + #[allow(unused)] + macro_rules! visit_list { + ($visitor: expr, $visit: ident, $flat_map: ident, $list: expr $$(; $$($arg: expr),*)?) => { + macro_if!{$($mut)? { + $list.flat_map_in_place(|x| $visitor.$flat_map(x $$(, $$($arg),*)?)) + } else { + visit_list!($visitor, $visit, $list $$(; $$($arg),*)?) + }} + }; + ($visitor: expr, $visit: ident, $list: expr $$(; $$($arg: expr),*)?) => { + for elem in $list { + try_v!($visitor.$visit(elem $$(, $$($arg),*)?)); + } + }; + } + /// Each method of the traits `Visitor` and `MutVisitor` trait is a hook /// to be potentially overridden. Each method's default implementation /// recursively visits the substructure of the input via the corresponding From 632dc06235bd86da941eaeabff53be33e70685b8 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 20:45:58 -0300 Subject: [PATCH 10/82] Pass Ident by reference --- compiler/rustc_ast/src/visitors.rs | 59 +++++++++---------- .../rustc_ast_passes/src/ast_validation.rs | 28 +++++---- compiler/rustc_ast_passes/src/node_count.rs | 2 +- .../src/deriving/default.rs | 2 +- compiler/rustc_lint/src/early.rs | 5 +- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/late.rs | 4 +- .../clippy_utils/src/ast_utils/ident_iter.rs | 4 +- src/tools/rustfmt/src/items.rs | 2 +- src/tools/rustfmt/src/visitor.rs | 6 +- 10 files changed, 60 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index e632f7c1303dd..3da172ba49e2e 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -298,7 +298,7 @@ macro_rules! make_ast_visitor { make_visit!{Variant; visit_variant, walk_variant} make_visit!{VariantData; visit_variant_data, walk_struct_def} - fn visit_ident(&mut self, _ident: Ident) -> Self::Result { + fn visit_ident(&mut self, _ident: &'ast Ident) -> Self::Result { Self::Result::output() } /// This method is a hack to workaround unstable of `stmt_expr_attributes`. @@ -427,7 +427,7 @@ pub mod visit { #[derive(Copy, Clone, Debug)] pub enum FnKind<'a> { /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. - Fn(FnCtxt, Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>), + Fn(FnCtxt, &'a Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>), /// E.g., `|x, y| body`. Closure(&'a ClosureBinder, &'a Option, &'a FnDecl, &'a Expr), @@ -507,12 +507,12 @@ pub mod visit { visitor: &mut V, Label { ident }: &'a Label, ) -> V::Result { - visitor.visit_ident(*ident) + visitor.visit_ident(ident) } pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result { let Lifetime { id: _, ident } = lifetime; - visitor.visit_ident(*ident) + visitor.visit_ident(ident) } pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result @@ -553,8 +553,7 @@ pub mod visit { visit_opt!(visitor, visit_expr, expr); } ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = - FnKind::Fn(FnCtxt::Free, *ident, sig, vis, generics, body.as_deref()); + let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body.as_deref()); try_visit!(visitor.visit_fn(kind, *span, *id)); } ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { @@ -623,7 +622,7 @@ pub mod visit { }) => { try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_ident, rename); visit_opt!(visitor, visit_block, body); } ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { @@ -631,9 +630,9 @@ pub mod visit { try_visit!(visitor.visit_path(prefix, *id)); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { - visitor.visit_ident(*ident); + visitor.visit_ident(ident); if let Some(rename) = rename { - visitor.visit_ident(*rename); + visitor.visit_ident(rename); } } } @@ -667,7 +666,7 @@ pub mod visit { variant; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_variant_data(data)); visit_opt!(visitor, visit_variant_discr, disr_expr); V::Result::output() @@ -677,7 +676,7 @@ pub mod visit { let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = f; walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_expr(expr)); V::Result::output() } @@ -685,7 +684,7 @@ pub mod visit { pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result { let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp; walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); try_visit!(visitor.visit_pat(pat)); V::Result::output() } @@ -760,7 +759,7 @@ pub mod visit { match kind { UseTreeKind::Simple(rename) => { // The extra IDs are handled during AST lowering. - visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_ident, rename); } UseTreeKind::Glob => {} UseTreeKind::Nested { ref items, span: _ } => { @@ -777,7 +776,7 @@ pub mod visit { segment: &'a PathSegment, ) -> V::Result { let PathSegment { ident, id: _, args } = segment; - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); visit_opt!(visitor, visit_generic_args, args); V::Result::output() } @@ -823,7 +822,7 @@ pub mod visit { constraint: &'a AssocItemConstraint, ) -> V::Result { let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint; - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); visit_opt!(visitor, visit_generic_args, gen_args); match kind { AssocItemConstraintKind::Equality { term } => match term { @@ -861,7 +860,7 @@ pub mod visit { try_visit!(visitor.visit_pat(subpattern)); } PatKind::Ident(_bmode, ident, optional_subpattern) => { - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); visit_opt!(visitor, visit_pat, optional_subpattern); } PatKind::Lit(expression) => try_visit!(visitor.visit_expr(expression)), @@ -886,7 +885,7 @@ pub mod visit { _ctxt: AssocCtxt, visitor: &mut V, ) -> V::Result { - let &Item { id, span, ident, ref vis, .. } = item; + let Item { id, span, ident, vis, .. } = item; match self { ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { try_visit!(visitor.visit_ty(ty)); @@ -895,7 +894,7 @@ pub mod visit { ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, span, id)); + try_visit!(visitor.visit_fn(kind, *span, *id)); } ForeignItemKind::TyAlias(box TyAlias { generics, @@ -953,7 +952,7 @@ pub mod visit { let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } = param; walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); match kind { GenericParamKind::Lifetime => (), @@ -1055,7 +1054,7 @@ pub mod visit { ctxt: AssocCtxt, visitor: &mut V, ) -> V::Result { - let &Item { id, span, ident, ref vis, .. } = item; + let Item { id, span, ident, vis, .. } = item; match self { AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { try_visit!(visitor.visit_generics(generics)); @@ -1065,7 +1064,7 @@ pub mod visit { AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, span, id)); + try_visit!(visitor.visit_fn(kind, *span, *id)); } AssocItemKind::Type(box TyAlias { generics, @@ -1091,7 +1090,7 @@ pub mod visit { }) => { try_visit!(visitor.visit_qself(qself)); try_visit!(visitor.visit_path(path, *id)); - visit_opt!(visitor, visit_ident, *rename); + visit_opt!(visitor, visit_ident, rename); visit_opt!(visitor, visit_block, body); } AssocItemKind::DelegationMac(box DelegationMac { @@ -1101,12 +1100,12 @@ pub mod visit { body, }) => { try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_path(prefix, id)); + try_visit!(visitor.visit_path(prefix, *id)); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { - visitor.visit_ident(*ident); + visitor.visit_ident(ident); if let Some(rename) = rename { - visitor.visit_ident(*rename); + visitor.visit_ident(rename); } } } @@ -1122,7 +1121,7 @@ pub mod visit { item: &'a Item, ctxt: AssocCtxt, ) -> V::Result { - let &Item { id: _, span: _, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; + let Item { id: _, span: _, ident, vis, attrs, kind, tokens: _ } = item; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_ident(ident)); @@ -1142,7 +1141,7 @@ pub mod visit { let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); - visit_opt!(visitor, visit_ident, *ident); + visit_opt!(visitor, visit_ident, ident); try_visit!(visitor.visit_ty(ty)); V::Result::output() } @@ -1227,7 +1226,7 @@ pub mod visit { for FormatArgument { kind, expr } in arguments.all_args() { match kind { FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - try_visit!(visitor.visit_ident(*ident)) + try_visit!(visitor.visit_ident(ident)) } FormatArgumentKind::Normal => {} } @@ -1347,7 +1346,7 @@ pub mod visit { } ExprKind::Field(subexpression, ident) => { try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ident(*ident)); + try_visit!(visitor.visit_ident(ident)); } ExprKind::Index(main_expression, index_expression, _span) => { try_visit!(visitor.visit_expr(main_expression)); @@ -1382,7 +1381,7 @@ pub mod visit { ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)), ExprKind::OffsetOf(container, fields) => { try_visit!(visitor.visit_ty(container)); - walk_list!(visitor, visit_ident, fields.iter().copied()); + walk_list!(visitor, visit_ident, fields.iter()); } ExprKind::Yield(optional_expression) => { visit_opt!(visitor, visit_expr, optional_expression); diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 20a4f2120dcdf..73aa2a870ad2a 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -249,7 +249,7 @@ impl<'a> AstValidator<'a> { } fn visit_struct_field_def(&mut self, field: &'a FieldDef) { - if let Some(ident) = field.ident + if let Some(ref ident) = field.ident && ident.name == kw::Underscore { self.visit_vis(&field.vis); @@ -899,7 +899,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } this.visit_vis(&item.vis); - this.visit_ident(item.ident); + this.visit_ident(&item.ident); let disallowed = matches!(constness, Const::No) .then(|| TildeConstReason::TraitImpl { span: item.span }); this.with_tilde_const(disallowed, |this| this.visit_generics(generics)); @@ -953,7 +953,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } this.visit_vis(&item.vis); - this.visit_ident(item.ident); + this.visit_ident(&item.ident); this.with_tilde_const( Some(TildeConstReason::Impl { span: item.span }), |this| this.visit_generics(generics), @@ -991,9 +991,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } self.visit_vis(&item.vis); - self.visit_ident(item.ident); - let kind = - FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref()); + self.visit_ident(&item.ident); + let kind = FnKind::Fn( + FnCtxt::Free, + &item.ident, + sig, + &item.vis, + generics, + body.as_deref(), + ); self.visit_fn(kind, item.span, item.id); walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. @@ -1058,7 +1064,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Equivalent of `visit::walk_item` for `ItemKind::Trait` that inserts a bound // context for the supertraits. this.visit_vis(&item.vis); - this.visit_ident(item.ident); + this.visit_ident(&item.ident); let disallowed = is_const_trait .is_none() .then(|| TildeConstReason::Trait { span: item.span }); @@ -1085,7 +1091,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ItemKind::Struct(vdata, generics) => match vdata { VariantData::Struct { fields, .. } => { self.visit_vis(&item.vis); - self.visit_ident(item.ident); + self.visit_ident(&item.ident); self.visit_generics(generics); // Permit `Anon{Struct,Union}` as field type. walk_list!(self, visit_struct_field_def, fields); @@ -1101,7 +1107,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { match vdata { VariantData::Struct { fields, .. } => { self.visit_vis(&item.vis); - self.visit_ident(item.ident); + self.visit_ident(&item.ident); self.visit_generics(generics); // Permit `Anon{Struct,Union}` as field type. walk_list!(self, visit_struct_field_def, fields); @@ -1521,10 +1527,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { || matches!(sig.header.constness, Const::Yes(_)) => { self.visit_vis(&item.vis); - self.visit_ident(item.ident); + self.visit_ident(&item.ident); let kind = FnKind::Fn( FnCtxt::Assoc(ctxt), - item.ident, + &item.ident, sig, &item.vis, generics, diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index e22e99f6e4d65..9e7204df8adf1 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -16,7 +16,7 @@ impl NodeCounter { } impl<'ast> Visitor<'ast> for NodeCounter { - fn visit_ident(&mut self, _ident: Ident) { + fn visit_ident(&mut self, _ident: &Ident) { self.count += 1; } fn visit_foreign_item(&mut self, i: &ForeignItem) { diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index 652e6f7740f9f..d4befd12190bf 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -222,7 +222,7 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, ' rustc_ast::visit::walk_attribute(self, attr); } fn visit_variant(&mut self, v: &'a rustc_ast::Variant) { - self.visit_ident(v.ident); + self.visit_ident(&v.ident); self.visit_vis(&v.vis); self.visit_variant_data(&v.data); visit_opt!(self, visit_anon_const, &v.disr_expr); diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 2285877c9ef26..b10865c34f9d4 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -190,8 +190,9 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> ast_visit::walk_ty(self, t); } - fn visit_ident(&mut self, ident: Ident) { - lint_callback!(self, check_ident, ident); + fn visit_ident(&mut self, ident: &Ident) { + // FIXME: Change check_ident so it receives a reference + lint_callback!(self, check_ident, *ident); } fn visit_local(&mut self, l: &'a ast::Local) { diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 0145ffd3a4b7c..a831fb5c2e324 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1317,7 +1317,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // Visit attributes after items for backward compatibility. // This way they can use `macro_rules` defined later. self.visit_vis(&item.vis); - self.visit_ident(item.ident); + self.visit_ident(&item.ident); item.kind.walk(item, AssocCtxt::Trait, self); visit::walk_list!(self, visit_attribute, &item.attrs); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index b84cbf9c62941..8b0abf57c2015 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1205,7 +1205,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r } fn visit_assoc_item_constraint(&mut self, constraint: &'ast AssocItemConstraint) { - self.visit_ident(constraint.ident); + self.visit_ident(&constraint.ident); if let Some(ref gen_args) = constraint.gen_args { // Forbid anonymous lifetimes in GAT parameters until proper semantics are decided. self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { @@ -4581,7 +4581,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { fn resolve_expr_field(&mut self, f: &'ast ExprField, e: &'ast Expr) { self.resolve_expr(&f.expr, Some(e)); - self.visit_ident(f.ident); + self.visit_ident(&f.ident); walk_list!(self, visit_attribute, f.attrs.iter()); } diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs b/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs index 032cd3ed7399f..22b2c895f7c50 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs @@ -39,7 +39,7 @@ impl From<&Attribute> for IdentIter { struct IdentCollector(Vec); impl Visitor<'_> for IdentCollector { - fn visit_ident(&mut self, ident: Ident) { - self.0.push(ident); + fn visit_ident(&mut self, ident: &Ident) { + self.0.push(*ident); } } diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index fc043a697e039..6cd02f1e17c40 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -3443,7 +3443,7 @@ impl Rewrite for ast::ForeignItem { visitor.visit_fn( visit::FnKind::Fn( fn_ctxt, - self.ident, + &self.ident, sig, &self.vis, generics, diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 8102fe7ad8f29..64e2a74f7460e 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -390,7 +390,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { block = b; self.rewrite_fn_before_block( indent, - ident, + *ident, &FnSig::from_fn_kind(&fk, fd, defaultness), mk_sp(s.lo(), b.span.lo()), ) @@ -549,7 +549,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { self.visit_fn( visit::FnKind::Fn( fn_ctxt, - item.ident, + &item.ident, sig, &item.vis, generics, @@ -652,7 +652,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let inner_attrs = inner_attributes(&ai.attrs); let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt); self.visit_fn( - visit::FnKind::Fn(fn_ctxt, ai.ident, sig, &ai.vis, generics, Some(body)), + visit::FnKind::Fn(fn_ctxt, &ai.ident, sig, &ai.vis, generics, Some(body)), &sig.decl, ai.span, defaultness, From 72457f5b2cefe324bd0d1f0dd03afba0661cb22c Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:01:09 -0300 Subject: [PATCH 11/82] Unify {visit,walk}_ident --- compiler/rustc_ast/src/visitors.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 3da172ba49e2e..79c184b424efc 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -39,7 +39,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! return_result { ($V: ty) => { macro_if!($($mut)? { () } else { <$V>::Result::output() }) @@ -95,7 +94,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! visit_span { ($vis: ident, $span: ident) => { macro_if!{ $($mut)? { @@ -107,7 +105,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! try_v { ($visit: expr) => { macro_if!{$($mut)? { $visit } else { try_visit!($visit) }} @@ -193,7 +190,6 @@ macro_rules! make_ast_visitor { make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} - make_visit!{Ident; visit_ident, walk_ident} make_visit!{Lifetime; visit_lifetime, walk_lifetime} make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} @@ -298,9 +294,6 @@ macro_rules! make_ast_visitor { make_visit!{Variant; visit_variant, walk_variant} make_visit!{VariantData; visit_variant_data, walk_struct_def} - fn visit_ident(&mut self, _ident: &'ast Ident) -> Self::Result { - Self::Result::output() - } /// This method is a hack to workaround unstable of `stmt_expr_attributes`. /// It can be removed once that feature is stabilized. fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { @@ -340,6 +333,7 @@ macro_rules! make_ast_visitor { make_visit!{GenericArgs; visit_generic_args, walk_generic_args} make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} make_visit!{Generics; visit_generics, walk_generics} + make_visit!{Ident; visit_ident, walk_ident} make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} make_visit!{Label; visit_label, walk_label} @@ -358,6 +352,15 @@ macro_rules! make_ast_visitor { make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} } + + pub fn walk_ident<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + ident: ref_t!(Ident) + ) -> result!(V) { + let Ident { name: _, span } = ident; + try_v!(visit_span!(vis, span)); + return_result!(V) + } } } @@ -1710,10 +1713,6 @@ pub mod mut_visit { smallvec![variant] } - fn walk_ident(vis: &mut T, Ident { name: _, span }: &mut Ident) { - vis.visit_span(span); - } - fn walk_path_segment(vis: &mut T, segment: &mut PathSegment) { let PathSegment { ident, id, args } = segment; vis.visit_id(id); From 6d12aeb3ac1467d9a32686174ccdcef7a9ee802b Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:03:01 -0300 Subject: [PATCH 12/82] Unify walk_label --- compiler/rustc_ast/src/visitors.rs | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 79c184b424efc..880f91c24d735 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -361,6 +361,15 @@ macro_rules! make_ast_visitor { try_v!(visit_span!(vis, span)); return_result!(V) } + + pub fn walk_label<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + label: ref_t!(Label) + ) -> result!(V) { + let Label { ident } = label; + try_v!(vis.visit_ident(ident)); + return_result!(V) + } } } @@ -506,13 +515,6 @@ pub mod visit { V::Result::output() } - pub fn walk_label<'a, V: Visitor<'a>>( - visitor: &mut V, - Label { ident }: &'a Label, - ) -> V::Result { - visitor.visit_ident(ident) - } - pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result { let Lifetime { id: _, ident } = lifetime; visitor.visit_ident(ident) @@ -2138,10 +2140,6 @@ pub mod mut_visit { smallvec![param] } - fn walk_label(vis: &mut T, Label { ident }: &mut Label) { - vis.visit_ident(ident); - } - fn walk_lifetime(vis: &mut T, Lifetime { id, ident }: &mut Lifetime) { vis.visit_id(id); vis.visit_ident(ident); From 736f784b6de5f4ca2c3c75cf5b37b0fbb9d92717 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:11:26 -0300 Subject: [PATCH 13/82] Unify {visit,walk}_lifetime --- compiler/rustc_ast/src/visitors.rs | 36 ++++++++++++++---------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 880f91c24d735..f7c0d63103f3d 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -82,7 +82,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! visit_id { ($vis: ident, $id: ident) => { macro_if!{ $($mut)? { @@ -190,7 +189,6 @@ macro_rules! make_ast_visitor { make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} - make_visit!{Lifetime; visit_lifetime, walk_lifetime} make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} @@ -285,7 +283,6 @@ macro_rules! make_ast_visitor { make_visit!{ForeignItem; visit_foreign_item, walk_item} make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Item; visit_item, walk_item} - make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} make_visit!{Param; visit_param, walk_param} make_visit!{PatField; visit_pat_field, walk_pat_field} make_visit!{Path, _ id: NodeId; visit_path, walk_path} @@ -337,6 +334,7 @@ macro_rules! make_ast_visitor { make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} make_visit!{Label; visit_label, walk_label} + make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} make_visit!{MacCall; visit_mac_call, walk_mac} make_visit!{Option>; visit_qself, walk_qself} make_visit!{PathSegment; visit_path_segment, walk_path_segment} @@ -370,6 +368,16 @@ macro_rules! make_ast_visitor { try_v!(vis.visit_ident(ident)); return_result!(V) } + + pub fn walk_lifetime<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + lifetime: ref_t!(Lifetime) + ) -> result!(V) { + let Lifetime { id, ident } = lifetime; + try_v!(visit_id!(vis, id)); + try_v!(vis.visit_ident(ident)); + return_result!(V) + } } } @@ -515,11 +523,6 @@ pub mod visit { V::Result::output() } - pub fn walk_lifetime<'a, V: Visitor<'a>>(visitor: &mut V, lifetime: &'a Lifetime) -> V::Result { - let Lifetime { id: _, ident } = lifetime; - visitor.visit_ident(ident) - } - pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result where V: Visitor<'a>, @@ -1468,7 +1471,7 @@ pub mod mut_visit { //! that are created by the expansion of a macro. use super::*; - use crate::visit::{AssocCtxt, BoundKind}; + use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt}; pub trait ExpectOne { fn expect_one(self, err: &'static str) -> A::Item; @@ -1655,7 +1658,7 @@ pub mod mut_visit { 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)); + visit_opt(lt, |lt| vis.visit_lifetime(lt, LifetimeCtxt::Ref)); vis.visit_mt(mt); } TyKind::BareFn(bft) => { @@ -1748,7 +1751,7 @@ pub mod mut_visit { fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { match arg { - GenericArg::Lifetime(lt) => vis.visit_lifetime(lt), + GenericArg::Lifetime(lt) => vis.visit_lifetime(lt, LifetimeCtxt::GenericArg), GenericArg::Type(ty) => vis.visit_ty(ty), GenericArg::Const(ct) => vis.visit_anon_const(ct), } @@ -2092,7 +2095,7 @@ pub mod mut_visit { fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { match pb { GenericBound::Trait(ty) => vis.visit_poly_trait_ref(ty), - GenericBound::Outlives(lifetime) => walk_lifetime(vis, lifetime), + GenericBound::Outlives(lifetime) => vis.visit_lifetime(lifetime, LifetimeCtxt::Bound), GenericBound::Use(args, span) => { for arg in args { vis.visit_precise_capturing_arg(arg); @@ -2105,7 +2108,7 @@ pub mod mut_visit { fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCapturingArg) { match arg { PreciseCapturingArg::Lifetime(lt) => { - vis.visit_lifetime(lt); + vis.visit_lifetime(lt, LifetimeCtxt::GenericArg); } PreciseCapturingArg::Arg(path, id) => { vis.visit_id(id); @@ -2140,11 +2143,6 @@ pub mod mut_visit { smallvec![param] } - fn walk_lifetime(vis: &mut T, Lifetime { id, ident }: &mut Lifetime) { - vis.visit_id(id); - vis.visit_ident(ident); - } - fn walk_generics(vis: &mut T, generics: &mut Generics) { let Generics { params, where_clause, span } = generics; params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); @@ -2177,7 +2175,7 @@ pub mod mut_visit { } WherePredicate::RegionPredicate(rp) => { let WhereRegionPredicate { span, lifetime, bounds } = rp; - vis.visit_lifetime(lifetime); + vis.visit_lifetime(lifetime, LifetimeCtxt::Bound); visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); vis.visit_span(span); } From 3436219aa6f632cd5805127e6c34d15e9754f5b7 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:15:33 -0300 Subject: [PATCH 14/82] Unify {visit,walk}_angle_bracketed_parameter_data --- compiler/rustc_ast/src/visitors.rs | 42 +++++++++++++----------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index f7c0d63103f3d..bb523b3ae098b 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -184,7 +184,6 @@ macro_rules! make_ast_visitor { // field access version will continue working and it would be easy to // forget to add handling for it. - make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} make_visit!{CaptureBy; visit_capture_by, walk_capture_by} make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{FnHeader; visit_fn_header, walk_fn_header} @@ -319,6 +318,7 @@ macro_rules! make_ast_visitor { } }} + make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} make_visit!{AnonConst; visit_anon_const, walk_anon_const} make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} make_visit!{Attribute; visit_attribute, walk_attribute} @@ -351,6 +351,21 @@ macro_rules! make_ast_visitor { make_visit!{P!(Ty); visit_ty, walk_ty} } + pub fn walk_angle_bracketed_parameter_data<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + data: ref_t!(AngleBracketedArgs) + ) -> result!(V) { + let AngleBracketedArgs { args, span } = data; + for arg in args { + match arg { + AngleBracketedArg::Arg(a) => try_v!(vis.visit_generic_arg(a)), + AngleBracketedArg::Constraint(c) => try_v!(vis.visit_assoc_item_constraint(c)), + } + } + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_ident<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, ident: ref_t!(Ident) @@ -794,15 +809,8 @@ pub mod visit { V: Visitor<'a>, { match generic_args { - GenericArgs::AngleBracketed(AngleBracketedArgs { span: _, args }) => { - for arg in args { - match arg { - AngleBracketedArg::Arg(a) => try_visit!(visitor.visit_generic_arg(a)), - AngleBracketedArg::Constraint(c) => { - try_visit!(visitor.visit_assoc_item_constraint(c)) - } - } - } + GenericArgs::AngleBracketed(args) => { + try_visit!(visitor.visit_angle_bracketed_parameter_data(args)); } GenericArgs::Parenthesized(data) => { let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data; @@ -1757,20 +1765,6 @@ pub mod mut_visit { } } - fn walk_angle_bracketed_parameter_data( - vis: &mut T, - data: &mut AngleBracketedArgs, - ) { - let AngleBracketedArgs { args, span } = data; - visit_thin_vec(args, |arg| match arg { - AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), - AngleBracketedArg::Constraint(constraint) => { - vis.visit_assoc_item_constraint(constraint) - } - }); - vis.visit_span(span); - } - fn walk_parenthesized_parameter_data(vis: &mut T, args: &mut ParenthesizedArgs) { let ParenthesizedArgs { inputs, output, span, inputs_span } = args; visit_thin_vec(inputs, |input| vis.visit_ty(input)); From 80ac89fe88a3e5be3dc3583fea85db3fd6caee73 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:20:36 -0300 Subject: [PATCH 15/82] Unify {visit,walk}_parenthesized_parameter_data --- compiler/rustc_ast/src/visitors.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index bb523b3ae098b..226b759417d27 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -119,7 +119,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! visit_list { ($visitor: expr, $visit: ident, $flat_map: ident, $list: expr $$(; $$($arg: expr),*)?) => { macro_if!{$($mut)? { @@ -192,7 +191,6 @@ macro_rules! make_ast_visitor { make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} make_visit!{MutTy; visit_mt, walk_mt} - make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} make_visit!{Path; visit_path, walk_path} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} make_visit!{UseTree; visit_use_tree, walk_use_tree} @@ -337,6 +335,7 @@ macro_rules! make_ast_visitor { make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} make_visit!{MacCall; visit_mac_call, walk_mac} make_visit!{Option>; visit_qself, walk_qself} + make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} @@ -393,6 +392,18 @@ macro_rules! make_ast_visitor { try_v!(vis.visit_ident(ident)); return_result!(V) } + + pub fn walk_parenthesized_parameter_data<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + args: ref_t!(ParenthesizedArgs) + ) -> result!(V) { + let ParenthesizedArgs { inputs, output, span, inputs_span } = args; + visit_list!(vis, visit_ty, inputs); + try_v!(vis.visit_fn_ret_ty(output)); + try_v!(visit_span!(vis, span)); + try_v!(visit_span!(vis, inputs_span)); + return_result!(V) + } } } @@ -812,10 +823,8 @@ pub mod visit { GenericArgs::AngleBracketed(args) => { try_visit!(visitor.visit_angle_bracketed_parameter_data(args)); } - GenericArgs::Parenthesized(data) => { - let ParenthesizedArgs { span: _, inputs, inputs_span: _, output } = data; - walk_list!(visitor, visit_ty, inputs); - try_visit!(visitor.visit_fn_ret_ty(output)); + GenericArgs::Parenthesized(args) => { + try_visit!(visitor.visit_parenthesized_parameter_data(args)); } GenericArgs::ParenthesizedElided(_span) => {} } @@ -1765,14 +1774,6 @@ pub mod mut_visit { } } - fn walk_parenthesized_parameter_data(vis: &mut T, args: &mut ParenthesizedArgs) { - let ParenthesizedArgs { inputs, output, span, inputs_span } = args; - visit_thin_vec(inputs, |input| vis.visit_ty(input)); - vis.visit_fn_ret_ty(output); - vis.visit_span(span); - vis.visit_span(inputs_span); - } - fn walk_local(vis: &mut T, local: &mut P) { let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut(); vis.visit_id(id); From 73f3285453511276004091dedcecbe4a04b0b86f Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:23:16 -0300 Subject: [PATCH 16/82] Unify walk_generic_args --- compiler/rustc_ast/src/visitors.rs | 42 +++++++++++++----------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 226b759417d27..4b2bd1c89a410 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -365,6 +365,24 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_generic_args<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + generic_args: ref_t!(GenericArgs) + ) -> result!(V) { + match generic_args { + GenericArgs::AngleBracketed(data) => { + try_v!(vis.visit_angle_bracketed_parameter_data(data)); + } + GenericArgs::Parenthesized(data) => { + try_v!(vis.visit_parenthesized_parameter_data(data)); + } + GenericArgs::ParenthesizedElided(span) => { + try_v!(visit_span!(vis, span)); + } + } + return_result!(V) + } + pub fn walk_ident<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, ident: ref_t!(Ident) @@ -815,22 +833,6 @@ pub mod visit { V::Result::output() } - pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) -> V::Result - where - V: Visitor<'a>, - { - match generic_args { - GenericArgs::AngleBracketed(args) => { - try_visit!(visitor.visit_angle_bracketed_parameter_data(args)); - } - GenericArgs::Parenthesized(args) => { - try_visit!(visitor.visit_parenthesized_parameter_data(args)); - } - GenericArgs::ParenthesizedElided(_span) => {} - } - V::Result::output() - } - pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result where V: Visitor<'a>, @@ -1758,14 +1760,6 @@ pub mod mut_visit { }) } - fn walk_generic_args(vis: &mut T, generic_args: &mut GenericArgs) { - match generic_args { - GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), - GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), - GenericArgs::ParenthesizedElided(span) => vis.visit_span(span), - } - } - fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { match arg { GenericArg::Lifetime(lt) => vis.visit_lifetime(lt, LifetimeCtxt::GenericArg), From b7df6f1689266bbcd3804dd92287a276a2812f78 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:25:33 -0300 Subject: [PATCH 17/82] Unify walk_fn_ret_ty --- compiler/rustc_ast/src/visitors.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 4b2bd1c89a410..41ef33cb1686a 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -365,6 +365,17 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_fn_ret_ty<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + ret_ty: ref_t!(FnRetTy) + ) -> result!(V) { + match ret_ty { + FnRetTy::Default(span) => { try_v!(visit_span!(vis, span)) } + FnRetTy::Ty(output_ty) => { try_v!(vis.visit_ty(output_ty)) } + } + return_result!(V) + } + pub fn walk_generic_args<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, generic_args: ref_t!(GenericArgs) @@ -1040,14 +1051,6 @@ pub mod visit { V::Result::output() } - pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) -> V::Result { - match ret_ty { - FnRetTy::Default(_span) => {} - FnRetTy::Ty(output_ty) => try_visit!(visitor.visit_ty(output_ty)), - } - V::Result::output() - } - pub fn walk_fn_decl<'a, V: Visitor<'a>>( visitor: &mut V, FnDecl { inputs, output }: &'a FnDecl, @@ -2074,13 +2077,6 @@ pub mod mut_visit { vis.visit_fn_ret_ty(output); } - fn walk_fn_ret_ty(vis: &mut T, fn_ret_ty: &mut FnRetTy) { - match fn_ret_ty { - FnRetTy::Default(span) => vis.visit_span(span), - FnRetTy::Ty(ty) => vis.visit_ty(ty), - } - } - fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { match pb { GenericBound::Trait(ty) => vis.visit_poly_trait_ref(ty), From 5238327dfbe306ca2ce10d4e71975e7e597b4815 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:28:10 -0300 Subject: [PATCH 18/82] Unify walk_anon_const --- compiler/rustc_ast/src/visitors.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 41ef33cb1686a..88dec6378951f 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -365,6 +365,16 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_anon_const<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + anon_const: ref_t!(AnonConst) + ) -> result!(V) { + let AnonConst { id, value } = anon_const; + try_v!(visit_id!(vis, id)); + try_v!(vis.visit_expr(value)); + return_result!(V) + } + pub fn walk_fn_ret_ty<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, ret_ty: ref_t!(FnRetTy) @@ -1203,14 +1213,6 @@ pub mod visit { 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) - } - pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result { let InlineAsm { asm_macro: _, @@ -2551,11 +2553,6 @@ pub mod mut_visit { vis.visit_span(span); } - fn walk_anon_const(vis: &mut T, AnonConst { id, value }: &mut AnonConst) { - vis.visit_id(id); - vis.visit_expr(value); - } - fn walk_inline_asm(vis: &mut T, asm: &mut InlineAsm) { // FIXME: Visit spans inside all this currently ignored stuff. let InlineAsm { From 26043fba935fe791066c40666ee0b7cc0b2f76f6 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:31:15 -0300 Subject: [PATCH 19/82] Unify walk_format_args --- compiler/rustc_ast/src/visitors.rs | 53 ++++++++++++++---------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 88dec6378951f..721d125044b66 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -386,6 +386,30 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_format_args<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + fmt: ref_t!(FormatArgs) + ) -> result!(V) { + // FIXME: visit the template exhaustively. + let FormatArgs { span, template: _, arguments } = fmt; + let arg_iter = macro_if!{$($mut)? { + arguments.all_args_mut() + } else { + arguments.all_args() + }}; + for FormatArgument { kind, expr } in arg_iter { + match kind { + FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { + try_v!(vis.visit_ident(ident)); + } + FormatArgumentKind::Normal => {} + } + try_v!(vis.visit_expr(expr)); + } + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_generic_args<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, generic_args: ref_t!(GenericArgs) @@ -1253,20 +1277,6 @@ pub mod visit { visitor.visit_path(path, *id) } - pub fn walk_format_args<'a, V: Visitor<'a>>(visitor: &mut V, fmt: &'a FormatArgs) -> V::Result { - let FormatArgs { span: _, template: _, arguments } = fmt; - for FormatArgument { kind, expr } in arguments.all_args() { - match kind { - FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - try_visit!(visitor.visit_ident(ident)) - } - FormatArgumentKind::Normal => {} - } - try_visit!(visitor.visit_expr(expr)); - } - V::Result::output() - } - pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result { let Expr { id, kind, span, attrs, tokens: _ } = expression; walk_list!(visitor, visit_attribute, attrs); @@ -2593,21 +2603,6 @@ pub mod mut_visit { vis.visit_path(path); } - fn walk_format_args(vis: &mut T, fmt: &mut FormatArgs) { - // FIXME: visit the template exhaustively. - let FormatArgs { span, template: _, arguments } = fmt; - for FormatArgument { kind, expr } in arguments.all_args_mut() { - match kind { - FormatArgumentKind::Named(ident) | FormatArgumentKind::Captured(ident) => { - vis.visit_ident(ident) - } - FormatArgumentKind::Normal => {} - } - vis.visit_expr(expr); - } - vis.visit_span(span); - } - pub fn walk_expr( vis: &mut T, Expr { kind, id, span, attrs, tokens }: &mut Expr, From 2458e614ded7e16b607d31d4d4d7d7adfbfb578a Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:33:44 -0300 Subject: [PATCH 20/82] Unify {visit,walk}_mt --- compiler/rustc_ast/src/visitors.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 721d125044b66..ef8d76caa15d7 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -190,7 +190,6 @@ macro_rules! make_ast_visitor { make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} - make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Path; visit_path, walk_path} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} make_visit!{UseTree; visit_use_tree, walk_use_tree} @@ -334,6 +333,7 @@ macro_rules! make_ast_visitor { make_visit!{Label; visit_label, walk_label} make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} make_visit!{MacCall; visit_mac_call, walk_mac} + make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Option>; visit_qself, walk_qself} make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} make_visit!{PathSegment; visit_path_segment, walk_path_segment} @@ -456,6 +456,15 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_mt<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + mt: ref_t!(MutTy) + ) -> result!(V) { + let MutTy { ty, mutbl: _ } = mt; + try_v!(vis.visit_ty(ty)); + return_result!(V) + } + pub fn walk_parenthesized_parameter_data<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, args: ref_t!(ParenthesizedArgs) @@ -790,11 +799,10 @@ pub mod visit { 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: _ }) => { + TyKind::Ptr(mt) => try_visit!(visitor.visit_mt(mt)), + TyKind::Ref(opt_lifetime, mt) | TyKind::PinnedRef(opt_lifetime, mt) => { visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref); - try_visit!(visitor.visit_ty(ty)); + try_visit!(visitor.visit_mt(mt)); } TyKind::Tup(tuple_element_types) => { walk_list!(visitor, visit_ty, tuple_element_types); @@ -2237,10 +2245,6 @@ pub mod mut_visit { smallvec![f] } - fn walk_mt(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) { - vis.visit_ty(ty); - } - pub fn walk_block(vis: &mut T, block: &mut P) { let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block.deref_mut(); From dfdd0b2a447c7940d93c02356f5268681bd4fb52 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:36:27 -0300 Subject: [PATCH 21/82] Unify walk_closure_binder --- compiler/rustc_ast/src/visitors.rs | 36 ++++++++++++------------------ 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index ef8d76caa15d7..8b62f7a83c966 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -375,6 +375,20 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_closure_binder<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + binder: ref_t!(ClosureBinder) + ) -> result!(V) { + match binder { + ClosureBinder::NotPresent => {} + ClosureBinder::For { generic_params, span } => { + visit_list!(vis, visit_generic_param, flat_map_generic_param, generic_params); + try_v!(visit_span!(vis, span)); + } + } + return_result!(V) + } + pub fn walk_fn_ret_ty<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, ret_ty: ref_t!(FnRetTy) @@ -1053,19 +1067,6 @@ pub mod visit { V::Result::output() } - pub fn walk_closure_binder<'a, V: Visitor<'a>>( - visitor: &mut V, - binder: &'a ClosureBinder, - ) -> V::Result { - match binder { - ClosureBinder::NotPresent => {} - ClosureBinder::For { generic_params, span: _ } => { - walk_list!(visitor, visit_generic_param, generic_params) - } - } - V::Result::output() - } - pub fn walk_where_predicate<'a, V: Visitor<'a>>( visitor: &mut V, predicate: &'a WherePredicate, @@ -2050,15 +2051,6 @@ pub mod mut_visit { } } - fn walk_closure_binder(vis: &mut T, binder: &mut ClosureBinder) { - match binder { - ClosureBinder::NotPresent => {} - ClosureBinder::For { span: _, generic_params } => { - generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - } - } - } - fn walk_coroutine_kind(vis: &mut T, coroutine_kind: &mut CoroutineKind) { match coroutine_kind { CoroutineKind::Async { span, closure_id, return_impl_trait_id } From 59607ec22bf169ebda42a64ab64e396f4fe24134 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:40:20 -0300 Subject: [PATCH 22/82] Unify walk_fn_decl --- compiler/rustc_ast/src/visitors.rs | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 8b62f7a83c966..10d52ba85ad09 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -321,6 +321,7 @@ macro_rules! make_ast_visitor { make_visit!{Attribute; visit_attribute, walk_attribute} make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} make_visit!{Crate; visit_crate, walk_crate} + make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{FormatArgs; visit_format_args, walk_format_args} make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} @@ -344,7 +345,6 @@ macro_rules! make_ast_visitor { make_visit!{P!(Block); visit_block, walk_block} make_visit!{P!(Expr); visit_expr, walk_expr} - make_visit!{P!(FnDecl); visit_fn_decl, walk_fn_decl} make_visit!{P!(Local); visit_local, walk_local} make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} @@ -389,6 +389,16 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_fn_decl<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + decl: ref_t!(FnDecl) + ) -> result!(V) { + let FnDecl { inputs, output } = decl; + visit_list!(vis, visit_param, flat_map_param, inputs); + try_v!(vis.visit_fn_ret_ty(output)); + return_result!(V) + } + pub fn walk_fn_ret_ty<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, ret_ty: ref_t!(FnRetTy) @@ -1094,14 +1104,6 @@ pub mod visit { V::Result::output() } - pub fn walk_fn_decl<'a, V: Visitor<'a>>( - visitor: &mut V, - FnDecl { inputs, output }: &'a FnDecl, - ) -> V::Result { - walk_list!(visitor, visit_param, inputs); - visitor.visit_fn_ret_ty(output) - } - pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { match kind { FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => { @@ -2083,12 +2085,6 @@ pub mod mut_visit { } } - fn walk_fn_decl(vis: &mut T, decl: &mut P) { - let FnDecl { inputs, output } = decl.deref_mut(); - inputs.flat_map_in_place(|param| vis.flat_map_param(param)); - vis.visit_fn_ret_ty(output); - } - fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { match pb { GenericBound::Trait(ty) => vis.visit_poly_trait_ref(ty), From f4504b694738e6e5bf203d474fdfb9d369250141 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:43:02 -0300 Subject: [PATCH 23/82] Unify walk_poly_trait_ref --- compiler/rustc_ast/src/visitors.rs | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 10d52ba85ad09..17b123a44dd83 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -500,6 +500,17 @@ macro_rules! make_ast_visitor { try_v!(visit_span!(vis, inputs_span)); return_result!(V) } + + pub fn walk_poly_trait_ref<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + trait_ref: ref_t!(PolyTraitRef) + ) -> result!(V) { + let PolyTraitRef { bound_generic_params, trait_ref, span, modifiers: _ } = trait_ref; + visit_list!(vis, visit_generic_param, flat_map_generic_param, bound_generic_params); + try_v!(vis.visit_trait_ref(trait_ref)); + try_v!(visit_span!(vis, span)); + return_result!(V) + } } } @@ -645,15 +656,6 @@ pub mod visit { V::Result::output() } - pub fn walk_poly_trait_ref<'a, V>(visitor: &mut V, trait_ref: &'a PolyTraitRef) -> V::Result - where - V: Visitor<'a>, - { - let PolyTraitRef { bound_generic_params, trait_ref, span: _, modifiers: _ } = trait_ref; - walk_list!(visitor, visit_generic_param, bound_generic_params); - visitor.visit_trait_ref(trait_ref) - } - pub fn walk_trait_ref<'a, V: Visitor<'a>>( visitor: &mut V, trait_ref: &'a TraitRef, @@ -2199,13 +2201,6 @@ pub mod mut_visit { vis.visit_path(path); } - fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { - let PolyTraitRef { bound_generic_params, trait_ref, span, modifiers: _ } = p; - bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_trait_ref(trait_ref); - vis.visit_span(span); - } - pub fn walk_flat_map_field_def( visitor: &mut T, mut fd: FieldDef, From aecb5e38b59f7d20503b48b469445f9bc34d6f9a Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:49:22 -0300 Subject: [PATCH 24/82] Unify {visit,walk}_where_clause --- compiler/rustc_ast/src/visitors.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 17b123a44dd83..48dbf61fc14f8 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -194,7 +194,6 @@ macro_rules! make_ast_visitor { make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} make_visit!{UseTree; visit_use_tree, walk_use_tree} make_visit!{VariantData; visit_variant_data, walk_variant_data} - make_visit!{WhereClause; visit_where_clause, walk_where_clause} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { walk_flat_map_item(self, ni) @@ -341,6 +340,7 @@ macro_rules! make_ast_visitor { make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} make_visit!{Visibility; visit_vis, walk_vis} + make_visit!{WhereClause; visit_where_clause, walk_where_clause} make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} make_visit!{P!(Block); visit_block, walk_block} @@ -511,6 +511,16 @@ macro_rules! make_ast_visitor { try_v!(visit_span!(vis, span)); return_result!(V) } + + pub fn walk_where_clause<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + wc: ref_t!(WhereClause) + ) -> result!(V) { + let WhereClause { has_where_token: _, predicates, span } = wc; + visit_list!(vis, visit_where_predicate, predicates); + try_v!(visit_span!(vis, span)); + return_result!(V) + } } } @@ -1073,9 +1083,8 @@ pub mod visit { pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result { let Generics { params, where_clause, span: _ } = generics; - let WhereClause { has_where_token: _, predicates, span: _ } = where_clause; walk_list!(visitor, visit_generic_param, params); - walk_list!(visitor, visit_where_predicate, predicates); + try_visit!(visitor.visit_where_clause(where_clause)); V::Result::output() } @@ -2153,12 +2162,6 @@ pub mod mut_visit { vis.visit_span(span_after); } - fn walk_where_clause(vis: &mut T, wc: &mut WhereClause) { - let WhereClause { has_where_token: _, predicates, span } = wc; - visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); - vis.visit_span(span); - } - fn walk_where_predicate(vis: &mut T, pred: &mut WherePredicate) { match pred { WherePredicate::BoundPredicate(bp) => { From 13b296ac210ca9a16c8ab110548c4cd05c5998ab Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:51:12 -0300 Subject: [PATCH 25/82] Unify walk_generics --- compiler/rustc_ast/src/visitors.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 48dbf61fc14f8..2e17ec49a5e51 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -452,6 +452,17 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_generics<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + generics: ref_t!(Generics) + ) -> result!(V) { + let Generics { params, where_clause, span } = generics; + visit_list!(vis, visit_generic_param, flat_map_generic_param, params); + try_v!(vis.visit_where_clause(where_clause)); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_ident<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, ident: ref_t!(Ident) @@ -1081,13 +1092,6 @@ pub mod visit { V::Result::output() } - pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) -> V::Result { - let Generics { params, where_clause, span: _ } = generics; - walk_list!(visitor, visit_generic_param, params); - try_visit!(visitor.visit_where_clause(where_clause)); - V::Result::output() - } - pub fn walk_where_predicate<'a, V: Visitor<'a>>( visitor: &mut V, predicate: &'a WherePredicate, @@ -2147,13 +2151,6 @@ pub mod mut_visit { smallvec![param] } - fn walk_generics(vis: &mut T, generics: &mut Generics) { - let Generics { params, where_clause, span } = generics; - params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_where_clause(where_clause); - vis.visit_span(span); - } - fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWhereClauses) { let TyAliasWhereClauses { before, after, split: _ } = tawcs; let TyAliasWhereClause { has_where_token: _, span: span_before } = before; From e49f8500f039c411c92e4839eb7080aa90e804df Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:53:40 -0300 Subject: [PATCH 26/82] Unify {visit,walk}_capture_by --- compiler/rustc_ast/src/visitors.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 2e17ec49a5e51..e176a68699a1c 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -183,7 +183,6 @@ macro_rules! make_ast_visitor { // field access version will continue working and it would be easy to // forget to add handling for it. - make_visit!{CaptureBy; visit_capture_by, walk_capture_by} make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} @@ -309,15 +308,13 @@ macro_rules! make_ast_visitor { fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { Self::Result::output() } - fn visit_capture_by(&mut self, _capture_by: &'ast CaptureBy) -> Self::Result { - Self::Result::output() - } }} make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} make_visit!{AnonConst; visit_anon_const, walk_anon_const} make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} make_visit!{Attribute; visit_attribute, walk_attribute} + make_visit!{CaptureBy; visit_capture_by, walk_capture_by} make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} make_visit!{Crate; visit_crate, walk_crate} make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} @@ -375,6 +372,19 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_capture_by<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + capture_by: ref_t!(CaptureBy) + ) -> result!(V) { + match capture_by { + CaptureBy::Ref => {} + CaptureBy::Value { move_kw } => { + try_v!(visit_span!(vis, move_kw)) + } + } + return_result!(V) + } + pub fn walk_closure_binder<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, binder: ref_t!(ClosureBinder) @@ -2845,15 +2855,6 @@ pub mod mut_visit { vis.visit_span(span); } - fn walk_capture_by(vis: &mut T, capture_by: &mut CaptureBy) { - match capture_by { - CaptureBy::Ref => {} - CaptureBy::Value { move_kw } => { - vis.visit_span(move_kw); - } - } - } - /// 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 From 2d9bbfeffc5b93e915c424a123cbe853b6bfe158 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 21:57:14 -0300 Subject: [PATCH 27/82] Unify {visit,walk}_enum_def --- compiler/rustc_ast/src/visitors.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index e176a68699a1c..699cba7c41a01 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -271,7 +271,6 @@ macro_rules! make_ast_visitor { make_visit!{Arm; visit_arm, walk_arm} make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} - make_visit!{EnumDef; visit_enum_def, walk_enum_def} make_visit!{ExprField; visit_expr_field, walk_expr_field} make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{ForeignItem; visit_foreign_item, walk_item} @@ -317,6 +316,7 @@ macro_rules! make_ast_visitor { make_visit!{CaptureBy; visit_capture_by, walk_capture_by} make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} make_visit!{Crate; visit_crate, walk_crate} + make_visit!{EnumDef; visit_enum_def, walk_enum_def} make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{FormatArgs; visit_format_args, walk_format_args} @@ -399,6 +399,15 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_enum_def<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + enum_def: ref_t!(EnumDef) + ) -> result!(V) { + let EnumDef { variants } = enum_def; + visit_list!(vis, visit_variant, flat_map_variant, variants); + return_result!(V) + } + pub fn walk_fn_decl<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, decl: ref_t!(FnDecl) @@ -813,14 +822,6 @@ pub mod visit { walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) } - pub fn walk_enum_def<'a, V: Visitor<'a>>( - visitor: &mut V, - EnumDef { variants }: &'a EnumDef, - ) -> V::Result { - walk_list!(visitor, visit_variant, variants); - V::Result::output() - } - pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -> V::Result where V: Visitor<'a>, @@ -2302,9 +2303,9 @@ pub mod mut_visit { visit_opt(ty, |ty| vis.visit_ty(ty)); walk_ty_alias_where_clauses(vis, where_clauses); } - ItemKind::Enum(EnumDef { variants }, generics) => { + ItemKind::Enum(enum_def, generics) => { vis.visit_generics(generics); - variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); + vis.visit_enum_def(enum_def); } ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { From a90eac5b02446fd81e4f699200ef69cb2d2f62a7 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:18:58 -0300 Subject: [PATCH 28/82] Unify {visit,walk}_pat_field --- compiler/rustc_ast/src/visitors.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 699cba7c41a01..f830c07d0f341 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -277,7 +277,6 @@ macro_rules! make_ast_visitor { make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Item; visit_item, walk_item} make_visit!{Param; visit_param, walk_param} - make_visit!{PatField; visit_pat_field, walk_pat_field} make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{Stmt; visit_stmt, walk_stmt} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} @@ -333,6 +332,7 @@ macro_rules! make_ast_visitor { make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Option>; visit_qself, walk_qself} make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} + make_visit!{PatField; visit_pat_field, walk_pat_field} make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} @@ -531,6 +531,19 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_pat_field<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + fp: ref_t!(PatField) + ) -> result!(V) { + let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + try_v!(vis.visit_ident(ident)); + try_v!(vis.visit_pat(pat)); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_poly_trait_ref<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, trait_ref: ref_t!(PolyTraitRef) @@ -845,14 +858,6 @@ pub mod visit { V::Result::output() } - pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) -> V::Result { - let PatField { ident, pat, is_shorthand: _, attrs, id: _, span: _, is_placeholder: _ } = fp; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(ident)); - try_visit!(visitor.visit_pat(pat)); - 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 { @@ -1658,12 +1663,7 @@ pub mod mut_visit { vis: &mut T, mut fp: PatField, ) -> SmallVec<[PatField; 1]> { - let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - vis.visit_pat(pat); - vis.visit_span(span); + vis.visit_pat_field(&mut fp); smallvec![fp] } From 71c720392cea48bb41c191e8fbdb7ca16a03ce7a Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:21:14 -0300 Subject: [PATCH 29/82] Unify {visit,walk}_param --- compiler/rustc_ast/src/visitors.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index f830c07d0f341..c1b0cfbe893f4 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -276,7 +276,6 @@ macro_rules! make_ast_visitor { make_visit!{ForeignItem; visit_foreign_item, walk_item} make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Item; visit_item, walk_item} - make_visit!{Param; visit_param, walk_param} make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{Stmt; visit_stmt, walk_stmt} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} @@ -331,6 +330,7 @@ macro_rules! make_ast_visitor { make_visit!{MacCall; visit_mac_call, walk_mac} make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Option>; visit_qself, walk_qself} + make_visit!{Param; visit_param, walk_param} make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} make_visit!{PatField; visit_pat_field, walk_pat_field} make_visit!{PathSegment; visit_path_segment, walk_path_segment} @@ -519,6 +519,19 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_param<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + param: ref_t!(Param) + ) -> result!(V) { + let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + try_v!(vis.visit_pat(pat)); + try_v!(vis.visit_ty(ty)); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_parenthesized_parameter_data<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, args: ref_t!(ParenthesizedArgs) @@ -1481,14 +1494,6 @@ pub mod visit { visitor.visit_expr_post(expression) } - pub fn walk_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Param) -> V::Result { - let Param { attrs, ty, pat, id: _, span: _, is_placeholder: _ } = param; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_ty(ty)); - V::Result::output() - } - pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result { let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm; walk_list!(visitor, visit_attribute, attrs); @@ -1891,12 +1896,7 @@ pub mod mut_visit { vis: &mut T, mut param: Param, ) -> SmallVec<[Param; 1]> { - let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - vis.visit_ty(ty); - vis.visit_span(span); + vis.visit_param(&mut param); smallvec![param] } From f90cad5b088357142037c1a7dcacea5cd87cc1a9 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:24:57 -0300 Subject: [PATCH 30/82] Unify walk_where_predicate --- compiler/rustc_ast/src/visitors.rs | 79 +++++++++++------------------- 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index c1b0cfbe893f4..33f3937d48e89 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -577,6 +577,34 @@ macro_rules! make_ast_visitor { try_v!(visit_span!(vis, span)); return_result!(V) } + + pub fn walk_where_predicate<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + predicate: ref_t!(WherePredicate) + ) -> result!(V) { + match predicate { + WherePredicate::BoundPredicate(bp) => { + let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; + visit_list!(vis, visit_generic_param, flat_map_generic_param, bound_generic_params); + try_v!(vis.visit_ty(bounded_ty)); + visit_list!(vis, visit_param_bound, bounds; BoundKind::Bound); + try_v!(visit_span!(vis, span)); + } + WherePredicate::RegionPredicate(rp) => { + let WhereRegionPredicate { span, lifetime, bounds } = rp; + try_v!(vis.visit_lifetime(lifetime, LifetimeCtxt::Bound)); + visit_list!(vis, visit_param_bound, bounds; BoundKind::Bound); + try_v!(visit_span!(vis, span)); + } + WherePredicate::EqPredicate(ep) => { + let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep; + try_v!(vis.visit_ty(lhs_ty)); + try_v!(vis.visit_ty(rhs_ty)); + try_v!(visit_span!(vis, span)); + } + } + return_result!(V) + } } } @@ -1121,33 +1149,6 @@ pub mod visit { V::Result::output() } - pub fn walk_where_predicate<'a, V: Visitor<'a>>( - visitor: &mut V, - predicate: &'a WherePredicate, - ) -> V::Result { - match predicate { - WherePredicate::BoundPredicate(WhereBoundPredicate { - bounded_ty, - bounds, - bound_generic_params, - span: _, - }) => { - walk_list!(visitor, visit_generic_param, bound_generic_params); - try_visit!(visitor.visit_ty(bounded_ty)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, span: _ }) => { - try_visit!(visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span: _ }) => { - try_visit!(visitor.visit_ty(lhs_ty)); - try_visit!(visitor.visit_ty(rhs_ty)); - } - } - V::Result::output() - } - pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { match kind { FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => { @@ -2170,30 +2171,6 @@ pub mod mut_visit { vis.visit_span(span_after); } - fn walk_where_predicate(vis: &mut T, pred: &mut WherePredicate) { - match pred { - WherePredicate::BoundPredicate(bp) => { - let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp; - bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_ty(bounded_ty); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - vis.visit_span(span); - } - WherePredicate::RegionPredicate(rp) => { - let WhereRegionPredicate { span, lifetime, bounds } = rp; - vis.visit_lifetime(lifetime, LifetimeCtxt::Bound); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - vis.visit_span(span); - } - WherePredicate::EqPredicate(ep) => { - let WhereEqPredicate { span, lhs_ty, rhs_ty } = ep; - vis.visit_ty(lhs_ty); - vis.visit_ty(rhs_ty); - vis.visit_span(span); - } - } - } - fn walk_variant_data(vis: &mut T, vdata: &mut VariantData) { match vdata { VariantData::Struct { fields, recovered: _ } => { From 87ca2933764850653a4427c8cd1d4df97e6dc3dc Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:32:29 -0300 Subject: [PATCH 31/82] Unify {visit,walk}_variant_data (renaming walk_struct_def) --- compiler/rustc_ast/src/visitors.rs | 43 ++++++++++----------- compiler/rustc_ast_passes/src/node_count.rs | 2 +- compiler/rustc_lint/src/early.rs | 2 +- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 33f3937d48e89..49fa2ad0fe956 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -192,7 +192,6 @@ macro_rules! make_ast_visitor { make_visit!{Path; visit_path, walk_path} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} make_visit!{UseTree; visit_use_tree, walk_use_tree} - make_visit!{VariantData; visit_variant_data, walk_variant_data} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { walk_flat_map_item(self, ni) @@ -280,7 +279,6 @@ macro_rules! make_ast_visitor { make_visit!{Stmt; visit_stmt, walk_stmt} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} make_visit!{Variant; visit_variant, walk_variant} - make_visit!{VariantData; visit_variant_data, walk_struct_def} /// This method is a hack to workaround unstable of `stmt_expr_attributes`. /// It can be removed once that feature is stabilized. @@ -336,6 +334,7 @@ macro_rules! make_ast_visitor { make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} + make_visit!{VariantData; visit_variant_data, walk_variant_data} make_visit!{Visibility; visit_vis, walk_vis} make_visit!{WhereClause; visit_where_clause, walk_where_clause} make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} @@ -568,6 +567,25 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_variant_data<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + vdata: ref_t!(VariantData) + ) -> result!(V) { + match vdata { + VariantData::Struct { fields, recovered: _ } => { + visit_list!(vis, visit_field_def, flat_map_field_def, fields); + } + VariantData::Tuple(fields, id) => { + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_field_def, flat_map_field_def, fields); + } + VariantData::Unit(id) => { + try_v!(visit_id!(vis, id)); + } + } + return_result!(V) + } + pub fn walk_where_clause<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, wc: ref_t!(WhereClause) @@ -1249,14 +1267,6 @@ pub mod visit { 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()); - V::Result::output() - } - pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result { let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field; walk_list!(visitor, visit_attribute, attrs); @@ -2171,19 +2181,6 @@ pub mod mut_visit { vis.visit_span(span_after); } - fn walk_variant_data(vis: &mut T, vdata: &mut VariantData) { - match vdata { - VariantData::Struct { fields, recovered: _ } => { - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } - VariantData::Tuple(fields, id) => { - vis.visit_id(id); - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); - } - VariantData::Unit(id) => vis.visit_id(id), - } - } - fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) { vis.visit_id(ref_id); vis.visit_path(path); diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index 9e7204df8adf1..4deb1eb9458aa 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -85,7 +85,7 @@ impl<'ast> Visitor<'ast> for NodeCounter { } fn visit_variant_data(&mut self, s: &VariantData) { self.count += 1; - walk_struct_def(self, s) + walk_variant_data(self, s) } fn visit_field_def(&mut self, s: &FieldDef) { self.count += 1; diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index b10865c34f9d4..f9436180efb58 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -168,7 +168,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> if let Some(ctor_node_id) = s.ctor_node_id() { self.check_id(ctor_node_id); } - ast_visit::walk_struct_def(self, s); + ast_visit::walk_variant_data(self, s); } fn visit_field_def(&mut self, s: &'a ast::FieldDef) { From 74e242cd38598d2eff583aed0c10b1271e484246 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:36:03 -0300 Subject: [PATCH 32/82] Unify {visit,walk}_expr_field --- compiler/rustc_ast/src/visitors.rs | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 49fa2ad0fe956..3d27cd7071b84 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -270,7 +270,6 @@ macro_rules! make_ast_visitor { make_visit!{Arm; visit_arm, walk_arm} make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} - make_visit!{ExprField; visit_expr_field, walk_expr_field} make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{ForeignItem; visit_foreign_item, walk_item} make_visit!{GenericParam; visit_generic_param, walk_generic_param} @@ -313,6 +312,7 @@ macro_rules! make_ast_visitor { make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} make_visit!{Crate; visit_crate, walk_crate} make_visit!{EnumDef; visit_enum_def, walk_enum_def} + make_visit!{ExprField; visit_expr_field, walk_expr_field} make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{FormatArgs; visit_format_args, walk_format_args} @@ -407,6 +407,19 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_expr_field<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + f: ref_t!(ExprField) + ) -> result!(V) { + let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + try_v!(vis.visit_ident(ident)); + try_v!(vis.visit_expr(expr)); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_fn_decl<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, decl: ref_t!(FnDecl) @@ -908,15 +921,6 @@ pub mod visit { V::Result::output() } - pub fn walk_expr_field<'a, V: Visitor<'a>>(visitor: &mut V, f: &'a ExprField) -> V::Result { - let ExprField { attrs, id: _, span: _, ident, expr, is_shorthand: _, is_placeholder: _ } = - f; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(ident)); - try_visit!(visitor.visit_expr(expr)); - 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 { @@ -2204,12 +2208,7 @@ pub mod mut_visit { vis: &mut T, mut f: ExprField, ) -> SmallVec<[ExprField; 1]> { - let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - vis.visit_expr(expr); - vis.visit_span(span); + vis.visit_expr_field(&mut f); smallvec![f] } From 82468f6130fecd11521a481f663a97a88ba5c00a Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:38:01 -0300 Subject: [PATCH 33/82] Unify {visit,walk}_arm --- compiler/rustc_ast/src/visitors.rs | 34 ++++++++++++++---------------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 3d27cd7071b84..cb27c646b7860 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -110,7 +110,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! visit_o { ($opt: expr, $fn: expr) => { if let Some(elem) = $opt { @@ -268,7 +267,6 @@ macro_rules! make_ast_visitor { /// or `ControlFlow`. type Result: VisitorResult = (); - make_visit!{Arm; visit_arm, walk_arm} make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{ForeignItem; visit_foreign_item, walk_item} @@ -306,6 +304,7 @@ macro_rules! make_ast_visitor { make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} make_visit!{AnonConst; visit_anon_const, walk_anon_const} + make_visit!{Arm; visit_arm, walk_arm} make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} make_visit!{Attribute; visit_attribute, walk_attribute} make_visit!{CaptureBy; visit_capture_by, walk_capture_by} @@ -371,6 +370,20 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_arm<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + arm: ref_t!(Arm) + ) -> result!(V) { + let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + try_v!(vis.visit_pat(pat)); + visit_o!(guard, |guard| vis.visit_expr(guard)); + visit_o!(body, |body| vis.visit_expr(body)); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_capture_by<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, capture_by: ref_t!(CaptureBy) @@ -1509,15 +1522,6 @@ pub mod visit { visitor.visit_expr_post(expression) } - pub fn walk_arm<'a, V: Visitor<'a>>(visitor: &mut V, arm: &'a Arm) -> V::Result { - let Arm { attrs, pat, guard, body, span: _, id: _, is_placeholder: _ } = arm; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - visit_opt!(visitor, visit_expr, guard); - visit_opt!(visitor, visit_expr, body); - V::Result::output() - } - pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result { let Visibility { kind, span: _, tokens: _ } = vis; match kind { @@ -1705,13 +1709,7 @@ pub mod mut_visit { } pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { - let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - visit_opt(guard, |guard| vis.visit_expr(guard)); - visit_opt(body, |body| vis.visit_expr(body)); - vis.visit_span(span); + vis.visit_arm(&mut arm); smallvec![arm] } From c956db5574ed98233d38a8fdd313d30734eb07f2 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:42:36 -0300 Subject: [PATCH 34/82] Unify visit_variant_discr --- compiler/rustc_ast/src/visitors.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index cb27c646b7860..c21298ae1f89a 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -291,9 +291,6 @@ macro_rules! make_ast_visitor { fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { walk_precise_capturing_arg(self, arg); } - fn visit_variant_discr(&mut self, discr: &'ast AnonConst) -> Self::Result { - self.visit_anon_const(discr) - } fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) -> Self::Result { Self::Result::output() } @@ -343,6 +340,11 @@ macro_rules! make_ast_visitor { make_visit!{P!(Local); visit_local, walk_local} make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} + + + fn visit_variant_discr(&mut self, discr: ref_t!(AnonConst)) -> result!() { + self.visit_anon_const(discr) + } } pub fn walk_angle_bracketed_parameter_data<$($lt,)? V: $trait$(<$lt>)?>( From f0957bee64c52971a555885dc13a176019eaaa19 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:44:41 -0300 Subject: [PATCH 35/82] Unify {visit,walk}_variant --- compiler/rustc_ast/src/visitors.rs | 41 +++++++++++++----------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index c21298ae1f89a..fa0cb29ce721d 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -275,7 +275,6 @@ macro_rules! make_ast_visitor { make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{Stmt; visit_stmt, walk_stmt} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} - make_visit!{Variant; visit_variant, walk_variant} /// This method is a hack to workaround unstable of `stmt_expr_attributes`. /// It can be removed once that feature is stabilized. @@ -330,6 +329,7 @@ macro_rules! make_ast_visitor { make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} + make_visit!{Variant; visit_variant, walk_variant} make_visit!{VariantData; visit_variant_data, walk_variant_data} make_visit!{Visibility; visit_vis, walk_vis} make_visit!{WhereClause; visit_where_clause, walk_where_clause} @@ -595,6 +595,21 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_variant<$($lt,)? V: $trait$(<$lt>)?>( + visitor: &mut V, + variant: ref_t!(Variant) + ) -> result!(V) { + let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant; + try_v!(visit_id!(visitor, id)); + visit_list!(visitor, visit_attribute, attrs); + try_v!(visitor.visit_vis(vis)); + try_v!(visitor.visit_ident(ident)); + try_v!(visitor.visit_variant_data(data)); + visit_o!(disr_expr, |disr_expr| visitor.visit_variant_discr(disr_expr)); + try_v!(visit_span!(visitor, span)); + return_result!(V) + } + pub fn walk_variant_data<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, vdata: ref_t!(VariantData) @@ -922,20 +937,6 @@ pub mod visit { walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) } - pub fn walk_variant<'a, V: Visitor<'a>>(visitor: &mut V, variant: &'a Variant) -> V::Result - where - V: Visitor<'a>, - { - let Variant { attrs, id: _, span: _, vis, ident, data, disr_expr, is_placeholder: _ } = - variant; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(ident)); - try_visit!(visitor.visit_variant_data(data)); - visit_opt!(visitor, visit_variant_discr, disr_expr); - 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 { @@ -1797,15 +1798,7 @@ pub mod mut_visit { visitor: &mut T, mut variant: Variant, ) -> SmallVec<[Variant; 1]> { - let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = - &mut variant; - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visitor.visit_ident(ident); - visitor.visit_variant_data(data); - visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr)); - visitor.visit_span(span); + visitor.visit_variant(&mut variant); smallvec![variant] } From 3398a69c8bb26f5defb9570c5a8a50d5fd7b770a Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:46:16 -0300 Subject: [PATCH 36/82] Unify walk_path_segment --- compiler/rustc_ast/src/visitors.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index fa0cb29ce721d..5bdf53ca7218c 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -584,6 +584,17 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_path_segment<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + segment: ref_t!(PathSegment) + ) -> result!(V) { + let PathSegment { id, ident, args } = segment; + try_v!(visit_id!(vis, id)); + try_v!(vis.visit_ident(ident)); + visit_o!(args, |args| vis.visit_generic_args(args)); + return_result!(V) + } + pub fn walk_poly_trait_ref<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, trait_ref: ref_t!(PolyTraitRef) @@ -1018,16 +1029,6 @@ pub mod visit { 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_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result where V: Visitor<'a>, @@ -1802,13 +1803,6 @@ pub mod mut_visit { smallvec![variant] } - fn walk_path_segment(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(vis: &mut T, Path { segments, span, tokens }: &mut Path) { for segment in segments { vis.visit_path_segment(segment); From 23ba653ed21ea1204bc337f310f904ab44a8791e Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:48:43 -0300 Subject: [PATCH 37/82] Unify walk_qself --- compiler/rustc_ast/src/visitors.rs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 5bdf53ca7218c..ff105db65eb22 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -546,6 +546,18 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_qself<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + qself: ref_t!(Option>) + ) -> result!(V) { + if let Some(qself) = qself { + let QSelf { ty, path_span, position: _ } = &$($mut)? **qself; + try_v!(vis.visit_ty(ty)); + try_v!(visit_span!(vis, path_span)); + } + return_result!(V) + } + pub fn walk_param<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, param: ref_t!(Param) @@ -993,14 +1005,6 @@ pub mod visit { V::Result::output() } - fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option>) -> V::Result { - if let Some(qself) = qself { - let QSelf { ty, path_span: _, position: _ } = &**qself; - try_visit!(visitor.visit_ty(ty)); - } - V::Result::output() - } - pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result { let Path { span: _, segments, tokens: _ } = path; walk_list!(visitor, visit_path_segment, segments); @@ -1811,14 +1815,6 @@ pub mod mut_visit { vis.visit_span(span); } - fn walk_qself(vis: &mut T, qself: &mut Option>) { - visit_opt(qself, |qself| { - let QSelf { ty, path_span, position: _ } = &mut **qself; - vis.visit_ty(ty); - vis.visit_span(path_span); - }) - } - fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { match arg { GenericArg::Lifetime(lt) => vis.visit_lifetime(lt, LifetimeCtxt::GenericArg), From 5e40db2bb255521ef18c0540cbc9ee3a0865b9bb Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:53:39 -0300 Subject: [PATCH 38/82] Unify {visit,walk}_field_def --- compiler/rustc_ast/src/visitors.rs | 33 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index ff105db65eb22..9c7d82f6a09df 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -268,7 +268,6 @@ macro_rules! make_ast_visitor { type Result: VisitorResult = (); make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} - make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{ForeignItem; visit_foreign_item, walk_item} make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Item; visit_item, walk_item} @@ -308,6 +307,7 @@ macro_rules! make_ast_visitor { make_visit!{Crate; visit_crate, walk_crate} make_visit!{EnumDef; visit_enum_def, walk_enum_def} make_visit!{ExprField; visit_expr_field, walk_expr_field} + make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{FormatArgs; visit_format_args, walk_format_args} @@ -435,6 +435,20 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_field_def<$($lt,)? V: $trait$(<$lt>)?>( + visitor: &mut V, + fd: ref_t!(FieldDef) + ) -> result!(V) { + let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = fd; + try_v!(visit_id!(visitor, id)); + visit_list!(visitor, visit_attribute, attrs); + try_v!(visitor.visit_vis(vis)); + visit_o!(ident, |ident| visitor.visit_ident(ident)); + try_v!(visitor.visit_ty(ty)); + try_v!(visit_span!(visitor, span)); + return_result!(V) + } + pub fn walk_fn_decl<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, decl: ref_t!(FnDecl) @@ -1292,15 +1306,6 @@ pub mod visit { V::Result::output() } - pub fn walk_field_def<'a, V: Visitor<'a>>(visitor: &mut V, field: &'a FieldDef) -> V::Result { - let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _ } = field; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - visit_opt!(visitor, visit_ident, ident); - try_visit!(visitor.visit_ty(ty)); - 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: _, could_be_bare_literal: _ } = block; walk_list!(visitor, visit_stmt, stmts); @@ -2177,13 +2182,7 @@ pub mod mut_visit { visitor: &mut T, mut fd: FieldDef, ) -> SmallVec<[FieldDef; 1]> { - let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd; - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visit_opt(ident, |ident| visitor.visit_ident(ident)); - visitor.visit_ty(ty); - visitor.visit_span(span); + visitor.visit_field_def(&mut fd); smallvec![fd] } From d1529f9f5ce5a0526b3d15c9a4566012d95f29d1 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 22:55:30 -0300 Subject: [PATCH 39/82] Unify walk_inline_asm --- compiler/rustc_ast/src/visitors.rs | 104 ++++++++++++----------------- 1 file changed, 41 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 9c7d82f6a09df..179d95565b6ec 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -532,6 +532,47 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_inline_asm<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + asm: ref_t!(InlineAsm) + ) -> result!(V) { + // FIXME: Visit spans inside all this currently ignored stuff. + let InlineAsm { + asm_macro: _, + template: _, + template_strs: _, + operands, + clobber_abis: _, + options: _, + line_spans: _, + } = asm; + for (op, span) in operands { + match op { + InlineAsmOperand::In { expr, reg: _ } + | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } + | InlineAsmOperand::InOut { expr, reg: _, late: _ } => { + try_v!(vis.visit_expr(expr)); + } + InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} + InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { + try_v!(vis.visit_expr(in_expr)); + visit_o!(out_expr, |out_expr| vis.visit_expr(out_expr)); + } + InlineAsmOperand::Const { anon_const } => { + try_v!(vis.visit_anon_const(anon_const)); + } + InlineAsmOperand::Sym { sym } => { + try_v!(vis.visit_inline_asm_sym(sym)); + } + InlineAsmOperand::Label { block } => { + try_v!(vis.visit_block(block)); + } + } + try_v!(visit_span!(vis, span)); + } + return_result!(V) + } + pub fn walk_label<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, label: ref_t!(Label) @@ -1333,38 +1374,6 @@ pub mod visit { visitor.visit_path(path, DUMMY_NODE_ID) } - pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) -> V::Result { - let InlineAsm { - asm_macro: _, - template: _, - template_strs: _, - operands, - clobber_abis: _, - options: _, - line_spans: _, - } = asm; - for (op, _span) in operands { - match op { - InlineAsmOperand::In { expr, reg: _ } - | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } - | InlineAsmOperand::InOut { expr, reg: _, late: _ } => { - try_visit!(visitor.visit_expr(expr)) - } - InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} - InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { - try_visit!(visitor.visit_expr(in_expr)); - visit_opt!(visitor, visit_expr, out_expr); - } - InlineAsmOperand::Const { anon_const } => { - try_visit!(visitor.visit_anon_const(anon_const)) - } - InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)), - InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)), - } - } - V::Result::output() - } - pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>( visitor: &mut V, InlineAsmSym { id, qself, path }: &'a InlineAsmSym, @@ -2516,37 +2525,6 @@ pub mod mut_visit { vis.visit_span(span); } - fn walk_inline_asm(vis: &mut T, asm: &mut InlineAsm) { - // FIXME: Visit spans inside all this currently ignored stuff. - let InlineAsm { - asm_macro: _, - template: _, - template_strs: _, - operands, - clobber_abis: _, - options: _, - line_spans: _, - } = asm; - for (op, span) in operands { - match op { - InlineAsmOperand::In { expr, reg: _ } - | InlineAsmOperand::Out { expr: Some(expr), reg: _, late: _ } - | InlineAsmOperand::InOut { expr, reg: _, late: _ } => vis.visit_expr(expr), - InlineAsmOperand::Out { expr: None, reg: _, late: _ } => {} - InlineAsmOperand::SplitInOut { in_expr, out_expr, reg: _, late: _ } => { - vis.visit_expr(in_expr); - if let Some(out_expr) = out_expr { - vis.visit_expr(out_expr); - } - } - InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const), - InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym), - InlineAsmOperand::Label { block } => vis.visit_block(block), - } - vis.visit_span(span); - } - } - fn walk_inline_asm_sym( vis: &mut T, InlineAsmSym { id, qself, path }: &mut InlineAsmSym, From bf12d09183e85eebb93c91efcfe890932db950c8 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:02:41 -0300 Subject: [PATCH 40/82] Add mut_only_visit! --- compiler/rustc_ast/src/visitors.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 179d95565b6ec..9e1955c1f6b07 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -104,6 +104,22 @@ macro_rules! make_ast_visitor { }; } + #[allow(unused)] + macro_rules! mut_only_visit { + ($name: ident) => { + macro_rules! $name { + ($vis: expr, $arg: expr) => { + macro_if!{ $($mut)? { + $name($vis, $arg) + } else { + // assign to _ to prevent unused_variable warnings + {let _ = (&$vis, &$arg);} + }} + }; + } + }; + } + macro_rules! try_v { ($visit: expr) => { macro_if!{$($mut)? { $visit } else { try_visit!($visit) }} From cbb90878e8e934e35b29a8a94248321f71fbe298 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:03:45 -0300 Subject: [PATCH 41/82] Unify walk_local --- compiler/rustc_ast/src/visitors.rs | 63 +++++++++++++----------------- 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 9e1955c1f6b07..ebefa788c6084 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -104,7 +104,6 @@ macro_rules! make_ast_visitor { }; } - #[allow(unused)] macro_rules! mut_only_visit { ($name: ident) => { macro_rules! $name { @@ -120,6 +119,8 @@ macro_rules! make_ast_visitor { }; } + mut_only_visit!{visit_lazy_tts} + macro_rules! try_v { ($visit: expr) => { macro_if!{$($mut)? { $visit } else { try_visit!($visit) }} @@ -336,6 +337,7 @@ macro_rules! make_ast_visitor { make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} make_visit!{Label; visit_label, walk_label} make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} + make_visit!{Local; visit_local, walk_local} make_visit!{MacCall; visit_mac_call, walk_mac} make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Option>; visit_qself, walk_qself} @@ -353,7 +355,6 @@ macro_rules! make_ast_visitor { make_visit!{P!(Block); visit_block, walk_block} make_visit!{P!(Expr); visit_expr, walk_expr} - make_visit!{P!(Local); visit_local, walk_local} make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} @@ -608,6 +609,31 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_local<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + local: ref_t!(Local) + ) -> result!(V) { + let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + try_v!(vis.visit_pat(pat)); + visit_o!(ty, |ty| vis.visit_ty(ty)); + match kind { + LocalKind::Decl => {} + LocalKind::Init(init) => { + try_v!(vis.visit_expr(init)); + } + LocalKind::InitElse(init, els) => { + try_v!(vis.visit_expr(init)); + try_v!(vis.visit_block(els)); + } + } + visit_lazy_tts!(vis, tokens); + visit_o!(colon_sp, |sp| try_v!(visit_span!(vis, sp))); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_mt<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, mt: ref_t!(MutTy) @@ -893,18 +919,6 @@ pub mod visit { V::Result::output() } - pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result { - let Local { id: _, pat, ty, kind, span: _, colon_sp: _, attrs, tokens: _ } = local; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_pat(pat)); - visit_opt!(visitor, visit_ty, ty); - if let Some((init, els)) = kind.init_else_opt() { - try_visit!(visitor.visit_expr(init)); - visit_opt!(visitor, visit_block, els); - } - V::Result::output() - } - pub fn walk_trait_ref<'a, V: Visitor<'a>>( visitor: &mut V, trait_ref: &'a TraitRef, @@ -1853,27 +1867,6 @@ pub mod mut_visit { } } - fn walk_local(vis: &mut T, local: &mut P) { - let Local { id, pat, ty, kind, span, colon_sp, attrs, tokens } = local.deref_mut(); - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_pat(pat); - visit_opt(ty, |ty| vis.visit_ty(ty)); - match kind { - LocalKind::Decl => {} - LocalKind::Init(init) => { - vis.visit_expr(init); - } - LocalKind::InitElse(init, els) => { - vis.visit_expr(init); - vis.visit_block(els); - } - } - visit_lazy_tts(vis, tokens); - visit_opt(colon_sp, |sp| vis.visit_span(sp)); - vis.visit_span(span); - } - fn walk_attribute(vis: &mut T, attr: &mut Attribute) { let Attribute { kind, id: _, style: _, span } = attr; match kind { From 5cac2361759559c0c3f0a49155938405f400c9d6 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:23:56 -0300 Subject: [PATCH 42/82] Unify {visit,walk}_use_tree --- compiler/rustc_ast/src/visitors.rs | 75 +++++++++++++----------------- 1 file changed, 33 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index ebefa788c6084..1a7ce84cef63b 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -207,7 +207,6 @@ macro_rules! make_ast_visitor { make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} make_visit!{Path; visit_path, walk_path} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} - make_visit!{UseTree; visit_use_tree, walk_use_tree} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { walk_flat_map_item(self, ni) @@ -290,7 +289,6 @@ macro_rules! make_ast_visitor { make_visit!{Item; visit_item, walk_item} make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{Stmt; visit_stmt, walk_stmt} - make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} /// This method is a hack to workaround unstable of `stmt_expr_attributes`. /// It can be removed once that feature is stabilized. @@ -347,6 +345,7 @@ macro_rules! make_ast_visitor { make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} + make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} make_visit!{Variant; visit_variant, walk_variant} make_visit!{VariantData; visit_variant_data, walk_variant_data} make_visit!{Visibility; visit_vis, walk_vis} @@ -715,6 +714,37 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_use_tree<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + use_tree: ref_t!(UseTree), + id: NodeId, + ) -> result!(V) { + let UseTree { prefix, kind, span } = use_tree; + // TODO: Remove this after unifying visit_path + try_v!(macro_if!{$($mut)? {{ + let _ = id; + vis.visit_path(prefix) + }} else { + vis.visit_path(prefix, id) + }}); + match kind { + UseTreeKind::Simple(rename) => { + // The extra IDs are handled during AST lowering. + visit_o!(rename, |rename: ref_t!(Ident)| vis.visit_ident(rename)); + } + UseTreeKind::Nested { items, span } => { + for (tree, id) in items { + try_v!(visit_id!(vis, id)); + vis.visit_use_tree(tree, *id, true); + } + try_v!(visit_span!(vis, span)); + } + UseTreeKind::Glob => {} + } + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_variant<$($lt,)? V: $trait$(<$lt>)?>( visitor: &mut V, variant: ref_t!(Variant) @@ -1096,28 +1126,6 @@ pub mod visit { V::Result::output() } - pub fn walk_use_tree<'a, V: Visitor<'a>>( - visitor: &mut V, - use_tree: &'a UseTree, - id: NodeId, - ) -> V::Result { - let UseTree { prefix, kind, span: _ } = use_tree; - try_visit!(visitor.visit_path(prefix, id)); - match kind { - UseTreeKind::Simple(rename) => { - // The extra IDs are handled during AST lowering. - visit_opt!(visitor, visit_ident, rename); - } - UseTreeKind::Glob => {} - UseTreeKind::Nested { ref items, span: _ } => { - for &(ref nested_tree, nested_id) in items { - try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true)); - } - } - } - V::Result::output() - } - pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result where V: Visitor<'a>, @@ -1743,23 +1751,6 @@ pub mod mut_visit { smallvec![fp] } - fn walk_use_tree(vis: &mut T, use_tree: &mut UseTree) { - let UseTree { prefix, kind, span } = use_tree; - vis.visit_path(prefix); - match kind { - UseTreeKind::Simple(rename) => visit_opt(rename, |rename| vis.visit_ident(rename)), - UseTreeKind::Nested { items, span } => { - for (tree, id) in items { - vis.visit_id(id); - vis.visit_use_tree(tree); - } - vis.visit_span(span); - } - UseTreeKind::Glob => {} - } - vis.visit_span(span); - } - pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { vis.visit_arm(&mut arm); smallvec![arm] @@ -2234,7 +2225,7 @@ pub mod mut_visit { fn walk(&mut self, span: Span, id: NodeId, vis: &mut impl MutVisitor) { match self { ItemKind::ExternCrate(_orig_name) => {} - ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), + ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree, id, false), ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { vis.visit_ty(ty); visit_opt(expr, |expr| vis.visit_expr(expr)); From 0de2305113996714c77dac4012fbbed21596ca12 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:41:09 -0300 Subject: [PATCH 43/82] Unify {visit,walk}_path --- compiler/rustc_ast/src/visitors.rs | 72 +++++++++++++----------------- 1 file changed, 31 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 1a7ce84cef63b..6c94792118440 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -205,7 +205,6 @@ macro_rules! make_ast_visitor { make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} - make_visit!{Path; visit_path, walk_path} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { @@ -287,7 +286,6 @@ macro_rules! make_ast_visitor { make_visit!{ForeignItem; visit_foreign_item, walk_item} make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Item; visit_item, walk_item} - make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{Stmt; visit_stmt, walk_stmt} /// This method is a hack to workaround unstable of `stmt_expr_attributes`. @@ -342,6 +340,7 @@ macro_rules! make_ast_visitor { make_visit!{Param; visit_param, walk_param} make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} make_visit!{PatField; visit_pat_field, walk_pat_field} + make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} @@ -692,6 +691,17 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_path<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + path: ref_t!(Path) + ) -> result!(V) { + let Path { span, segments, tokens } = path; + visit_list!(vis, visit_path_segment, segments); + visit_lazy_tts!(vis, tokens); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_path_segment<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, segment: ref_t!(PathSegment) @@ -720,13 +730,7 @@ macro_rules! make_ast_visitor { id: NodeId, ) -> result!(V) { let UseTree { prefix, kind, span } = use_tree; - // TODO: Remove this after unifying visit_path - try_v!(macro_if!{$($mut)? {{ - let _ = id; - vis.visit_path(prefix) - }} else { - vis.visit_path(prefix, id) - }}); + try_v!(vis.visit_path(prefix, id)); match kind { UseTreeKind::Simple(rename) => { // The extra IDs are handled during AST lowering. @@ -1120,12 +1124,6 @@ pub mod visit { V::Result::output() } - pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) -> V::Result { - let Path { span: _, segments, tokens: _ } = path; - walk_list!(visitor, visit_path_segment, segments); - V::Result::output() - } - pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result where V: Visitor<'a>, @@ -1808,7 +1806,7 @@ pub mod mut_visit { } TyKind::Path(qself, path) => { vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); } TyKind::Array(ty, length) => { vis.visit_ty(ty); @@ -1842,14 +1840,6 @@ pub mod mut_visit { smallvec![variant] } - fn walk_path(vis: &mut T, Path { segments, span, tokens }: &mut Path) { - for segment in segments { - vis.visit_path_segment(segment); - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); - } - fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { match arg { GenericArg::Lifetime(lt) => vis.visit_lifetime(lt, LifetimeCtxt::GenericArg), @@ -1866,7 +1856,7 @@ pub mod mut_visit { item: AttrItem { unsafety: _, path, args, tokens }, tokens: attr_tokens, } = &mut **normal; - vis.visit_path(path); + vis.visit_path(path, DUMMY_NODE_ID); visit_attr_args(vis, args); visit_lazy_tts(vis, tokens); visit_lazy_tts(vis, attr_tokens); @@ -1878,7 +1868,7 @@ pub mod mut_visit { fn walk_mac(vis: &mut T, mac: &mut MacCall) { let MacCall { path, args } = mac; - vis.visit_path(path); + vis.visit_path(path, DUMMY_NODE_ID); visit_delim_args(vis, args); } @@ -2049,11 +2039,11 @@ pub mod mut_visit { token::NtLiteral(expr) => vis.visit_expr(expr), token::NtMeta(item) => { let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); - vis.visit_path(path); + vis.visit_path(path, DUMMY_NODE_ID); visit_attr_args(vis, args); visit_lazy_tts(vis, tokens); } - token::NtPath(path) => vis.visit_path(path), + token::NtPath(path) => vis.visit_path(path, DUMMY_NODE_ID), token::NtVis(visib) => vis.visit_vis(visib), } } @@ -2143,7 +2133,7 @@ pub mod mut_visit { } PreciseCapturingArg::Arg(path, id) => { vis.visit_id(id); - vis.visit_path(path); + vis.visit_path(path, *id); } } } @@ -2184,7 +2174,7 @@ pub mod mut_visit { fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) { vis.visit_id(ref_id); - vis.visit_path(path); + vis.visit_path(path, *ref_id); } pub fn walk_flat_map_field_def( @@ -2317,7 +2307,7 @@ pub mod mut_visit { }) => { vis.visit_id(id); vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); if let Some(rename) = rename { vis.visit_ident(rename); } @@ -2327,7 +2317,7 @@ pub mod mut_visit { } ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { vis.visit_qself(qself); - vis.visit_path(prefix); + vis.visit_path(prefix, id); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { vis.visit_ident(ident); @@ -2378,7 +2368,7 @@ pub mod mut_visit { }) => { visitor.visit_id(id); visitor.visit_qself(qself); - visitor.visit_path(path); + visitor.visit_path(path, *id); if let Some(rename) = rename { visitor.visit_ident(rename); } @@ -2393,7 +2383,7 @@ pub mod mut_visit { body, }) => { visitor.visit_qself(qself); - visitor.visit_path(prefix); + visitor.visit_path(prefix, id); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { visitor.visit_ident(ident); @@ -2495,16 +2485,16 @@ pub mod mut_visit { PatKind::Lit(e) => vis.visit_expr(e), PatKind::TupleStruct(qself, path, elems) => { vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); visit_thin_vec(elems, |elem| vis.visit_pat(elem)); } PatKind::Path(qself, path) => { vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); } PatKind::Struct(qself, path, fields, _etc) => { vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); fields.flat_map_in_place(|field| vis.flat_map_pat_field(field)); } PatKind::Box(inner) => vis.visit_pat(inner), @@ -2531,7 +2521,7 @@ pub mod mut_visit { ) { vis.visit_id(id); vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); } pub fn walk_expr( @@ -2668,7 +2658,7 @@ pub mod mut_visit { ExprKind::Underscore => {} ExprKind::Path(qself, path) => { vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); } ExprKind::Break(label, expr) => { visit_opt(label, |label| vis.visit_label(label)); @@ -2696,7 +2686,7 @@ pub mod mut_visit { ExprKind::Struct(se) => { let StructExpr { qself, path, fields, rest } = se.deref_mut(); vis.visit_qself(qself); - vis.visit_path(path); + vis.visit_path(path, *id); fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); match rest { StructRest::Base(expr) => vis.visit_expr(expr), @@ -2782,7 +2772,7 @@ pub mod mut_visit { VisibilityKind::Public | VisibilityKind::Inherited => {} VisibilityKind::Restricted { path, id, shorthand: _ } => { vis.visit_id(id); - vis.visit_path(path); + vis.visit_path(path, *id); } } visit_lazy_tts(vis, tokens); From 978fa3f732768ac000b8d2a17e3f8b5f65c5f6ac Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:47:47 -0300 Subject: [PATCH 44/82] Unify walk_generic_argz --- compiler/rustc_ast/src/visitors.rs | 31 ++++++++++++------------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 6c94792118440..dc14d3eb3c798 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -509,6 +509,18 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_generic_arg<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + arg: ref_t!(GenericArg) + ) -> result!(V) { + match arg { + GenericArg::Lifetime(lt) => try_v!(vis.visit_lifetime(lt, LifetimeCtxt::GenericArg)), + GenericArg::Type(ty) => try_v!(vis.visit_ty(ty)), + GenericArg::Const(ct) => try_v!(vis.visit_anon_const(ct)), + } + return_result!(V) + } + pub fn walk_generic_args<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, generic_args: ref_t!(GenericArgs) @@ -1124,17 +1136,6 @@ pub mod visit { V::Result::output() } - pub fn walk_generic_arg<'a, V>(visitor: &mut V, generic_arg: &'a GenericArg) -> V::Result - where - V: Visitor<'a>, - { - match generic_arg { - GenericArg::Lifetime(lt) => visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg), - GenericArg::Type(ty) => visitor.visit_ty(ty), - GenericArg::Const(ct) => visitor.visit_anon_const(ct), - } - } - pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( visitor: &mut V, constraint: &'a AssocItemConstraint, @@ -1840,14 +1841,6 @@ pub mod mut_visit { smallvec![variant] } - fn walk_generic_arg(vis: &mut T, arg: &mut GenericArg) { - match arg { - GenericArg::Lifetime(lt) => vis.visit_lifetime(lt, LifetimeCtxt::GenericArg), - GenericArg::Type(ty) => vis.visit_ty(ty), - GenericArg::Const(ct) => vis.visit_anon_const(ct), - } - } - fn walk_attribute(vis: &mut T, attr: &mut Attribute) { let Attribute { kind, id: _, style: _, span } = attr; match kind { From a4abc8600b2e6130611c6809e0c89a10fae19879 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:48:46 -0300 Subject: [PATCH 45/82] Unify walk_param_bound --- compiler/rustc_ast/src/visitors.rs | 48 ++++++++++++------------------ 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index dc14d3eb3c798..071ee7c254b5a 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -539,6 +539,25 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_param_bound<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + bound: ref_t!(GenericBound) + ) -> result!(V) { + match bound { + GenericBound::Trait(typ) => { + try_v!(vis.visit_poly_trait_ref(typ)); + } + GenericBound::Outlives(lifetime) => { + try_v!(vis.visit_lifetime(lifetime, LifetimeCtxt::Bound)); + } + GenericBound::Use(args, span) => { + visit_list!(vis, visit_precise_capturing_arg, args); + try_v!(visit_span!(vis, span)) + } + } + return_result!(V) + } + pub fn walk_generics<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, generics: ref_t!(Generics) @@ -1234,22 +1253,6 @@ pub mod visit { } } - pub fn walk_param_bound<'a, V: Visitor<'a>>( - visitor: &mut V, - bound: &'a GenericBound, - ) -> V::Result { - match bound { - GenericBound::Trait(typ) => visitor.visit_poly_trait_ref(typ), - GenericBound::Outlives(lifetime) => { - visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound) - } - GenericBound::Use(args, _span) => { - walk_list!(visitor, visit_precise_capturing_arg, args); - V::Result::output() - } - } - } - pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( visitor: &mut V, arg: &'a PreciseCapturingArg, @@ -2106,19 +2109,6 @@ pub mod mut_visit { } } - fn walk_param_bound(vis: &mut T, pb: &mut GenericBound) { - match pb { - GenericBound::Trait(ty) => vis.visit_poly_trait_ref(ty), - GenericBound::Outlives(lifetime) => vis.visit_lifetime(lifetime, LifetimeCtxt::Bound), - GenericBound::Use(args, span) => { - for arg in args { - vis.visit_precise_capturing_arg(arg); - } - vis.visit_span(span); - } - } - } - fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCapturingArg) { match arg { PreciseCapturingArg::Lifetime(lt) => { From ac3e06ea640635769faa472726330808efacd05d Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:57:31 -0300 Subject: [PATCH 46/82] Unify {visit,walk}_precise_capturing_arg --- compiler/rustc_ast/src/visitors.rs | 47 +++++++++++------------------- 1 file changed, 17 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 071ee7c254b5a..4dc653af8576e 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -205,7 +205,6 @@ macro_rules! make_ast_visitor { make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} - make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { walk_flat_map_item(self, ni) @@ -299,9 +298,6 @@ macro_rules! make_ast_visitor { fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { walk_fn(self, fk) } - fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { - walk_precise_capturing_arg(self, arg); - } fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) -> Self::Result { Self::Result::output() } @@ -343,6 +339,7 @@ macro_rules! make_ast_visitor { make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} + make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} make_visit!{Variant; visit_variant, walk_variant} @@ -755,6 +752,22 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_precise_capturing_arg<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + arg: ref_t!(PreciseCapturingArg) + ) -> result!(V) { + match arg { + PreciseCapturingArg::Lifetime(lt) => { + try_v!(vis.visit_lifetime(lt, LifetimeCtxt::GenericArg)); + } + PreciseCapturingArg::Arg(path, id) => { + try_v!(visit_id!(vis, id)); + try_v!(vis.visit_path(path, *id)); + } + } + return_result!(V) + } + pub fn walk_use_tree<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, use_tree: ref_t!(UseTree), @@ -1253,20 +1266,6 @@ pub mod visit { } } - pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( - visitor: &mut V, - arg: &'a PreciseCapturingArg, - ) { - match arg { - PreciseCapturingArg::Lifetime(lt) => { - visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg); - } - PreciseCapturingArg::Arg(path, id) => { - visitor.visit_path(path, *id); - } - } - } - pub fn walk_generic_param<'a, V: Visitor<'a>>( visitor: &mut V, param: &'a GenericParam, @@ -2109,18 +2108,6 @@ pub mod mut_visit { } } - fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCapturingArg) { - match arg { - PreciseCapturingArg::Lifetime(lt) => { - vis.visit_lifetime(lt, LifetimeCtxt::GenericArg); - } - PreciseCapturingArg::Arg(path, id) => { - vis.visit_id(id); - vis.visit_path(path, *id); - } - } - } - pub fn walk_flat_map_generic_param( vis: &mut T, mut param: GenericParam, From eba661f424b15df3b2c8ba97556d990ef6de8300 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sat, 12 Oct 2024 23:58:09 -0300 Subject: [PATCH 47/82] Unify walk_trait_ref --- compiler/rustc_ast/src/visitors.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 4dc653af8576e..1439165ab0f32 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -768,6 +768,16 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_trait_ref<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + trait_ref: ref_t!(TraitRef) + ) -> result!(V) { + let TraitRef { path, ref_id } = trait_ref; + try_v!(visit_id!(vis, ref_id)); + try_v!(vis.visit_path(path, *ref_id)); + return_result!(V) + } + pub fn walk_use_tree<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, use_tree: ref_t!(UseTree), @@ -997,14 +1007,6 @@ pub mod visit { V::Result::output() } - 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 { fn walk<'a, V: Visitor<'a>>( &'a self, @@ -2142,11 +2144,6 @@ pub mod mut_visit { vis.visit_span(span_after); } - fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) { - vis.visit_id(ref_id); - vis.visit_path(path, *ref_id); - } - pub fn walk_flat_map_field_def( visitor: &mut T, mut fd: FieldDef, From 3863002700bdad3d144ede4c519ad1b76a3bf4e9 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 00:00:05 -0300 Subject: [PATCH 48/82] Unify {visit,walk}_block --- compiler/rustc_ast/src/visitors.rs | 29 +++++++++++++---------------- compiler/rustc_expand/src/expand.rs | 2 +- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 1439165ab0f32..e8d9d6a1b0c44 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -311,6 +311,7 @@ macro_rules! make_ast_visitor { make_visit!{Arm; visit_arm, walk_arm} make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} make_visit!{Attribute; visit_attribute, walk_attribute} + make_visit!{Block; visit_block, walk_block} make_visit!{CaptureBy; visit_capture_by, walk_capture_by} make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} make_visit!{Crate; visit_crate, walk_crate} @@ -348,7 +349,6 @@ macro_rules! make_ast_visitor { make_visit!{WhereClause; visit_where_clause, walk_where_clause} make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} - make_visit!{P!(Block); visit_block, walk_block} make_visit!{P!(Expr); visit_expr, walk_expr} make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} @@ -398,6 +398,18 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_block<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + block: ref_t!(Block) + ) -> result!(V) { + let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = block; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_stmt, flat_map_stmt, stmts); + visit_lazy_tts!(vis, tokens); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_capture_by<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, capture_by: ref_t!(CaptureBy) @@ -1388,12 +1400,6 @@ pub mod visit { 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: _, could_be_bare_literal: _ } = 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 { @@ -2160,15 +2166,6 @@ pub mod mut_visit { smallvec![f] } - pub fn walk_block(vis: &mut T, block: &mut P) { - let Block { id, stmts, rules: _, span, tokens, could_be_bare_literal: _ } = - block.deref_mut(); - vis.visit_id(id); - stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); - visit_lazy_tts(vis, tokens); - vis.visit_span(span); - } - pub fn walk_item_kind( kind: &mut impl WalkItemKind, span: Span, diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index a872b12e744c4..91277ba82ea19 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -2198,7 +2198,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.flat_map_node(AstNodeWrapper::new(node, OptExprTag)) } - fn visit_block(&mut self, node: &mut P) { + fn visit_block(&mut self, node: &mut ast::Block) { let orig_dir_ownership = mem::replace( &mut self.cx.current_expansion.dir_ownership, DirOwnership::UnownedViaBlock, From 097269d8007cd592dd317b6cd8188f7836707fe4 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 00:09:50 -0300 Subject: [PATCH 49/82] Unify walk_pat --- compiler/rustc_ast/src/visitors.rs | 138 +++++++++++------------------ 1 file changed, 53 insertions(+), 85 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index e8d9d6a1b0c44..84d4af32a2dde 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -886,6 +886,59 @@ macro_rules! make_ast_visitor { } return_result!(V) } + + pub fn walk_pat<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + pattern: ref_t!(Pat) + ) -> result!(V) { + let Pat { id, kind, span, tokens } = pattern; + try_v!(visit_id!(vis, id)); + match kind { + PatKind::Err(_guar) => {} + PatKind::Wild | PatKind::Rest | PatKind::Never => {} + PatKind::Ident(_binding_mode, ident, sub) => { + try_v!(vis.visit_ident(ident)); + visit_o!(sub, |sub| vis.visit_pat(sub)); + } + PatKind::Lit(e) => { + try_v!(vis.visit_expr(e)); + } + PatKind::TupleStruct(qself, path, elems) => { + try_v!(vis.visit_qself(qself)); + try_v!(vis.visit_path(path, *id)); + visit_list!(vis, visit_pat, elems); + } + PatKind::Path(qself, path) => { + try_v!(vis.visit_qself(qself)); + try_v!(vis.visit_path(path, *id)); + } + PatKind::Struct(qself, path, fields, _etc) => { + try_v!(vis.visit_qself(qself)); + try_v!(vis.visit_path(path, *id)); + visit_list!(vis, visit_pat_field, flat_map_pat_field, fields); + } + PatKind::Box(inner) | PatKind::Deref(inner) | PatKind::Paren(inner) => { + try_v!(vis.visit_pat(inner)); + } + PatKind::Ref(inner, _mutbl) => { + try_v!(vis.visit_pat(inner)); + } + PatKind::Range(e1, e2, Spanned { span, node: _ }) => { + visit_o!(e1, |e| vis.visit_expr(e)); + visit_o!(e2, |e| vis.visit_expr(e)); + try_v!(visit_span!(vis, span)); + } + PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { + visit_list!(vis, visit_pat, elems); + } + PatKind::MacCall(mac) => { + try_v!(vis.visit_mac_call(mac)); + } + } + visit_lazy_tts!(vis, tokens); + try_v!(visit_span!(vis, span)); + return_result!(V) + } } } @@ -1201,48 +1254,6 @@ pub mod visit { 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::Lit(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::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 { fn walk<'a, V: Visitor<'a>>( &'a self, @@ -2436,49 +2447,6 @@ pub mod mut_visit { } } - pub fn walk_pat(vis: &mut T, pat: &mut P) { - let Pat { id, kind, span, tokens } = pat.deref_mut(); - vis.visit_id(id); - match kind { - PatKind::Err(_guar) => {} - 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::Lit(e) => vis.visit_expr(e), - PatKind::TupleStruct(qself, path, elems) => { - vis.visit_qself(qself); - vis.visit_path(path, *id); - visit_thin_vec(elems, |elem| vis.visit_pat(elem)); - } - PatKind::Path(qself, path) => { - vis.visit_qself(qself); - vis.visit_path(path, *id); - } - PatKind::Struct(qself, path, fields, _etc) => { - vis.visit_qself(qself); - vis.visit_path(path, *id); - 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::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), - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); - } - fn walk_inline_asm_sym( vis: &mut T, InlineAsmSym { id, qself, path }: &mut InlineAsmSym, From 479cc1c2c19c4dc21fe10c25f920863a51eb44f1 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 00:10:57 -0300 Subject: [PATCH 50/82] Unify walk_inline_asm_sym --- compiler/rustc_ast/src/visitors.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 84d4af32a2dde..625dacfba2f04 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -628,6 +628,17 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_inline_asm_sym<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + asm_sym: ref_t!(InlineAsmSym) + ) -> result!(V) { + let InlineAsmSym { id, qself, path } = asm_sym; + try_v!(visit_id!(vis, id)); + try_v!(vis.visit_qself(qself)); + try_v!(vis.visit_path(path, *id)); + return_result!(V) + } + pub fn walk_label<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, label: ref_t!(Label) @@ -1432,14 +1443,6 @@ pub mod visit { visitor.visit_path(path, DUMMY_NODE_ID) } - pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>( - visitor: &mut V, - InlineAsmSym { id, qself, path }: &'a InlineAsmSym, - ) -> V::Result { - try_visit!(visitor.visit_qself(qself)); - visitor.visit_path(path, *id) - } - pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result { let Expr { id, kind, span, attrs, tokens: _ } = expression; walk_list!(visitor, visit_attribute, attrs); @@ -2447,15 +2450,6 @@ pub mod mut_visit { } } - fn walk_inline_asm_sym( - vis: &mut T, - InlineAsmSym { id, qself, path }: &mut InlineAsmSym, - ) { - vis.visit_id(id); - vis.visit_qself(qself); - vis.visit_path(path, *id); - } - pub fn walk_expr( vis: &mut T, Expr { kind, id, span, attrs, tokens }: &mut Expr, From 1b036e885b56e9d3b536c55a3806a81c8790db43 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 00:12:34 -0300 Subject: [PATCH 51/82] Unify walk_vis --- compiler/rustc_ast/src/visitors.rs | 41 +++++++++++++----------------- 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 625dacfba2f04..a9d8fbe871c05 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -860,6 +860,23 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_vis<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + visibility: ref_t!(Visibility) + ) -> result!(V) { + let Visibility { kind, span, tokens } = visibility; + match kind { + VisibilityKind::Public | VisibilityKind::Inherited => {} + VisibilityKind::Restricted { path, id, shorthand: _ } => { + try_v!(visit_id!(vis, id)); + try_v!(vis.visit_path(path, *id)); + } + } + visit_lazy_tts!(vis, tokens); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_where_clause<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, wc: ref_t!(WhereClause) @@ -1605,17 +1622,6 @@ pub mod visit { visitor.visit_expr_post(expression) } - pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) -> V::Result { - let Visibility { kind, span: _, tokens: _ } = vis; - match kind { - VisibilityKind::Restricted { path, id, shorthand: _ } => { - try_visit!(visitor.visit_path(path, *id)); - } - VisibilityKind::Public | VisibilityKind::Inherited => {} - } - V::Result::output() - } - pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result { let Attribute { kind, id: _, style: _, span: _ } = attr; match kind { @@ -2692,19 +2698,6 @@ pub mod mut_visit { } } - fn walk_vis(vis: &mut T, visibility: &mut Visibility) { - let Visibility { kind, span, tokens } = visibility; - match kind { - VisibilityKind::Public | VisibilityKind::Inherited => {} - VisibilityKind::Restricted { path, id, shorthand: _ } => { - vis.visit_id(id); - vis.visit_path(path, *id); - } - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); - } - /// 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 From d64f965cd2dcceeb44546e0d37e0f9438e8f1e3b Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 09:21:15 -0300 Subject: [PATCH 52/82] Unify {visit,walk}_generic_param --- compiler/rustc_ast/src/visitors.rs | 66 ++++++++++++------------------ 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index a9d8fbe871c05..3508d680894ad 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -283,7 +283,6 @@ macro_rules! make_ast_visitor { make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} make_visit!{ForeignItem; visit_foreign_item, walk_item} - make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Item; visit_item, walk_item} make_visit!{Stmt; visit_stmt, walk_stmt} @@ -324,6 +323,7 @@ macro_rules! make_ast_visitor { make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} make_visit!{GenericArgs; visit_generic_args, walk_generic_args} make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} + make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Generics; visit_generics, walk_generics} make_visit!{Ident; visit_ident, walk_ident} make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} @@ -567,6 +567,30 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_generic_param<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + param: ref_t!(GenericParam) + ) -> result!(V) { + let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + try_v!(vis.visit_ident(ident)); + visit_list!(vis, visit_param_bound, bounds; BoundKind::Bound); + match kind { + GenericParamKind::Lifetime => {} + GenericParamKind::Type { default } => { + visit_o!(default, |default| vis.visit_ty(default)); + } + GenericParamKind::Const { ty, kw_span, default } => { + try_v!(vis.visit_ty(ty)); + visit_o!(default, |default| vis.visit_anon_const(default)); + try_v!(visit_span!(vis, kw_span)); + } + } + visit_o!(colon_span, |span| visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_generics<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, generics: ref_t!(Generics) @@ -1319,26 +1343,6 @@ pub mod visit { } } - pub fn walk_generic_param<'a, V: Visitor<'a>>( - visitor: &mut V, - param: &'a GenericParam, - ) -> V::Result { - let GenericParam { id: _, ident, attrs, bounds, is_placeholder: _, kind, colon_span: _ } = - param; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_ident(ident)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - match kind { - GenericParamKind::Lifetime => (), - GenericParamKind::Type { default } => visit_opt!(visitor, visit_ty, default), - GenericParamKind::Const { ty, default, kw_span: _ } => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_anon_const, default); - } - } - V::Result::output() - } - pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { match kind { FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => { @@ -2140,25 +2144,7 @@ pub mod mut_visit { vis: &mut T, mut param: GenericParam, ) -> SmallVec<[GenericParam; 1]> { - let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = - &mut param; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); - match kind { - GenericParamKind::Lifetime => {} - GenericParamKind::Type { default } => { - visit_opt(default, |default| vis.visit_ty(default)); - } - GenericParamKind::Const { ty, kw_span: _, default } => { - vis.visit_ty(ty); - visit_opt(default, |default| vis.visit_anon_const(default)); - } - } - if let Some(colon_span) = colon_span { - vis.visit_span(colon_span); - } + vis.visit_generic_param(&mut param); smallvec![param] } From 5887760a6420bec7c07a96a1514b88ee10ce51c5 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 09:29:48 -0300 Subject: [PATCH 53/82] Unify walk_crate --- compiler/rustc_ast/src/visitors.rs | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 3508d680894ad..7fa9b5f5bd9ec 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -437,6 +437,20 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_crate<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + krate: ref_t!(Crate) + ) -> result!(V) { + let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + visit_list!(vis, visit_item, flat_map_item, items); + let ModSpans { inner_span, inject_use_span } = spans; + try_v!(visit_span!(vis, inner_span)); + try_v!(visit_span!(vis, inject_use_span)); + return_result!(V) + } + pub fn walk_enum_def<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, enum_def: ref_t!(EnumDef) @@ -1117,13 +1131,6 @@ pub mod visit { make_ast_visitor!(Visitor<'ast>); - pub fn walk_crate<'a, V: Visitor<'a>>(visitor: &mut V, krate: &'a Crate) -> V::Result { - let Crate { attrs, items, spans: _, id: _, is_placeholder: _ } = krate; - walk_list!(visitor, visit_attribute, attrs); - walk_list!(visitor, visit_item, items); - V::Result::output() - } - impl WalkItemKind for ItemKind { fn walk<'a, V: Visitor<'a>>( &'a self, @@ -2387,16 +2394,6 @@ pub mod mut_visit { visit_safety(vis, safety); } - pub fn walk_crate(vis: &mut T, krate: &mut Crate) { - let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; - vis.visit_id(id); - visit_attrs(vis, attrs); - items.flat_map_in_place(|item| vis.flat_map_item(item)); - let ModSpans { inner_span, inject_use_span } = spans; - vis.visit_span(inner_span); - vis.visit_span(inject_use_span); - } - /// Mutates one item, returning the item again. pub fn walk_flat_map_item( visitor: &mut impl MutVisitor, From ad94bfd1226524b5cc7b551accb4a915b621e0e8 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:15:04 -0300 Subject: [PATCH 54/82] Add visit_attr_args and Unify walk_attr_args --- compiler/rustc_ast/src/visitors.rs | 55 ++++++++++++++---------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 7fa9b5f5bd9ec..6f5ee3b4699d9 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -120,6 +120,7 @@ macro_rules! make_ast_visitor { } mut_only_visit!{visit_lazy_tts} + mut_only_visit!{visit_delim_args} macro_rules! try_v { ($visit: expr) => { @@ -309,6 +310,7 @@ macro_rules! make_ast_visitor { make_visit!{AnonConst; visit_anon_const, walk_anon_const} make_visit!{Arm; visit_arm, walk_arm} make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} + make_visit!{AttrArgs; visit_attr_args, walk_attr_args} make_visit!{Attribute; visit_attribute, walk_attribute} make_visit!{Block; visit_block, walk_block} make_visit!{CaptureBy; visit_capture_by, walk_capture_by} @@ -398,6 +400,26 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_attr_args<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + args: ref_t!(AttrArgs) + ) -> result!(V) { + match args { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => { + visit_delim_args!(vis, args); + } + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { + try_v!(vis.visit_expr(expr)); + try_v!(visit_span!(vis, eq_span)); + } + AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { + unreachable!("in literal form when visiting mac args eq: {:?}", lit) + } + } + return_result!(V) + } + pub fn walk_block<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, block: ref_t!(Block) @@ -1640,24 +1662,12 @@ pub mod visit { let NormalAttr { item, tokens: _ } = &**normal; let AttrItem { unsafety: _, path, args, tokens: _ } = item; try_visit!(visitor.visit_path(path, DUMMY_NODE_ID)); - try_visit!(walk_attr_args(visitor, args)); + try_visit!(visitor.visit_attr_args(args)); } AttrKind::DocComment(_kind, _sym) => {} } V::Result::output() } - - pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -> V::Result { - match args { - AttrArgs::Empty => {} - AttrArgs::Delimited(_args) => {} - AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => try_visit!(visitor.visit_expr(expr)), - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when walking mac args eq: {:?}", lit) - } - } - V::Result::output() - } } pub mod mut_visit { @@ -1756,21 +1766,6 @@ pub mod mut_visit { 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(vis: &mut T, args: &mut AttrArgs) { - match args { - AttrArgs::Empty => {} - AttrArgs::Delimited(args) => visit_delim_args(vis, args), - AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { - vis.visit_expr(expr); - vis.visit_span(eq_span); - } - AttrArgs::Eq(_eq_span, AttrArgsEq::Hir(lit)) => { - unreachable!("in literal form when visiting mac args eq: {:?}", lit) - } - } - } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_delim_args(vis: &mut T, args: &mut DelimArgs) { let DelimArgs { dspan, delim: _, tokens } = args; @@ -1891,7 +1886,7 @@ pub mod mut_visit { tokens: attr_tokens, } = &mut **normal; vis.visit_path(path, DUMMY_NODE_ID); - visit_attr_args(vis, args); + vis.visit_attr_args(args); visit_lazy_tts(vis, tokens); visit_lazy_tts(vis, attr_tokens); } @@ -2074,7 +2069,7 @@ pub mod mut_visit { token::NtMeta(item) => { let AttrItem { unsafety: _, path, args, tokens } = item.deref_mut(); vis.visit_path(path, DUMMY_NODE_ID); - visit_attr_args(vis, args); + vis.visit_attr_args(args); visit_lazy_tts(vis, tokens); } token::NtPath(path) => vis.visit_path(path, DUMMY_NODE_ID), From 5002c218605912b2eb3dbc11928c278213b89f28 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 09:52:15 -0300 Subject: [PATCH 55/82] Add {visit,walk}_safety --- compiler/rustc_ast/src/visitors.rs | 61 ++++++++++++++++++------------ 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 6f5ee3b4699d9..f79f59f751be6 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -343,6 +343,7 @@ macro_rules! make_ast_visitor { make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} + make_visit!{Safety; visit_safety, walk_safety} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} make_visit!{Variant; visit_variant, walk_variant} @@ -851,6 +852,20 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_safety<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + safety: ref_t!(Safety) + ) -> result!(V) { + match safety { + Safety::Unsafe(span) + | Safety::Safe(span) => { + try_v!(visit_span!(vis, span)) + } + Safety::Default => {} + } + return_result!(V) + } + pub fn walk_trait_ref<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, trait_ref: ref_t!(TraitRef) @@ -1177,13 +1192,17 @@ pub mod visit { let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body.as_deref()); try_visit!(visitor.visit_fn(kind, *span, *id)); } - ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { - ModKind::Loaded(items, _inline, _inner_span) => { - walk_list!(visitor, visit_item, items); + ItemKind::Mod(safety, mod_kind) => { + try_visit!(visitor.visit_safety(safety)); + match mod_kind { + ModKind::Loaded(items, _inline, _inner_span) => { + walk_list!(visitor, visit_item, items); + } + ModKind::Unloaded => {} } - ModKind::Unloaded => {} - }, - ItemKind::ForeignMod(ForeignMod { safety: _, abi: _, items }) => { + } + ItemKind::ForeignMod(ForeignMod { safety, abi: _, items }) => { + try_visit!(visitor.visit_safety(safety)); walk_list!(visitor, visit_foreign_item, items); } ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), @@ -1204,7 +1223,7 @@ pub mod visit { } ItemKind::Impl(box Impl { defaultness: _, - safety: _, + safety, generics, constness: _, polarity: _, @@ -1212,6 +1231,7 @@ pub mod visit { self_ty, items, }) => { + try_visit!(visitor.visit_safety(safety)); try_visit!(visitor.visit_generics(generics)); visit_opt!(visitor, visit_trait_ref, of_trait); try_visit!(visitor.visit_ty(self_ty)); @@ -1222,7 +1242,8 @@ pub mod visit { try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_variant_data(struct_definition)); } - ItemKind::Trait(box Trait { safety: _, is_auto: _, generics, bounds, items }) => { + ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { + try_visit!(visitor.visit_safety(safety)); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); @@ -1284,8 +1305,9 @@ pub mod visit { walk_list!(visitor, visit_ty, tuple_element_types); } TyKind::BareFn(function_declaration) => { - let BareFnTy { safety: _, ext: _, generic_params, decl, decl_span: _ } = + let BareFnTy { safety, ext: _, generic_params, decl, decl_span: _ } = &**function_declaration; + try_visit!(visitor.visit_safety(safety)); walk_list!(visitor, visit_generic_param, generic_params); try_visit!(visitor.visit_fn_decl(decl)); } @@ -1830,7 +1852,7 @@ pub mod mut_visit { } TyKind::BareFn(bft) => { let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = bft.deref_mut(); - visit_safety(vis, safety); + vis.visit_safety(safety); generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); vis.visit_fn_decl(decl); vis.visit_span(decl_span); @@ -1865,7 +1887,7 @@ pub mod mut_visit { fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { let ForeignMod { safety, abi: _, items } = foreign_mod; - visit_safety(vis, safety); + vis.visit_safety(safety); items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); } @@ -2085,15 +2107,6 @@ pub mod mut_visit { } } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. - fn visit_safety(vis: &mut T, safety: &mut Safety) { - match safety { - Safety::Unsafe(span) => vis.visit_span(span), - Safety::Safe(span) => vis.visit_span(span), - Safety::Default => {} - } - } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_polarity(vis: &mut T, polarity: &mut ImplPolarity) { match polarity { @@ -2200,7 +2213,7 @@ pub mod mut_visit { vis.visit_fn(FnKind::Fn(sig, generics, body), span, id); } ItemKind::Mod(safety, mod_kind) => { - visit_safety(vis, safety); + vis.visit_safety(safety); match mod_kind { ModKind::Loaded( items, @@ -2249,7 +2262,7 @@ pub mod mut_visit { items, }) => { visit_defaultness(vis, defaultness); - visit_safety(vis, safety); + vis.visit_safety(safety); vis.visit_generics(generics); visit_constness(vis, constness); visit_polarity(vis, polarity); @@ -2258,7 +2271,7 @@ pub mod mut_visit { items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Impl)); } ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { - visit_safety(vis, safety); + vis.visit_safety(safety); vis.visit_generics(generics); visit_bounds(vis, bounds, BoundKind::Bound); items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait)); @@ -2386,7 +2399,7 @@ pub mod mut_visit { let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; visit_constness(vis, constness); coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); - visit_safety(vis, safety); + vis.visit_safety(safety); } /// Mutates one item, returning the item again. From ba05c886ccdb959fb9226d91f6dbc2bfd2f8ea81 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:22:58 -0300 Subject: [PATCH 56/82] Unify walk_ty --- compiler/rustc_ast/src/visitors.rs | 165 ++++++++++++----------------- 1 file changed, 67 insertions(+), 98 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index f79f59f751be6..9c47876662732 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -356,7 +356,6 @@ macro_rules! make_ast_visitor { make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} - fn visit_variant_discr(&mut self, discr: ref_t!(AnonConst)) -> result!() { self.visit_anon_const(discr) } @@ -1042,6 +1041,73 @@ macro_rules! make_ast_visitor { try_v!(visit_span!(vis, span)); return_result!(V) } + + pub fn walk_ty<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + ty: ref_t!(Ty) + ) -> result!(V) { + let Ty { id, kind, span, tokens } = ty; + try_v!(visit_id!(vis, id)); + match kind { + TyKind::Err(_guar) => {} + TyKind::Infer + | TyKind::ImplicitSelf + | TyKind::Dummy + | TyKind::Never + | TyKind::CVarArgs => {} + TyKind::Slice(ty) => { + try_v!(vis.visit_ty(ty)); + } + TyKind::Ptr(mt) => { + try_v!(vis.visit_mt(mt)); + } + TyKind::Ref(lt, mt) | TyKind::PinnedRef(lt, mt) => { + visit_o!(lt, |lt| vis.visit_lifetime(lt, LifetimeCtxt::Ref)); + try_v!(vis.visit_mt(mt)); + } + TyKind::BareFn(bft) => { + let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = & $($mut)? **bft; + try_v!(vis.visit_safety(safety)); + visit_list!(vis, visit_generic_param, flat_map_generic_param, generic_params); + try_v!(vis.visit_fn_decl(decl)); + try_v!(visit_span!(vis, decl_span)); + } + TyKind::Tup(tys) => { + visit_list!(vis, visit_ty, tys); + } + TyKind::Paren(ty) => { + try_v!(vis.visit_ty(ty)) + } + TyKind::Pat(ty, pat) => { + try_v!(vis.visit_ty(ty)); + try_v!(vis.visit_pat(pat)); + } + TyKind::Path(qself, path) => { + try_v!(vis.visit_qself(qself)); + try_v!(vis.visit_path(path, *id)); + } + TyKind::Array(ty, length) => { + try_v!(vis.visit_ty(ty)); + try_v!(vis.visit_anon_const(length)); + } + TyKind::Typeof(expr) => { + try_v!(vis.visit_anon_const(expr)); + }, + TyKind::TraitObject(bounds, _syntax) => { + visit_list!(vis, visit_param_bound, bounds; BoundKind::TraitObject); + } + TyKind::ImplTrait(id, bounds) => { + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_param_bound, bounds; BoundKind::Impl); + } + TyKind::MacCall(mac) => { + try_v!(vis.visit_mac_call(mac)) + } + } + visit_lazy_tts!(vis, tokens); + try_v!(visit_span!(vis, span)); + return_result!(V) + } } } @@ -1292,52 +1358,6 @@ pub mod visit { walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) } - 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(mt) => try_visit!(visitor.visit_mt(mt)), - TyKind::Ref(opt_lifetime, mt) | TyKind::PinnedRef(opt_lifetime, mt) => { - visit_opt!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Ref); - try_visit!(visitor.visit_mt(mt)); - } - 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; - try_visit!(visitor.visit_safety(safety)); - walk_list!(visitor, visit_generic_param, generic_params); - try_visit!(visitor.visit_fn_decl(decl)); - } - 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_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_assoc_item_constraint<'a, V: Visitor<'a>>( visitor: &mut V, constraint: &'a AssocItemConstraint, @@ -1834,57 +1854,6 @@ pub mod mut_visit { vis.visit_span(span); } - pub fn walk_ty(vis: &mut T, ty: &mut P) { - 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, LifetimeCtxt::Ref)); - vis.visit_mt(mt); - } - TyKind::BareFn(bft) => { - let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = bft.deref_mut(); - vis.visit_safety(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::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_pat(pat); - } - TyKind::Path(qself, path) => { - vis.visit_qself(qself); - vis.visit_path(path, *id); - } - 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), - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); - } - fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { let ForeignMod { safety, abi: _, items } = foreign_mod; vis.visit_safety(safety); From b7078cf18cd5c075b7d1beb22116d0d26a8c360f Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:38:02 -0300 Subject: [PATCH 57/82] Unify walk_assoc_item_constraint --- compiler/rustc_ast/src/visitors.rs | 67 ++++++++++++------------------ 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 9c47876662732..70ddc3655c515 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -400,6 +400,33 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_assoc_item_constraint<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + constraint: ref_t!(AssocItemConstraint) + ) -> result!(V) { + let AssocItemConstraint { id, ident, gen_args, kind, span } = constraint; + try_v!(visit_id!(vis, id)); + try_v!(vis.visit_ident(ident)); + visit_o!(gen_args, |gen_args| vis.visit_generic_args(gen_args)); + match kind { + AssocItemConstraintKind::Equality { term } => { + match term { + Term::Ty(ty) => { + try_v!(vis.visit_ty(ty)); + } + Term::Const(c) => { + try_v!(vis.visit_anon_const(c)); + } + } + } + AssocItemConstraintKind::Bound { bounds } => { + visit_list!(vis, visit_param_bound, bounds; BoundKind::Bound); + } + } + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_attr_args<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, args: ref_t!(AttrArgs) @@ -1358,25 +1385,6 @@ pub mod visit { walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) } - pub fn walk_assoc_item_constraint<'a, V: Visitor<'a>>( - visitor: &mut V, - constraint: &'a AssocItemConstraint, - ) -> V::Result { - let AssocItemConstraint { id: _, ident, gen_args, kind, span: _ } = constraint; - try_visit!(visitor.visit_ident(ident)); - visit_opt!(visitor, visit_generic_args, gen_args); - match kind { - AssocItemConstraintKind::Equality { term } => match term { - Term::Ty(ty) => try_visit!(visitor.visit_ty(ty)), - Term::Const(c) => try_visit!(visitor.visit_anon_const(c)), - }, - AssocItemConstraintKind::Bound { bounds } => { - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - } - } - V::Result::output() - } - impl WalkItemKind for ForeignItemKind { fn walk<'a, V: Visitor<'a>>( &'a self, @@ -1833,27 +1841,6 @@ pub mod mut_visit { smallvec![arm] } - fn walk_assoc_item_constraint( - vis: &mut T, - AssocItemConstraint { id, ident, gen_args, kind, span }: &mut AssocItemConstraint, - ) { - vis.visit_id(id); - vis.visit_ident(ident); - if let Some(gen_args) = gen_args { - vis.visit_generic_args(gen_args); - } - match kind { - AssocItemConstraintKind::Equality { term } => match term { - Term::Ty(ty) => vis.visit_ty(ty), - Term::Const(c) => vis.visit_anon_const(c), - }, - AssocItemConstraintKind::Bound { bounds } => { - visit_bounds(vis, bounds, BoundKind::Bound) - } - } - vis.visit_span(span); - } - fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { let ForeignMod { safety, abi: _, items } = foreign_mod; vis.visit_safety(safety); From 364dc87fc21be6b397e55e882d20eaf120c15428 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:43:20 -0300 Subject: [PATCH 58/82] Unify walk_mac_call --- compiler/rustc_ast/src/visitors.rs | 23 ++++++++++----------- compiler/rustc_ast_passes/src/node_count.rs | 2 +- compiler/rustc_lint/src/early.rs | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 70ddc3655c515..82dc1128c052a 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -333,7 +333,7 @@ macro_rules! make_ast_visitor { make_visit!{Label; visit_label, walk_label} make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} make_visit!{Local; visit_local, walk_local} - make_visit!{MacCall; visit_mac_call, walk_mac} + make_visit!{MacCall; visit_mac_call, walk_mac_call} make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Option>; visit_qself, walk_qself} make_visit!{Param; visit_param, walk_param} @@ -770,6 +770,16 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_mac_call<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + mac: ref_t!(MacCall) + ) -> result!(V) { + let MacCall { path, args } = mac; + try_v!(vis.visit_path(path, DUMMY_NODE_ID)); + visit_delim_args!(vis, args); + return_result!(V) + } + pub fn walk_mt<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, mt: ref_t!(MutTy) @@ -1538,11 +1548,6 @@ pub mod visit { V::Result::output() } - 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_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result { let Expr { id, kind, span, attrs, tokens: _ } = expression; walk_list!(visitor, visit_attribute, attrs); @@ -1873,12 +1878,6 @@ pub mod mut_visit { vis.visit_span(span); } - fn walk_mac(vis: &mut T, mac: &mut MacCall) { - let MacCall { path, args } = mac; - vis.visit_path(path, DUMMY_NODE_ID); - visit_delim_args(vis, args); - } - fn walk_macro_def(vis: &mut T, macro_def: &mut MacroDef) { let MacroDef { body, macro_rules: _ } = macro_def; visit_delim_args(vis, body); diff --git a/compiler/rustc_ast_passes/src/node_count.rs b/compiler/rustc_ast_passes/src/node_count.rs index 4deb1eb9458aa..1b18378e992ae 100644 --- a/compiler/rustc_ast_passes/src/node_count.rs +++ b/compiler/rustc_ast_passes/src/node_count.rs @@ -105,7 +105,7 @@ impl<'ast> Visitor<'ast> for NodeCounter { } fn visit_mac_call(&mut self, mac: &MacCall) { self.count += 1; - walk_mac(self, mac) + walk_mac_call(self, mac) } fn visit_path(&mut self, path: &Path, _id: NodeId) { self.count += 1; diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index f9436180efb58..032418453a27c 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -296,7 +296,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> fn visit_mac_call(&mut self, mac: &'a ast::MacCall) { lint_callback!(self, check_mac, mac); - ast_visit::walk_mac(self, mac); + ast_visit::walk_mac_call(self, mac); } } From 0fa7e60a116408dc304dd68b8721d30db3f3683c Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:45:37 -0300 Subject: [PATCH 59/82] Unify walk_attribute --- compiler/rustc_ast/src/visitors.rs | 55 +++++++++++++----------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 82dc1128c052a..b8a739cdf3e6e 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -447,6 +447,29 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_attribute<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + attr: ref_t!(Attribute) + ) -> result!(V) { + let Attribute { kind, id:_, style: _, span } = attr; + match kind { + AttrKind::Normal(normal) => { + let NormalAttr { + item: AttrItem { unsafety, path, args, tokens }, + tokens: attr_tokens, + } = &$($mut)? **normal; + try_v!(vis.visit_safety(unsafety)); + try_v!(vis.visit_path(path, DUMMY_NODE_ID)); + try_v!(vis.visit_attr_args(args)); + visit_lazy_tts!(vis, tokens); + visit_lazy_tts!(vis, attr_tokens); + } + AttrKind::DocComment(_kind, _sym) => {} + } + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_block<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, block: ref_t!(Block) @@ -1709,20 +1732,6 @@ pub mod visit { visitor.visit_expr_post(expression) } - - pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) -> V::Result { - let Attribute { kind, id: _, style: _, span: _ } = attr; - match kind { - 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_attr_args(args)); - } - AttrKind::DocComment(_kind, _sym) => {} - } - V::Result::output() - } } pub mod mut_visit { @@ -1860,24 +1869,6 @@ pub mod mut_visit { smallvec![variant] } - fn walk_attribute(vis: &mut T, attr: &mut Attribute) { - let Attribute { kind, id: _, style: _, span } = attr; - match kind { - AttrKind::Normal(normal) => { - let NormalAttr { - item: AttrItem { unsafety: _, path, args, tokens }, - tokens: attr_tokens, - } = &mut **normal; - vis.visit_path(path, DUMMY_NODE_ID); - vis.visit_attr_args(args); - visit_lazy_tts(vis, tokens); - visit_lazy_tts(vis, attr_tokens); - } - AttrKind::DocComment(_kind, _sym) => {} - } - vis.visit_span(span); - } - fn walk_macro_def(vis: &mut T, macro_def: &mut MacroDef) { let MacroDef { body, macro_rules: _ } = macro_def; visit_delim_args(vis, body); From f4e0a22cd40bff595ef63961c96d28144430aa4b Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:49:27 -0300 Subject: [PATCH 60/82] Unify {visit,walk}_foreign_mod --- compiler/rustc_ast/src/visitors.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index b8a739cdf3e6e..d54b1b7625bbd 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -202,7 +202,6 @@ macro_rules! make_ast_visitor { make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{FnHeader; visit_fn_header, walk_fn_header} - make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} @@ -321,6 +320,7 @@ macro_rules! make_ast_visitor { make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} + make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} make_visit!{FormatArgs; visit_format_args, walk_format_args} make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} make_visit!{GenericArgs; visit_generic_args, walk_generic_args} @@ -580,6 +580,16 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_foreign_mod<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + foreign_mod: ref_t!(ForeignMod) + ) -> result!(V) { + let ForeignMod { safety, abi: _, items } = foreign_mod; + try_v!(vis.visit_safety(safety)); + visit_list!(vis, visit_foreign_item, flat_map_foreign_item, items); + return_result!(V) + } + pub fn walk_format_args<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, fmt: ref_t!(FormatArgs) @@ -1327,9 +1337,8 @@ pub mod visit { ModKind::Unloaded => {} } } - ItemKind::ForeignMod(ForeignMod { safety, abi: _, items }) => { - try_visit!(visitor.visit_safety(safety)); - walk_list!(visitor, visit_foreign_item, items); + ItemKind::ForeignMod(foreign_mod) => { + try_visit!(visitor.visit_foreign_mod(foreign_mod)); } ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), ItemKind::TyAlias(box TyAlias { @@ -1855,12 +1864,6 @@ pub mod mut_visit { smallvec![arm] } - fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { - let ForeignMod { safety, abi: _, items } = foreign_mod; - vis.visit_safety(safety); - items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); - } - pub fn walk_flat_map_variant( visitor: &mut T, mut variant: Variant, From ac7bb6049d651e7ff1570f9f1fbed83cac58e750 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:59:36 -0300 Subject: [PATCH 61/82] Unify {visit,walk}_macro_def --- compiler/rustc_ast/src/visitors.rs | 23 ++++++++++++----------- compiler/rustc_lint/src/early.rs | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index d54b1b7625bbd..66f7510329183 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -202,7 +202,6 @@ macro_rules! make_ast_visitor { make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{FnHeader; visit_fn_header, walk_fn_header} - make_visit!{MacroDef; visit_macro_def, walk_macro_def} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} @@ -297,9 +296,6 @@ macro_rules! make_ast_visitor { fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { walk_fn(self, fk) } - fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) -> Self::Result { - Self::Result::output() - } fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { Self::Result::output() } @@ -334,6 +330,7 @@ macro_rules! make_ast_visitor { make_visit!{Lifetime, _ ctxt: LifetimeCtxt; visit_lifetime, walk_lifetime} make_visit!{Local; visit_local, walk_local} make_visit!{MacCall; visit_mac_call, walk_mac_call} + make_visit!{MacroDef, _ id: NodeId; visit_macro_def, walk_macro_def} make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Option>; visit_qself, walk_qself} make_visit!{Param; visit_param, walk_param} @@ -813,6 +810,15 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_macro_def<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + macro_def: ref_t!(MacroDef), + ) -> result!(V) { + let MacroDef { body, macro_rules: _ } = macro_def; + visit_delim_args!(vis, body); + return_result!(V) + } + pub fn walk_mt<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, mt: ref_t!(MutTy) @@ -1388,7 +1394,7 @@ pub mod visit { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - ItemKind::MacroDef(ts) => try_visit!(visitor.visit_mac_def(ts, *id)), + ItemKind::MacroDef(ts) => try_visit!(visitor.visit_macro_def(ts, *id)), ItemKind::Delegation(box Delegation { id, qself, @@ -1872,11 +1878,6 @@ pub mod mut_visit { smallvec![variant] } - fn walk_macro_def(vis: &mut T, macro_def: &mut MacroDef) { - let MacroDef { body, macro_rules: _ } = macro_def; - visit_delim_args(vis, body); - } - fn walk_meta_list_item(vis: &mut T, li: &mut MetaItemInner) { match li { MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi), @@ -2230,7 +2231,7 @@ pub mod mut_visit { visit_bounds(vis, bounds, BoundKind::Bound); } ItemKind::MacCall(m) => vis.visit_mac_call(m), - ItemKind::MacroDef(def) => vis.visit_macro_def(def), + ItemKind::MacroDef(def) => vis.visit_macro_def(def, id), ItemKind::Delegation(box Delegation { id, qself, diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 032418453a27c..a140d59210355 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -289,7 +289,7 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> lint_callback!(self, check_attribute, attr); } - fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) { + fn visit_macro_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) { lint_callback!(self, check_mac_def, mac); self.check_id(id); } From 089d0ee704c488cb4a9c20c640048b6c89862763 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 11:12:31 -0300 Subject: [PATCH 62/82] Unify {visit,walk}_ty_alias_where_clauses --- compiler/rustc_ast/src/visitors.rs | 36 ++++++++++++++++++------------ 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 66f7510329183..65050fa1969c4 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -342,6 +342,7 @@ macro_rules! make_ast_visitor { make_visit!{PreciseCapturingArg; visit_precise_capturing_arg, walk_precise_capturing_arg} make_visit!{Safety; visit_safety, walk_safety} make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} + make_visit!{TyAliasWhereClauses; visit_ty_alias_where_clauses, walk_ty_alias_where_clauses} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} make_visit!{Variant; visit_variant, walk_variant} make_visit!{VariantData; visit_variant_data, walk_variant_data} @@ -951,6 +952,18 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_ty_alias_where_clauses<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + tawcs: ref_t!(TyAliasWhereClauses) + ) -> result!(V) { + let TyAliasWhereClauses { before, after, split: _ } = tawcs; + let TyAliasWhereClause { has_where_token: _, span: span_before } = before; + let TyAliasWhereClause { has_where_token: _, span: span_after } = after; + try_v!(visit_span!(vis, span_before)); + try_v!(visit_span!(vis, span_after)); + return_result!(V) + } + pub fn walk_use_tree<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, use_tree: ref_t!(UseTree), @@ -1352,11 +1365,12 @@ pub mod visit { bounds, ty, defaultness: _, - where_clauses: _, + where_clauses, }) => { try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); visit_opt!(visitor, visit_ty, ty); + try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); } ItemKind::Enum(enum_definition, generics) => { try_visit!(visitor.visit_generics(generics)); @@ -1456,11 +1470,12 @@ pub mod visit { bounds, ty, defaultness: _, - where_clauses: _, + where_clauses, }) => { try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); visit_opt!(visitor, visit_ty, ty); + try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); } ForeignItemKind::MacCall(mac) => { try_visit!(visitor.visit_mac_call(mac)); @@ -1512,11 +1527,12 @@ pub mod visit { bounds, ty, defaultness: _, - where_clauses: _, + where_clauses, }) => { try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); visit_opt!(visitor, visit_ty, ty); + try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); } AssocItemKind::MacCall(mac) => { try_visit!(visitor.visit_mac_call(mac)); @@ -2113,14 +2129,6 @@ pub mod mut_visit { smallvec![param] } - fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWhereClauses) { - let TyAliasWhereClauses { before, after, split: _ } = tawcs; - let TyAliasWhereClause { has_where_token: _, span: span_before } = before; - let TyAliasWhereClause { has_where_token: _, span: span_after } = after; - vis.visit_span(span_before); - vis.visit_span(span_after); - } - pub fn walk_flat_map_field_def( visitor: &mut T, mut fd: FieldDef, @@ -2190,7 +2198,7 @@ pub mod mut_visit { 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); + vis.visit_ty_alias_where_clauses(where_clauses); } ItemKind::Enum(enum_def, generics) => { vis.visit_generics(generics); @@ -2290,7 +2298,7 @@ pub mod mut_visit { 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); + visitor.visit_ty_alias_where_clauses(where_clauses); } AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), AssocItemKind::Delegation(box Delegation { @@ -2390,7 +2398,7 @@ pub mod mut_visit { 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); + visitor.visit_ty_alias_where_clauses(where_clauses); } ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), } From fcb93ebadfd1236761f305d43c84e3d2bb50c87a Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 10:51:10 -0300 Subject: [PATCH 63/82] Unify WalkItemKind and unimpl it for AssocItemKind --- compiler/rustc_ast/src/visitors.rs | 432 +++++++++--------- compiler/rustc_builtin_macros/src/cfg_eval.rs | 4 +- .../rustc_builtin_macros/src/test_harness.rs | 2 +- compiler/rustc_expand/src/expand.rs | 4 +- compiler/rustc_expand/src/placeholders.rs | 2 +- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- 6 files changed, 226 insertions(+), 220 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 65050fa1969c4..77f559e8cfd99 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -220,9 +220,9 @@ macro_rules! make_ast_visitor { fn flat_map_assoc_item( &mut self, i: P, - _ctxt: AssocCtxt, + ctxt: AssocCtxt, ) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, i) + walk_flat_map_assoc_item(self, i, ctxt) } /// `Span` and `NodeId` are mutated at the caller site. @@ -1197,6 +1197,17 @@ macro_rules! make_ast_visitor { try_v!(visit_span!(vis, span)); return_result!(V) } + + pub trait WalkItemKind: Sized { + fn walk<$($lt,)? V: $trait$(<$lt>)?>( + &$($lt)? $($mut)? self, + id: NodeId, + span: Span, + vis: ref_t!(Visibility), + ident: ref_t!(Ident), + visitor: &mut V, + ) -> result!(V); + } } } @@ -1312,28 +1323,20 @@ pub mod visit { GenericArg, } - pub trait WalkItemKind: Sized { - fn walk<'a, V: Visitor<'a>>( - &'a self, - item: &'a Item, - ctxt: AssocCtxt, - visitor: &mut V, - ) -> V::Result; - } - make_ast_visitor!(Visitor<'ast>); impl WalkItemKind for ItemKind { fn walk<'a, V: Visitor<'a>>( &'a self, - item: &'a Item, - _ctxt: AssocCtxt, + id: NodeId, + span: Span, + vis: &'a Visibility, + ident: &'a Ident, visitor: &mut V, ) -> V::Result { - let Item { id, span, vis, ident, .. } = item; match self { ItemKind::ExternCrate(_rename) => {} - ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, *id, false)), + ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)), ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); @@ -1345,7 +1348,7 @@ pub mod visit { } ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, *span, *id)); + try_visit!(visitor.visit_fn(kind, span, id)); } ItemKind::Mod(safety, mod_kind) => { try_visit!(visitor.visit_safety(safety)); @@ -1408,7 +1411,7 @@ pub mod visit { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - ItemKind::MacroDef(ts) => try_visit!(visitor.visit_macro_def(ts, *id)), + ItemKind::MacroDef(ts) => try_visit!(visitor.visit_macro_def(ts, id)), ItemKind::Delegation(box Delegation { id, qself, @@ -1424,7 +1427,7 @@ pub mod visit { } ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_path(prefix, *id)); + try_visit!(visitor.visit_path(prefix, id)); if let Some(suffixes) = suffixes { for (ident, rename) in suffixes { visitor.visit_ident(ident); @@ -1444,17 +1447,23 @@ pub mod visit { visitor: &mut V, item: &'a Item, ) -> V::Result { - walk_assoc_item(visitor, item, AssocCtxt::Trait /*ignored*/) + let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; + walk_list!(visitor, visit_attribute, attrs); + try_visit!(visitor.visit_vis(vis)); + try_visit!(visitor.visit_ident(ident)); + try_visit!(kind.walk(*id, *span, vis, ident, visitor)); + V::Result::output() } impl WalkItemKind for ForeignItemKind { fn walk<'a, V: Visitor<'a>>( &'a self, - item: &'a Item, - _ctxt: AssocCtxt, + id: NodeId, + span: Span, + vis: &'a Visibility, + ident: &'a Ident, visitor: &mut V, ) -> V::Result { - let Item { id, span, ident, vis, .. } = item; match self { ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { try_visit!(visitor.visit_ty(ty)); @@ -1463,7 +1472,7 @@ pub mod visit { ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, *span, *id)); + try_visit!(visitor.visit_fn(kind, span, id)); } ForeignItemKind::TyAlias(box TyAlias { generics, @@ -1503,86 +1512,68 @@ pub mod visit { V::Result::output() } - impl WalkItemKind for AssocItemKind { - fn walk<'a, V: Visitor<'a>>( - &'a self, - item: &'a Item, - ctxt: AssocCtxt, - visitor: &mut V, - ) -> V::Result { - let Item { id, span, ident, vis, .. } = item; - match self { - AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = - FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); - try_visit!(visitor.visit_fn(kind, *span, *id)); - } - AssocItemKind::Type(box TyAlias { - generics, - bounds, - ty, - defaultness: _, - where_clauses, - }) => { - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); - } - AssocItemKind::MacCall(mac) => { - try_visit!(visitor.visit_mac_call(mac)); - } - AssocItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_path(path, *id)); - 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_assoc_item<'a, V: Visitor<'a>>( visitor: &mut V, - item: &'a Item, + item: &'a AssocItem, ctxt: AssocCtxt, ) -> V::Result { - let Item { id: _, span: _, ident, vis, attrs, kind, tokens: _ } = item; + let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; walk_list!(visitor, visit_attribute, attrs); try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_ident(ident)); - try_visit!(kind.walk(item, ctxt, visitor)); + match kind { + AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { + try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_ty(ty)); + visit_opt!(visitor, visit_expr, expr); + } + AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + let kind = + FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); + try_visit!(visitor.visit_fn(kind, *span, *id)); + } + AssocItemKind::Type(box TyAlias { + generics, + bounds, + ty, + defaultness: _, + where_clauses, + }) => { + try_visit!(visitor.visit_generics(generics)); + walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); + visit_opt!(visitor, visit_ty, ty); + try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); + } + AssocItemKind::MacCall(mac) => { + try_visit!(visitor.visit_mac_call(mac)); + } + AssocItemKind::Delegation(box Delegation { + id, + qself, + path, + rename, + body, + from_glob: _, + }) => { + try_visit!(visitor.visit_qself(qself)); + try_visit!(visitor.visit_path(path, *id)); + 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() } @@ -1789,10 +1780,6 @@ pub mod mut_visit { } } - pub trait WalkItemKind { - fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor); - } - make_ast_visitor!(MutVisitor, mut); /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful @@ -2145,48 +2132,50 @@ pub mod mut_visit { smallvec![f] } - pub fn walk_item_kind( - kind: &mut impl WalkItemKind, - span: Span, - id: NodeId, - vis: &mut impl MutVisitor, - ) { - kind.walk(span, id, vis) + pub fn walk_item_kind(item: &mut Item, vis: &mut impl MutVisitor) { + item.kind.walk(item.id, item.span, &mut item.vis, &mut item.ident, vis) } impl WalkItemKind for ItemKind { - fn walk(&mut self, span: Span, id: NodeId, vis: &mut impl MutVisitor) { + fn walk( + &mut self, + id: NodeId, + span: Span, + _vis: &mut Visibility, + _ident: &mut Ident, + visitor: &mut V, + ) { match self { ItemKind::ExternCrate(_orig_name) => {} - ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree, id, false), + ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, id, false), ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { - vis.visit_ty(ty); - visit_opt(expr, |expr| vis.visit_expr(expr)); + visitor.visit_ty(ty); + visit_opt(expr, |expr| visitor.visit_expr(expr)); } ItemKind::Const(item) => { - visit_const_item(item, vis); + visit_const_item(item, visitor); } ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(vis, defaultness); - vis.visit_fn(FnKind::Fn(sig, generics, body), span, id); + visit_defaultness(visitor, defaultness); + visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); } ItemKind::Mod(safety, mod_kind) => { - vis.visit_safety(safety); + visitor.visit_safety(safety); 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); + items.flat_map_in_place(|item| visitor.flat_map_item(item)); + visitor.visit_span(inner_span); + visitor.visit_span(inject_use_span); } ModKind::Unloaded => {} } } - ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm), - ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm), + ItemKind::ForeignMod(nm) => visitor.visit_foreign_mod(nm), + ItemKind::GlobalAsm(asm) => visitor.visit_inline_asm(asm), ItemKind::TyAlias(box TyAlias { defaultness, generics, @@ -2194,20 +2183,20 @@ pub mod mut_visit { bounds, ty, }) => { - visit_defaultness(vis, defaultness); - vis.visit_generics(generics); - visit_bounds(vis, bounds, BoundKind::Bound); - visit_opt(ty, |ty| vis.visit_ty(ty)); - vis.visit_ty_alias_where_clauses(where_clauses); + visit_defaultness(visitor, defaultness); + visitor.visit_generics(generics); + visit_bounds(visitor, bounds, BoundKind::Bound); + visit_opt(ty, |ty| visitor.visit_ty(ty)); + visitor.visit_ty_alias_where_clauses(where_clauses); } ItemKind::Enum(enum_def, generics) => { - vis.visit_generics(generics); - vis.visit_enum_def(enum_def); + visitor.visit_generics(generics); + visitor.visit_enum_def(enum_def); } ItemKind::Struct(variant_data, generics) | ItemKind::Union(variant_data, generics) => { - vis.visit_generics(generics); - vis.visit_variant_data(variant_data); + visitor.visit_generics(generics); + visitor.visit_variant_data(variant_data); } ItemKind::Impl(box Impl { defaultness, @@ -2219,89 +2208,32 @@ pub mod mut_visit { self_ty, items, }) => { - visit_defaultness(vis, defaultness); - vis.visit_safety(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)); + visit_defaultness(visitor, defaultness); + visitor.visit_safety(safety); + visitor.visit_generics(generics); + visit_constness(visitor, constness); + visit_polarity(visitor, polarity); + visit_opt(of_trait, |trait_ref| visitor.visit_trait_ref(trait_ref)); + visitor.visit_ty(self_ty); + items.flat_map_in_place(|item| { + visitor.flat_map_assoc_item(item, AssocCtxt::Impl) + }); } ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { - vis.visit_safety(safety); - vis.visit_generics(generics); - visit_bounds(vis, bounds, BoundKind::Bound); - items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait)); + visitor.visit_safety(safety); + visitor.visit_generics(generics); + visit_bounds(visitor, bounds, BoundKind::Bound); + items.flat_map_in_place(|item| { + visitor.flat_map_assoc_item(item, AssocCtxt::Trait) + }); } ItemKind::TraitAlias(generics, bounds) => { - vis.visit_generics(generics); - visit_bounds(vis, bounds, BoundKind::Bound); - } - ItemKind::MacCall(m) => vis.visit_mac_call(m), - ItemKind::MacroDef(def) => vis.visit_macro_def(def, id), - ItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - vis.visit_id(id); - vis.visit_qself(qself); - vis.visit_path(path, *id); - 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, id); - 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 { - fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) { - match self { - AssocItemKind::Const(item) => { - visit_const_item(item, visitor); - } - AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); - visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); - } - AssocItemKind::Type(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - }) => { - visit_defaultness(visitor, defaultness); visitor.visit_generics(generics); visit_bounds(visitor, bounds, BoundKind::Bound); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - visitor.visit_ty_alias_where_clauses(where_clauses); } - AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), - AssocItemKind::Delegation(box Delegation { + ItemKind::MacCall(m) => visitor.visit_mac_call(m), + ItemKind::MacroDef(def) => visitor.visit_macro_def(def, id), + ItemKind::Delegation(box Delegation { id, qself, path, @@ -2319,12 +2251,7 @@ pub mod mut_visit { visitor.visit_block(body); } } - AssocItemKind::DelegationMac(box DelegationMac { - qself, - prefix, - suffixes, - body, - }) => { + ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { visitor.visit_qself(qself); visitor.visit_path(prefix, id); if let Some(suffixes) = suffixes { @@ -2370,14 +2297,93 @@ pub mod mut_visit { visit_attrs(visitor, attrs); visitor.visit_vis(vis); visitor.visit_ident(ident); - kind.walk(*span, *id, visitor); + kind.walk(*id, *span, vis, ident, visitor); + visit_lazy_tts(visitor, tokens); + visitor.visit_span(span); + smallvec![item] + } + + /// Mutates one item, returning the item again. + pub fn walk_flat_map_assoc_item( + visitor: &mut impl MutVisitor, + mut item: P, + _ctxt: AssocCtxt, + ) -> SmallVec<[P; 1]> { + let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); + visitor.visit_id(id); + visit_attrs(visitor, attrs); + visitor.visit_vis(vis); + visitor.visit_ident(ident); + match kind { + AssocItemKind::Const(item) => { + visit_const_item(item, visitor); + } + AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + visit_defaultness(visitor, defaultness); + visitor.visit_fn(FnKind::Fn(sig, generics, body), *span, *id); + } + AssocItemKind::Type(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + }) => { + visit_defaultness(visitor, defaultness); + visitor.visit_generics(generics); + visit_bounds(visitor, bounds, BoundKind::Bound); + visit_opt(ty, |ty| visitor.visit_ty(ty)); + visitor.visit_ty_alias_where_clauses(where_clauses); + } + AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), + AssocItemKind::Delegation(box Delegation { + id, + qself, + path, + rename, + body, + from_glob: _, + }) => { + visitor.visit_id(id); + visitor.visit_qself(qself); + visitor.visit_path(path, *id); + 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, *id); + 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); + } + } + } visit_lazy_tts(visitor, tokens); visitor.visit_span(span); smallvec![item] } impl WalkItemKind for ForeignItemKind { - fn walk(&mut self, span: Span, id: NodeId, visitor: &mut impl MutVisitor) { + fn walk( + &mut self, + id: NodeId, + span: Span, + _vis: &mut Visibility, + _ident: &mut Ident, + visitor: &mut V, + ) { match self { ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { visitor.visit_ty(ty); diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index b686a8cf935ca..e82cd0bce0f38 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -247,10 +247,10 @@ impl MutVisitor for CfgEval<'_> { fn flat_map_assoc_item( &mut self, item: P, - _ctxt: AssocCtxt, + ctxt: AssocCtxt, ) -> SmallVec<[P; 1]> { let item = configure!(self, item); - mut_visit::walk_flat_map_item(self, item) + mut_visit::walk_flat_map_assoc_item(self, item, ctxt) } fn flat_map_foreign_item( diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 953484533087c..d4e0dd525504c 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -144,7 +144,7 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { item.kind { let prev_tests = mem::take(&mut self.tests); - walk_item_kind(&mut item.kind, item.span, item.id, self); + walk_item_kind(item, self); self.add_test_cases(item.id, span, prev_tests); } else { // But in those cases, we emit a lint to warn the user of these missing tests. diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 91277ba82ea19..b803b489b1e7c 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1302,7 +1302,7 @@ impl InvocationCollectorNode for AstNodeWrapper, TraitItemTag> fragment.make_trait_items() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_item(visitor, self.wrapped) + walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Trait) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) @@ -1343,7 +1343,7 @@ impl InvocationCollectorNode for AstNodeWrapper, ImplItemTag> fragment.make_impl_items() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_item(visitor, self.wrapped) + walk_flat_map_assoc_item(visitor, self.wrapped, AssocCtxt::Impl) } fn is_mac_call(&self) -> bool { matches!(self.wrapped.kind, AssocItemKind::MacCall(..)) diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 610c69e9d21b4..90206b19bd587 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -286,7 +286,7 @@ impl MutVisitor for PlaceholderExpander { AssocCtxt::Impl => it.make_impl_items(), } } - _ => walk_flat_map_item(self, item), + _ => walk_flat_map_assoc_item(self, item, ctxt), } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index a831fb5c2e324..bed6d5231db1e 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1318,7 +1318,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> { // This way they can use `macro_rules` defined later. self.visit_vis(&item.vis); self.visit_ident(&item.ident); - item.kind.walk(item, AssocCtxt::Trait, self); + item.kind.walk(item.id, item.span, &item.vis, &item.ident, self); visit::walk_list!(self, visit_attribute, &item.attrs); } _ => visit::walk_item(self, item), From f42dcf11cfe8b119b7026d364ca12ac8cb67bfcf Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 12:53:30 -0300 Subject: [PATCH 64/82] Unify {visit,walk}{,_foreign}_item --- compiler/rustc_ast/src/visitors.rs | 60 ++++++++++--------- compiler/rustc_builtin_macros/src/cfg_eval.rs | 2 +- compiler/rustc_expand/src/expand.rs | 2 +- compiler/rustc_expand/src/placeholders.rs | 2 +- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 77f559e8cfd99..bff40bd5b70b9 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -206,7 +206,7 @@ macro_rules! make_ast_visitor { make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, ni) + walk_flat_map_foreign_item(self, ni) } fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { @@ -281,8 +281,6 @@ macro_rules! make_ast_visitor { type Result: VisitorResult = (); make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} - make_visit!{ForeignItem; visit_foreign_item, walk_item} - make_visit!{Item; visit_item, walk_item} make_visit!{Stmt; visit_stmt, walk_stmt} /// This method is a hack to workaround unstable of `stmt_expr_attributes`. @@ -354,6 +352,10 @@ macro_rules! make_ast_visitor { make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} + // Default implementations are generic over WalkItemKind + make_visit!{ForeignItem; visit_foreign_item, walk_item} + make_visit!{Item; visit_item, walk_item} + fn visit_variant_discr(&mut self, discr: ref_t!(AnonConst)) -> result!() { self.visit_anon_const(discr) } @@ -1208,6 +1210,21 @@ macro_rules! make_ast_visitor { visitor: &mut V, ) -> result!(V); } + + pub fn walk_item<$($lt,)? V: $trait$(<$lt>)?>( + visitor: &mut V, + item: ref_t!(Item), + ) -> result!(V) { + let Item { id, span, ident, vis, attrs, kind, tokens } = item; + try_v!(visit_id!(visitor, id)); + visit_list!(visitor, visit_attribute, attrs); + try_v!(visitor.visit_vis(vis)); + try_v!(visitor.visit_ident(ident)); + try_v!(kind.walk(*id, *span, vis, ident, visitor)); + visit_lazy_tts!(visitor, tokens); + try_v!(visit_span!(visitor, span)); + return_result!(V) + } } } @@ -1443,18 +1460,6 @@ pub mod visit { } } - pub fn walk_item<'a, V: Visitor<'a>>( - visitor: &mut V, - item: &'a Item, - ) -> V::Result { - let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(ident)); - try_visit!(kind.walk(*id, *span, vis, ident, visitor)); - V::Result::output() - } - impl WalkItemKind for ForeignItemKind { fn walk<'a, V: Visitor<'a>>( &'a self, @@ -2288,18 +2293,19 @@ pub mod mut_visit { } /// Mutates one item, returning the item again. - pub fn walk_flat_map_item( - visitor: &mut impl MutVisitor, - mut item: P>, - ) -> SmallVec<[P>; 1]> { - let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visitor.visit_ident(ident); - kind.walk(*id, *span, vis, ident, visitor); - visit_lazy_tts(visitor, tokens); - visitor.visit_span(span); + pub fn walk_flat_map_item( + vis: &mut impl MutVisitor, + mut item: P, + ) -> SmallVec<[P; 1]> { + vis.visit_item(&mut item); + smallvec![item] + } + + pub fn walk_flat_map_foreign_item( + vis: &mut impl MutVisitor, + mut item: P, + ) -> SmallVec<[P; 1]> { + vis.visit_foreign_item(&mut item); smallvec![item] } diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index e82cd0bce0f38..d4142709b716a 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -258,7 +258,7 @@ impl MutVisitor for CfgEval<'_> { foreign_item: P, ) -> SmallVec<[P; 1]> { let foreign_item = configure!(self, foreign_item); - mut_visit::walk_flat_map_item(self, foreign_item) + mut_visit::walk_flat_map_foreign_item(self, foreign_item) } fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index b803b489b1e7c..9641ab38b1408 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1381,7 +1381,7 @@ impl InvocationCollectorNode for P { fragment.make_foreign_items() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_item(visitor, self) + walk_flat_map_foreign_item(visitor, self) } fn is_mac_call(&self) -> bool { matches!(self.kind, ForeignItemKind::MacCall(..)) diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 90206b19bd587..bae16a18bcbfd 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -296,7 +296,7 @@ impl MutVisitor for PlaceholderExpander { ) -> SmallVec<[P; 1]> { match item.kind { ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(), - _ => walk_flat_map_item(self, item), + _ => walk_flat_map_foreign_item(self, item), } } From 0595ae1f264694044dd0883b6c67e525d42ca966 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 13:29:57 -0300 Subject: [PATCH 65/82] Unify FnKind --- compiler/rustc_ast/src/visitors.rs | 88 +++++++++++-------- .../rustc_ast_passes/src/ast_validation.rs | 19 +--- src/tools/rustfmt/src/items.rs | 11 +-- src/tools/rustfmt/src/visitor.rs | 15 +--- 4 files changed, 59 insertions(+), 74 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index bff40bd5b70b9..938fd0420cbf5 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -151,6 +151,28 @@ macro_rules! make_ast_visitor { }; } + macro_rules! fn_kind_derives { + ($i: item) => { + macro_if!{$($mut)? { + #[derive(Debug)] + $i + } else { + #[derive(Debug, Copy, Clone)] + $i + }} + } + } + + fn_kind_derives!{ + pub enum FnKind<'a> { + /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. + Fn(FnCtxt, &'a $($mut)? Ident, &'a $($mut)? FnSig, &'a $($mut)? Visibility, &'a $($mut)? Generics, &'a $($mut)? Option>), + + /// E.g., `|x, y| body`. + Closure(&'a $($mut)? ClosureBinder, &'a $($mut)? Option, &'a $($mut)? P!(FnDecl), &'a $($mut)? P!(Expr)), + } + } + /// Each method of the traits `Visitor` and `MutVisitor` trait is a hook /// to be potentially overridden. Each method's default implementation /// recursively visits the substructure of the input via the corresponding @@ -1291,15 +1313,6 @@ pub mod visit { } } - #[derive(Copy, Clone, Debug)] - pub enum FnKind<'a> { - /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`. - Fn(FnCtxt, &'a Ident, &'a FnSig, &'a Visibility, &'a Generics, Option<&'a Block>), - - /// E.g., `|x, y| body`. - Closure(&'a ClosureBinder, &'a Option, &'a FnDecl, &'a Expr), - } - impl<'a> FnKind<'a> { pub fn header(&self) -> Option<&'a FnHeader> { match *self { @@ -1364,7 +1377,7 @@ pub mod visit { visit_opt!(visitor, visit_expr, expr); } ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body.as_deref()); + let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body); try_visit!(visitor.visit_fn(kind, span, id)); } ItemKind::Mod(safety, mod_kind) => { @@ -1475,8 +1488,7 @@ pub mod visit { visit_opt!(visitor, visit_expr, expr); } ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = - FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); + let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body); try_visit!(visitor.visit_fn(kind, span, id)); } ForeignItemKind::TyAlias(box TyAlias { @@ -1533,8 +1545,7 @@ pub mod visit { visit_opt!(visitor, visit_expr, expr); } AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { - let kind = - FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); + let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body); try_visit!(visitor.visit_fn(kind, *span, *id)); } AssocItemKind::Type(box TyAlias { @@ -1772,7 +1783,7 @@ pub mod mut_visit { //! that are created by the expansion of a macro. use super::*; - use crate::visit::{AssocCtxt, BoundKind, LifetimeCtxt}; + use crate::visit::{AssocCtxt, BoundKind, FnCtxt, LifetimeCtxt}; pub trait ExpectOne { fn expect_one(self, err: &'static str) -> A::Item; @@ -2095,7 +2106,7 @@ pub mod mut_visit { fn walk_fn(vis: &mut T, kind: FnKind<'_>) { match kind { - FnKind::Fn(FnSig { header, decl, span }, generics, body) => { + FnKind::Fn(_, _, FnSig { header, decl, span }, _, generics, body) => { // Identifier and visibility are visited as a part of the item. vis.visit_fn_header(header); vis.visit_generics(generics); @@ -2105,7 +2116,8 @@ pub mod mut_visit { } vis.visit_span(span); } - FnKind::Closure(binder, decl, body) => { + FnKind::Closure(binder, coroutine_kind, decl, body) => { + coroutine_kind.as_mut().map(|ck| vis.visit_coroutine_kind(ck)); vis.visit_closure_binder(binder); vis.visit_fn_decl(decl); vis.visit_expr(body); @@ -2146,8 +2158,8 @@ pub mod mut_visit { &mut self, id: NodeId, span: Span, - _vis: &mut Visibility, - _ident: &mut Ident, + vis: &mut Visibility, + ident: &mut Ident, visitor: &mut V, ) { match self { @@ -2162,7 +2174,11 @@ pub mod mut_visit { } ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { visit_defaultness(visitor, defaultness); - visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); + visitor.visit_fn( + FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body), + span, + id, + ); } ItemKind::Mod(safety, mod_kind) => { visitor.visit_safety(safety); @@ -2313,7 +2329,7 @@ pub mod mut_visit { pub fn walk_flat_map_assoc_item( visitor: &mut impl MutVisitor, mut item: P, - _ctxt: AssocCtxt, + ctxt: AssocCtxt, ) -> SmallVec<[P; 1]> { let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); visitor.visit_id(id); @@ -2326,7 +2342,11 @@ pub mod mut_visit { } AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { visit_defaultness(visitor, defaultness); - visitor.visit_fn(FnKind::Fn(sig, generics, body), *span, *id); + visitor.visit_fn( + FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body), + *span, + *id, + ); } AssocItemKind::Type(box TyAlias { defaultness, @@ -2386,8 +2406,8 @@ pub mod mut_visit { &mut self, id: NodeId, span: Span, - _vis: &mut Visibility, - _ident: &mut Ident, + vis: &mut Visibility, + ident: &mut Ident, visitor: &mut V, ) { match self { @@ -2397,7 +2417,11 @@ pub mod mut_visit { } ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { visit_defaultness(visitor, defaultness); - visitor.visit_fn(FnKind::Fn(sig, generics, body), span, id); + visitor.visit_fn( + FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body), + span, + id, + ); } ForeignItemKind::TyAlias(box TyAlias { defaultness, @@ -2506,11 +2530,8 @@ pub mod mut_visit { fn_arg_span, }) => { visit_constness(vis, constness); - coroutine_kind - .as_mut() - .map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); vis.visit_capture_by(capture_clause); - vis.visit_fn(FnKind::Closure(binder, fn_decl, body), *span, *id); + vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id); vis.visit_span(fn_decl_span); vis.visit_span(fn_arg_span); } @@ -2754,13 +2775,4 @@ pub mod mut_visit { 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()`. - Fn(&'a mut FnSig, &'a mut Generics, &'a mut Option>), - - /// E.g., `|x, y| body`. - Closure(&'a mut ClosureBinder, &'a mut P, &'a mut P), - } } diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 73aa2a870ad2a..255068ce8dcbe 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -992,14 +992,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.visit_vis(&item.vis); self.visit_ident(&item.ident); - let kind = FnKind::Fn( - FnCtxt::Free, - &item.ident, - sig, - &item.vis, - generics, - body.as_deref(), - ); + let kind = FnKind::Fn(FnCtxt::Free, &item.ident, sig, &item.vis, generics, body); self.visit_fn(kind, item.span, item.id); walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. @@ -1528,14 +1521,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { { self.visit_vis(&item.vis); self.visit_ident(&item.ident); - let kind = FnKind::Fn( - FnCtxt::Assoc(ctxt), - &item.ident, - sig, - &item.vis, - generics, - body.as_deref(), - ); + let kind = + FnKind::Fn(FnCtxt::Assoc(ctxt), &item.ident, sig, &item.vis, generics, body); walk_list!(self, visit_attribute, &item.attrs); self.visit_fn(kind, item.span, item.id); } diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs index 6cd02f1e17c40..2992d6a7de07a 100644 --- a/src/tools/rustfmt/src/items.rs +++ b/src/tools/rustfmt/src/items.rs @@ -3434,21 +3434,14 @@ impl Rewrite for ast::ForeignItem { ref generics, ref body, } = **fn_kind; - if let Some(ref body) = body { + if body.is_some() { let mut visitor = FmtVisitor::from_context(context); visitor.block_indent = shape.indent; visitor.last_pos = self.span.lo(); let inner_attrs = inner_attributes(&self.attrs); let fn_ctxt = visit::FnCtxt::Foreign; visitor.visit_fn( - visit::FnKind::Fn( - fn_ctxt, - &self.ident, - sig, - &self.vis, - generics, - Some(body), - ), + visit::FnKind::Fn(fn_ctxt, &self.ident, sig, &self.vis, generics, body), &sig.decl, self.span, defaultness, diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 64e2a74f7460e..9b116b620b79d 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -540,21 +540,14 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ref generics, ref body, } = **fn_kind; - if let Some(ref body) = body { + if body.is_some() { let inner_attrs = inner_attributes(&item.attrs); let fn_ctxt = match sig.header.ext { ast::Extern::None => visit::FnCtxt::Free, _ => visit::FnCtxt::Foreign, }; self.visit_fn( - visit::FnKind::Fn( - fn_ctxt, - &item.ident, - sig, - &item.vis, - generics, - Some(body), - ), + visit::FnKind::Fn(fn_ctxt, &item.ident, sig, &item.vis, generics, body), &sig.decl, item.span, defaultness, @@ -648,11 +641,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { ref generics, ref body, } = **fn_kind; - if let Some(ref body) = body { + if body.is_some() { let inner_attrs = inner_attributes(&ai.attrs); let fn_ctxt = visit::FnCtxt::Assoc(assoc_ctxt); self.visit_fn( - visit::FnKind::Fn(fn_ctxt, &ai.ident, sig, &ai.vis, generics, Some(body)), + visit::FnKind::Fn(fn_ctxt, &ai.ident, sig, &ai.vis, generics, body), &sig.decl, ai.span, defaultness, From fd615f62ba3c9c6d64dcb01afc4c9ce441ad7e65 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 13:51:48 -0300 Subject: [PATCH 66/82] Unify {visit,walk}_coroutine_kind --- compiler/rustc_ast/src/visitors.rs | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 938fd0420cbf5..86c18cfb3775a 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -222,7 +222,6 @@ macro_rules! make_ast_visitor { // field access version will continue working and it would be easy to // forget to add handling for it. - make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} @@ -330,6 +329,7 @@ macro_rules! make_ast_visitor { make_visit!{Block; visit_block, walk_block} make_visit!{CaptureBy; visit_capture_by, walk_capture_by} make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} + make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{Crate; visit_crate, walk_crate} make_visit!{EnumDef; visit_enum_def, walk_enum_def} make_visit!{ExprField; visit_expr_field, walk_expr_field} @@ -531,6 +531,22 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_coroutine_kind<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + coroutine_kind: ref_t!(CoroutineKind) + ) -> result!(V) { + 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_v!(visit_id!(vis, closure_id)); + try_v!(visit_id!(vis, return_impl_trait_id)); + try_v!(visit_span!(vis, span)); + } + } + return_result!(V) + } + pub fn walk_crate<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, krate: ref_t!(Crate) @@ -2092,18 +2108,6 @@ pub mod mut_visit { } } - fn walk_coroutine_kind(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(vis: &mut T, kind: FnKind<'_>) { match kind { FnKind::Fn(_, _, FnSig { header, decl, span }, _, generics, body) => { From 9dbcb65b41a4039ad76314e3c84a1f28918f5959 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 13:52:34 -0300 Subject: [PATCH 67/82] Unify {visit,walk}_fn --- compiler/rustc_ast/src/visitors.rs | 80 ++++++++++++------------------ 1 file changed, 33 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 86c18cfb3775a..7d757579b61f9 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -173,6 +173,12 @@ macro_rules! make_ast_visitor { } } + macro_rules! FnKind { + () => { + macro_if!{$($lt)? { FnKind<$($lt)?> } else { FnKind<'_> }} + }; + } + /// Each method of the traits `Visitor` and `MutVisitor` trait is a hook /// to be potentially overridden. Each method's default implementation /// recursively visits the substructure of the input via the corresponding @@ -246,11 +252,6 @@ macro_rules! make_ast_visitor { walk_flat_map_assoc_item(self, i, ctxt) } - /// `Span` and `NodeId` are mutated at the caller site. - fn visit_fn(&mut self, fk: FnKind<'_>, _: Span, _: NodeId) { - walk_fn(self, fk) - } - fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { walk_flat_map_stmt(self, s) } @@ -312,9 +313,6 @@ macro_rules! make_ast_visitor { fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { Self::Result::output() } - fn visit_fn(&mut self, fk: FnKind<'ast>, _: Span, _: NodeId) -> Self::Result { - walk_fn(self, fk) - } fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { Self::Result::output() } @@ -378,6 +376,10 @@ macro_rules! make_ast_visitor { make_visit!{ForeignItem; visit_foreign_item, walk_item} make_visit!{Item; visit_item, walk_item} + fn visit_fn(&mut self, fn_kind: FnKind!(), _span: Span, _id: NodeId) -> result!() { + walk_fn(self, fn_kind) + } + fn visit_variant_discr(&mut self, discr: ref_t!(AnonConst)) -> result!() { self.visit_anon_const(discr) } @@ -1263,6 +1265,29 @@ macro_rules! make_ast_visitor { try_v!(visit_span!(visitor, span)); return_result!(V) } + + pub fn walk_fn<$($lt,)? V: $trait$(<$lt>)?>( + visitor: &mut V, + kind: FnKind!() + ) -> result!(V) { + match kind { + FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span }, _vis, generics, body) => { + // Identifier and visibility are visited as a part of the item. + try_v!(visitor.visit_fn_header(header)); + try_v!(visitor.visit_generics(generics)); + try_v!(visitor.visit_fn_decl(decl)); + visit_o!(body, |body| visitor.visit_block(body)); + try_v!(visit_span!(visitor, span)) + } + FnKind::Closure(binder, coroutine_kind, decl, body) => { + visit_o!(coroutine_kind, |ck| visitor.visit_coroutine_kind(ck)); + try_v!(visitor.visit_closure_binder(binder)); + try_v!(visitor.visit_fn_decl(decl)); + try_v!(visitor.visit_expr(body)); + } + } + return_result!(V) + } } } @@ -1527,24 +1552,6 @@ pub mod visit { } } - pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) -> V::Result { - match kind { - FnKind::Fn(_ctxt, _ident, FnSig { header, decl, span: _ }, _vis, generics, body) => { - // Identifier and visibility are visited as a part of the item. - try_visit!(visitor.visit_fn_header(header)); - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_fn_decl(decl)); - visit_opt!(visitor, visit_block, body); - } - FnKind::Closure(binder, _coroutine_kind, decl, body) => { - try_visit!(visitor.visit_closure_binder(binder)); - try_visit!(visitor.visit_fn_decl(decl)); - try_visit!(visitor.visit_expr(body)); - } - } - V::Result::output() - } - pub fn walk_assoc_item<'a, V: Visitor<'a>>( visitor: &mut V, item: &'a AssocItem, @@ -2108,27 +2115,6 @@ pub mod mut_visit { } } - fn walk_fn(vis: &mut T, kind: FnKind<'_>) { - match kind { - FnKind::Fn(_, _, FnSig { header, decl, span }, _, generics, body) => { - // Identifier and visibility are visited as a part of the item. - vis.visit_fn_header(header); - vis.visit_generics(generics); - vis.visit_fn_decl(decl); - if let Some(body) = body { - vis.visit_block(body); - } - vis.visit_span(span); - } - FnKind::Closure(binder, coroutine_kind, decl, body) => { - coroutine_kind.as_mut().map(|ck| vis.visit_coroutine_kind(ck)); - vis.visit_closure_binder(binder); - vis.visit_fn_decl(decl); - vis.visit_expr(body); - } - } - } - pub fn walk_flat_map_generic_param( vis: &mut T, mut param: GenericParam, From 0bae8064f61a224b70f0c136f6a59f8265d5fb0a Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Sun, 13 Oct 2024 10:02:52 -0300 Subject: [PATCH 68/82] Add {visit,walk}_constness --- compiler/rustc_ast/src/visitors.rs | 34 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 7d757579b61f9..a4db4ba92e5be 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -327,6 +327,7 @@ macro_rules! make_ast_visitor { make_visit!{Block; visit_block, walk_block} make_visit!{CaptureBy; visit_capture_by, walk_capture_by} make_visit!{ClosureBinder; visit_closure_binder, walk_closure_binder} + make_visit!{Const; visit_constness, walk_constness} make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{Crate; visit_crate, walk_crate} make_visit!{EnumDef; visit_enum_def, walk_enum_def} @@ -533,6 +534,19 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_constness<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + constness: ref_t!(Const) + ) -> result!(V) { + match constness { + Const::Yes(span) => { + try_v!(visit_span!(vis, span)); + } + Const::No => {} + } + return_result!(V) + } + pub fn walk_coroutine_kind<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, coroutine_kind: ref_t!(CoroutineKind) @@ -1454,7 +1468,7 @@ pub mod visit { defaultness: _, safety, generics, - constness: _, + constness, polarity: _, of_trait, self_ty, @@ -1462,6 +1476,7 @@ pub mod visit { }) => { try_visit!(visitor.visit_safety(safety)); try_visit!(visitor.visit_generics(generics)); + try_visit!(visitor.visit_constness(constness)); visit_opt!(visitor, visit_trait_ref, of_trait); try_visit!(visitor.visit_ty(self_ty)); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); @@ -1713,13 +1728,14 @@ pub mod visit { binder, capture_clause, coroutine_kind, - constness: _, + constness, movability: _, fn_decl, body, fn_decl_span: _, fn_arg_span: _, }) => { + try_visit!(visitor.visit_constness(constness)); try_visit!(visitor.visit_capture_by(capture_clause)); try_visit!(visitor.visit_fn( FnKind::Closure(binder, coroutine_kind, fn_decl, body), @@ -2107,14 +2123,6 @@ pub mod mut_visit { } } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. - fn visit_constness(vis: &mut T, constness: &mut Const) { - match constness { - Const::Yes(span) => vis.visit_span(span), - Const::No => {} - } - } - pub fn walk_flat_map_generic_param( vis: &mut T, mut param: GenericParam, @@ -2222,7 +2230,7 @@ pub mod mut_visit { visit_defaultness(visitor, defaultness); visitor.visit_safety(safety); visitor.visit_generics(generics); - visit_constness(visitor, constness); + visitor.visit_constness(constness); visit_polarity(visitor, polarity); visit_opt(of_trait, |trait_ref| visitor.visit_trait_ref(trait_ref)); visitor.visit_ty(self_ty); @@ -2293,7 +2301,7 @@ pub mod mut_visit { fn walk_fn_header(vis: &mut T, header: &mut FnHeader) { let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; - visit_constness(vis, constness); + vis.visit_constness(constness); coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); vis.visit_safety(safety); } @@ -2519,7 +2527,7 @@ pub mod mut_visit { fn_decl_span, fn_arg_span, }) => { - visit_constness(vis, constness); + vis.visit_constness(constness); vis.visit_capture_by(capture_clause); vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id); vis.visit_span(fn_decl_span); From 04239d4355a246c755f8351e2812813b53716af0 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:05:57 -0300 Subject: [PATCH 69/82] Unify {visit,walk}_fn_header --- compiler/rustc_ast/src/visitors.rs | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index a4db4ba92e5be..68d7d286cb097 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -228,7 +228,6 @@ macro_rules! make_ast_visitor { // field access version will continue working and it would be easy to // forget to add handling for it. - make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} @@ -313,9 +312,6 @@ macro_rules! make_ast_visitor { fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { Self::Result::output() } - fn visit_fn_header(&mut self, _header: &'ast FnHeader) -> Self::Result { - Self::Result::output() - } }} make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} @@ -334,6 +330,7 @@ macro_rules! make_ast_visitor { make_visit!{ExprField; visit_expr_field, walk_expr_field} make_visit!{FieldDef; visit_field_def, walk_field_def} make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} + make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} make_visit!{ForeignMod; visit_foreign_mod, walk_foreign_mod} make_visit!{FormatArgs; visit_format_args, walk_format_args} @@ -623,6 +620,17 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_fn_header<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + header: ref_t!(FnHeader) + ) -> result!(V) { + let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; + try_v!(vis.visit_constness(constness)); + visit_o!(coroutine_kind, |ck| vis.visit_coroutine_kind(ck)); + try_v!(vis.visit_safety(safety)); + return_result!(V) + } + pub fn walk_fn_ret_ty<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, ret_ty: ref_t!(FnRetTy) @@ -2299,13 +2307,6 @@ pub mod mut_visit { visit_opt(expr, |expr| visitor.visit_expr(expr)); } - fn walk_fn_header(vis: &mut T, header: &mut FnHeader) { - let FnHeader { safety, coroutine_kind, constness, ext: _ } = header; - vis.visit_constness(constness); - coroutine_kind.as_mut().map(|coroutine_kind| vis.visit_coroutine_kind(coroutine_kind)); - vis.visit_safety(safety); - } - /// Mutates one item, returning the item again. pub fn walk_flat_map_item( vis: &mut impl MutVisitor, From 2618c86c1bd5675d13ee75ee612564dd9fb9ef24 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:21:37 -0300 Subject: [PATCH 70/82] Add {visit,walk}_impl_polarity --- compiler/rustc_ast/src/visitors.rs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 68d7d286cb097..94f19951a8ce8 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -340,6 +340,7 @@ macro_rules! make_ast_visitor { make_visit!{GenericParam; visit_generic_param, walk_generic_param} make_visit!{Generics; visit_generics, walk_generics} make_visit!{Ident; visit_ident, walk_ident} + make_visit!{ImplPolarity; visit_impl_polarity, walk_impl_polarity} make_visit!{InlineAsm; visit_inline_asm, walk_inline_asm} make_visit!{InlineAsmSym; visit_inline_asm_sym, walk_inline_asm_sym} make_visit!{Label; visit_label, walk_label} @@ -769,6 +770,19 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_impl_polarity<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + polarity: ref_t!(ImplPolarity) + ) -> result!(V) { + match polarity { + ImplPolarity::Positive => {} + ImplPolarity::Negative(span) => { + try_v!(visit_span!(vis, span)); + } + } + return_result!(V) + } + pub fn walk_inline_asm<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, asm: ref_t!(InlineAsm) @@ -1477,7 +1491,7 @@ pub mod visit { safety, generics, constness, - polarity: _, + polarity, of_trait, self_ty, items, @@ -1485,6 +1499,7 @@ pub mod visit { try_visit!(visitor.visit_safety(safety)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_constness(constness)); + try_visit!(visitor.visit_impl_polarity(polarity)); visit_opt!(visitor, visit_trait_ref, of_trait); try_visit!(visitor.visit_ty(self_ty)); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); @@ -2123,14 +2138,6 @@ pub mod mut_visit { } } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. - fn visit_polarity(vis: &mut T, polarity: &mut ImplPolarity) { - match polarity { - ImplPolarity::Positive => {} - ImplPolarity::Negative(span) => vis.visit_span(span), - } - } - pub fn walk_flat_map_generic_param( vis: &mut T, mut param: GenericParam, @@ -2239,7 +2246,7 @@ pub mod mut_visit { visitor.visit_safety(safety); visitor.visit_generics(generics); visitor.visit_constness(constness); - visit_polarity(visitor, polarity); + visitor.visit_impl_polarity(polarity); visit_opt(of_trait, |trait_ref| visitor.visit_trait_ref(trait_ref)); visitor.visit_ty(self_ty); items.flat_map_in_place(|item| { From a8392b1ef13002fdd21b88163854140c78d05a4d Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:28:33 -0300 Subject: [PATCH 71/82] Add {visit,walk}_defaultness --- compiler/rustc_ast/src/visitors.rs | 65 ++++++++++++++++++------------ 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 94f19951a8ce8..83030f42750f6 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -326,6 +326,7 @@ macro_rules! make_ast_visitor { make_visit!{Const; visit_constness, walk_constness} make_visit!{CoroutineKind; visit_coroutine_kind, walk_coroutine_kind} make_visit!{Crate; visit_crate, walk_crate} + make_visit!{Defaultness; visit_defaultness, walk_defaultness} make_visit!{EnumDef; visit_enum_def, walk_enum_def} make_visit!{ExprField; visit_expr_field, walk_expr_field} make_visit!{FieldDef; visit_field_def, walk_field_def} @@ -575,6 +576,19 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_defaultness<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + defaultness: ref_t!(Defaultness) + ) -> result!(V) { + match defaultness { + Defaultness::Default(span) => { + try_v!(visit_span!(vis, span)) + } + Defaultness::Final => {} + } + return_result!(V) + } + pub fn walk_enum_def<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, enum_def: ref_t!(EnumDef) @@ -1448,12 +1462,14 @@ pub mod visit { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } - ItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { + ItemKind::Const(box ConstItem { defaultness, generics, ty, expr }) => { + try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } - ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + try_visit!(visitor.visit_defaultness(defaultness)); let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body); try_visit!(visitor.visit_fn(kind, span, id)); } @@ -1474,9 +1490,10 @@ pub mod visit { generics, bounds, ty, - defaultness: _, + defaultness, where_clauses, }) => { + try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); visit_opt!(visitor, visit_ty, ty); @@ -1487,7 +1504,7 @@ pub mod visit { try_visit!(visitor.visit_enum_def(enum_definition)); } ItemKind::Impl(box Impl { - defaultness: _, + defaultness, safety, generics, constness, @@ -1496,6 +1513,7 @@ pub mod visit { self_ty, items, }) => { + try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_safety(safety)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_constness(constness)); @@ -1566,7 +1584,8 @@ pub mod visit { try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } - ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + try_visit!(visitor.visit_defaultness(defaultness)); let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body); try_visit!(visitor.visit_fn(kind, span, id)); } @@ -1574,9 +1593,10 @@ pub mod visit { generics, bounds, ty, - defaultness: _, + defaultness, where_clauses, }) => { + try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); visit_opt!(visitor, visit_ty, ty); @@ -1600,12 +1620,14 @@ pub mod visit { try_visit!(visitor.visit_vis(vis)); try_visit!(visitor.visit_ident(ident)); match kind { - AssocItemKind::Const(box ConstItem { defaultness: _, generics, ty, expr }) => { + AssocItemKind::Const(box ConstItem { defaultness, generics, ty, expr }) => { + try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_ty(ty)); visit_opt!(visitor, visit_expr, expr); } - AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { + AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + try_visit!(visitor.visit_defaultness(defaultness)); let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body); try_visit!(visitor.visit_fn(kind, *span, *id)); } @@ -1613,9 +1635,10 @@ pub mod visit { generics, bounds, ty, - defaultness: _, + defaultness, where_clauses, }) => { + try_visit!(visitor.visit_defaultness(defaultness)); try_visit!(visitor.visit_generics(generics)); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); visit_opt!(visitor, visit_ty, ty); @@ -2130,14 +2153,6 @@ pub mod mut_visit { } } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. - fn visit_defaultness(vis: &mut T, defaultness: &mut Defaultness) { - match defaultness { - Defaultness::Default(span) => vis.visit_span(span), - Defaultness::Final => {} - } - } - pub fn walk_flat_map_generic_param( vis: &mut T, mut param: GenericParam, @@ -2186,7 +2201,7 @@ pub mod mut_visit { visit_const_item(item, visitor); } ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_fn( FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body), span, @@ -2217,7 +2232,7 @@ pub mod mut_visit { bounds, ty, }) => { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_generics(generics); visit_bounds(visitor, bounds, BoundKind::Bound); visit_opt(ty, |ty| visitor.visit_ty(ty)); @@ -2242,7 +2257,7 @@ pub mod mut_visit { self_ty, items, }) => { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_safety(safety); visitor.visit_generics(generics); visitor.visit_constness(constness); @@ -2308,7 +2323,7 @@ pub mod mut_visit { ConstItem { defaultness, generics, ty, expr }: &mut ConstItem, visitor: &mut T, ) { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_generics(generics); visitor.visit_ty(ty); visit_opt(expr, |expr| visitor.visit_expr(expr)); @@ -2347,7 +2362,7 @@ pub mod mut_visit { visit_const_item(item, visitor); } AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_fn( FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body), *span, @@ -2361,7 +2376,7 @@ pub mod mut_visit { bounds, ty, }) => { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_generics(generics); visit_bounds(visitor, bounds, BoundKind::Bound); visit_opt(ty, |ty| visitor.visit_ty(ty)); @@ -2422,7 +2437,7 @@ pub mod mut_visit { visit_opt(expr, |expr| visitor.visit_expr(expr)); } ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_fn( FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body), span, @@ -2436,7 +2451,7 @@ pub mod mut_visit { bounds, ty, }) => { - visit_defaultness(visitor, defaultness); + visitor.visit_defaultness(defaultness); visitor.visit_generics(generics); visit_bounds(visitor, bounds, BoundKind::Bound); visit_opt(ty, |ty| visitor.visit_ty(ty)); From 201db75cacc743a46536c179bf813aa39c720221 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:30:42 -0300 Subject: [PATCH 72/82] Unify impl WalkItemKind for ItemKind --- compiler/rustc_ast/src/visitors.rs | 400 ++++++++++------------------- 1 file changed, 138 insertions(+), 262 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 83030f42750f6..4c862ce665792 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -1301,6 +1301,144 @@ macro_rules! make_ast_visitor { ) -> result!(V); } + impl WalkItemKind for ItemKind { + fn walk<$($lt,)? V: $trait$(<$lt>)?>( + &$($lt)? $($mut)? self, + id: NodeId, + span: Span, + vis: ref_t!(Visibility), + ident: ref_t!(Ident), + visitor: &mut V, + ) -> result!(V) { + match self { + ItemKind::ExternCrate(_orig_name) => {} + ItemKind::Use(use_tree) => { + try_v!(visitor.visit_use_tree(use_tree, id, false)); + } + ItemKind::Static(box StaticItem { safety, mutability: _, ty, expr }) => { + try_v!(visitor.visit_safety(safety)); + try_v!(visitor.visit_ty(ty)); + visit_o!(expr, |expr| visitor.visit_expr(expr)); + } + ItemKind::Const(box ConstItem { defaultness, generics, ty, expr }) => { + try_v!(visitor.visit_defaultness(defaultness)); + try_v!(visitor.visit_generics(generics)); + try_v!(visitor.visit_ty(ty)); + visit_o!(expr, |expr| visitor.visit_expr(expr)); + } + ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + try_v!(visitor.visit_defaultness(defaultness)); + let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body); + try_v!(visitor.visit_fn(kind, span, id)); + } + ItemKind::Mod(safety, mod_kind) => { + try_v!(visitor.visit_safety(safety)); + match mod_kind { + ModKind::Loaded( + items, + _inline, + ModSpans { inner_span, inject_use_span }, + ) => { + visit_list!(visitor, visit_item, flat_map_item, items); + try_v!(visit_span!(visitor, inner_span)); + try_v!(visit_span!(visitor, inject_use_span)); + } + ModKind::Unloaded => {} + } + } + ItemKind::ForeignMod(foreign_mod) => { + try_v!(visitor.visit_foreign_mod(foreign_mod)); + } + ItemKind::GlobalAsm(asm) => { + try_v!(visitor.visit_inline_asm(asm)) + } + ItemKind::TyAlias(box TyAlias { + defaultness, + generics, + bounds, + ty, + where_clauses, + }) => { + try_v!(visitor.visit_defaultness(defaultness)); + try_v!(visitor.visit_generics(generics)); + visit_list!(visitor, visit_param_bound, bounds; BoundKind::Bound); + visit_o!(ty, |ty| visitor.visit_ty(ty)); + try_v!(visitor.visit_ty_alias_where_clauses(where_clauses)); + } + ItemKind::Enum(enum_definition, generics) => { + try_v!(visitor.visit_generics(generics)); + try_v!(visitor.visit_enum_def(enum_definition)); + } + ItemKind::Struct(struct_definition, generics) + | ItemKind::Union(struct_definition, generics) => { + try_v!(visitor.visit_generics(generics)); + try_v!(visitor.visit_variant_data(struct_definition)); + } + ItemKind::Impl(box Impl { + defaultness, + safety, + generics, + constness, + polarity, + of_trait, + self_ty, + items, + }) => { + try_v!(visitor.visit_defaultness(defaultness)); + try_v!(visitor.visit_safety(safety)); + try_v!(visitor.visit_generics(generics)); + try_v!(visitor.visit_constness(constness)); + try_v!(visitor.visit_impl_polarity(polarity)); + visit_o!(of_trait, |trait_ref| visitor.visit_trait_ref(trait_ref)); + try_v!(visitor.visit_ty(self_ty)); + visit_list!(visitor, visit_assoc_item, flat_map_assoc_item, items; AssocCtxt::Impl); + } + ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { + try_v!(visitor.visit_safety(safety)); + try_v!(visitor.visit_generics(generics)); + visit_list!(visitor, visit_param_bound, bounds; BoundKind::Bound); + visit_list!(visitor, visit_assoc_item, flat_map_assoc_item, items; AssocCtxt::Trait); + } + ItemKind::TraitAlias(generics, bounds) => { + try_v!(visitor.visit_generics(generics)); + visit_list!(visitor, visit_param_bound, bounds; BoundKind::Bound); + } + ItemKind::MacCall(mac) => { + try_v!(visitor.visit_mac_call(mac)) + } + ItemKind::MacroDef(ts) => { + try_v!(visitor.visit_macro_def(ts, id)); + } + ItemKind::Delegation(box Delegation { + id, + qself, + path, + rename, + body, + from_glob: _, + }) => { + try_v!(visit_id!(visitor, id)); + try_v!(visitor.visit_qself(qself)); + try_v!(visitor.visit_path(path, *id)); + visit_o!(rename, |rename| visitor.visit_ident(rename)); + visit_o!(body, |body| visitor.visit_block(body)); + } + ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { + try_v!(visitor.visit_qself(qself)); + try_v!(visitor.visit_path(prefix, id)); + if let Some(suffixes) = suffixes { + for (ident, rename) in suffixes { + try_v!(visitor.visit_ident(ident)); + visit_o!(rename, |rename| visitor.visit_ident(rename)); + } + } + visit_o!(body, |body| visitor.visit_block(body)); + } + } + return_result!(V) + } + } + pub fn walk_item<$($lt,)? V: $trait$(<$lt>)?>( visitor: &mut V, item: ref_t!(Item), @@ -1446,130 +1584,6 @@ pub mod visit { make_ast_visitor!(Visitor<'ast>); - impl WalkItemKind for ItemKind { - fn walk<'a, V: Visitor<'a>>( - &'a self, - id: NodeId, - span: Span, - vis: &'a Visibility, - ident: &'a Ident, - visitor: &mut V, - ) -> V::Result { - match self { - ItemKind::ExternCrate(_rename) => {} - ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)), - ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ItemKind::Const(box ConstItem { defaultness, generics, ty, expr }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - let kind = FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body); - try_visit!(visitor.visit_fn(kind, span, id)); - } - ItemKind::Mod(safety, mod_kind) => { - try_visit!(visitor.visit_safety(safety)); - match mod_kind { - ModKind::Loaded(items, _inline, _inner_span) => { - walk_list!(visitor, visit_item, items); - } - ModKind::Unloaded => {} - } - } - ItemKind::ForeignMod(foreign_mod) => { - try_visit!(visitor.visit_foreign_mod(foreign_mod)); - } - ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), - ItemKind::TyAlias(box TyAlias { - generics, - bounds, - ty, - defaultness, - where_clauses, - }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); - } - ItemKind::Enum(enum_definition, generics) => { - 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_defaultness(defaultness)); - try_visit!(visitor.visit_safety(safety)); - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_constness(constness)); - try_visit!(visitor.visit_impl_polarity(polarity)); - visit_opt!(visitor, visit_trait_ref, of_trait); - try_visit!(visitor.visit_ty(self_ty)); - walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); - } - ItemKind::Struct(struct_definition, generics) - | ItemKind::Union(struct_definition, generics) => { - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_variant_data(struct_definition)); - } - ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { - try_visit!(visitor.visit_safety(safety)); - 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(generics, bounds) => { - 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(ts) => try_visit!(visitor.visit_macro_def(ts, id)), - ItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_path(path, *id)); - 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() - } - } - impl WalkItemKind for ForeignItemKind { fn walk<'a, V: Visitor<'a>>( &'a self, @@ -2181,144 +2195,6 @@ pub mod mut_visit { item.kind.walk(item.id, item.span, &mut item.vis, &mut item.ident, vis) } - impl WalkItemKind for ItemKind { - fn walk( - &mut self, - id: NodeId, - span: Span, - vis: &mut Visibility, - ident: &mut Ident, - visitor: &mut V, - ) { - match self { - ItemKind::ExternCrate(_orig_name) => {} - ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, id, false), - ItemKind::Static(box StaticItem { ty, safety: _, mutability: _, expr }) => { - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); - } - ItemKind::Const(item) => { - visit_const_item(item, visitor); - } - ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visitor.visit_defaultness(defaultness); - visitor.visit_fn( - FnKind::Fn(FnCtxt::Free, ident, sig, vis, generics, body), - span, - id, - ); - } - ItemKind::Mod(safety, mod_kind) => { - visitor.visit_safety(safety); - match mod_kind { - ModKind::Loaded( - items, - _inline, - ModSpans { inner_span, inject_use_span }, - ) => { - items.flat_map_in_place(|item| visitor.flat_map_item(item)); - visitor.visit_span(inner_span); - visitor.visit_span(inject_use_span); - } - ModKind::Unloaded => {} - } - } - ItemKind::ForeignMod(nm) => visitor.visit_foreign_mod(nm), - ItemKind::GlobalAsm(asm) => visitor.visit_inline_asm(asm), - ItemKind::TyAlias(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - }) => { - visitor.visit_defaultness(defaultness); - visitor.visit_generics(generics); - visit_bounds(visitor, bounds, BoundKind::Bound); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - visitor.visit_ty_alias_where_clauses(where_clauses); - } - ItemKind::Enum(enum_def, generics) => { - visitor.visit_generics(generics); - visitor.visit_enum_def(enum_def); - } - ItemKind::Struct(variant_data, generics) - | ItemKind::Union(variant_data, generics) => { - visitor.visit_generics(generics); - visitor.visit_variant_data(variant_data); - } - ItemKind::Impl(box Impl { - defaultness, - safety, - generics, - constness, - polarity, - of_trait, - self_ty, - items, - }) => { - visitor.visit_defaultness(defaultness); - visitor.visit_safety(safety); - visitor.visit_generics(generics); - visitor.visit_constness(constness); - visitor.visit_impl_polarity(polarity); - visit_opt(of_trait, |trait_ref| visitor.visit_trait_ref(trait_ref)); - visitor.visit_ty(self_ty); - items.flat_map_in_place(|item| { - visitor.flat_map_assoc_item(item, AssocCtxt::Impl) - }); - } - ItemKind::Trait(box Trait { safety, is_auto: _, generics, bounds, items }) => { - visitor.visit_safety(safety); - visitor.visit_generics(generics); - visit_bounds(visitor, bounds, BoundKind::Bound); - items.flat_map_in_place(|item| { - visitor.flat_map_assoc_item(item, AssocCtxt::Trait) - }); - } - ItemKind::TraitAlias(generics, bounds) => { - visitor.visit_generics(generics); - visit_bounds(visitor, bounds, BoundKind::Bound); - } - ItemKind::MacCall(m) => visitor.visit_mac_call(m), - ItemKind::MacroDef(def) => visitor.visit_macro_def(def, id), - ItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - visitor.visit_id(id); - visitor.visit_qself(qself); - visitor.visit_path(path, *id); - if let Some(rename) = rename { - visitor.visit_ident(rename); - } - if let Some(body) = body { - visitor.visit_block(body); - } - } - ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => { - visitor.visit_qself(qself); - 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); - } - } - } - if let Some(body) = body { - visitor.visit_block(body); - } - } - } - } - } - fn visit_const_item( ConstItem { defaultness, generics, ty, expr }: &mut ConstItem, visitor: &mut T, From b31b31bae72a597ecd26ad6cf830fab261f452c3 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:32:11 -0300 Subject: [PATCH 73/82] Unify impl WalkItemKind for ForeignItemKind --- compiler/rustc_ast/src/visitors.rs | 122 ++++++++++------------------- 1 file changed, 42 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 4c862ce665792..64f3a9a88dbbd 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -1439,6 +1439,48 @@ macro_rules! make_ast_visitor { } } + impl WalkItemKind for ForeignItemKind { + fn walk<$($lt,)? V: $trait$(<$lt>)?>( + &$($lt)? $($mut)? self, + id: NodeId, + span: Span, + vis: ref_t!(Visibility), + ident: ref_t!(Ident), + visitor: &mut V, + ) -> result!(V) { + match self { + ForeignItemKind::Static(box StaticItem { safety, ty, mutability: _, expr }) => { + try_v!(visitor.visit_safety(safety)); + try_v!(visitor.visit_ty(ty)); + visit_o!(expr, |expr| visitor.visit_expr(expr)); + } + ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + try_v!(visitor.visit_defaultness(defaultness)); + let kind = + FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body); + visitor.visit_fn(kind, span, id); + } + ForeignItemKind::TyAlias(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + }) => { + try_v!(visitor.visit_defaultness(defaultness)); + try_v!(visitor.visit_generics(generics)); + visit_list!(visitor, visit_param_bound, bounds; BoundKind::Bound); + visit_o!(ty, |ty| visitor.visit_ty(ty)); + try_v!(visitor.visit_ty_alias_where_clauses(where_clauses)); + } + ForeignItemKind::MacCall(mac) => { + try_v!(visitor.visit_mac_call(mac)); + } + } + return_result!(V) + } + } + pub fn walk_item<$($lt,)? V: $trait$(<$lt>)?>( visitor: &mut V, item: ref_t!(Item), @@ -1584,46 +1626,6 @@ pub mod visit { make_ast_visitor!(Visitor<'ast>); - impl WalkItemKind for ForeignItemKind { - fn walk<'a, V: Visitor<'a>>( - &'a self, - id: NodeId, - span: Span, - vis: &'a Visibility, - ident: &'a Ident, - visitor: &mut V, - ) -> V::Result { - match self { - ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body); - try_visit!(visitor.visit_fn(kind, span, id)); - } - ForeignItemKind::TyAlias(box TyAlias { - generics, - bounds, - ty, - defaultness, - where_clauses, - }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); - } - ForeignItemKind::MacCall(mac) => { - try_visit!(visitor.visit_mac_call(mac)); - } - } - V::Result::output() - } - } - pub fn walk_assoc_item<'a, V: Visitor<'a>>( visitor: &mut V, item: &'a AssocItem, @@ -2298,46 +2300,6 @@ pub mod mut_visit { smallvec![item] } - impl WalkItemKind for ForeignItemKind { - fn walk( - &mut self, - id: NodeId, - span: Span, - vis: &mut Visibility, - ident: &mut Ident, - visitor: &mut V, - ) { - match self { - ForeignItemKind::Static(box StaticItem { ty, mutability: _, expr, safety: _ }) => { - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); - } - ForeignItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visitor.visit_defaultness(defaultness); - visitor.visit_fn( - FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body), - span, - id, - ); - } - ForeignItemKind::TyAlias(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - }) => { - visitor.visit_defaultness(defaultness); - visitor.visit_generics(generics); - visit_bounds(visitor, bounds, BoundKind::Bound); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - visitor.visit_ty_alias_where_clauses(where_clauses); - } - ForeignItemKind::MacCall(mac) => visitor.visit_mac_call(mac), - } - } - } - pub fn walk_expr( vis: &mut T, Expr { kind, id, span, attrs, tokens }: &mut Expr, From 0e75ea0dbf06ae8f602452773af2f4b777fcdb8e Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:39:57 -0300 Subject: [PATCH 74/82] Unify {visit,walk}_assoc_item --- compiler/rustc_ast/src/visitors.rs | 233 ++++++++++------------------- 1 file changed, 80 insertions(+), 153 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 64f3a9a88dbbd..8966ec5a0c53d 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -301,7 +301,6 @@ macro_rules! make_ast_visitor { /// or `ControlFlow`. type Result: VisitorResult = (); - make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} make_visit!{Stmt; visit_stmt, walk_stmt} /// This method is a hack to workaround unstable of `stmt_expr_attributes`. @@ -372,9 +371,10 @@ macro_rules! make_ast_visitor { make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} - // Default implementations are generic over WalkItemKind - make_visit!{ForeignItem; visit_foreign_item, walk_item} + // Item variants make_visit!{Item; visit_item, walk_item} + make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} + make_visit!{ForeignItem; visit_foreign_item, walk_item} fn visit_fn(&mut self, fn_kind: FnKind!(), _span: Span, _id: NodeId) -> result!() { walk_fn(self, fn_kind) @@ -1496,6 +1496,81 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_assoc_item<$($lt,)? V: $trait$(<$lt>)?>( + visitor: &mut V, + item: ref_t!(Item), + ctxt: AssocCtxt + ) -> result!(V) { + let Item { attrs, id, span, vis, ident, kind, tokens } = item; + try_v!(visit_id!(visitor, id)); + visit_list!(visitor, visit_attribute, attrs); + try_v!(visitor.visit_vis(vis)); + try_v!(visitor.visit_ident(ident)); + match kind { + AssocItemKind::Const(box ConstItem { defaultness, generics, ty, expr }) => { + try_v!(visitor.visit_defaultness(defaultness)); + try_v!(visitor.visit_generics(generics)); + try_v!(visitor.visit_ty(ty)); + visit_o!(expr, |expr| visitor.visit_expr(expr)); + } + AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { + try_v!(visitor.visit_defaultness(defaultness)); + let kind = + FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body); + try_v!(visitor.visit_fn(kind, *span, *id)); + } + AssocItemKind::Type(box TyAlias { + defaultness, + generics, + where_clauses, + bounds, + ty, + }) => { + try_v!(visitor.visit_defaultness(defaultness)); + try_v!(visitor.visit_generics(generics)); + visit_list!(visitor, visit_param_bound, bounds; BoundKind::Bound); + visit_o!(ty, |ty| visitor.visit_ty(ty)); + try_v!(visitor.visit_ty_alias_where_clauses(where_clauses)); + } + AssocItemKind::MacCall(mac) => { + try_v!(visitor.visit_mac_call(mac)); + } + AssocItemKind::Delegation(box Delegation { + id, + qself, + path, + rename, + body, + from_glob: _, + }) => { + try_v!(visit_id!(visitor, id)); + try_v!(visitor.visit_qself(qself)); + try_v!(visitor.visit_path(path, *id)); + visit_o!(rename, |rename| visitor.visit_ident(rename)); + visit_o!(body, |body| visitor.visit_block(body)); + } + AssocItemKind::DelegationMac(box DelegationMac { + qself, + prefix, + suffixes, + body, + }) => { + try_v!(visitor.visit_qself(qself)); + try_v!(visitor.visit_path(prefix, *id)); + if let Some(suffixes) = suffixes { + for (ident, rename) in suffixes { + try_v!(visitor.visit_ident(ident)); + visit_o!(rename, |rename| visitor.visit_ident(rename)); + } + } + visit_o!(body, |body| visitor.visit_block(body)); + } + } + visit_lazy_tts!(visitor, tokens); + try_v!(visit_span!(visitor, span)); + return_result!(V) + } + pub fn walk_fn<$($lt,)? V: $trait$(<$lt>)?>( visitor: &mut V, kind: FnKind!() @@ -1626,73 +1701,6 @@ pub mod visit { make_ast_visitor!(Visitor<'ast>); - pub fn walk_assoc_item<'a, V: Visitor<'a>>( - visitor: &mut V, - item: &'a AssocItem, - ctxt: AssocCtxt, - ) -> V::Result { - let Item { id, span, ident, vis, attrs, kind, tokens: _ } = item; - walk_list!(visitor, visit_attribute, attrs); - try_visit!(visitor.visit_vis(vis)); - try_visit!(visitor.visit_ident(ident)); - match kind { - AssocItemKind::Const(box ConstItem { defaultness, generics, ty, expr }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - try_visit!(visitor.visit_generics(generics)); - try_visit!(visitor.visit_ty(ty)); - visit_opt!(visitor, visit_expr, expr); - } - AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body); - try_visit!(visitor.visit_fn(kind, *span, *id)); - } - AssocItemKind::Type(box TyAlias { - generics, - bounds, - ty, - defaultness, - where_clauses, - }) => { - try_visit!(visitor.visit_defaultness(defaultness)); - try_visit!(visitor.visit_generics(generics)); - walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); - visit_opt!(visitor, visit_ty, ty); - try_visit!(visitor.visit_ty_alias_where_clauses(where_clauses)); - } - AssocItemKind::MacCall(mac) => { - try_visit!(visitor.visit_mac_call(mac)); - } - AssocItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_path(path, *id)); - 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_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) -> V::Result { let Stmt { id: _, kind, span: _ } = statement; match kind { @@ -1960,11 +1968,6 @@ pub mod mut_visit { 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(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_delim_args(vis: &mut T, args: &mut DelimArgs) { let DelimArgs { dspan, delim: _, tokens } = args; @@ -2197,16 +2200,6 @@ pub mod mut_visit { item.kind.walk(item.id, item.span, &mut item.vis, &mut item.ident, vis) } - fn visit_const_item( - ConstItem { defaultness, generics, ty, expr }: &mut ConstItem, - visitor: &mut T, - ) { - visitor.visit_defaultness(defaultness); - visitor.visit_generics(generics); - visitor.visit_ty(ty); - visit_opt(expr, |expr| visitor.visit_expr(expr)); - } - /// Mutates one item, returning the item again. pub fn walk_flat_map_item( vis: &mut impl MutVisitor, @@ -2226,77 +2219,11 @@ pub mod mut_visit { /// Mutates one item, returning the item again. pub fn walk_flat_map_assoc_item( - visitor: &mut impl MutVisitor, + vis: &mut impl MutVisitor, mut item: P, ctxt: AssocCtxt, ) -> SmallVec<[P; 1]> { - let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); - visitor.visit_id(id); - visit_attrs(visitor, attrs); - visitor.visit_vis(vis); - visitor.visit_ident(ident); - match kind { - AssocItemKind::Const(item) => { - visit_const_item(item, visitor); - } - AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => { - visitor.visit_defaultness(defaultness); - visitor.visit_fn( - FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body), - *span, - *id, - ); - } - AssocItemKind::Type(box TyAlias { - defaultness, - generics, - where_clauses, - bounds, - ty, - }) => { - visitor.visit_defaultness(defaultness); - visitor.visit_generics(generics); - visit_bounds(visitor, bounds, BoundKind::Bound); - visit_opt(ty, |ty| visitor.visit_ty(ty)); - visitor.visit_ty_alias_where_clauses(where_clauses); - } - AssocItemKind::MacCall(mac) => visitor.visit_mac_call(mac), - AssocItemKind::Delegation(box Delegation { - id, - qself, - path, - rename, - body, - from_glob: _, - }) => { - visitor.visit_id(id); - visitor.visit_qself(qself); - visitor.visit_path(path, *id); - 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, *id); - 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); - } - } - } - visit_lazy_tts(visitor, tokens); - visitor.visit_span(span); + vis.visit_assoc_item(&mut item, ctxt); smallvec![item] } From d6a89c12a1878ba06d2232a359f4fd1b13015a00 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:48:58 -0300 Subject: [PATCH 75/82] Remove visit_expr_post --- compiler/rustc_ast/src/visitors.rs | 5 +---- compiler/rustc_lint/src/early.rs | 28 +++++++++++++--------------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 8966ec5a0c53d..c1dd7c6d1d226 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -308,9 +308,6 @@ macro_rules! make_ast_visitor { fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { self.visit_expr(ex) } - fn visit_expr_post(&mut self, _ex: &'ast Expr) -> Self::Result { - Self::Result::output() - } }} make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} @@ -1877,7 +1874,7 @@ pub mod visit { ExprKind::Dummy => {} } - visitor.visit_expr_post(expression) + V::Result::output() } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index a140d59210355..267b28c2affb6 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -121,6 +121,19 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> self.with_lint_attrs(e.id, &e.attrs, |cx| { lint_callback!(cx, check_expr, e); ast_visit::walk_expr(cx, e); + + // Explicitly check for lints associated with 'closure_id', since + // it does not have a corresponding AST node + match e.kind { + ast::ExprKind::Closure(box ast::Closure { + coroutine_kind: Some(coroutine_kind), + .. + }) => { + cx.check_id(coroutine_kind.closure_id()); + } + _ => {} + } + lint_callback!(cx, check_expr_post, e); }) } @@ -215,21 +228,6 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> }) } - fn visit_expr_post(&mut self, e: &'a ast::Expr) { - // Explicitly check for lints associated with 'closure_id', since - // it does not have a corresponding AST node - match e.kind { - ast::ExprKind::Closure(box ast::Closure { - coroutine_kind: Some(coroutine_kind), - .. - }) => { - self.check_id(coroutine_kind.closure_id()); - } - _ => {} - } - lint_callback!(self, check_expr_post, e); - } - fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) { lint_callback!(self, check_generic_arg, arg); ast_visit::walk_generic_arg(self, arg); From f097c351e6176d0a95b8a424cdaf506bfd9701e6 Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 14:54:17 -0300 Subject: [PATCH 76/82] Unify walk_expr --- compiler/rustc_ast/src/visitors.rs | 566 +++++++++++------------------ 1 file changed, 203 insertions(+), 363 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index c1dd7c6d1d226..7986035a2464d 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -1167,6 +1167,209 @@ macro_rules! make_ast_visitor { return_result!(V) } + pub fn walk_expr<$($lt,)? V: $trait$(<$lt>)?>( + vis: &mut V, + expr: ref_t!(Expr) + ) -> result!(V) { + let Expr { kind, id, span, attrs, tokens } = expr; + try_v!(visit_id!(vis, id)); + visit_list!(vis, visit_attribute, attrs); + match kind { + ExprKind::Array(exprs) + | ExprKind::Tup(exprs) => { + visit_list!(vis, visit_expr, filter_map_expr, exprs); + } + ExprKind::ConstBlock(anon_const) => { + try_v!(vis.visit_anon_const(anon_const)); + } + ExprKind::Repeat(expr, count) => { + try_v!(vis.visit_expr(expr)); + try_v!(vis.visit_anon_const(count)); + } + ExprKind::Call(f, args) => { + try_v!(vis.visit_expr(f)); + visit_list!(vis, visit_expr, filter_map_expr, args); + } + ExprKind::MethodCall(box MethodCall { + seg, + receiver, + args, + span, + }) => { + try_v!(vis.visit_method_receiver_expr(receiver)); + try_v!(vis.visit_path_segment(seg)); + visit_list!(vis, visit_expr, filter_map_expr, args); + try_v!(visit_span!(vis, span)); + } + ExprKind::Binary(_op, lhs, rhs) => { + try_v!(vis.visit_expr(lhs)); + try_v!(vis.visit_expr(rhs)); + } + ExprKind::Unary(_op, expr) => { + try_v!(vis.visit_expr(expr)); + } + ExprKind::Cast(expr, typ) + | ExprKind::Type(expr, typ) => { + try_v!(vis.visit_expr(expr)); + try_v!(vis.visit_ty(typ)); + } + ExprKind::AddrOf(_kind, _mutbl, expr) => { + try_v!(vis.visit_expr(expr)); + } + ExprKind::Let(pat, expr, span, _recovered) => { + try_v!(vis.visit_pat(pat)); + try_v!(vis.visit_expr(expr)); + try_v!(visit_span!(vis, span)); + } + ExprKind::If(cond, if_block, else_block) => { + try_v!(vis.visit_expr(cond)); + try_v!(vis.visit_block(if_block)); + visit_o!(else_block, |else_block| ensure_sufficient_stack(|| vis.visit_expr(else_block))); + } + ExprKind::While(cond, body, label) => { + visit_o!(label, |label| vis.visit_label(label)); + try_v!(vis.visit_expr(cond)); + try_v!(vis.visit_block(body)); + } + ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { + visit_o!(label, |label| vis.visit_label(label)); + try_v!(vis.visit_pat(pat)); + try_v!(vis.visit_expr(iter)); + try_v!(vis.visit_block(body)); + } + ExprKind::Loop(body, label, span) => { + visit_o!(label, |label| vis.visit_label(label)); + try_v!(vis.visit_block(body)); + try_v!(visit_span!(vis, span)); + } + ExprKind::Match(expr, arms, _kind) => { + try_v!(vis.visit_expr(expr)); + visit_list!(vis, visit_arm, flat_map_arm, arms); + } + ExprKind::Closure(box Closure { + binder, + capture_clause, + constness, + coroutine_kind, + movability: _, + fn_decl, + body, + fn_decl_span, + fn_arg_span, + }) => { + try_v!(vis.visit_constness(constness)); + try_v!(vis.visit_capture_by(capture_clause)); + try_v!(vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id)); + try_v!(visit_span!(vis, fn_decl_span)); + try_v!(visit_span!(vis, fn_arg_span)); + } + ExprKind::Block(block, label) => { + visit_o!(label, |label| vis.visit_label(label)); + try_v!(vis.visit_block(block)); + } + ExprKind::Gen(capture_by, body, _kind, decl_span) => { + try_v!(vis.visit_capture_by(capture_by)); + try_v!(vis.visit_block(body)); + try_v!(visit_span!(vis, decl_span)); + } + ExprKind::Await(expr, await_kw_span) => { + try_v!(vis.visit_expr(expr)); + try_v!(visit_span!(vis, await_kw_span)); + } + ExprKind::Assign(lhs, rhs, span) => { + try_v!(vis.visit_expr(lhs)); + try_v!(vis.visit_expr(rhs)); + try_v!(visit_span!(vis, span)); + } + ExprKind::AssignOp(_op, lhs, rhs) => { + try_v!(vis.visit_expr(lhs)); + try_v!(vis.visit_expr(rhs)); + } + ExprKind::Field(el, ident) => { + try_v!(vis.visit_expr(el)); + try_v!(vis.visit_ident(ident)); + } + ExprKind::Index(main_expr, index_expr, brackets_span) => { + try_v!(vis.visit_expr(main_expr)); + try_v!(vis.visit_expr(index_expr)); + try_v!(visit_span!(vis, brackets_span)); + } + ExprKind::Range(start, end, _lim) => { + visit_o!(start, |start| vis.visit_expr(start)); + visit_o!(end, |end| vis.visit_expr(end)); + } + ExprKind::Underscore => {} + ExprKind::Path(qself, path) => { + try_v!(vis.visit_qself(qself)); + try_v!(vis.visit_path(path, *id)); + } + ExprKind::Break(label, expr) => { + visit_o!(label, |label| vis.visit_label(label)); + visit_o!(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Continue(label) => { + visit_o!(label, |label| vis.visit_label(label)); + } + ExprKind::Ret(expr) + | ExprKind::Yeet(expr) + | ExprKind::Yield(expr) => { + visit_o!(expr, |expr| vis.visit_expr(expr)); + } + ExprKind::Become(expr) => { + try_v!(vis.visit_expr(expr)) + } + ExprKind::InlineAsm(asm) => { + try_v!(vis.visit_inline_asm(asm)) + } + ExprKind::FormatArgs(fmt) => { + try_v!(vis.visit_format_args(fmt)) + } + ExprKind::OffsetOf(container, fields) => { + try_v!(vis.visit_ty(container)); + let fields = macro_if!{$($mut)? { + fields.iter_mut() + } else { + fields.iter() + }}; + visit_list!(vis, visit_ident, fields); + } + ExprKind::MacCall(mac) => { + try_v!(vis.visit_mac_call(mac)) + } + ExprKind::Struct(se) => { + let StructExpr { qself, path, fields, rest } = &$($mut)? **se; + try_v!(vis.visit_qself(qself)); + try_v!(vis.visit_path(path, *id)); + visit_list!(vis, visit_expr_field, flat_map_expr_field, fields); + match rest { + StructRest::Base(expr) => { + try_v!(vis.visit_expr(expr)); + } + StructRest::Rest(span) => { + try_v!(visit_span!(vis, span)); + } + StructRest::None => {} + } + } + ExprKind::Paren(expr) => { + try_v!(vis.visit_expr(expr)); + } + ExprKind::Try(expr) => { + try_v!(vis.visit_expr(expr)); + } + ExprKind::TryBlock(expr) => { + try_v!(vis.visit_block(expr)); + } + ExprKind::Lit(_token) => {} + ExprKind::IncludedBytes(_bytes) => {} + ExprKind::Err(_guar) => {} + ExprKind::Dummy => {} + } + visit_lazy_tts!(vis, tokens); + try_v!(visit_span!(vis, span)); + return_result!(V) + } + pub fn walk_pat<$($lt,)? V: $trait$(<$lt>)?>( vis: &mut V, pattern: ref_t!(Pat) @@ -1713,169 +1916,6 @@ pub mod visit { } V::Result::output() } - - pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V::Result { - let Expr { id, kind, span, attrs, tokens: _ } = expression; - walk_list!(visitor, visit_attribute, attrs); - match kind { - ExprKind::Array(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::ConstBlock(anon_const) => try_visit!(visitor.visit_anon_const(anon_const)), - ExprKind::Repeat(element, count) => { - try_visit!(visitor.visit_expr(element)); - try_visit!(visitor.visit_anon_const(count)); - } - ExprKind::Struct(se) => { - let StructExpr { qself, path, fields, rest } = &**se; - try_visit!(visitor.visit_qself(qself)); - try_visit!(visitor.visit_path(path, *id)); - walk_list!(visitor, visit_expr_field, fields); - match rest { - StructRest::Base(expr) => try_visit!(visitor.visit_expr(expr)), - StructRest::Rest(_span) => {} - StructRest::None => {} - } - } - ExprKind::Tup(subexpressions) => { - walk_list!(visitor, visit_expr, subexpressions); - } - ExprKind::Call(callee_expression, arguments) => { - try_visit!(visitor.visit_expr(callee_expression)); - walk_list!(visitor, visit_expr, arguments); - } - ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => { - try_visit!(visitor.visit_expr(receiver)); - try_visit!(visitor.visit_path_segment(seg)); - walk_list!(visitor, visit_expr, args); - } - ExprKind::Binary(_op, left_expression, right_expression) => { - try_visit!(visitor.visit_expr(left_expression)); - try_visit!(visitor.visit_expr(right_expression)); - } - ExprKind::AddrOf(_kind, _mutbl, subexpression) => { - try_visit!(visitor.visit_expr(subexpression)); - } - ExprKind::Unary(_op, subexpression) => { - try_visit!(visitor.visit_expr(subexpression)); - } - ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => { - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ty(typ)); - } - ExprKind::Let(pat, expr, _span, _recovered) => { - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_expr(expr)); - } - ExprKind::If(head_expression, if_block, optional_else) => { - try_visit!(visitor.visit_expr(head_expression)); - try_visit!(visitor.visit_block(if_block)); - visit_opt!(visitor, visit_expr, optional_else); - } - ExprKind::While(subexpression, block, opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_block(block)); - } - ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { - visit_opt!(visitor, visit_label, label); - try_visit!(visitor.visit_pat(pat)); - try_visit!(visitor.visit_expr(iter)); - try_visit!(visitor.visit_block(body)); - } - ExprKind::Loop(block, opt_label, _span) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_block(block)); - } - ExprKind::Match(subexpression, arms, _kind) => { - try_visit!(visitor.visit_expr(subexpression)); - walk_list!(visitor, visit_arm, arms); - } - ExprKind::Closure(box Closure { - binder, - capture_clause, - coroutine_kind, - constness, - movability: _, - fn_decl, - body, - fn_decl_span: _, - fn_arg_span: _, - }) => { - try_visit!(visitor.visit_constness(constness)); - try_visit!(visitor.visit_capture_by(capture_clause)); - try_visit!(visitor.visit_fn( - FnKind::Closure(binder, coroutine_kind, fn_decl, body), - *span, - *id - )) - } - ExprKind::Block(block, opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - try_visit!(visitor.visit_block(block)); - } - ExprKind::Gen(_capt, body, _kind, _decl_span) => try_visit!(visitor.visit_block(body)), - ExprKind::Await(expr, _span) => try_visit!(visitor.visit_expr(expr)), - ExprKind::Assign(lhs, rhs, _span) => { - try_visit!(visitor.visit_expr(lhs)); - try_visit!(visitor.visit_expr(rhs)); - } - ExprKind::AssignOp(_op, left_expression, right_expression) => { - try_visit!(visitor.visit_expr(left_expression)); - try_visit!(visitor.visit_expr(right_expression)); - } - ExprKind::Field(subexpression, ident) => { - try_visit!(visitor.visit_expr(subexpression)); - try_visit!(visitor.visit_ident(ident)); - } - ExprKind::Index(main_expression, index_expression, _span) => { - try_visit!(visitor.visit_expr(main_expression)); - try_visit!(visitor.visit_expr(index_expression)); - } - ExprKind::Range(start, end, _limit) => { - visit_opt!(visitor, visit_expr, start); - visit_opt!(visitor, visit_expr, end); - } - ExprKind::Underscore => {} - ExprKind::Path(maybe_qself, path) => { - try_visit!(visitor.visit_qself(maybe_qself)); - try_visit!(visitor.visit_path(path, *id)); - } - ExprKind::Break(opt_label, opt_expr) => { - visit_opt!(visitor, visit_label, opt_label); - visit_opt!(visitor, visit_expr, opt_expr); - } - ExprKind::Continue(opt_label) => { - visit_opt!(visitor, visit_label, opt_label); - } - ExprKind::Ret(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Yeet(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Become(expr) => try_visit!(visitor.visit_expr(expr)), - ExprKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)), - ExprKind::Paren(subexpression) => try_visit!(visitor.visit_expr(subexpression)), - ExprKind::InlineAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), - ExprKind::FormatArgs(f) => try_visit!(visitor.visit_format_args(f)), - ExprKind::OffsetOf(container, fields) => { - try_visit!(visitor.visit_ty(container)); - walk_list!(visitor, visit_ident, fields.iter()); - } - ExprKind::Yield(optional_expression) => { - visit_opt!(visitor, visit_expr, optional_expression); - } - ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)), - ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)), - ExprKind::Lit(_token) => {} - ExprKind::IncludedBytes(_bytes) => {} - ExprKind::Err(_guar) => {} - ExprKind::Dummy => {} - } - - V::Result::output() - } } pub mod mut_visit { @@ -1936,17 +1976,6 @@ pub mod mut_visit { } } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. - #[inline] - fn visit_opt(opt: &mut Option, mut visit_elem: F) - where - F: FnMut(&mut T), - { - if let Some(elem) = opt { - visit_elem(elem); - } - } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_attrs(vis: &mut T, attrs: &mut AttrVec) { for attr in attrs.iter_mut() { @@ -1960,11 +1989,6 @@ pub mod mut_visit { 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(vis: &mut T, exprs: &mut ThinVec>) { - 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_delim_args(vis: &mut T, args: &mut DelimArgs) { let DelimArgs { dspan, delim: _, tokens } = args; @@ -2224,190 +2248,6 @@ pub mod mut_visit { smallvec![item] } - pub fn walk_expr( - vis: &mut T, - Expr { kind, id, span, attrs, tokens }: &mut Expr, - ) { - vis.visit_id(id); - visit_attrs(vis, attrs); - match kind { - ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs), - ExprKind::ConstBlock(anon_const) => { - vis.visit_anon_const(anon_const); - } - ExprKind::Repeat(expr, count) => { - vis.visit_expr(expr); - vis.visit_anon_const(count); - } - ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs), - ExprKind::Call(f, args) => { - vis.visit_expr(f); - visit_thin_exprs(vis, args); - } - ExprKind::MethodCall(box MethodCall { - seg: PathSegment { ident, id, args: seg_args }, - receiver, - args: call_args, - span, - }) => { - vis.visit_method_receiver_expr(receiver); - vis.visit_id(id); - vis.visit_ident(ident); - visit_opt(seg_args, |args| vis.visit_generic_args(args)); - visit_thin_exprs(vis, call_args); - vis.visit_span(span); - } - ExprKind::Binary(_binop, lhs, rhs) => { - vis.visit_expr(lhs); - vis.visit_expr(rhs); - } - ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs), - ExprKind::Cast(expr, ty) => { - vis.visit_expr(expr); - vis.visit_ty(ty); - } - ExprKind::Type(expr, ty) => { - vis.visit_expr(expr); - vis.visit_ty(ty); - } - ExprKind::AddrOf(_kind, _mut, ohs) => vis.visit_expr(ohs), - ExprKind::Let(pat, scrutinee, span, _recovered) => { - vis.visit_pat(pat); - vis.visit_expr(scrutinee); - vis.visit_span(span); - } - ExprKind::If(cond, tr, fl) => { - vis.visit_expr(cond); - vis.visit_block(tr); - visit_opt(fl, |fl| ensure_sufficient_stack(|| vis.visit_expr(fl))); - } - ExprKind::While(cond, body, label) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_expr(cond); - vis.visit_block(body); - } - ExprKind::ForLoop { pat, iter, body, label, kind: _ } => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_pat(pat); - vis.visit_expr(iter); - vis.visit_block(body); - } - ExprKind::Loop(body, label, span) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_block(body); - vis.visit_span(span); - } - ExprKind::Match(expr, arms, _kind) => { - vis.visit_expr(expr); - arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); - } - ExprKind::Closure(box Closure { - binder, - capture_clause, - constness, - coroutine_kind, - movability: _, - fn_decl, - body, - fn_decl_span, - fn_arg_span, - }) => { - vis.visit_constness(constness); - vis.visit_capture_by(capture_clause); - vis.visit_fn(FnKind::Closure(binder, coroutine_kind, fn_decl, body), *span, *id); - vis.visit_span(fn_decl_span); - vis.visit_span(fn_arg_span); - } - ExprKind::Block(blk, label) => { - visit_opt(label, |label| vis.visit_label(label)); - vis.visit_block(blk); - } - ExprKind::Gen(_capture_by, body, _kind, decl_span) => { - vis.visit_block(body); - vis.visit_span(decl_span); - } - ExprKind::Await(expr, await_kw_span) => { - vis.visit_expr(expr); - vis.visit_span(await_kw_span); - } - ExprKind::Assign(el, er, span) => { - vis.visit_expr(el); - vis.visit_expr(er); - vis.visit_span(span); - } - ExprKind::AssignOp(_op, el, er) => { - vis.visit_expr(el); - vis.visit_expr(er); - } - ExprKind::Field(el, ident) => { - vis.visit_expr(el); - vis.visit_ident(ident); - } - ExprKind::Index(el, er, brackets_span) => { - vis.visit_expr(el); - vis.visit_expr(er); - vis.visit_span(brackets_span); - } - ExprKind::Range(e1, e2, _lim) => { - visit_opt(e1, |e1| vis.visit_expr(e1)); - visit_opt(e2, |e2| vis.visit_expr(e2)); - } - ExprKind::Underscore => {} - ExprKind::Path(qself, path) => { - vis.visit_qself(qself); - vis.visit_path(path, *id); - } - ExprKind::Break(label, expr) => { - visit_opt(label, |label| vis.visit_label(label)); - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Continue(label) => { - visit_opt(label, |label| vis.visit_label(label)); - } - ExprKind::Ret(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Yeet(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Become(expr) => vis.visit_expr(expr), - ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm), - ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt), - ExprKind::OffsetOf(container, fields) => { - vis.visit_ty(container); - for field in fields.iter_mut() { - vis.visit_ident(field); - } - } - ExprKind::MacCall(mac) => vis.visit_mac_call(mac), - ExprKind::Struct(se) => { - let StructExpr { qself, path, fields, rest } = se.deref_mut(); - vis.visit_qself(qself); - vis.visit_path(path, *id); - fields.flat_map_in_place(|field| vis.flat_map_expr_field(field)); - match rest { - StructRest::Base(expr) => vis.visit_expr(expr), - StructRest::Rest(_span) => {} - StructRest::None => {} - } - } - ExprKind::Paren(expr) => { - vis.visit_expr(expr); - } - ExprKind::Yield(expr) => { - visit_opt(expr, |expr| vis.visit_expr(expr)); - } - ExprKind::Try(expr) => vis.visit_expr(expr), - ExprKind::TryBlock(body) => vis.visit_block(body), - ExprKind::Lit(_token) => {} - ExprKind::IncludedBytes(_bytes) => {} - ExprKind::Err(_guar) => {} - ExprKind::Dummy => {} - } - visit_lazy_tts(vis, tokens); - vis.visit_span(span); - } - pub fn noop_filter_map_expr(vis: &mut T, mut e: P) -> Option> { Some({ vis.visit_expr(&mut e); From a6d7eccaca927fc05dddef52eddb615cf1ef555b Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 15:13:00 -0300 Subject: [PATCH 77/82] Add flat maps to make_visit! --- compiler/rustc_ast/src/visitors.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 7986035a2464d..c03562f5e7bb9 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -59,6 +59,28 @@ macro_rules! make_ast_visitor { $walk(self, node $$($$(, $arg)?)*) } }; + ( + $ty: ty + $$(, $$($arg: ident)? $$(_ $ignored_arg: ident)?: $arg_ty: ty)*; + $visit: ident, $walk: ident, + $flat_map: ident, $walk_flat_map: ident + ) => { + make_visit!{ + $ty + $$(, $$($arg)? $$(_ $ignored_arg)?: $arg_ty)*; + $visit, $walk + } + + macro_if!{$($mut)? { + fn $flat_map( + &mut self, + node: $ty + $$(, $$($arg)? $$($ignored_arg)?: $arg_ty)* + ) -> SmallVec<[$ty; 1]> { + $walk_flat_map(self, node $$(, $$($arg)? $$($ignored_arg)?)*) + } + }} + }; } macro_rules! P { From 6b814ca4e5c29ffd02ad0061095d73cf06d766cb Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 15:24:20 -0300 Subject: [PATCH 78/82] Use make_visit! to write flat maps --- compiler/rustc_ast/src/visitors.rs | 64 +++++------------------------- 1 file changed, 10 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index c03562f5e7bb9..7b3f72604f47b 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -253,34 +253,10 @@ macro_rules! make_ast_visitor { make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} - fn flat_map_foreign_item(&mut self, ni: P) -> SmallVec<[P; 1]> { - walk_flat_map_foreign_item(self, ni) - } - - fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { - walk_flat_map_item(self, i) - } - - fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { - walk_flat_map_field_def(self, fd) - } - - fn flat_map_assoc_item( - &mut self, - i: P, - ctxt: AssocCtxt, - ) -> SmallVec<[P; 1]> { - walk_flat_map_assoc_item(self, i, ctxt) - } - fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> { walk_flat_map_stmt(self, s) } - fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { - walk_flat_map_arm(self, arm) - } - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. /// It can be removed once that feature is stabilized. fn visit_method_receiver_expr(&mut self, ex: &mut P) { @@ -291,22 +267,6 @@ macro_rules! make_ast_visitor { noop_filter_map_expr(self, e) } - fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { - walk_flat_map_variant(self, v) - } - - fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { - walk_flat_map_param(self, param) - } - - fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { - walk_flat_map_generic_param(self, param) - } - - fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { - walk_flat_map_expr_field(self, f) - } - fn visit_id(&mut self, _id: &mut NodeId) { // Do nothing. } @@ -314,10 +274,6 @@ macro_rules! make_ast_visitor { fn visit_span(&mut self, _sp: &mut Span) { // Do nothing. } - - fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { - walk_flat_map_pat_field(self, fp) - } } else { /// The result type of the `visit_*` methods. Can be either `()`, /// or `ControlFlow`. @@ -334,7 +290,7 @@ macro_rules! make_ast_visitor { make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} make_visit!{AnonConst; visit_anon_const, walk_anon_const} - make_visit!{Arm; visit_arm, walk_arm} + make_visit!{Arm; visit_arm, walk_arm, flat_map_arm, walk_flat_map_arm} make_visit!{AssocItemConstraint; visit_assoc_item_constraint, walk_assoc_item_constraint} make_visit!{AttrArgs; visit_attr_args, walk_attr_args} make_visit!{Attribute; visit_attribute, walk_attribute} @@ -346,8 +302,8 @@ macro_rules! make_ast_visitor { make_visit!{Crate; visit_crate, walk_crate} make_visit!{Defaultness; visit_defaultness, walk_defaultness} make_visit!{EnumDef; visit_enum_def, walk_enum_def} - make_visit!{ExprField; visit_expr_field, walk_expr_field} - make_visit!{FieldDef; visit_field_def, walk_field_def} + make_visit!{ExprField; visit_expr_field, walk_expr_field, flat_map_expr_field, walk_flat_map_expr_field} + make_visit!{FieldDef; visit_field_def, walk_field_def, flat_map_field_def, walk_flat_map_field_def} make_visit!{FnDecl; visit_fn_decl, walk_fn_decl} make_visit!{FnHeader; visit_fn_header, walk_fn_header} make_visit!{FnRetTy; visit_fn_ret_ty, walk_fn_ret_ty} @@ -356,7 +312,7 @@ macro_rules! make_ast_visitor { make_visit!{GenericArg; visit_generic_arg, walk_generic_arg} make_visit!{GenericArgs; visit_generic_args, walk_generic_args} make_visit!{GenericBound, _ ctxt: BoundKind; visit_param_bound, walk_param_bound} - make_visit!{GenericParam; visit_generic_param, walk_generic_param} + make_visit!{GenericParam; visit_generic_param, walk_generic_param, flat_map_generic_param, walk_flat_map_generic_param} make_visit!{Generics; visit_generics, walk_generics} make_visit!{Ident; visit_ident, walk_ident} make_visit!{ImplPolarity; visit_impl_polarity, walk_impl_polarity} @@ -369,9 +325,9 @@ macro_rules! make_ast_visitor { make_visit!{MacroDef, _ id: NodeId; visit_macro_def, walk_macro_def} make_visit!{MutTy; visit_mt, walk_mt} make_visit!{Option>; visit_qself, walk_qself} - make_visit!{Param; visit_param, walk_param} + make_visit!{Param; visit_param, walk_param, flat_map_param, walk_flat_map_param} make_visit!{ParenthesizedArgs; visit_parenthesized_parameter_data, walk_parenthesized_parameter_data} - make_visit!{PatField; visit_pat_field, walk_pat_field} + make_visit!{PatField; visit_pat_field, walk_pat_field, flat_map_pat_field, walk_flat_map_pat_field} make_visit!{Path, _ id: NodeId; visit_path, walk_path} make_visit!{PathSegment; visit_path_segment, walk_path_segment} make_visit!{PolyTraitRef; visit_poly_trait_ref, walk_poly_trait_ref} @@ -380,7 +336,7 @@ macro_rules! make_ast_visitor { make_visit!{TraitRef; visit_trait_ref, walk_trait_ref} make_visit!{TyAliasWhereClauses; visit_ty_alias_where_clauses, walk_ty_alias_where_clauses} make_visit!{UseTree, id: NodeId, _ nested: bool; visit_use_tree, walk_use_tree} - make_visit!{Variant; visit_variant, walk_variant} + make_visit!{Variant; visit_variant, walk_variant, flat_map_variant, walk_flat_map_variant} make_visit!{VariantData; visit_variant_data, walk_variant_data} make_visit!{Visibility; visit_vis, walk_vis} make_visit!{WhereClause; visit_where_clause, walk_where_clause} @@ -391,9 +347,9 @@ macro_rules! make_ast_visitor { make_visit!{P!(Ty); visit_ty, walk_ty} // Item variants - make_visit!{Item; visit_item, walk_item} - make_visit!{AssocItem, ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item} - make_visit!{ForeignItem; visit_foreign_item, walk_item} + make_visit!{P!(Item); visit_item, walk_item, flat_map_item, walk_flat_map_item} + make_visit!{P!(AssocItem), ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item, flat_map_assoc_item, walk_flat_map_assoc_item} + make_visit!{P!(ForeignItem); visit_foreign_item, walk_item, flat_map_foreign_item, walk_flat_map_foreign_item} fn visit_fn(&mut self, fn_kind: FnKind!(), _span: Span, _id: NodeId) -> result!() { walk_fn(self, fn_kind) From 24465fd0ae70d7bad2385043df247e9de220063c Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Mon, 14 Oct 2024 15:35:05 -0300 Subject: [PATCH 79/82] Add make_walk_flat_map --- compiler/rustc_ast/src/visitors.rs | 112 +++++++++-------------------- 1 file changed, 32 insertions(+), 80 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 7b3f72604f47b..487d308212e6b 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -1771,6 +1771,38 @@ macro_rules! make_ast_visitor { } return_result!(V) } + + macro_if!{$($mut)? { + macro_rules! make_walk_flat_map { + ( + $ty: ty + $$(, $arg: ident : $arg_ty: ty)*; + $walk_flat_map: ident, + $visit: ident + ) => { + pub fn $walk_flat_map( + vis: &mut impl $trait$(<$lt>)?, + mut arg: $ty + $$(, $arg: $arg_ty)* + ) -> SmallVec<[$ty; 1]> { + vis.$visit(&mut arg $$(, $arg)*); + smallvec![arg] + } + } + } + + make_walk_flat_map!{Arm; walk_flat_map_arm, visit_arm} + make_walk_flat_map!{ExprField; walk_flat_map_expr_field, visit_expr_field} + make_walk_flat_map!{FieldDef; walk_flat_map_field_def, visit_field_def} + make_walk_flat_map!{GenericParam; walk_flat_map_generic_param, visit_generic_param} + make_walk_flat_map!{Param; walk_flat_map_param, visit_param} + make_walk_flat_map!{PatField; walk_flat_map_pat_field, visit_pat_field} + make_walk_flat_map!{Variant; walk_flat_map_variant, visit_variant} + + make_walk_flat_map!{P; walk_flat_map_item, visit_item} + make_walk_flat_map!{P, ctxt: AssocCtxt; walk_flat_map_assoc_item, visit_assoc_item} + make_walk_flat_map!{P; walk_flat_map_foreign_item, visit_foreign_item} + }} } } @@ -1979,27 +2011,6 @@ pub mod mut_visit { vis.visit_span(close); } - pub fn walk_flat_map_pat_field( - vis: &mut T, - mut fp: PatField, - ) -> SmallVec<[PatField; 1]> { - vis.visit_pat_field(&mut fp); - smallvec![fp] - } - - pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { - vis.visit_arm(&mut arm); - smallvec![arm] - } - - pub fn walk_flat_map_variant( - visitor: &mut T, - mut variant: Variant, - ) -> SmallVec<[Variant; 1]> { - visitor.visit_variant(&mut variant); - smallvec![variant] - } - fn walk_meta_list_item(vis: &mut T, li: &mut MetaItemInner) { match li { MetaItemInner::MetaItem(mi) => vis.visit_meta_item(mi), @@ -2017,14 +2028,6 @@ pub mod mut_visit { vis.visit_span(span); } - pub fn walk_flat_map_param( - vis: &mut T, - mut param: Param, - ) -> SmallVec<[Param; 1]> { - vis.visit_param(&mut param); - smallvec![param] - } - // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. fn visit_attr_tt(vis: &mut T, tt: &mut AttrTokenTree) { match tt { @@ -2171,61 +2174,10 @@ pub mod mut_visit { } } - pub fn walk_flat_map_generic_param( - vis: &mut T, - mut param: GenericParam, - ) -> SmallVec<[GenericParam; 1]> { - vis.visit_generic_param(&mut param); - smallvec![param] - } - - pub fn walk_flat_map_field_def( - visitor: &mut T, - mut fd: FieldDef, - ) -> SmallVec<[FieldDef; 1]> { - visitor.visit_field_def(&mut fd); - smallvec![fd] - } - - pub fn walk_flat_map_expr_field( - vis: &mut T, - mut f: ExprField, - ) -> SmallVec<[ExprField; 1]> { - vis.visit_expr_field(&mut f); - smallvec![f] - } - pub fn walk_item_kind(item: &mut Item, vis: &mut impl MutVisitor) { item.kind.walk(item.id, item.span, &mut item.vis, &mut item.ident, vis) } - /// Mutates one item, returning the item again. - pub fn walk_flat_map_item( - vis: &mut impl MutVisitor, - mut item: P, - ) -> SmallVec<[P; 1]> { - vis.visit_item(&mut item); - smallvec![item] - } - - pub fn walk_flat_map_foreign_item( - vis: &mut impl MutVisitor, - mut item: P, - ) -> SmallVec<[P; 1]> { - vis.visit_foreign_item(&mut item); - smallvec![item] - } - - /// Mutates one item, returning the item again. - pub fn walk_flat_map_assoc_item( - vis: &mut impl MutVisitor, - mut item: P, - ctxt: AssocCtxt, - ) -> SmallVec<[P; 1]> { - vis.visit_assoc_item(&mut item, ctxt); - smallvec![item] - } - pub fn noop_filter_map_expr(vis: &mut T, mut e: P) -> Option> { Some({ vis.visit_expr(&mut e); From 64404292f5ce8e25803cac1d25cb93077273af7f Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Tue, 15 Oct 2024 14:54:32 -0300 Subject: [PATCH 80/82] Unify visit_method_receiver_expr --- compiler/rustc_ast/src/visitors.rs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index 487d308212e6b..fbd58f4ceee1b 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -257,12 +257,6 @@ macro_rules! make_ast_visitor { walk_flat_map_stmt(self, s) } - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. - /// It can be removed once that feature is stabilized. - fn visit_method_receiver_expr(&mut self, ex: &mut P) { - self.visit_expr(ex) - } - fn filter_map_expr(&mut self, e: P) -> Option> { noop_filter_map_expr(self, e) } @@ -280,12 +274,6 @@ macro_rules! make_ast_visitor { type Result: VisitorResult = (); make_visit!{Stmt; visit_stmt, walk_stmt} - - /// This method is a hack to workaround unstable of `stmt_expr_attributes`. - /// It can be removed once that feature is stabilized. - fn visit_method_receiver_expr(&mut self, ex: &'ast Expr) -> Self::Result { - self.visit_expr(ex) - } }} make_visit!{AngleBracketedArgs; visit_angle_bracketed_parameter_data, walk_angle_bracketed_parameter_data} @@ -355,6 +343,12 @@ macro_rules! make_ast_visitor { walk_fn(self, fn_kind) } + /// This method is a hack to workaround unstable of `stmt_expr_attributes`. + /// It can be removed once that feature is stabilized. + fn visit_method_receiver_expr(&mut self, ex: ref_t!(P!(Expr))) -> result!() { + self.visit_expr(ex) + } + fn visit_variant_discr(&mut self, discr: ref_t!(AnonConst)) -> result!() { self.visit_anon_const(discr) } From fdc62e479a7ce06fff690068c9947793afffac0b Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Tue, 15 Oct 2024 15:06:39 -0300 Subject: [PATCH 81/82] Unify comment --- compiler/rustc_ast/src/visitors.rs | 73 ++++++++++++++++-------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index fbd58f4ceee1b..ea8f704efb060 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -211,45 +211,52 @@ macro_rules! make_ast_visitor { /// future changes to this trait in case a new method with a new default /// implementation gets introduced.) pub trait $trait$(<$lt>)?: Sized { + + + // Methods in these traits have the form: + // + // fn visit_t(&mut self, t: ref_t!(T)) -> result!(); + // + // In addition to those the mutable version also has methods of the form: + // + // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; + // fn filter_map_t(&mut self, t: T) -> Option; + // + // Any additions to this trait should happen in form of a call to a public + // `walk_*` function that only calls out to the visitor again, not other + // `walk_*` functions. This is a necessary API workaround to the problem of + // not being able to call out to the default implementation of an overridden + // method. + // + // When writing these methods, it is better to use destructuring like this: + // + // fn walk_abc(&mut self, abc: &mut ABC) { + // let ABC { a, b, c: _ } = abc; + // visit_a(a); + // visit_b(b); + // } + // + // than to use field access like this: + // + // fn walk_abc(&mut self, abc: &mut ABC) { + // visit_a(&mut abc.a); + // visit_b(&mut abc.b); + // // ignore abc.c + // } + // + // As well as being more concise, the former is explicit about which fields + // are skipped. Furthermore, if a new field is added, the destructuring + // version will cause a compile error, which is good. In comparison, the + // field access version will continue working and it would be easy to + // forget to add handling for it. + + macro_if!{$($mut)? { /// Mutable token visiting only exists for the `macro_rules` token marker and should not be /// used otherwise. Token visitor would be entirely separate from the regular visitor if /// the marker didn't have to visit AST fragments in nonterminal tokens. const VISIT_TOKENS: bool = false; - // Methods in this trait have one of three forms: - // - // fn visit_t(&mut self, t: &mut T); // common - // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // rare - // fn filter_map_t(&mut self, t: T) -> Option; // 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) { - // visit_a(a); - // visit_b(b); - // } - // - // than to use field access like this: - // - // fn visit_abc(&mut self, abc: &mut ABC) { - // visit_a(&mut abc.a); - // visit_b(&mut abc.b); - // // ignore abc.c - // } - // - // As well as being more concise, the former is explicit about which fields - // are skipped. Furthermore, if a new field is added, the destructuring - // version will cause a compile error, which is good. In comparison, the - // field access version will continue working and it would be easy to - // forget to add handling for it. - make_visit!{MetaItem; visit_meta_item, walk_meta_item} make_visit!{MetaItemInner; visit_meta_list_item, walk_meta_list_item} From 87e6380a75b35ee58d29e3428547ced7f164a6fa Mon Sep 17 00:00:00 2001 From: maxcabrajac Date: Tue, 15 Oct 2024 15:10:12 -0300 Subject: [PATCH 82/82] Add FIXME asking for removal of some P!s --- compiler/rustc_ast/src/visitors.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_ast/src/visitors.rs b/compiler/rustc_ast/src/visitors.rs index ea8f704efb060..cb3e817ab2933 100644 --- a/compiler/rustc_ast/src/visitors.rs +++ b/compiler/rustc_ast/src/visitors.rs @@ -337,11 +337,13 @@ macro_rules! make_ast_visitor { make_visit!{WhereClause; visit_where_clause, walk_where_clause} make_visit!{WherePredicate; visit_where_predicate, walk_where_predicate} + // FIXME: Remove these P!s make_visit!{P!(Expr); visit_expr, walk_expr} make_visit!{P!(Pat); visit_pat, walk_pat} make_visit!{P!(Ty); visit_ty, walk_ty} // Item variants + // FIXME: Remove these P!s make_visit!{P!(Item); visit_item, walk_item, flat_map_item, walk_flat_map_item} make_visit!{P!(AssocItem), ctxt: AssocCtxt; visit_assoc_item, walk_assoc_item, flat_map_assoc_item, walk_flat_map_assoc_item} make_visit!{P!(ForeignItem); visit_foreign_item, walk_item, flat_map_foreign_item, walk_flat_map_foreign_item}