about summary refs log tree commit diff
path: root/compiler/rustc_ast/src/mut_visit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast/src/mut_visit.rs')
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs259
1 files changed, 240 insertions, 19 deletions
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 3eae19f4daa..06708e2e703 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -12,14 +12,14 @@ use std::panic;
 
 use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_span::source_map::Spanned;
-use rustc_span::{Ident, Span};
+use rustc_span::{Ident, Span, Symbol};
 use smallvec::{SmallVec, smallvec};
 use thin_vec::ThinVec;
 
 use crate::ast::*;
 use crate::ptr::P;
 use crate::tokenstream::*;
-use crate::visit::{AssocCtxt, BoundKind, FnCtxt, VisitorResult, try_visit, visit_opt, walk_list};
+use crate::visit::{AssocCtxt, BoundKind, FnCtxt, LifetimeCtxt, VisitorResult, try_visit};
 
 mod sealed {
     use rustc_ast_ir::visit::VisitorResult;
@@ -36,11 +36,249 @@ mod sealed {
 
 use sealed::MutVisitorResult;
 
+pub(crate) trait MutVisitable<V: MutVisitor> {
+    type Extra: Copy;
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra);
+}
+
+impl<V: MutVisitor, T: ?Sized> MutVisitable<V> for P<T>
+where
+    T: MutVisitable<V>,
+{
+    type Extra = T::Extra;
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        (**self).visit_mut(visitor, extra)
+    }
+}
+
+impl<V: MutVisitor, T> MutVisitable<V> for Option<T>
+where
+    T: MutVisitable<V>,
+{
+    type Extra = T::Extra;
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        if let Some(this) = self {
+            this.visit_mut(visitor, extra)
+        }
+    }
+}
+
+impl<V: MutVisitor, T> MutVisitable<V> for Spanned<T>
+where
+    T: MutVisitable<V>,
+{
+    type Extra = T::Extra;
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        let Spanned { span, node } = self;
+        span.visit_mut(visitor, ());
+        node.visit_mut(visitor, extra);
+    }
+}
+
+impl<V: MutVisitor, T> MutVisitable<V> for [T]
+where
+    T: MutVisitable<V>,
+{
+    type Extra = T::Extra;
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        for item in self {
+            item.visit_mut(visitor, extra);
+        }
+    }
+}
+
+impl<V: MutVisitor, T> MutVisitable<V> for Vec<T>
+where
+    T: MutVisitable<V>,
+{
+    type Extra = T::Extra;
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        for item in self {
+            item.visit_mut(visitor, extra);
+        }
+    }
+}
+
+impl<V: MutVisitor, T> MutVisitable<V> for (T,)
+where
+    T: MutVisitable<V>,
+{
+    type Extra = T::Extra;
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        self.0.visit_mut(visitor, extra);
+    }
+}
+
+impl<V: MutVisitor, T1, T2> MutVisitable<V> for (T1, T2)
+where
+    T1: MutVisitable<V, Extra = ()>,
+    T2: MutVisitable<V, Extra = ()>,
+{
+    type Extra = ();
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        self.0.visit_mut(visitor, extra);
+        self.1.visit_mut(visitor, extra);
+    }
+}
+
+impl<V: MutVisitor, T1, T2, T3> MutVisitable<V> for (T1, T2, T3)
+where
+    T1: MutVisitable<V, Extra = ()>,
+    T2: MutVisitable<V, Extra = ()>,
+    T3: MutVisitable<V, Extra = ()>,
+{
+    type Extra = ();
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        self.0.visit_mut(visitor, extra);
+        self.1.visit_mut(visitor, extra);
+        self.2.visit_mut(visitor, extra);
+    }
+}
+
+impl<V: MutVisitor, T1, T2, T3, T4> MutVisitable<V> for (T1, T2, T3, T4)
+where
+    T1: MutVisitable<V, Extra = ()>,
+    T2: MutVisitable<V, Extra = ()>,
+    T3: MutVisitable<V, Extra = ()>,
+    T4: MutVisitable<V, Extra = ()>,
+{
+    type Extra = ();
+    fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+        self.0.visit_mut(visitor, extra);
+        self.1.visit_mut(visitor, extra);
+        self.2.visit_mut(visitor, extra);
+        self.3.visit_mut(visitor, extra);
+    }
+}
+
+pub trait MutWalkable<V: MutVisitor> {
+    fn walk_mut(&mut self, visitor: &mut V);
+}
+
+macro_rules! visit_visitable {
+    (mut $visitor:expr, $($expr:expr),* $(,)?) => {{
+        $(MutVisitable::visit_mut($expr, $visitor, ());)*
+    }};
+}
+
+macro_rules! visit_visitable_with {
+    (mut $visitor:expr, $expr:expr, $extra:expr $(,)?) => {
+        MutVisitable::visit_mut($expr, $visitor, $extra)
+    };
+}
+
+macro_rules! walk_walkable {
+    ($visitor:expr, $expr:expr, mut) => {
+        MutWalkable::walk_mut($expr, $visitor)
+    };
+}
+
+macro_rules! impl_visitable {
+    (|&mut $self:ident: $self_ty:ty,
+      $vis:ident: &mut $vis_ty:ident,
+      $extra:ident: $extra_ty:ty| $block:block) => {
+        #[allow(unused_parens, non_local_definitions)]
+        impl<$vis_ty: MutVisitor> MutVisitable<$vis_ty> for $self_ty {
+            type Extra = $extra_ty;
+            fn visit_mut(&mut $self, $vis: &mut $vis_ty, $extra: Self::Extra) -> V::Result {
+                $block
+            }
+        }
+    };
+}
+
+macro_rules! impl_walkable {
+    ($(<$K:ident: $Kb:ident>)? |&mut $self:ident: $self_ty:ty,
+      $vis:ident: &mut $vis_ty:ident| $block:block) => {
+        #[allow(unused_parens, non_local_definitions)]
+        impl<$($K: $Kb,)? $vis_ty: MutVisitor> MutWalkable<$vis_ty> for $self_ty {
+            fn walk_mut(&mut $self, $vis: &mut $vis_ty) -> V::Result {
+                $block
+            }
+        }
+    };
+}
+
+macro_rules! impl_visitable_noop {
+    (<mut> $($ty:ty,)*) => {
+        $(
+            impl_visitable!(|&mut self: $ty, _vis: &mut V, _extra: ()| {});
+        )*
+    };
+}
+
+macro_rules! impl_visitable_list {
+    (<mut> $($ty:ty,)*) => {
+        $(impl<V: MutVisitor, T> MutVisitable<V> for $ty
+        where
+            for<'a> &'a mut $ty: IntoIterator<Item = &'a mut T>,
+            T: MutVisitable<V>,
+        {
+            type Extra = <T as MutVisitable<V>>::Extra;
+
+            #[inline]
+            fn visit_mut(&mut self, visitor: &mut V, extra: Self::Extra) {
+                for i in self {
+                    i.visit_mut(visitor, extra);
+                }
+            }
+        })*
+    }
+}
+
+macro_rules! impl_visitable_direct {
+    (<mut> $($ty:ty,)*) => {
+        $(impl_visitable!(
+            |&mut self: $ty, visitor: &mut V, _extra: ()| {
+                MutWalkable::walk_mut(self, visitor)
+            }
+        );)*
+    }
+}
+
+macro_rules! impl_visitable_calling_walkable {
+    (<mut>
+        $( fn $method:ident($ty:ty $(, $extra_name:ident: $extra_ty:ty)?); )*
+    ) => {
+        $(fn $method(&mut self, node: &mut $ty $(, $extra_name:$extra_ty)?) {
+            impl_visitable!(|&mut self: $ty, visitor: &mut V, extra: ($($extra_ty)?)| {
+                let ($($extra_name)?) = extra;
+                visitor.$method(self $(, $extra_name)?);
+            });
+            walk_walkable!(self, node, mut)
+        })*
+    }
+}
+
+macro_rules! define_named_walk {
+    ((mut) $Visitor:ident
+        $( pub fn $method:ident($ty:ty); )*
+    ) => {
+        $(pub fn $method<V: $Visitor>(visitor: &mut V, node: &mut $ty) {
+            walk_walkable!(visitor, node, mut)
+        })*
+    };
+}
+
 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)*;)+) => {
         $(
+            #[allow(unused_parens)]
+            impl<V: MutVisitor> MutVisitable<V> for ThinVec<$Ty> {
+                type Extra = ($($ParamTy),*);
+
+                #[inline]
+                fn visit_mut(
+                    &mut self,
+                    visitor: &mut V,
+                    ($($param),*): Self::Extra,
+                ) -> V::Result {
+                    $name(visitor, self $(, $param)*)
+                }
+            }
+
             fn $name<V: MutVisitor>(
                 vis: &mut V,
                 values: &mut ThinVec<$Ty>,
@@ -78,15 +316,6 @@ pub fn walk_flat_map_pat_field<T: MutVisitor>(
     smallvec![fp]
 }
 
-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);
-}
-
 macro_rules! generate_walk_flat_map_fns {
     ($($fn_name:ident($Ty:ty$(,$extra_name:ident: $ExtraTy:ty)*) => $visit_fn_name:ident;)+) => {$(
         pub fn $fn_name<V: MutVisitor>(vis: &mut V, mut value: $Ty$(,$extra_name: $ExtraTy)*) -> SmallVec<[$Ty; 1]> {
@@ -109,14 +338,6 @@ generate_walk_flat_map_fns! {
     walk_flat_map_assoc_item(P<AssocItem>, ctxt: AssocCtxt) => visit_assoc_item;
 }
 
-fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWhereClauses) {
-    let TyAliasWhereClauses { before, after, split: _ } = tawcs;
-    let TyAliasWhereClause { has_where_token: _, span: span_before } = before;
-    let TyAliasWhereClause { has_where_token: _, span: span_after } = after;
-    vis.visit_span(span_before);
-    vis.visit_span(span_after);
-}
-
 pub fn walk_filter_map_expr<T: MutVisitor>(vis: &mut T, mut e: P<Expr>) -> Option<P<Expr>> {
     vis.visit_expr(&mut e);
     Some(e)