@@ -3,15 +3,14 @@ use std::rc::Rc;
33use std:: sync:: Arc ;
44use std:: { iter, mem} ;
55
6- use rustc_ast as ast;
76use rustc_ast:: mut_visit:: * ;
87use rustc_ast:: ptr:: P ;
98use rustc_ast:: tokenstream:: TokenStream ;
109use rustc_ast:: visit:: { self , AssocCtxt , Visitor , VisitorResult , try_visit, walk_list} ;
1110use rustc_ast:: {
12- AssocItemKind , AstNodeWrapper , AttrArgs , AttrStyle , AttrVec , ExprKind , ForeignItemKind ,
13- HasAttrs , HasNodeId , Inline , ItemKind , MacStmtStyle , MetaItemInner , MetaItemKind , ModKind ,
14- NodeId , PatKind , StmtKind , TyKind , token,
11+ self as ast , AssocItemKind , AstNodeWrapper , AttrArgs , AttrStyle , AttrVec , DUMMY_NODE_ID ,
12+ ExprKind , ForeignItemKind , HasAttrs , HasNodeId , Inline , ItemKind , MacStmtStyle , MetaItemInner ,
13+ MetaItemKind , ModKind , NodeId , PatKind , StmtKind , TyKind , token,
1514} ;
1615use rustc_ast_pretty:: pprust;
1716use rustc_data_structures:: flat_map_in_place:: FlatMapInPlace ;
@@ -131,13 +130,9 @@ macro_rules! ast_fragments {
131130 pub ( crate ) fn mut_visit_with<F : MutVisitor >( & mut self , vis: & mut F ) {
132131 match self {
133132 AstFragment :: OptExpr ( opt_expr) => {
134- visit_clobber( opt_expr, |opt_expr| {
135- if let Some ( expr) = opt_expr {
136- vis. filter_map_expr( expr)
137- } else {
138- None
139- }
140- } ) ;
133+ if let Some ( expr) = opt_expr. take( ) {
134+ * opt_expr = vis. filter_map_expr( expr)
135+ }
141136 }
142137 AstFragment :: MethodReceiverExpr ( expr) => vis. visit_method_receiver_expr( expr) ,
143138 $( $( AstFragment :: $Kind( ast) => vis. $mut_visit_ast( ast) , ) ?) *
@@ -1782,11 +1777,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
17821777/// This struct is a hack to workaround unstable of `stmt_expr_attributes`.
17831778/// It can be removed once that feature is stabilized.
17841779struct MethodReceiverTag ;
1785- impl DummyAstNode for MethodReceiverTag {
1786- fn dummy ( ) -> MethodReceiverTag {
1787- MethodReceiverTag
1788- }
1789- }
1780+
17901781impl InvocationCollectorNode for AstNodeWrapper < P < ast:: Expr > , MethodReceiverTag > {
17911782 type OutputTy = Self ;
17921783 const KIND : AstFragmentKind = AstFragmentKind :: MethodReceiverExpr ;
@@ -1852,6 +1843,57 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>(
18521843 } )
18531844}
18541845
1846+ /// Required for `visit_node` obtained an owned `Node` from `&mut Node`.
1847+ trait DummyValue {
1848+ fn dummy ( ) -> Self ;
1849+ }
1850+
1851+ impl DummyValue for ast:: Crate {
1852+ fn dummy ( ) -> Self {
1853+ ast:: Crate {
1854+ attrs : Default :: default ( ) ,
1855+ items : Default :: default ( ) ,
1856+ spans : Default :: default ( ) ,
1857+ id : DUMMY_NODE_ID ,
1858+ is_placeholder : Default :: default ( ) ,
1859+ }
1860+ }
1861+ }
1862+
1863+ impl DummyValue for P < ast:: Ty > {
1864+ fn dummy ( ) -> Self {
1865+ P ( ast:: Ty {
1866+ id : DUMMY_NODE_ID ,
1867+ kind : TyKind :: Dummy ,
1868+ span : Default :: default ( ) ,
1869+ tokens : Default :: default ( ) ,
1870+ } )
1871+ }
1872+ }
1873+
1874+ impl DummyValue for P < ast:: Pat > {
1875+ fn dummy ( ) -> Self {
1876+ P ( ast:: Pat {
1877+ id : DUMMY_NODE_ID ,
1878+ kind : PatKind :: Wild ,
1879+ span : Default :: default ( ) ,
1880+ tokens : Default :: default ( ) ,
1881+ } )
1882+ }
1883+ }
1884+
1885+ impl DummyValue for P < ast:: Expr > {
1886+ fn dummy ( ) -> Self {
1887+ ast:: Expr :: dummy ( )
1888+ }
1889+ }
1890+
1891+ impl DummyValue for AstNodeWrapper < P < ast:: Expr > , MethodReceiverTag > {
1892+ fn dummy ( ) -> Self {
1893+ AstNodeWrapper :: new ( ast:: Expr :: dummy ( ) , MethodReceiverTag )
1894+ }
1895+ }
1896+
18551897struct InvocationCollector < ' a , ' b > {
18561898 cx : & ' a mut ExtCtxt < ' b > ,
18571899 invocations : Vec < ( Invocation , Option < Arc < SyntaxExtension > > ) > ,
@@ -2135,7 +2177,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
21352177 }
21362178 }
21372179
2138- fn visit_node < Node : InvocationCollectorNode < OutputTy = Node > + DummyAstNode > (
2180+ fn visit_node < Node : InvocationCollectorNode < OutputTy = Node > + DummyValue > (
21392181 & mut self ,
21402182 node : & mut Node ,
21412183 ) {
@@ -2155,22 +2197,23 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
21552197 self . expand_cfg_attr ( node, & attr, pos) ;
21562198 continue ;
21572199 }
2158- _ => visit_clobber ( node, |node| {
2159- self . collect_attr ( ( attr, pos, derives) , node. to_annotatable ( ) , Node :: KIND )
2200+ _ => {
2201+ let n = mem:: replace ( node, Node :: dummy ( ) ) ;
2202+ * node = self
2203+ . collect_attr ( ( attr, pos, derives) , n. to_annotatable ( ) , Node :: KIND )
21602204 . make_ast :: < Node > ( )
2161- } ) ,
2205+ }
21622206 } ,
21632207 None if node. is_mac_call ( ) => {
2164- visit_clobber ( node, |node| {
2165- // Do not clobber unless it's actually a macro (uncommon case).
2166- let ( mac, attrs, _) = node. take_mac_call ( ) ;
2167- self . check_attributes ( & attrs, & mac) ;
2168- self . collect_bang ( mac, Node :: KIND ) . make_ast :: < Node > ( )
2169- } )
2208+ let n = mem:: replace ( node, Node :: dummy ( ) ) ;
2209+ let ( mac, attrs, _) = n. take_mac_call ( ) ;
2210+ self . check_attributes ( & attrs, & mac) ;
2211+
2212+ * node = self . collect_bang ( mac, Node :: KIND ) . make_ast :: < Node > ( )
21702213 }
21712214 None if node. delegation ( ) . is_some ( ) => unreachable ! ( ) ,
21722215 None => {
2173- assign_id ! ( self , node. node_id_mut( ) , || node. walk( self ) )
2216+ assign_id ! ( self , node. node_id_mut( ) , || node. walk( self ) ) ;
21742217 }
21752218 } ;
21762219 }
@@ -2273,11 +2316,11 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
22732316 }
22742317
22752318 fn visit_crate ( & mut self , node : & mut ast:: Crate ) {
2276- self . visit_node ( node)
2319+ self . visit_node ( node) ;
22772320 }
22782321
22792322 fn visit_ty ( & mut self , node : & mut P < ast:: Ty > ) {
2280- self . visit_node ( node)
2323+ self . visit_node ( node) ;
22812324 }
22822325
22832326 fn visit_pat ( & mut self , node : & mut P < ast:: Pat > ) {
@@ -2289,15 +2332,12 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
22892332 if let Some ( attr) = node. attrs . first ( ) {
22902333 self . cfg ( ) . maybe_emit_expr_attr_err ( attr) ;
22912334 }
2292- self . visit_node ( node)
2335+ self . visit_node ( node) ;
22932336 }
22942337
22952338 fn visit_method_receiver_expr ( & mut self , node : & mut P < ast:: Expr > ) {
2296- visit_clobber ( node, |node| {
2297- let mut wrapper = AstNodeWrapper :: new ( node, MethodReceiverTag ) ;
2298- self . visit_node ( & mut wrapper) ;
2299- wrapper. wrapped
2300- } )
2339+ let wrapper = AstNodeWrapper :: from_mut ( node, MethodReceiverTag ) ;
2340+ self . visit_node ( wrapper) ;
23012341 }
23022342
23032343 fn filter_map_expr ( & mut self , node : P < ast:: Expr > ) -> Option < P < ast:: Expr > > {
0 commit comments