From b8c6b0f705a7ea4ffb81b4cc37bd819a48b752b8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 9 May 2025 16:20:32 +1000 Subject: [PATCH 1/2] expand: Use `Option` instead of `SmallVec<1>` where possible. For most of the AST fragment kinds involved in expansion, we use `SmallVec<[T; 1]>` for the type produced. This is necessary for things like items and statements, but for many other things like arms, variants, and params, we never produce more than one, so an `Option` is sufficient. Specifics: - Numerous `flat_map_foo` methods that currently return a `SmallVec` are renamed as `filter_map_foo` and now return an `Option`. (This mirrors the existing `filter_map_expr`.) - Likewise, numerous plural `make_foos` methods that are also renamed as singular `make_foo`. - Also, various AST fragment kinds are renamed from plural to singular. - The `ast_fragments!` macro gets a new `option` kind, to augment the existing `one` and `many` kinds. - `visit_clobber_opt` is added. It's similar to `visit_clobber`. - In `expect_from_annotables`, it now checks that there aren't any excess elements in the iterator. - The associated type `InvocationCollectorNode::OutputTy` no longer has a default value, because it now varies more. It used to mostly be `SmallVec`, but not it is sometimes `SmallVec`, sometimes `Option`, and sometimes something else. --- compiler/rustc_ast/src/mut_visit.rs | 125 ++++---- compiler/rustc_builtin_macros/src/cfg_eval.rs | 31 +- .../src/deriving/coerce_pointee.rs | 2 +- compiler/rustc_expand/src/base.rs | 44 +-- compiler/rustc_expand/src/expand.rs | 272 ++++++++++-------- compiler/rustc_expand/src/placeholders.rs | 123 ++++---- 6 files changed, 310 insertions(+), 287 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index a90349f318c09..792cc8b765752 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -48,9 +48,9 @@ pub trait WalkItemKind { pub trait MutVisitor: Sized { // 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 + // fn visit_t(&mut self, t: &mut T); + // fn filter_map_t(&mut self, t: T) -> Option; + // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // // 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 @@ -119,8 +119,8 @@ pub trait MutVisitor: Sized { 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 filter_map_field_def(&mut self, fd: FieldDef) -> Option { + walk_filter_map_field_def(self, fd) } fn visit_assoc_item(&mut self, i: &mut P, ctxt: AssocCtxt) { @@ -168,8 +168,8 @@ pub trait MutVisitor: Sized { walk_arm(self, arm); } - fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> { - walk_flat_map_arm(self, arm) + fn filter_map_arm(&mut self, arm: Arm) -> Option { + walk_filter_map_arm(self, arm) } fn visit_pat(&mut self, p: &mut P) { @@ -222,8 +222,8 @@ pub trait MutVisitor: Sized { walk_variant(self, v); } - fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> { - walk_flat_map_variant(self, v) + fn filter_map_variant(&mut self, v: Variant) -> Option { + walk_filter_map_variant(self, v) } fn visit_ident(&mut self, i: &mut Ident) { @@ -282,8 +282,8 @@ pub trait MutVisitor: Sized { walk_param(self, param); } - fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> { - walk_flat_map_param(self, param) + fn filter_map_param(&mut self, param: Param) -> Option { + walk_filter_map_param(self, param) } fn visit_generics(&mut self, generics: &mut Generics) { @@ -306,8 +306,8 @@ pub trait MutVisitor: Sized { walk_generic_param(self, param) } - fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> { - walk_flat_map_generic_param(self, param) + fn filter_map_generic_param(&mut self, param: GenericParam) -> Option { + walk_filter_map_generic_param(self, param) } fn visit_param_bound(&mut self, tpb: &mut GenericBound, _ctxt: BoundKind) { @@ -326,19 +326,19 @@ pub trait MutVisitor: Sized { walk_expr_field(self, f); } - fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> { - walk_flat_map_expr_field(self, f) + fn filter_map_expr_field(&mut self, f: ExprField) -> Option { + walk_filter_map_expr_field(self, f) } fn visit_where_clause(&mut self, where_clause: &mut WhereClause) { walk_where_clause(self, where_clause); } - fn flat_map_where_predicate( + fn filter_map_where_predicate( &mut self, where_predicate: WherePredicate, - ) -> SmallVec<[WherePredicate; 1]> { - walk_flat_map_where_predicate(self, where_predicate) + ) -> Option { + walk_filter_map_where_predicate(self, where_predicate) } fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) { @@ -363,8 +363,8 @@ pub trait MutVisitor: Sized { walk_pat_field(self, fp) } - fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> { - walk_flat_map_pat_field(self, fp) + fn filter_map_pat_field(&mut self, fp: PatField) -> Option { + walk_filter_map_pat_field(self, fp) } fn visit_inline_asm(&mut self, asm: &mut InlineAsm) { @@ -400,6 +400,11 @@ pub fn visit_clobber(t: &mut T, f: impl FnOnce(T) -> T) { *t = f(old_t); } +pub fn visit_clobber_opt(t: &mut Option, f: impl FnOnce(T) -> Option) { + let old_t = std::mem::replace(t, None); + *t = old_t.and_then(|new_t| f(new_t)); +} + // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] fn visit_vec(elems: &mut Vec, mut visit_elem: F) @@ -485,12 +490,9 @@ pub fn walk_pat_field(vis: &mut T, fp: &mut PatField) { vis.visit_span(span); } -pub fn walk_flat_map_pat_field( - vis: &mut T, - mut fp: PatField, -) -> SmallVec<[PatField; 1]> { +pub fn walk_filter_map_pat_field(vis: &mut T, mut fp: PatField) -> Option { vis.visit_pat_field(&mut fp); - smallvec![fp] + Some(fp) } fn walk_use_tree(vis: &mut T, use_tree: &mut UseTree) { @@ -520,9 +522,9 @@ pub fn walk_arm(vis: &mut T, arm: &mut Arm) { vis.visit_span(span); } -pub fn walk_flat_map_arm(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> { +pub fn walk_filter_map_arm(vis: &mut T, mut arm: Arm) -> Option { vis.visit_arm(&mut arm); - smallvec![arm] + Some(arm) } fn walk_assoc_item_constraint( @@ -560,13 +562,13 @@ pub fn walk_ty(vis: &mut T, ty: &mut P) { 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)); + generic_params.flat_map_in_place(|param| vis.filter_map_generic_param(param)); vis.visit_fn_decl(decl); vis.visit_span(decl_span); } TyKind::UnsafeBinder(binder) => { let UnsafeBinderTy { generic_params, inner_ty } = binder.deref_mut(); - generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + generic_params.flat_map_in_place(|param| vis.filter_map_generic_param(param)); vis.visit_ty(inner_ty); } TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)), @@ -627,12 +629,12 @@ pub fn walk_variant(visitor: &mut T, variant: &mut Variant) { visitor.visit_span(span); } -pub fn walk_flat_map_variant( +pub fn walk_filter_map_variant( vis: &mut T, mut variant: Variant, -) -> SmallVec<[Variant; 1]> { +) -> Option { vis.visit_variant(&mut variant); - smallvec![variant] + Some(variant) } fn walk_ident(vis: &mut T, Ident { name: _, span }: &mut Ident) { @@ -766,9 +768,9 @@ pub fn walk_param(vis: &mut T, param: &mut Param) { vis.visit_span(span); } -pub fn walk_flat_map_param(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> { +pub fn walk_filter_map_param(vis: &mut T, mut param: Param) -> Option { vis.visit_param(&mut param); - smallvec![param] + Some(param) } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. @@ -791,7 +793,7 @@ 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)); + generic_params.flat_map_in_place(|param| vis.filter_map_generic_param(param)); } } } @@ -860,7 +862,7 @@ fn walk_contract(vis: &mut T, contract: &mut P) { 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)); + inputs.flat_map_in_place(|param| vis.filter_map_param(param)); vis.visit_fn_ret_ty(output); } @@ -917,17 +919,17 @@ pub fn walk_generic_param(vis: &mut T, param: &mut GenericParam) } } -pub fn walk_flat_map_generic_param( +pub fn walk_filter_map_generic_param( vis: &mut T, mut param: GenericParam, -) -> SmallVec<[GenericParam; 1]> { +) -> Option { vis.visit_generic_param(&mut param); - smallvec![param] + Some(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)); + params.flat_map_in_place(|param| vis.filter_map_generic_param(param)); vis.visit_where_clause(where_clause); vis.visit_span(span); } @@ -942,27 +944,27 @@ fn walk_ty_alias_where_clauses(vis: &mut T, tawcs: &mut TyAliasWh fn walk_where_clause(vis: &mut T, wc: &mut WhereClause) { let WhereClause { has_where_token: _, predicates, span } = wc; - predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate)); + predicates.flat_map_in_place(|predicate| vis.filter_map_where_predicate(predicate)); vis.visit_span(span); } -pub fn walk_flat_map_where_predicate( +pub fn walk_filter_map_where_predicate( vis: &mut T, mut pred: WherePredicate, -) -> SmallVec<[WherePredicate; 1]> { +) -> Option { let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred; vis.visit_id(id); visit_attrs(vis, attrs); vis.visit_where_predicate_kind(kind); vis.visit_span(span); - smallvec![pred] + Some(pred) } pub fn walk_where_predicate_kind(vis: &mut T, kind: &mut WherePredicateKind) { match kind { WherePredicateKind::BoundPredicate(bp) => { let WhereBoundPredicate { bound_generic_params, bounded_ty, bounds } = bp; - bound_generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); + bound_generic_params.flat_map_in_place(|param| vis.filter_map_generic_param(param)); vis.visit_ty(bounded_ty); visit_vec(bounds, |bound| vis.visit_param_bound(bound, BoundKind::Bound)); } @@ -982,11 +984,11 @@ pub fn walk_where_predicate_kind(vis: &mut T, kind: &mut WherePre 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)); + fields.flat_map_in_place(|field| vis.filter_map_field_def(field)); } VariantData::Tuple(fields, id) => { vis.visit_id(id); - fields.flat_map_in_place(|field| vis.flat_map_field_def(field)); + fields.flat_map_in_place(|field| vis.filter_map_field_def(field)); } VariantData::Unit(id) => vis.visit_id(id), } @@ -1000,7 +1002,7 @@ fn walk_trait_ref(vis: &mut T, TraitRef { path, ref_id }: &mut Tr fn walk_poly_trait_ref(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)); + bound_generic_params.flat_map_in_place(|param| vis.filter_map_generic_param(param)); vis.visit_trait_ref(trait_ref); vis.visit_span(span); } @@ -1033,12 +1035,9 @@ pub fn walk_field_def(visitor: &mut T, fd: &mut FieldDef) { visitor.visit_span(span); } -pub fn walk_flat_map_field_def( - vis: &mut T, - mut fd: FieldDef, -) -> SmallVec<[FieldDef; 1]> { +pub fn walk_filter_map_field_def(vis: &mut T, mut fd: FieldDef) -> Option { vis.visit_field_def(&mut fd); - smallvec![fd] + Some(fd) } pub fn walk_expr_field(vis: &mut T, f: &mut ExprField) { @@ -1050,12 +1049,12 @@ pub fn walk_expr_field(vis: &mut T, f: &mut ExprField) { vis.visit_span(span); } -pub fn walk_flat_map_expr_field( +pub fn walk_filter_map_expr_field( vis: &mut T, mut f: ExprField, -) -> SmallVec<[ExprField; 1]> { +) -> Option { vis.visit_expr_field(&mut f); - smallvec![f] + Some(f) } fn walk_mt(vis: &mut T, MutTy { ty, mutbl: _ }: &mut MutTy) { @@ -1149,7 +1148,7 @@ impl WalkItemKind for ItemKind { ItemKind::Enum(ident, EnumDef { variants }, generics) => { vis.visit_ident(ident); vis.visit_generics(generics); - variants.flat_map_in_place(|variant| vis.flat_map_variant(variant)); + variants.flat_map_in_place(|variant| vis.filter_map_variant(variant)); } ItemKind::Struct(ident, variant_data, generics) | ItemKind::Union(ident, variant_data, generics) => { @@ -1439,7 +1438,7 @@ pub fn walk_pat(vis: &mut T, pat: &mut P) { 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)); + fields.flat_map_in_place(|field| vis.filter_map_pat_field(field)); } PatKind::Box(inner) => vis.visit_pat(inner), PatKind::Deref(inner) => vis.visit_pat(inner), @@ -1595,7 +1594,7 @@ pub fn walk_expr(vis: &mut T, Expr { kind, id, span, attrs, token } ExprKind::Match(expr, arms, _kind) => { vis.visit_expr(expr); - arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); + arms.flat_map_in_place(|arm| vis.filter_map_arm(arm)); } ExprKind::Closure(box Closure { binder, @@ -1684,7 +1683,7 @@ pub fn walk_expr(vis: &mut T, Expr { kind, id, span, attrs, token 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)); + fields.flat_map_in_place(|field| vis.filter_map_expr_field(field)); match rest { StructRest::Base(expr) => vis.visit_expr(expr), StructRest::Rest(_span) => {} @@ -1717,10 +1716,8 @@ pub fn walk_expr(vis: &mut T, Expr { kind, id, span, attrs, token } pub fn noop_filter_map_expr(vis: &mut T, mut e: P) -> Option> { - Some({ - vis.visit_expr(&mut e); - e - }) + vis.visit_expr(&mut e); + Some(e) } pub fn walk_flat_map_stmt( diff --git a/compiler/rustc_builtin_macros/src/cfg_eval.rs b/compiler/rustc_builtin_macros/src/cfg_eval.rs index da01e3e9607bb..8c00c65c97ec8 100644 --- a/compiler/rustc_builtin_macros/src/cfg_eval.rs +++ b/compiler/rustc_builtin_macros/src/cfg_eval.rs @@ -172,12 +172,9 @@ impl MutVisitor for CfgEval<'_> { Some(expr) } - fn flat_map_generic_param( - &mut self, - param: ast::GenericParam, - ) -> SmallVec<[ast::GenericParam; 1]> { + fn filter_map_generic_param(&mut self, param: ast::GenericParam) -> Option { let param = configure!(self, param); - mut_visit::walk_flat_map_generic_param(self, param) + mut_visit::walk_filter_map_generic_param(self, param) } fn flat_map_stmt(&mut self, stmt: ast::Stmt) -> SmallVec<[ast::Stmt; 1]> { @@ -207,33 +204,33 @@ impl MutVisitor for CfgEval<'_> { mut_visit::walk_flat_map_foreign_item(self, foreign_item) } - fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { + fn filter_map_arm(&mut self, arm: ast::Arm) -> Option { let arm = configure!(self, arm); - mut_visit::walk_flat_map_arm(self, arm) + mut_visit::walk_filter_map_arm(self, arm) } - fn flat_map_expr_field(&mut self, field: ast::ExprField) -> SmallVec<[ast::ExprField; 1]> { + fn filter_map_expr_field(&mut self, field: ast::ExprField) -> Option { let field = configure!(self, field); - mut_visit::walk_flat_map_expr_field(self, field) + mut_visit::walk_filter_map_expr_field(self, field) } - fn flat_map_pat_field(&mut self, fp: ast::PatField) -> SmallVec<[ast::PatField; 1]> { + fn filter_map_pat_field(&mut self, fp: ast::PatField) -> Option { let fp = configure!(self, fp); - mut_visit::walk_flat_map_pat_field(self, fp) + mut_visit::walk_filter_map_pat_field(self, fp) } - fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> { + fn filter_map_param(&mut self, p: ast::Param) -> Option { let p = configure!(self, p); - mut_visit::walk_flat_map_param(self, p) + mut_visit::walk_filter_map_param(self, p) } - fn flat_map_field_def(&mut self, sf: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> { + fn filter_map_field_def(&mut self, sf: ast::FieldDef) -> Option { let sf = configure!(self, sf); - mut_visit::walk_flat_map_field_def(self, sf) + mut_visit::walk_filter_map_field_def(self, sf) } - fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> { + fn filter_map_variant(&mut self, variant: ast::Variant) -> Option { let variant = configure!(self, variant); - mut_visit::walk_flat_map_variant(self, variant) + mut_visit::walk_filter_map_variant(self, variant) } } diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs index 446d8afeedd7f..5f6c15210f56f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs +++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs @@ -394,7 +394,7 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> { rustc_ast::WherePredicateKind::BoundPredicate(bound) => { bound .bound_generic_params - .flat_map_in_place(|param| self.flat_map_generic_param(param)); + .flat_map_in_place(|param| self.filter_map_generic_param(param)); self.visit_ty(&mut bound.bounded_ty); for bound in &mut bound.bounds { self.visit_param_bound(bound, BoundKind::Bound) diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 55751aa49089b..58582ec47625c 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -435,35 +435,35 @@ pub trait MacResult { None } - fn make_arms(self: Box) -> Option> { + fn make_arm(self: Box) -> Option> { None } - fn make_expr_fields(self: Box) -> Option> { + fn make_expr_field(self: Box) -> Option> { None } - fn make_pat_fields(self: Box) -> Option> { + fn make_pat_field(self: Box) -> Option> { None } - fn make_generic_params(self: Box) -> Option> { + fn make_generic_param(self: Box) -> Option> { None } - fn make_params(self: Box) -> Option> { + fn make_param(self: Box) -> Option> { None } - fn make_field_defs(self: Box) -> Option> { + fn make_field_def(self: Box) -> Option> { None } - fn make_variants(self: Box) -> Option> { + fn make_variant(self: Box) -> Option> { None } - fn make_where_predicates(self: Box) -> Option> { + fn make_where_predicate(self: Box) -> Option> { None } @@ -654,32 +654,32 @@ impl MacResult for DummyResult { })) } - fn make_arms(self: Box) -> Option> { - Some(SmallVec::new()) + fn make_arm(self: Box) -> Option> { + Some(None) } - fn make_expr_fields(self: Box) -> Option> { - Some(SmallVec::new()) + fn make_expr_field(self: Box) -> Option> { + Some(None) } - fn make_pat_fields(self: Box) -> Option> { - Some(SmallVec::new()) + fn make_pat_field(self: Box) -> Option> { + Some(None) } - fn make_generic_params(self: Box) -> Option> { - Some(SmallVec::new()) + fn make_generic_param(self: Box) -> Option> { + Some(None) } - fn make_params(self: Box) -> Option> { - Some(SmallVec::new()) + fn make_param(self: Box) -> Option> { + Some(None) } - fn make_field_defs(self: Box) -> Option> { - Some(SmallVec::new()) + fn make_field_def(self: Box) -> Option> { + Some(None) } - fn make_variants(self: Box) -> Option> { - Some(SmallVec::new()) + fn make_variant(self: Box) -> Option> { + Some(None) } fn make_crate(self: Box) -> Option { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 81d4d59ee0451..47ab0bf43a4b2 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -48,8 +48,9 @@ macro_rules! ast_fragments { ( $($Kind:ident($AstTy:ty) { $kind_name:expr; - $(one fn $mut_visit_ast:ident; fn $visit_ast:ident;)? - $(many fn $flat_map_ast_elt:ident; fn $visit_ast_elt:ident($($args:tt)*);)? + $(one fn $mut_visit_ast:ident; fn $one_visit_ast:ident;)? + $(option fn $filter_map_ast:ident; fn $option_visit_ast:ident;)? + $(many fn $flat_map_ast_elt:ident; fn $many_visit_ast:ident($($many_args:tt)*);)? fn $make_ast:ident; })* ) => { @@ -131,18 +132,17 @@ macro_rules! ast_fragments { pub(crate) fn mut_visit_with(&mut self, vis: &mut F) { match self { AstFragment::OptExpr(opt_expr) => { - visit_clobber(opt_expr, |opt_expr| { - if let Some(expr) = opt_expr { - vis.filter_map_expr(expr) - } else { - None - } - }); + visit_clobber_opt(opt_expr, |expr| vis.filter_map_expr(expr)); } AstFragment::MethodReceiverExpr(expr) => vis.visit_method_receiver_expr(expr), $($(AstFragment::$Kind(ast) => vis.$mut_visit_ast(ast),)?)* $($(AstFragment::$Kind(ast) => - ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($args)*)),)?)* + ast.flat_map_in_place(|ast| vis.$flat_map_ast_elt(ast, $($many_args)*)),)?)* + $($( + AstFragment::$Kind(ast) => { + visit_clobber_opt(ast, |ast| vis.$filter_map_ast(ast)); + } + )?)* } } @@ -150,9 +150,21 @@ macro_rules! ast_fragments { match self { AstFragment::OptExpr(Some(expr)) => try_visit!(visitor.visit_expr(expr)), AstFragment::OptExpr(None) => {} - AstFragment::MethodReceiverExpr(expr) => try_visit!(visitor.visit_method_receiver_expr(expr)), - $($(AstFragment::$Kind(ast) => try_visit!(visitor.$visit_ast(ast)),)?)* - $($(AstFragment::$Kind(ast) => walk_list!(visitor, $visit_ast_elt, &ast[..], $($args)*),)?)* + AstFragment::MethodReceiverExpr(expr) => { + try_visit!(visitor.visit_method_receiver_expr(expr)) + } + $($( + AstFragment::$Kind(ast) => try_visit!(visitor.$one_visit_ast(ast)), + )?)* + $($( + AstFragment::$Kind(ast) => { + walk_list!(visitor, $many_visit_ast, &ast[..], $($many_args)*) + } + )?)* + $($( + AstFragment::$Kind(Some(ast)) => try_visit!(visitor.$option_visit_ast(ast)), + AstFragment::$Kind(None) => {} + )?)* } V::Result::output() } @@ -201,42 +213,39 @@ ast_fragments! { fn visit_foreign_item(); fn make_foreign_items; } - Arms(SmallVec<[ast::Arm; 1]>) { - "match arm"; many fn flat_map_arm; fn visit_arm(); fn make_arms; + Arm(Option) { + "match arm"; option fn filter_map_arm; fn visit_arm; fn make_arm; } - ExprFields(SmallVec<[ast::ExprField; 1]>) { - "field expression"; many fn flat_map_expr_field; fn visit_expr_field(); fn make_expr_fields; + ExprField(Option) { + "field expression"; + option fn filter_map_expr_field; + fn visit_expr_field; + fn make_expr_field; } - PatFields(SmallVec<[ast::PatField; 1]>) { - "field pattern"; - many fn flat_map_pat_field; - fn visit_pat_field(); - fn make_pat_fields; + PatField(Option) { + "field pattern"; option fn filter_map_pat_field; fn visit_pat_field; fn make_pat_field; } - GenericParams(SmallVec<[ast::GenericParam; 1]>) { + GenericParam(Option) { "generic parameter"; - many fn flat_map_generic_param; - fn visit_generic_param(); - fn make_generic_params; + option fn filter_map_generic_param; + fn visit_generic_param; + fn make_generic_param; } - Params(SmallVec<[ast::Param; 1]>) { - "function parameter"; many fn flat_map_param; fn visit_param(); fn make_params; + Param(Option) { + "function parameter"; option fn filter_map_param; fn visit_param; fn make_param; } - FieldDefs(SmallVec<[ast::FieldDef; 1]>) { - "field"; - many fn flat_map_field_def; - fn visit_field_def(); - fn make_field_defs; + FieldDef(Option) { + "field"; option fn filter_map_field_def; fn visit_field_def; fn make_field_def; } - Variants(SmallVec<[ast::Variant; 1]>) { - "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants; + Variant(Option) { + "variant"; option fn filter_map_variant; fn visit_variant; fn make_variant; } - WherePredicates(SmallVec<[ast::WherePredicate; 1]>) { + WherePredicate(Option) { "where predicate"; - many fn flat_map_where_predicate; - fn visit_where_predicate(); - fn make_where_predicates; - } + option fn filter_map_where_predicate; + fn visit_where_predicate; + fn make_where_predicate; + } Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; } } @@ -264,14 +273,14 @@ impl AstFragmentKind { | AstFragmentKind::TraitImplItems | AstFragmentKind::ForeignItems | AstFragmentKind::Crate => SupportsMacroExpansion::Yes { supports_inner_attrs: true }, - AstFragmentKind::Arms - | AstFragmentKind::ExprFields - | AstFragmentKind::PatFields - | AstFragmentKind::GenericParams - | AstFragmentKind::Params - | AstFragmentKind::FieldDefs - | AstFragmentKind::Variants - | AstFragmentKind::WherePredicates => SupportsMacroExpansion::No, + AstFragmentKind::Arm + | AstFragmentKind::ExprField + | AstFragmentKind::PatField + | AstFragmentKind::GenericParam + | AstFragmentKind::Param + | AstFragmentKind::FieldDef + | AstFragmentKind::Variant + | AstFragmentKind::WherePredicate => SupportsMacroExpansion::No, } } @@ -280,31 +289,48 @@ impl AstFragmentKind { items: I, ) -> AstFragment { let mut items = items.into_iter(); + + macro_rules! expect_one { + ($items:ident, $expect:ident, $ast_fragment_ctor:path) => {{ + let fragment = $items.next().expect("expected exactly one AST fragment").$expect(); + assert!($items.next().is_none()); + $ast_fragment_ctor(fragment) + }}; + } + + macro_rules! expect_one_as_option { + ($items:ident, $expect:ident, $ast_fragment_ctor:path) => {{ + let fragment = $items.next().expect("expected exactly one AST fragment").$expect(); + assert!($items.next().is_none()); + $ast_fragment_ctor(Some(fragment)) + }}; + } + match self { - AstFragmentKind::Arms => { - AstFragment::Arms(items.map(Annotatable::expect_arm).collect()) + AstFragmentKind::Arm => { + expect_one_as_option!(items, expect_arm, AstFragment::Arm) + } + AstFragmentKind::ExprField => { + expect_one_as_option!(items, expect_expr_field, AstFragment::ExprField) } - AstFragmentKind::ExprFields => { - AstFragment::ExprFields(items.map(Annotatable::expect_expr_field).collect()) + AstFragmentKind::PatField => { + expect_one_as_option!(items, expect_pat_field, AstFragment::PatField) } - AstFragmentKind::PatFields => { - AstFragment::PatFields(items.map(Annotatable::expect_pat_field).collect()) + AstFragmentKind::GenericParam => { + expect_one_as_option!(items, expect_generic_param, AstFragment::GenericParam) } - AstFragmentKind::GenericParams => { - AstFragment::GenericParams(items.map(Annotatable::expect_generic_param).collect()) + AstFragmentKind::Param => { + expect_one_as_option!(items, expect_param, AstFragment::Param) } - AstFragmentKind::Params => { - AstFragment::Params(items.map(Annotatable::expect_param).collect()) + AstFragmentKind::FieldDef => { + expect_one_as_option!(items, expect_field_def, AstFragment::FieldDef) } - AstFragmentKind::FieldDefs => { - AstFragment::FieldDefs(items.map(Annotatable::expect_field_def).collect()) + AstFragmentKind::Variant => { + expect_one_as_option!(items, expect_variant, AstFragment::Variant) } - AstFragmentKind::Variants => { - AstFragment::Variants(items.map(Annotatable::expect_variant).collect()) + AstFragmentKind::WherePredicate => { + expect_one_as_option!(items, expect_where_predicate, AstFragment::WherePredicate) } - AstFragmentKind::WherePredicates => AstFragment::WherePredicates( - items.map(Annotatable::expect_where_predicate).collect(), - ), AstFragmentKind::Items => { AstFragment::Items(items.map(Annotatable::expect_item).collect()) } @@ -323,17 +349,19 @@ impl AstFragmentKind { AstFragmentKind::Stmts => { AstFragment::Stmts(items.map(Annotatable::expect_stmt).collect()) } - AstFragmentKind::Expr => AstFragment::Expr( - items.next().expect("expected exactly one expression").expect_expr(), - ), - AstFragmentKind::MethodReceiverExpr => AstFragment::MethodReceiverExpr( - items.next().expect("expected exactly one expression").expect_expr(), - ), + AstFragmentKind::Expr => { + expect_one!(items, expect_expr, AstFragment::Expr) + } + AstFragmentKind::MethodReceiverExpr => { + expect_one!(items, expect_expr, AstFragment::MethodReceiverExpr) + } AstFragmentKind::OptExpr => { - AstFragment::OptExpr(items.next().map(Annotatable::expect_expr)) + let fragment = AstFragment::OptExpr(items.next().map(Annotatable::expect_expr)); + assert!(items.next().is_none()); + fragment } AstFragmentKind::Crate => { - AstFragment::Crate(items.next().expect("expected exactly one crate").expect_crate()) + expect_one!(items, expect_crate, AstFragment::Crate) } AstFragmentKind::Pat | AstFragmentKind::Ty => { panic!("patterns and types aren't annotatable") @@ -1026,14 +1054,14 @@ pub fn parse_ast_fragment<'a>( CommaRecoveryMode::LikelyTuple, )?), AstFragmentKind::Crate => AstFragment::Crate(this.parse_crate_mod()?), - AstFragmentKind::Arms - | AstFragmentKind::ExprFields - | AstFragmentKind::PatFields - | AstFragmentKind::GenericParams - | AstFragmentKind::Params - | AstFragmentKind::FieldDefs - | AstFragmentKind::Variants - | AstFragmentKind::WherePredicates => panic!("unexpected AST fragment kind"), + AstFragmentKind::Arm + | AstFragmentKind::ExprField + | AstFragmentKind::PatField + | AstFragmentKind::GenericParam + | AstFragmentKind::Param + | AstFragmentKind::FieldDef + | AstFragmentKind::Variant + | AstFragmentKind::WherePredicate => panic!("unexpected AST fragment kind"), }) } @@ -1115,7 +1143,7 @@ enum AddSemicolon { /// A trait implemented for all `AstFragment` nodes and providing all pieces /// of functionality used by `InvocationCollector`. trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { - type OutputTy = SmallVec<[Self; 1]>; + type OutputTy; type ItemKind = ItemKind; const KIND: AstFragmentKind; fn to_annotatable(self) -> Annotatable; @@ -1174,6 +1202,7 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized { } impl InvocationCollectorNode for P { + type OutputTy = SmallVec<[Self; 1]>; const KIND: AstFragmentKind = AstFragmentKind::Items; fn to_annotatable(self) -> Annotatable { Annotatable::Item(self) @@ -1450,6 +1479,7 @@ impl InvocationCollectorNode for AstNodeWrapper, TraitImplItem } impl InvocationCollectorNode for P { + type OutputTy = SmallVec<[Self; 1]>; const KIND: AstFragmentKind = AstFragmentKind::ForeignItems; fn to_annotatable(self) -> Annotatable { Annotatable::ForeignItem(self) @@ -1473,110 +1503,119 @@ impl InvocationCollectorNode for P { } impl InvocationCollectorNode for ast::Variant { - const KIND: AstFragmentKind = AstFragmentKind::Variants; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::Variant; fn to_annotatable(self) -> Annotatable { Annotatable::Variant(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_variants() + fragment.make_variant() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_variant(visitor, self) + walk_filter_map_variant(visitor, self) } } impl InvocationCollectorNode for ast::WherePredicate { - const KIND: AstFragmentKind = AstFragmentKind::WherePredicates; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::WherePredicate; fn to_annotatable(self) -> Annotatable { Annotatable::WherePredicate(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_where_predicates() + fragment.make_where_predicate() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_where_predicate(visitor, self) + walk_filter_map_where_predicate(visitor, self) } } impl InvocationCollectorNode for ast::FieldDef { - const KIND: AstFragmentKind = AstFragmentKind::FieldDefs; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::FieldDef; fn to_annotatable(self) -> Annotatable { Annotatable::FieldDef(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_field_defs() + fragment.make_field_def() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_field_def(visitor, self) + walk_filter_map_field_def(visitor, self) } } impl InvocationCollectorNode for ast::PatField { - const KIND: AstFragmentKind = AstFragmentKind::PatFields; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::PatField; fn to_annotatable(self) -> Annotatable { Annotatable::PatField(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_pat_fields() + fragment.make_pat_field() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_pat_field(visitor, self) + walk_filter_map_pat_field(visitor, self) } } impl InvocationCollectorNode for ast::ExprField { - const KIND: AstFragmentKind = AstFragmentKind::ExprFields; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::ExprField; fn to_annotatable(self) -> Annotatable { Annotatable::ExprField(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_expr_fields() + fragment.make_expr_field() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_expr_field(visitor, self) + walk_filter_map_expr_field(visitor, self) } } impl InvocationCollectorNode for ast::Param { - const KIND: AstFragmentKind = AstFragmentKind::Params; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::Param; fn to_annotatable(self) -> Annotatable { Annotatable::Param(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_params() + fragment.make_param() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_param(visitor, self) + walk_filter_map_param(visitor, self) } } impl InvocationCollectorNode for ast::GenericParam { - const KIND: AstFragmentKind = AstFragmentKind::GenericParams; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::GenericParam; fn to_annotatable(self) -> Annotatable { Annotatable::GenericParam(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_generic_params() + fragment.make_generic_param() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_generic_param(visitor, self) + walk_filter_map_generic_param(visitor, self) } } impl InvocationCollectorNode for ast::Arm { - const KIND: AstFragmentKind = AstFragmentKind::Arms; + type OutputTy = Option; + const KIND: AstFragmentKind = AstFragmentKind::Arm; fn to_annotatable(self) -> Annotatable { Annotatable::Arm(self) } fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy { - fragment.make_arms() + fragment.make_arm() } fn walk_flat_map(self, visitor: &mut V) -> Self::OutputTy { - walk_flat_map_arm(visitor, self) + walk_filter_map_arm(visitor, self) } } impl InvocationCollectorNode for ast::Stmt { + type OutputTy = SmallVec<[Self; 1]>; const KIND: AstFragmentKind = AstFragmentKind::Stmts; fn to_annotatable(self) -> Annotatable { Annotatable::Stmt(P(self)) @@ -2205,41 +2244,38 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { self.flat_map_node(node) } - fn flat_map_variant(&mut self, node: ast::Variant) -> SmallVec<[ast::Variant; 1]> { + fn filter_map_variant(&mut self, node: ast::Variant) -> Option { self.flat_map_node(node) } - fn flat_map_where_predicate( + fn filter_map_where_predicate( &mut self, node: ast::WherePredicate, - ) -> SmallVec<[ast::WherePredicate; 1]> { + ) -> Option { self.flat_map_node(node) } - fn flat_map_field_def(&mut self, node: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> { + fn filter_map_field_def(&mut self, node: ast::FieldDef) -> Option { self.flat_map_node(node) } - fn flat_map_pat_field(&mut self, node: ast::PatField) -> SmallVec<[ast::PatField; 1]> { + fn filter_map_pat_field(&mut self, node: ast::PatField) -> Option { self.flat_map_node(node) } - fn flat_map_expr_field(&mut self, node: ast::ExprField) -> SmallVec<[ast::ExprField; 1]> { + fn filter_map_expr_field(&mut self, node: ast::ExprField) -> Option { self.flat_map_node(node) } - fn flat_map_param(&mut self, node: ast::Param) -> SmallVec<[ast::Param; 1]> { + fn filter_map_param(&mut self, node: ast::Param) -> Option { self.flat_map_node(node) } - fn flat_map_generic_param( - &mut self, - node: ast::GenericParam, - ) -> SmallVec<[ast::GenericParam; 1]> { + fn filter_map_generic_param(&mut self, node: ast::GenericParam) -> Option { self.flat_map_node(node) } - fn flat_map_arm(&mut self, node: ast::Arm) -> SmallVec<[ast::Arm; 1]> { + fn filter_map_arm(&mut self, node: ast::Arm) -> Option { self.flat_map_node(node) } diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index 0136292decbcf..a5f019a731198 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -124,7 +124,7 @@ pub(crate) fn placeholder( }); ast::Stmt { id, span, kind: ast::StmtKind::MacCall(mac) } }]), - AstFragmentKind::Arms => AstFragment::Arms(smallvec![ast::Arm { + AstFragmentKind::Arm => AstFragment::Arm(Some(ast::Arm { attrs: Default::default(), body: Some(expr_placeholder()), guard: None, @@ -132,8 +132,8 @@ pub(crate) fn placeholder( pat: pat(), span, is_placeholder: true, - }]), - AstFragmentKind::ExprFields => AstFragment::ExprFields(smallvec![ast::ExprField { + })), + AstFragmentKind::ExprField => AstFragment::ExprField(Some(ast::ExprField { attrs: Default::default(), expr: expr_placeholder(), id, @@ -141,8 +141,8 @@ pub(crate) fn placeholder( is_shorthand: false, span, is_placeholder: true, - }]), - AstFragmentKind::PatFields => AstFragment::PatFields(smallvec![ast::PatField { + })), + AstFragmentKind::PatField => AstFragment::PatField(Some(ast::PatField { attrs: Default::default(), id, ident, @@ -150,27 +150,25 @@ pub(crate) fn placeholder( pat: pat(), span, is_placeholder: true, - }]), - AstFragmentKind::GenericParams => AstFragment::GenericParams(smallvec![{ - ast::GenericParam { - attrs: Default::default(), - bounds: Default::default(), - id, - ident, - is_placeholder: true, - kind: ast::GenericParamKind::Lifetime, - colon_span: None, - } - }]), - AstFragmentKind::Params => AstFragment::Params(smallvec![ast::Param { + })), + AstFragmentKind::GenericParam => AstFragment::GenericParam(Some(ast::GenericParam { + attrs: Default::default(), + bounds: Default::default(), + id, + ident, + is_placeholder: true, + kind: ast::GenericParamKind::Lifetime, + colon_span: None, + })), + AstFragmentKind::Param => AstFragment::Param(Some(ast::Param { attrs: Default::default(), id, pat: pat(), span, ty: ty(), is_placeholder: true, - }]), - AstFragmentKind::FieldDefs => AstFragment::FieldDefs(smallvec![ast::FieldDef { + })), + AstFragmentKind::FieldDef => AstFragment::FieldDef(Some(ast::FieldDef { attrs: Default::default(), id, ident: None, @@ -180,12 +178,12 @@ pub(crate) fn placeholder( is_placeholder: true, safety: Safety::Default, default: None, - }]), - AstFragmentKind::Variants => AstFragment::Variants(smallvec![ast::Variant { + })), + AstFragmentKind::Variant => AstFragment::Variant(Some(ast::Variant { attrs: Default::default(), data: ast::VariantData::Struct { fields: Default::default(), - recovered: ast::Recovered::No + recovered: ast::Recovered::No, }, disr_expr: None, id, @@ -193,20 +191,18 @@ pub(crate) fn placeholder( span, vis, is_placeholder: true, - }]), - AstFragmentKind::WherePredicates => { - AstFragment::WherePredicates(smallvec![ast::WherePredicate { - attrs: Default::default(), - id, - span, - kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { - bound_generic_params: Default::default(), - bounded_ty: ty(), - bounds: Default::default(), - }), - is_placeholder: true, - }]) - } + })), + AstFragmentKind::WherePredicate => AstFragment::WherePredicate(Some(ast::WherePredicate { + attrs: Default::default(), + id, + span, + kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate { + bound_generic_params: Default::default(), + bounded_ty: ty(), + bounds: Default::default(), + }), + is_placeholder: true, + })), } } @@ -227,73 +223,70 @@ impl PlaceholderExpander { } impl MutVisitor for PlaceholderExpander { - fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> { + fn filter_map_arm(&mut self, arm: ast::Arm) -> Option { if arm.is_placeholder { - self.remove(arm.id).make_arms() + self.remove(arm.id).make_arm() } else { - walk_flat_map_arm(self, arm) + walk_filter_map_arm(self, arm) } } - fn flat_map_expr_field(&mut self, field: ast::ExprField) -> SmallVec<[ast::ExprField; 1]> { + fn filter_map_expr_field(&mut self, field: ast::ExprField) -> Option { if field.is_placeholder { - self.remove(field.id).make_expr_fields() + self.remove(field.id).make_expr_field() } else { - walk_flat_map_expr_field(self, field) + walk_filter_map_expr_field(self, field) } } - fn flat_map_pat_field(&mut self, fp: ast::PatField) -> SmallVec<[ast::PatField; 1]> { + fn filter_map_pat_field(&mut self, fp: ast::PatField) -> Option { if fp.is_placeholder { - self.remove(fp.id).make_pat_fields() + self.remove(fp.id).make_pat_field() } else { - walk_flat_map_pat_field(self, fp) + walk_filter_map_pat_field(self, fp) } } - fn flat_map_generic_param( - &mut self, - param: ast::GenericParam, - ) -> SmallVec<[ast::GenericParam; 1]> { + fn filter_map_generic_param(&mut self, param: ast::GenericParam) -> Option { if param.is_placeholder { - self.remove(param.id).make_generic_params() + self.remove(param.id).make_generic_param() } else { - walk_flat_map_generic_param(self, param) + walk_filter_map_generic_param(self, param) } } - fn flat_map_param(&mut self, p: ast::Param) -> SmallVec<[ast::Param; 1]> { + fn filter_map_param(&mut self, p: ast::Param) -> Option { if p.is_placeholder { - self.remove(p.id).make_params() + self.remove(p.id).make_param() } else { - walk_flat_map_param(self, p) + walk_filter_map_param(self, p) } } - fn flat_map_field_def(&mut self, sf: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> { + fn filter_map_field_def(&mut self, sf: ast::FieldDef) -> Option { if sf.is_placeholder { - self.remove(sf.id).make_field_defs() + self.remove(sf.id).make_field_def() } else { - walk_flat_map_field_def(self, sf) + walk_filter_map_field_def(self, sf) } } - fn flat_map_variant(&mut self, variant: ast::Variant) -> SmallVec<[ast::Variant; 1]> { + fn filter_map_variant(&mut self, variant: ast::Variant) -> Option { if variant.is_placeholder { - self.remove(variant.id).make_variants() + self.remove(variant.id).make_variant() } else { - walk_flat_map_variant(self, variant) + walk_filter_map_variant(self, variant) } } - fn flat_map_where_predicate( + fn filter_map_where_predicate( &mut self, predicate: ast::WherePredicate, - ) -> SmallVec<[ast::WherePredicate; 1]> { + ) -> Option { if predicate.is_placeholder { - self.remove(predicate.id).make_where_predicates() + self.remove(predicate.id).make_where_predicate() } else { - walk_flat_map_where_predicate(self, predicate) + walk_filter_map_where_predicate(self, predicate) } } From 4360fac71db05cd96896716786bc8973e01aed1e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 20 May 2025 08:47:29 +1000 Subject: [PATCH 2/2] Remove out-of-date `noop_*` names. `mut_visit.rs` has a single mfunction with a `noop_` prefix: `noop_filter_map_expr`. This commit renames as `walk_filter_map_expr` which is consistent with other functions in this file. The commit also removes out-of-date comments that refer to `noop_*` methods. --- compiler/rustc_ast/src/mut_visit.rs | 23 ++--------------------- compiler/rustc_expand/src/placeholders.rs | 2 +- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 792cc8b765752..771047841d3b0 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -52,12 +52,6 @@ pub trait MutVisitor: Sized { // fn filter_map_t(&mut self, t: T) -> Option; // fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>; // - // 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) { @@ -191,7 +185,7 @@ pub trait MutVisitor: Sized { } fn filter_map_expr(&mut self, e: P) -> Option> { - noop_filter_map_expr(self, e) + walk_filter_map_expr(self, e) } fn visit_generic_arg(&mut self, arg: &mut GenericArg) { @@ -393,8 +387,6 @@ super::common_visitor_and_walkers!((mut) MutVisitor); /// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful /// when using a `flat_map_*` or `filter_map_*` method within a `visit_` /// method. -// -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. pub fn visit_clobber(t: &mut T, f: impl FnOnce(T) -> T) { let old_t = std::mem::replace(t, T::dummy()); *t = f(old_t); @@ -405,7 +397,6 @@ pub fn visit_clobber_opt(t: &mut Option, f: impl FnOnce(T) -> Option) { *t = old_t.and_then(|new_t| f(new_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 @@ -416,7 +407,6 @@ where } } -// 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 @@ -427,7 +417,6 @@ where } } -// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] fn visit_opt(opt: &mut Option, mut visit_elem: F) where @@ -438,30 +427,25 @@ where } } -// 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 => {} @@ -473,7 +457,6 @@ fn visit_attr_args(vis: &mut T, args: &mut AttrArgs) { } } -// 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; let DelimSpan { open, close } = dspan; @@ -773,7 +756,6 @@ pub fn walk_filter_map_param(vis: &mut T, mut param: Param) -> Op Some(param) } -// 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), @@ -781,7 +763,6 @@ fn visit_defaultness(vis: &mut T, defaultness: &mut Defaultness) } } -// 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 => {} @@ -1715,7 +1696,7 @@ pub fn walk_expr(vis: &mut T, Expr { kind, id, span, attrs, token vis.visit_span(span); } -pub fn noop_filter_map_expr(vis: &mut T, mut e: P) -> Option> { +pub fn walk_filter_map_expr(vis: &mut T, mut e: P) -> Option> { vis.visit_expr(&mut e); Some(e) } diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index a5f019a731198..6ebe9c43135d1 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -342,7 +342,7 @@ impl MutVisitor for PlaceholderExpander { fn filter_map_expr(&mut self, expr: P) -> Option> { match expr.kind { ast::ExprKind::MacCall(_) => self.remove(expr.id).make_opt_expr(), - _ => noop_filter_map_expr(self, expr), + _ => walk_filter_map_expr(self, expr), } }