@@ -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 DummyAstNode {
1848+ fn dummy ( ) -> Self ;
1849+ }
1850+
1851+ impl DummyAstNode 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 DummyAstNode 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 DummyAstNode 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 DummyAstNode for P < ast:: Expr > {
1886+ fn dummy ( ) -> Self {
1887+ ast:: Expr :: dummy ( )
1888+ }
1889+ }
1890+
1891+ impl DummyAstNode 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 > > ) > ,
@@ -2155,18 +2197,19 @@ 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 => {
@@ -2293,11 +2336,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
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+ self . visit_node ( AstNodeWrapper :: from_mut ( node, MethodReceiverTag ) )
23012340 }
23022341
23032342 fn filter_map_expr ( & mut self , node : P < ast:: Expr > ) -> Option < P < ast:: Expr > > {
0 commit comments