@@ -3,15 +3,14 @@ use std::rc::Rc;
3
3
use std:: sync:: Arc ;
4
4
use std:: { iter, mem} ;
5
5
6
- use rustc_ast as ast;
7
6
use rustc_ast:: mut_visit:: * ;
8
7
use rustc_ast:: ptr:: P ;
9
8
use rustc_ast:: tokenstream:: TokenStream ;
10
9
use rustc_ast:: visit:: { self , AssocCtxt , Visitor , VisitorResult , try_visit, walk_list} ;
11
10
use 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,
15
14
} ;
16
15
use rustc_ast_pretty:: pprust;
17
16
use rustc_data_structures:: flat_map_in_place:: FlatMapInPlace ;
@@ -131,13 +130,9 @@ macro_rules! ast_fragments {
131
130
pub ( crate ) fn mut_visit_with<F : MutVisitor >( & mut self , vis: & mut F ) {
132
131
match self {
133
132
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
+ }
141
136
}
142
137
AstFragment :: MethodReceiverExpr ( expr) => vis. visit_method_receiver_expr( expr) ,
143
138
$( $( AstFragment :: $Kind( ast) => vis. $mut_visit_ast( ast) , ) ?) *
@@ -1782,11 +1777,7 @@ impl InvocationCollectorNode for AstNodeWrapper<P<ast::Expr>, OptExprTag> {
1782
1777
/// This struct is a hack to workaround unstable of `stmt_expr_attributes`.
1783
1778
/// It can be removed once that feature is stabilized.
1784
1779
struct MethodReceiverTag ;
1785
- impl DummyAstNode for MethodReceiverTag {
1786
- fn dummy ( ) -> MethodReceiverTag {
1787
- MethodReceiverTag
1788
- }
1789
- }
1780
+
1790
1781
impl InvocationCollectorNode for AstNodeWrapper < P < ast:: Expr > , MethodReceiverTag > {
1791
1782
type OutputTy = Self ;
1792
1783
const KIND : AstFragmentKind = AstFragmentKind :: MethodReceiverExpr ;
@@ -1852,6 +1843,57 @@ fn build_single_delegations<'a, Node: InvocationCollectorNode>(
1852
1843
} )
1853
1844
}
1854
1845
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
+
1855
1897
struct InvocationCollector < ' a , ' b > {
1856
1898
cx : & ' a mut ExtCtxt < ' b > ,
1857
1899
invocations : Vec < ( Invocation , Option < Arc < SyntaxExtension > > ) > ,
@@ -2155,18 +2197,19 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
2155
2197
self . expand_cfg_attr ( node, & attr, pos) ;
2156
2198
continue ;
2157
2199
}
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 )
2160
2204
. make_ast :: < Node > ( )
2161
- } ) ,
2205
+ }
2162
2206
} ,
2163
2207
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 > ( )
2170
2213
}
2171
2214
None if node. delegation ( ) . is_some ( ) => unreachable ! ( ) ,
2172
2215
None => {
@@ -2293,11 +2336,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
2293
2336
}
2294
2337
2295
2338
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 ) )
2301
2340
}
2302
2341
2303
2342
fn filter_map_expr ( & mut self , node : P < ast:: Expr > ) -> Option < P < ast:: Expr > > {
0 commit comments