diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 811cb0be9f9..61f2f91635d 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -104,8 +104,16 @@ pub trait MutVisitor: Sized { walk_use_tree(self, use_tree); } + fn visit_foreign_item(&mut self, ni: &mut P) { + walk_item(self, ni); + } + 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 visit_item(&mut self, i: &mut P) { + walk_item(self, i); } fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { @@ -116,10 +124,18 @@ pub trait MutVisitor: Sized { walk_fn_header(self, header); } + fn visit_field_def(&mut self, fd: &mut FieldDef) { + walk_field_def(self, fd); + } + fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> { walk_flat_map_field_def(self, fd) } + fn visit_assoc_item(&mut self, i: &mut P, ctxt: AssocCtxt) { + walk_assoc_item(self, i, ctxt) + } + fn flat_map_assoc_item( &mut self, i: P, @@ -153,6 +169,10 @@ pub trait MutVisitor: Sized { walk_flat_map_stmt(self, s) } + fn visit_arm(&mut self, arm: &mut Arm) { + walk_arm(self, arm); + } + fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { walk_flat_map_arm(self, arm) } @@ -199,6 +219,10 @@ pub trait MutVisitor: Sized { walk_foreign_mod(self, nm); } + fn visit_variant(&mut self, v: &mut Variant) { + walk_variant(self, v); + } + fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { walk_flat_map_variant(self, v) } @@ -251,6 +275,10 @@ pub trait MutVisitor: Sized { walk_attribute(self, at); } + fn visit_param(&mut self, param: &mut Param) { + walk_param(self, param); + } + fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { walk_flat_map_param(self, param) } @@ -271,6 +299,10 @@ pub trait MutVisitor: Sized { walk_variant_data(self, vdata); } + fn visit_generic_param(&mut self, param: &mut GenericParam) { + walk_generic_param(self, param) + } + fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { walk_flat_map_generic_param(self, param) } @@ -287,6 +319,10 @@ pub trait MutVisitor: Sized { walk_mt(self, mt); } + fn visit_expr_field(&mut self, f: &mut ExprField) { + walk_expr_field(self, f); + } + fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { walk_flat_map_expr_field(self, f) } @@ -311,6 +347,10 @@ pub trait MutVisitor: Sized { // Do nothing. } + fn visit_pat_field(&mut self, fp: &mut PatField) { + walk_pat_field(self, fp) + } + fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { walk_flat_map_pat_field(self, fp) } @@ -429,16 +469,20 @@ pub fn visit_delim_span(vis: &mut T, DelimSpan { open, close }: & 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; +pub fn walk_pat_field(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( + vis: &mut T, + mut fp: PatField, +) -> SmallVec<[PatField; 1]> { + vis.visit_pat_field(&mut fp); smallvec![fp] } @@ -459,14 +503,18 @@ fn walk_use_tree(vis: &mut T, use_tree: &mut UseTree) { 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; +pub fn walk_arm(vis: &mut T, arm: &mut Arm) { + let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = 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); +} + +pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { + vis.visit_arm(&mut arm); smallvec![arm] } @@ -543,11 +591,8 @@ fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { 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; +pub fn walk_variant(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); @@ -555,6 +600,13 @@ pub fn walk_flat_map_variant( 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( + vis: &mut T, + mut variant: Variant, +) -> SmallVec<[Variant; 1]> { + vis.visit_variant(&mut variant); smallvec![variant] } @@ -685,13 +737,17 @@ fn walk_meta_item(vis: &mut T, mi: &mut MetaItem) { 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; +pub fn walk_param(vis: &mut T, param: &mut Param) { + let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_pat(pat); vis.visit_ty(ty); 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] } @@ -950,11 +1006,8 @@ fn walk_precise_capturing_arg(vis: &mut T, arg: &mut PreciseCaptu } } -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; +pub fn walk_generic_param(vis: &mut T, param: &mut GenericParam) { + let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_ident(ident); @@ -972,6 +1025,13 @@ pub fn walk_flat_map_generic_param( if let Some(colon_span) = colon_span { vis.visit_span(colon_span); } +} + +pub fn walk_flat_map_generic_param( + vis: &mut T, + mut param: GenericParam, +) -> SmallVec<[GenericParam; 1]> { + vis.visit_generic_param(&mut param); smallvec![param] } @@ -1054,30 +1114,38 @@ fn walk_poly_trait_ref(vis: &mut T, p: &mut PolyTraitRef) { 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; +pub fn walk_field_def(visitor: &mut T, fd: &mut FieldDef) { + let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = 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); +} + +pub fn walk_flat_map_field_def( + vis: &mut T, + mut fd: FieldDef, +) -> SmallVec<[FieldDef; 1]> { + vis.visit_field_def(&mut fd); smallvec![fd] } +pub fn walk_expr_field(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( 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] } @@ -1331,18 +1399,19 @@ pub fn walk_crate(vis: &mut T, krate: &mut Crate) { vis.visit_span(inject_use_span); } -pub fn walk_flat_map_item>( - visitor: &mut impl MutVisitor, - item: P>, -) -> SmallVec<[P>; 1]> { - walk_flat_map_assoc_item(visitor, item, ()) +pub fn walk_item(visitor: &mut impl MutVisitor, item: &mut P>>) { + walk_item_ctxt(visitor, item, ()) } -pub fn walk_flat_map_assoc_item( +pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P, ctxt: AssocCtxt) { + walk_item_ctxt(visitor, item, ctxt) +} + +fn walk_item_ctxt( visitor: &mut impl MutVisitor, - mut item: P>, + item: &mut P>, ctxt: K::Ctxt, -) -> SmallVec<[P>; 1]> { +) { let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut(); visitor.visit_id(id); visit_attrs(visitor, attrs); @@ -1351,6 +1420,27 @@ pub fn walk_flat_map_assoc_item( kind.walk(*span, *id, ident, vis, ctxt, 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] +} + +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] } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index c121e7711ee..0302c9fa7f8 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -463,13 +463,6 @@ impl WalkItemKind for ItemKind { } } -pub fn walk_item<'a, V: Visitor<'a>>( - visitor: &mut V, - item: &'a Item>, -) -> V::Result { - walk_assoc_item(visitor, item, ()) -} - pub fn walk_enum_def<'a, V: Visitor<'a>>( visitor: &mut V, EnumDef { variants }: &'a EnumDef, @@ -931,7 +924,22 @@ impl WalkItemKind for AssocItemKind { } } -pub fn walk_assoc_item<'a, V: Visitor<'a>, K: WalkItemKind>( +pub fn walk_item<'a, V: Visitor<'a>>( + visitor: &mut V, + item: &'a Item>, +) -> V::Result { + walk_item_ctxt(visitor, item, ()) +} + +pub fn walk_assoc_item<'a, V: Visitor<'a>>( + visitor: &mut V, + item: &'a AssocItem, + ctxt: AssocCtxt, +) -> V::Result { + walk_item_ctxt(visitor, item, ctxt) +} + +fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>( visitor: &mut V, item: &'a Item, ctxt: K::Ctxt, diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index e7ee6b43e27..d46a1bd3d31 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -215,7 +215,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_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index ba5d34359aa..b2048c534a4 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -1,6 +1,6 @@ // Code that generates a test runner to run all the tests in a crate -use std::{iter, mem}; +use std::mem; use rustc_ast as ast; use rustc_ast::entry::EntryPointType; @@ -19,7 +19,7 @@ use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency}; use rustc_span::symbol::{Ident, Symbol, sym}; use rustc_span::{DUMMY_SP, Span}; use rustc_target::spec::PanicStrategy; -use smallvec::{SmallVec, smallvec}; +use smallvec::smallvec; use thin_vec::{ThinVec, thin_vec}; use tracing::debug; @@ -129,8 +129,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { c.items.push(mk_main(&mut self.cx)); } - fn flat_map_item(&mut self, mut i: P) -> SmallVec<[P; 1]> { - let item = &mut *i; + fn visit_item(&mut self, item: &mut P) { + let item = &mut **item; + if let Some(name) = get_test_name(&item) { debug!("this is a test item"); @@ -158,7 +159,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> { // But in those cases, we emit a lint to warn the user of these missing tests. walk_item(&mut InnerItemLinter { sess: self.cx.ext_cx.sess }, &item); } - smallvec![i] } } @@ -198,40 +198,30 @@ struct EntryPointCleaner<'a> { } impl<'a> MutVisitor for EntryPointCleaner<'a> { - fn flat_map_item(&mut self, i: P) -> SmallVec<[P; 1]> { + fn visit_item(&mut self, item: &mut P) { self.depth += 1; - let item = walk_flat_map_item(self, i).expect_one("noop did something"); + ast::mut_visit::walk_item(self, item); self.depth -= 1; // Remove any #[rustc_main] or #[start] from the AST so it doesn't // clash with the one we're going to add, but mark it as // #[allow(dead_code)] to avoid printing warnings. - let item = match entry_point_type(&item, self.depth == 0) { + match entry_point_type(&item, self.depth == 0) { EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => { - item.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| { - let allow_dead_code = attr::mk_attr_nested_word( - &self.sess.psess.attr_id_generator, - ast::AttrStyle::Outer, - ast::Safety::Default, - sym::allow, - sym::dead_code, - self.def_site, - ); - let attrs = attrs - .into_iter() - .filter(|attr| { - !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start) - }) - .chain(iter::once(allow_dead_code)) - .collect(); - - ast::Item { id, ident, attrs, kind, vis, span, tokens } - }) + let allow_dead_code = attr::mk_attr_nested_word( + &self.sess.psess.attr_id_generator, + ast::AttrStyle::Outer, + ast::Safety::Default, + sym::allow, + sym::dead_code, + self.def_site, + ); + item.attrs + .retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start)); + item.attrs.push(allow_dead_code); } - EntryPointType::None | EntryPointType::OtherMain => item, + EntryPointType::None | EntryPointType::OtherMain => {} }; - - smallvec![item] } } @@ -292,7 +282,7 @@ fn generate_test_harness( /// Most of the Ident have the usual def-site hygiene for the AST pass. The /// exception is the `test_const`s. These have a syntax context that has two /// opaque marks: one from the expansion of `test` or `test_case`, and one -/// generated in `TestHarnessGenerator::flat_map_item`. When resolving this +/// generated in `TestHarnessGenerator::visit_item`. When resolving this /// identifier after failing to find a matching identifier in the root module /// we remove the outer mark, and try resolving at its def-site, which will /// then resolve to `test_const`. diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 91786462b40..19c2d466f7c 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1382,7 +1382,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 90206b19bd5..bae16a18bcb 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), } } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index ef9b3dbd13b..4f3184f1d7c 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -230,15 +230,16 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) { - self.with_lint_attrs(item.id, &item.attrs, |cx| match ctxt { - ast_visit::AssocCtxt::Trait => { - lint_callback!(cx, check_trait_item, item); - ast_visit::walk_assoc_item(cx, item, ctxt); - } - ast_visit::AssocCtxt::Impl => { - lint_callback!(cx, check_impl_item, item); - ast_visit::walk_assoc_item(cx, item, ctxt); + self.with_lint_attrs(item.id, &item.attrs, |cx| { + match ctxt { + ast_visit::AssocCtxt::Trait => { + lint_callback!(cx, check_trait_item, item); + } + ast_visit::AssocCtxt::Impl => { + lint_callback!(cx, check_impl_item, item); + } } + ast_visit::walk_assoc_item(cx, item, ctxt); }); }