diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 08726ee6b4115..77cbdde61a426 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -208,11 +208,7 @@ pub trait MutVisitor: Sized { } fn visit_ident(&mut self, i: &mut Ident) { - walk_ident(self, i); - } - - fn visit_modifiers(&mut self, m: &mut TraitBoundModifiers) { - walk_modifiers(self, m); + self.visit_span(&mut i.span); } fn visit_path(&mut self, p: &mut Path) { @@ -367,6 +363,33 @@ pub trait MutVisitor: Sized { super::common_visitor_and_walkers!((mut) MutVisitor); +macro_rules! generate_flat_map_visitor_fns { + ($($name:ident, $Ty:ty, $flat_map_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => { + $( + fn $name<V: MutVisitor>( + vis: &mut V, + values: &mut ThinVec<$Ty>, + $( + $param: $ParamTy, + )* + ) { + values.flat_map_in_place(|value| vis.$flat_map_fn(value$(,$param)*)); + } + )+ + } +} + +generate_flat_map_visitor_fns! { + visit_items, P<Item>, flat_map_item; + visit_foreign_items, P<ForeignItem>, flat_map_foreign_item; + visit_generic_params, GenericParam, flat_map_generic_param; + visit_stmts, Stmt, flat_map_stmt; + visit_exprs, P<Expr>, filter_map_expr; + visit_pat_fields, PatField, flat_map_pat_field; + visit_variants, Variant, flat_map_variant; + visit_assoc_items, P<AssocItem>, flat_map_assoc_item, ctxt: AssocCtxt; +} + #[inline] fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F) where @@ -403,15 +426,6 @@ fn visit_attrs<T: MutVisitor>(vis: &mut T, attrs: &mut AttrVec) { } } -#[allow(unused)] -fn visit_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut Vec<P<Expr>>) { - exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) -} - -fn visit_thin_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut ThinVec<P<Expr>>) { - exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) -} - fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) { match args { AttrArgs::Empty => {} @@ -430,15 +444,6 @@ fn visit_delim_args<T: MutVisitor>(vis: &mut T, args: &mut DelimArgs) { vis.visit_span(close); } -pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) { - let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - vis.visit_pat(pat); - vis.visit_span(span); -} - pub fn walk_flat_map_pat_field<T: MutVisitor>( vis: &mut T, mut fp: PatField, @@ -447,21 +452,13 @@ pub fn walk_flat_map_pat_field<T: MutVisitor>( smallvec![fp] } -fn walk_use_tree<T: MutVisitor>(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); +fn visit_nested_use_tree<V: MutVisitor>( + vis: &mut V, + nested_tree: &mut UseTree, + nested_id: &mut NodeId, +) { + vis.visit_id(nested_id); + vis.visit_use_tree(nested_tree); } pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) { @@ -498,31 +495,6 @@ fn walk_assoc_item_constraint<T: MutVisitor>( vis.visit_span(span); } -pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut TyPat) { - let TyPat { id, kind, span, tokens: _ } = ty; - vis.visit_id(id); - match kind { - TyPatKind::Range(start, end, _include_end) => { - visit_opt(start, |c| vis.visit_anon_const(c)); - visit_opt(end, |c| vis.visit_anon_const(c)); - } - TyPatKind::Or(variants) => visit_thin_vec(variants, |p| vis.visit_ty_pat(p)), - TyPatKind::Err(_) => {} - } - vis.visit_span(span); -} - -pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) { - let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant; - visitor.visit_id(id); - 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); -} - pub fn walk_flat_map_variant<T: MutVisitor>( vis: &mut T, mut variant: Variant, @@ -531,25 +503,6 @@ pub fn walk_flat_map_variant<T: MutVisitor>( smallvec![variant] } -fn walk_ident<T: MutVisitor>(vis: &mut T, Ident { name: _, span }: &mut Ident) { - vis.visit_span(span); -} - -fn walk_path<T: MutVisitor>(vis: &mut T, Path { segments, span, tokens: _ }: &mut Path) { - for segment in segments { - vis.visit_path_segment(segment); - } - vis.visit_span(span); -} - -fn walk_qself<T: MutVisitor>(vis: &mut T, qself: &mut Option<P<QSelf>>) { - 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<T: MutVisitor>(vis: &mut T, generic_args: &mut GenericArgs) { match generic_args { GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), @@ -583,27 +536,6 @@ fn walk_parenthesized_parameter_data<T: MutVisitor>(vis: &mut T, args: &mut Pare vis.visit_span(inputs_span); } -fn walk_local<T: MutVisitor>(vis: &mut T, local: &mut Local) { - let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local; - visit_opt(super_, |sp| vis.visit_span(sp)); - vis.visit_id(id); - visit_attrs(vis, attrs); - 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_opt(colon_sp, |sp| vis.visit_span(sp)); - vis.visit_span(span); -} - fn walk_attribute<T: MutVisitor>(vis: &mut T, attr: &mut Attribute) { let Attribute { kind, id: _, style: _, span } = attr; match kind { @@ -853,35 +785,6 @@ fn walk_variant_data<T: MutVisitor>(vis: &mut T, vdata: &mut VariantData) { } } -fn walk_trait_ref<T: MutVisitor>(vis: &mut T, TraitRef { path, ref_id }: &mut TraitRef) { - vis.visit_id(ref_id); - vis.visit_path(path); -} - -fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) { - let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p; - vis.visit_modifiers(modifiers); - bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - vis.visit_trait_ref(trait_ref); - vis.visit_span(span); -} - -fn walk_modifiers<V: MutVisitor>(vis: &mut V, m: &mut TraitBoundModifiers) { - let TraitBoundModifiers { constness, asyncness, polarity } = m; - match constness { - BoundConstness::Never => {} - BoundConstness::Always(span) | BoundConstness::Maybe(span) => vis.visit_span(span), - } - match asyncness { - BoundAsyncness::Normal => {} - BoundAsyncness::Async(span) => vis.visit_span(span), - } - match polarity { - BoundPolarity::Positive => {} - BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => vis.visit_span(span), - } -} - pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) { let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _, safety, default } = fd; visitor.visit_id(id); @@ -902,15 +805,6 @@ pub fn walk_flat_map_field_def<T: MutVisitor>( smallvec![fd] } -pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) { - let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f; - vis.visit_id(id); - visit_attrs(vis, attrs); - vis.visit_ident(ident); - vis.visit_expr(expr); - vis.visit_span(span); -} - pub fn walk_flat_map_expr_field<T: MutVisitor>( vis: &mut T, mut f: ExprField, @@ -930,16 +824,6 @@ pub fn walk_item_kind<K: WalkItemKind>( kind.walk(span, id, visibility, ctxt, vis) } -pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) { - let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; - vis.visit_id(id); - 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); -} - pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> { vis.visit_item(&mut item); smallvec![item] @@ -1021,7 +905,7 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token vis.visit_id(id); visit_attrs(vis, attrs); match kind { - ExprKind::Array(exprs) => visit_thin_exprs(vis, exprs), + ExprKind::Array(exprs) => visit_exprs(vis, exprs), ExprKind::ConstBlock(anon_const) => { vis.visit_anon_const(anon_const); } @@ -1029,10 +913,10 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token vis.visit_expr(expr); vis.visit_anon_const(count); } - ExprKind::Tup(exprs) => visit_thin_exprs(vis, exprs), + ExprKind::Tup(exprs) => visit_exprs(vis, exprs), ExprKind::Call(f, args) => { vis.visit_expr(f); - visit_thin_exprs(vis, args); + visit_exprs(vis, args); } ExprKind::MethodCall(box MethodCall { seg: PathSegment { ident, id, args: seg_args }, @@ -1044,7 +928,7 @@ pub fn walk_expr<T: MutVisitor>(vis: &mut T, Expr { kind, id, span, attrs, token vis.visit_id(id); vis.visit_ident(ident); visit_opt(seg_args, |args| vis.visit_generic_args(args)); - visit_thin_exprs(vis, call_args); + visit_exprs(vis, call_args); vis.visit_span(span); } ExprKind::Binary(binop, lhs, rhs) => { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 1f7c97380dc27..d2f22b04a671f 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -219,9 +219,6 @@ pub trait Visitor<'ast>: Sized { 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) } @@ -246,13 +243,12 @@ pub trait Visitor<'ast>: Sized { fn visit_path(&mut self, path: &'ast Path) -> 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_use_tree(&mut self, use_tree: &'ast UseTree) -> Self::Result { + walk_use_tree(self, use_tree) + } + fn visit_nested_use_tree(&mut self, use_tree: &'ast UseTree, id: NodeId) -> Self::Result { + try_visit!(self.visit_id(id)); + self.visit_use_tree(use_tree) } fn visit_path_segment(&mut self, path_segment: &'ast PathSegment) -> Self::Result { walk_path_segment(self, path_segment) @@ -378,13 +374,39 @@ macro_rules! common_visitor_and_walkers { } } - fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, polarity: &$($lt)? $($mut)? ImplPolarity) $(-> <V as Visitor<$lt>>::Result)? { + fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + polarity: &$($lt)? $($mut)? ImplPolarity, + ) $(-> <V as Visitor<$lt>>::Result)? { match polarity { ImplPolarity::Positive => { $(<V as Visitor<$lt>>::Result::output())? } ImplPolarity::Negative(span) => visit_span(vis, span), } } + $(${ignore($lt)} + #[inline] + )? + fn visit_modifiers<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + m: &$($lt)? $($mut)? TraitBoundModifiers + ) $(-> <V as Visitor<$lt>>::Result)? { + let TraitBoundModifiers { constness, asyncness, polarity } = m; + match constness { + BoundConstness::Never => {} + BoundConstness::Always(span) | BoundConstness::Maybe(span) => try_visit!(visit_span(vis, span)), + } + match asyncness { + BoundAsyncness::Normal => {} + BoundAsyncness::Async(span) => try_visit!(visit_span(vis, span)), + } + match polarity { + BoundPolarity::Positive => {} + BoundPolarity::Negative(span) | BoundPolarity::Maybe(span) => try_visit!(visit_span(vis, span)), + } + $(<V as Visitor<$lt>>::Result::output())? + } + fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) $(-> <V as Visitor<$lt>>::Result)? { walk_list!(visitor, visit_param_bound, bounds, ctxt); $(<V as Visitor<$lt>>::Result::output())? @@ -446,8 +468,7 @@ macro_rules! common_visitor_and_walkers { ) $(-> <V as Visitor<$lt>>::Result)? { match self { ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident), - // FIXME(fee1-dead): look into this weird assymetry - ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree$(${ignore($lt)}, id, false)?), + ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree), ItemKind::Static(box StaticItem { ident, ty, @@ -478,12 +499,7 @@ macro_rules! common_visitor_and_walkers { ModSpans { inner_span, inject_use_span }, _, ) => { - $(${ignore($mut)} - items.flat_map_in_place(|item| vis.flat_map_item(item)); - )? - $(${ignore($lt)} - walk_list!(vis, visit_item, items); - )? + try_visit!(visit_items(vis, items)); try_visit!(visit_span(vis, inner_span)); try_visit!(visit_span(vis, inject_use_span)); } @@ -515,10 +531,7 @@ macro_rules! common_visitor_and_walkers { ItemKind::Enum(ident, generics, enum_definition) => { try_visit!(vis.visit_ident(ident)); try_visit!(vis.visit_generics(generics)); - $(${ignore($mut)} - enum_definition.variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); - )? - $(${ignore($lt)}vis.visit_enum_def(enum_definition))? + visit_variants(vis, &$($mut)? enum_definition.variants) } ItemKind::Struct(ident, generics, variant_data) | ItemKind::Union(ident, generics, variant_data) => { @@ -543,35 +556,14 @@ macro_rules! common_visitor_and_walkers { try_visit!(visit_polarity(vis, polarity)); visit_opt!(vis, visit_trait_ref, of_trait); try_visit!(vis.visit_ty(self_ty)); - $(${ignore($mut)} - items.flat_map_in_place(|item| { - vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() }) - }); - )? - $(${ignore($lt)} - walk_list!( - vis, - visit_assoc_item, - items, - AssocCtxt::Impl { of_trait: of_trait.is_some() } - ); - <V as Visitor<$lt>>::Result::output() - )? + visit_assoc_items(vis, items, AssocCtxt::Impl { of_trait: of_trait.is_some() }) } ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => { try_visit!(visit_safety(vis, safety)); try_visit!(vis.visit_ident(ident)); try_visit!(vis.visit_generics(generics)); try_visit!(visit_bounds(vis, bounds, BoundKind::Bound)); - $(${ignore($mut)} - items.flat_map_in_place(|item| { - vis.flat_map_assoc_item(item, AssocCtxt::Trait) - }); - )? - $(${ignore($lt)} - walk_list!(vis, visit_assoc_item, items, AssocCtxt::Trait); - <V as Visitor<$lt>>::Result::output() - )? + visit_assoc_items(vis, items, AssocCtxt::Trait) } ItemKind::TraitAlias(ident, generics, bounds) => { try_visit!(vis.visit_ident(ident)); @@ -616,7 +608,10 @@ macro_rules! common_visitor_and_walkers { } } - fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, item: &$($lt)? $($mut)? ConstItem) $(-> <V as Visitor<$lt>>::Result)? { + fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + item: &$($lt)? $($mut)? ConstItem, + ) $(-> <V as Visitor<$lt>>::Result)? { let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item; try_visit!(visit_defaultness(vis, defaultness)); try_visit!(vis.visit_ident(ident)); @@ -629,13 +624,7 @@ macro_rules! common_visitor_and_walkers { fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) $(-> <V as Visitor<$lt>>::Result)? { let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod; try_visit!(visit_safety(vis, safety)); - $(${ignore($mut)} - items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); - )? - $( - walk_list!(vis, visit_foreign_item, items); - <V as Visitor<$lt>>::Result::output() - )? + visit_foreign_items(vis, items) } fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>( @@ -780,15 +769,13 @@ macro_rules! common_visitor_and_walkers { vis: &mut V, coroutine_kind: &$($lt)? $($mut)? CoroutineKind, ) $(-> <V as Visitor<$lt>>::Result)? { - match coroutine_kind { - CoroutineKind::Async { span, closure_id, return_impl_trait_id } + let (CoroutineKind::Async { span, closure_id, return_impl_trait_id } | CoroutineKind::Gen { span, closure_id, return_impl_trait_id } - | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id } => { - try_visit!(visit_id(vis, closure_id)); - try_visit!(visit_id(vis, return_impl_trait_id)); - visit_span(vis, span) - } - } + | CoroutineKind::AsyncGen { span, closure_id, return_impl_trait_id }) + = coroutine_kind; + try_visit!(visit_id(vis, closure_id)); + try_visit!(visit_id(vis, return_impl_trait_id)); + visit_span(vis, span) } pub fn walk_pat<$($lt,)? V: $Visitor$(<$lt>)?>( @@ -817,15 +804,7 @@ macro_rules! common_visitor_and_walkers { PatKind::Struct(opt_qself, path, fields, _rest) => { try_visit!(vis.visit_qself(opt_qself)); try_visit!(vis.visit_path(path)); - - $( - ${ignore($lt)} - walk_list!(vis, visit_pat_field, fields); - )? - $( - ${ignore($mut)} - fields.flat_map_in_place(|field| vis.flat_map_pat_field(field)); - )? + try_visit!(visit_pat_fields(vis, fields)); } PatKind::Box(subpattern) | PatKind::Deref(subpattern) | PatKind::Paren(subpattern) => { try_visit!(vis.visit_pat(subpattern)); @@ -876,14 +855,7 @@ macro_rules! common_visitor_and_walkers { ) $(-> <V as Visitor<$lt>>::Result)? { let Block { stmts, id, rules: _, span, tokens: _ } = block; try_visit!(visit_id(vis, id)); - $( - ${ignore($lt)} - walk_list!(vis, visit_stmt, stmts); - )? - $( - ${ignore($mut)} - stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt)); - )? + try_visit!(visit_stmts(vis, stmts)); visit_span(vis, span) } @@ -911,28 +883,13 @@ macro_rules! common_visitor_and_walkers { let BareFnTy { safety, ext: _, generic_params, decl, decl_span } = &$($mut)? **function_declaration; visit_safety(vis, safety); - $( - ${ignore($lt)} - walk_list!(vis, visit_generic_param, generic_params); - )? - $( - ${ignore($mut)} - generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - )? - + try_visit!(visit_generic_params(vis, generic_params)); try_visit!(vis.visit_fn_decl(decl)); try_visit!(visit_span(vis, decl_span)); } TyKind::UnsafeBinder(binder) => { - $( - ${ignore($lt)} - walk_list!(vis, visit_generic_param, &binder.generic_params); - )? - $( - ${ignore($mut)} - binder.generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - )? - try_visit!(vis.visit_ty(&$($mut)?binder.inner_ty)); + try_visit!(visit_generic_params(vis, &$($mut)? binder.generic_params)); + try_visit!(vis.visit_ty(&$($mut)? binder.inner_ty)); } TyKind::Path(maybe_qself, path) => { try_visit!(vis.visit_qself(maybe_qself)); @@ -959,130 +916,204 @@ macro_rules! common_visitor_and_walkers { } visit_span(vis, span) } - }; -} -common_visitor_and_walkers!(Visitor<'a>); + pub fn walk_crate<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + krate: &$($lt)? $($mut)? Crate, + ) $(-> <V as Visitor<$lt>>::Result)? { + let Crate { attrs, items, spans, id, is_placeholder: _ } = krate; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(visit_items(vis, items)); + let ModSpans { inner_span, inject_use_span } = spans; + try_visit!(visit_span(vis, inner_span)); + visit_span(vis, inject_use_span) + } -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<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + local: &$($lt)? $($mut)? Local, + ) $(-> <V as Visitor<$lt>>::Result)? { + let Local { id, super_, pat, ty, kind, span, colon_sp, attrs, tokens: _ } = local; + if let Some(sp) = super_ { + try_visit!(visit_span(vis, sp)); + } + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_pat(pat)); + visit_opt!(vis, visit_ty, ty); + match kind { + LocalKind::Decl => {} + LocalKind::Init(init) => { + try_visit!(vis.visit_expr(init)) + } + LocalKind::InitElse(init, els) => { + try_visit!(vis.visit_expr(init)); + try_visit!(vis.visit_block(els)); + } + } + if let Some(sp) = colon_sp { + try_visit!(visit_span(vis, sp)); + } + visit_span(vis, span) + } -pub fn walk_local<'a, V: Visitor<'a>>(visitor: &mut V, local: &'a Local) -> V::Result { - let Local { id: _, super_: _, 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_poly_trait_ref<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + p: &$($lt)? $($mut)? PolyTraitRef, + ) $(-> <V as Visitor<$lt>>::Result)? { + let PolyTraitRef { bound_generic_params, modifiers, trait_ref, span } = p; + try_visit!(visit_modifiers(vis, modifiers)); + try_visit!(visit_generic_params(vis, bound_generic_params)); + try_visit!(vis.visit_trait_ref(trait_ref)); + visit_span(vis, span) + } -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<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + TraitRef { path, ref_id }: &$($lt)? $($mut)? TraitRef, + ) $(-> <V as Visitor<$lt>>::Result)? { + try_visit!(vis.visit_path(path)); + visit_id(vis, ref_id) + } -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; - try_visit!(visitor.visit_path(path)); - visitor.visit_id(*ref_id) -} + pub fn walk_variant<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + variant: &$($lt)? $($mut)? Variant, + ) $(-> <V as Visitor<$lt>>::Result)? { + let Variant { attrs, id, span, vis: visibility, ident, data, disr_expr, is_placeholder: _ } = variant; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_vis(visibility)); + try_visit!(vis.visit_ident(ident)); + try_visit!(vis.visit_variant_data(data)); + $(${ignore($lt)} visit_opt!(vis, visit_variant_discr, disr_expr); )? + $(${ignore($mut)} visit_opt!(vis, visit_anon_const, disr_expr); )? + visit_span(vis, span) + } -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_expr_field<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + f: &$($lt)? $($mut)? ExprField, + ) $(-> <V as Visitor<$lt>>::Result)? { + let ExprField { attrs, id, span, ident, expr, is_shorthand: _, is_placeholder: _ } = f; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_ident(ident)); + try_visit!(vis.visit_expr(expr)); + visit_span(vis, span) + } -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_pat_field<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + fp: &$($lt)? $($mut)? PatField, + ) $(-> <V as Visitor<$lt>>::Result)? { + let PatField { ident, pat, is_shorthand: _, attrs, id, span, is_placeholder: _ } = fp; + try_visit!(visit_id(vis, id)); + walk_list!(vis, visit_attribute, attrs); + try_visit!(vis.visit_ident(ident)); + try_visit!(vis.visit_pat(pat)); + visit_span(vis, span) + } -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_pat<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + tp: &$($lt)? $($mut)? TyPat, + ) $(-> <V as Visitor<$lt>>::Result)? { + let TyPat { id, kind, span, tokens: _ } = tp; + try_visit!(visit_id(vis, id)); + match kind { + TyPatKind::Range(start, end, _include_end) => { + visit_opt!(vis, visit_anon_const, start); + visit_opt!(vis, visit_anon_const, end); + } + TyPatKind::Or(variants) => walk_list!(vis, visit_ty_pat, variants), + TyPatKind::Err(_) => {} + } + visit_span(vis, span) + } -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() -} + fn walk_qself<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + qself: &$($lt)? $($mut)? Option<P<QSelf>>, + ) $(-> <V as Visitor<$lt>>::Result)? { + if let Some(qself) = qself { + let QSelf { ty, path_span, position: _ } = &$($mut)? **qself; + try_visit!(vis.visit_ty(ty)); + try_visit!(visit_span(vis, path_span)); + } + $(<V as Visitor<$lt>>::Result::output())? + } -pub fn walk_ty_pat<'a, V: Visitor<'a>>(visitor: &mut V, tp: &'a TyPat) -> V::Result { - let TyPat { id: _, kind, span: _, tokens: _ } = tp; - match kind { - TyPatKind::Range(start, end, _include_end) => { - visit_opt!(visitor, visit_anon_const, start); - visit_opt!(visitor, visit_anon_const, end); + pub fn walk_path<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + path: &$($lt)? $($mut)? Path, + ) $(-> <V as Visitor<$lt>>::Result)? { + let Path { span, segments, tokens: _ } = path; + walk_list!(vis, visit_path_segment, segments); + visit_span(vis, span) } - TyPatKind::Or(variants) => walk_list!(visitor, visit_ty_pat, variants), - TyPatKind::Err(_) => {} - } - V::Result::output() + + pub fn walk_use_tree<$($lt,)? V: $Visitor$(<$lt>)?>( + vis: &mut V, + use_tree: &$($lt)? $($mut)? UseTree, + ) $(-> <V as Visitor<$lt>>::Result)? { + let UseTree { prefix, kind, span } = use_tree; + try_visit!(vis.visit_path(prefix)); + match kind { + UseTreeKind::Simple(rename) => { + // The extra IDs are handled during AST lowering. + visit_opt!(vis, visit_ident, rename); + } + UseTreeKind::Glob => {} + UseTreeKind::Nested { items, span } => { + for (nested_tree, nested_id) in items { + try_visit!(visit_nested_use_tree(vis, nested_tree, nested_id)); + } + try_visit!(visit_span(vis, span)); + } + } + visit_span(vis, span) + } + }; } -fn walk_qself<'a, V: Visitor<'a>>(visitor: &mut V, qself: &'a Option<P<QSelf>>) -> V::Result { - if let Some(qself) = qself { - let QSelf { ty, path_span: _, position: _ } = &**qself; - try_visit!(visitor.visit_ty(ty)); +common_visitor_and_walkers!(Visitor<'a>); + +macro_rules! generate_list_visit_fns { + ($($name:ident, $Ty:ty, $visit_fn:ident$(, $param:ident: $ParamTy:ty)*;)+) => { + $( + fn $name<'a, V: Visitor<'a>>( + vis: &mut V, + values: &'a ThinVec<$Ty>, + $( + $param: $ParamTy, + )* + ) -> V::Result { + walk_list!(vis, $visit_fn, values$(,$param)*); + V::Result::output() + } + )+ } - 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() +generate_list_visit_fns! { + visit_items, P<Item>, visit_item; + visit_foreign_items, P<ForeignItem>, visit_foreign_item; + visit_generic_params, GenericParam, visit_generic_param; + visit_stmts, Stmt, visit_stmt; + visit_pat_fields, PatField, visit_pat_field; + visit_variants, Variant, visit_variant; + visit_assoc_items, P<AssocItem>, visit_assoc_item, ctxt: AssocCtxt; } -pub fn walk_use_tree<'a, V: Visitor<'a>>( - visitor: &mut V, - use_tree: &'a UseTree, - id: NodeId, +#[expect(rustc::pass_by_value)] // needed for symmetry with mut_visit +fn visit_nested_use_tree<'a, V: Visitor<'a>>( + vis: &mut V, + nested_tree: &'a UseTree, + &nested_id: &NodeId, ) -> V::Result { - let UseTree { prefix, kind, span: _ } = use_tree; - try_visit!(visitor.visit_id(id)); - try_visit!(visitor.visit_path(prefix)); - match kind { - UseTreeKind::Simple(rename) => { - // The extra IDs are handled during AST lowering. - visit_opt!(visitor, visit_ident, rename); - } - UseTreeKind::Glob => {} - UseTreeKind::Nested { items, span: _ } => { - for &(ref nested_tree, nested_id) in items { - try_visit!(visitor.visit_use_tree(nested_tree, nested_id, true)); - } - } - } - V::Result::output() + vis.visit_nested_use_tree(nested_tree, nested_id) } pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) -> V::Result diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 275714c2d0e44..3afed9784de51 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -307,18 +307,14 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { self.parent_item = parent_item; } - fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef) { - for variant in &enum_definition.variants { - self.check_for_lang( - Target::Variant, - self.resolver.node_id_to_def_id[&variant.id], - &variant.attrs, - variant.span, - None, - ); - } - - visit::walk_enum_def(self, enum_definition); + fn visit_variant(&mut self, variant: &'ast ast::Variant) { + self.check_for_lang( + Target::Variant, + self.resolver.node_id_to_def_id[&variant.id], + &variant.attrs, + variant.span, + None, + ); } fn visit_assoc_item(&mut self, i: &'ast ast::AssocItem, ctxt: visit::AssocCtxt) { diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 9b824572b66ee..2e870c47f8eb7 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -100,6 +100,21 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> { } } + fn check_use_tree(&mut self, use_tree: &'a ast::UseTree, id: ast::NodeId) { + if self.r.effective_visibilities.is_exported(self.r.local_def_id(id)) { + self.check_import_as_underscore(use_tree, id); + return; + } + + if let ast::UseTreeKind::Nested { ref items, .. } = use_tree.kind { + if items.is_empty() { + self.unused_import(self.base_id).add(id); + } + } else { + self.check_import(id); + } + } + fn unused_import(&mut self, id: ast::NodeId) -> &mut UnusedImport { let use_tree_id = self.base_id; let use_tree = self.base_use_tree.unwrap().clone(); @@ -225,13 +240,21 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> { impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> { fn visit_item(&mut self, item: &'a ast::Item) { - match item.kind { + self.item_span = item.span_with_attributes(); + match &item.kind { // Ignore is_public import statements because there's no way to be sure // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. ast::ItemKind::Use(..) if item.span.is_dummy() => return, - ast::ItemKind::ExternCrate(orig_name, ident) => { + // Use the base UseTree's NodeId as the item id + // This allows the grouping of all the lints in the same item + ast::ItemKind::Use(use_tree) => { + self.base_id = item.id; + self.base_use_tree = Some(use_tree); + self.check_use_tree(use_tree, item.id); + } + &ast::ItemKind::ExternCrate(orig_name, ident) => { self.extern_crate_items.push(ExternCrateToLint { id: item.id, span: item.span, @@ -245,32 +268,12 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'ra, 'tcx> { _ => {} } - self.item_span = item.span_with_attributes(); visit::walk_item(self, item); } - fn visit_use_tree(&mut self, use_tree: &'a ast::UseTree, id: ast::NodeId, nested: bool) { - // Use the base UseTree's NodeId as the item id - // This allows the grouping of all the lints in the same item - if !nested { - self.base_id = id; - self.base_use_tree = Some(use_tree); - } - - if self.r.effective_visibilities.is_exported(self.r.local_def_id(id)) { - self.check_import_as_underscore(use_tree, id); - return; - } - - if let ast::UseTreeKind::Nested { ref items, .. } = use_tree.kind { - if items.is_empty() { - self.unused_import(self.base_id).add(id); - } - } else { - self.check_import(id); - } - - visit::walk_use_tree(self, use_tree, id); + fn visit_nested_use_tree(&mut self, use_tree: &'a ast::UseTree, id: ast::NodeId) { + self.check_use_tree(use_tree, id); + visit::walk_use_tree(self, use_tree); } } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 25485be562269..dc16fe212b110 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -147,7 +147,10 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { DefKind::Macro(macro_kind) } ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, - ItemKind::Use(..) => return visit::walk_item(self, i), + ItemKind::Use(use_tree) => { + self.create_def(i.id, None, DefKind::Use, use_tree.span); + return visit::walk_item(self, i); + } ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => { return self.visit_macro_invoc(i.id); } @@ -232,9 +235,9 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } } - fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) { + fn visit_nested_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId) { self.create_def(id, None, DefKind::Use, use_tree.span); - visit::walk_use_tree(self, use_tree, id); + visit::walk_use_tree(self, use_tree); } fn visit_foreign_item(&mut self, fi: &'a ForeignItem) {