@@ -11,7 +11,7 @@ use crate::ast::*;
11
11
use crate :: ptr:: P ;
12
12
use crate :: token:: { self , Token } ;
13
13
use crate :: tokenstream:: * ;
14
- use crate :: visit:: { AssocCtxt , BoundKind } ;
14
+ use crate :: visit:: { AssocCtxt , BoundKind , FnCtxt } ;
15
15
16
16
use rustc_data_structures:: flat_map_in_place:: FlatMapInPlace ;
17
17
use rustc_data_structures:: stack:: ensure_sufficient_stack;
@@ -36,7 +36,7 @@ impl<A: Array> ExpectOne<A> for SmallVec<A> {
36
36
}
37
37
38
38
pub trait NoopVisitItemKind {
39
- fn noop_visit ( & mut self , visitor : & mut impl MutVisitor ) ;
39
+ fn noop_visit ( & mut self , ctxt : Option < AssocCtxt > , visitor : & mut impl MutVisitor ) ;
40
40
}
41
41
42
42
pub trait MutVisitor : Sized {
@@ -95,11 +95,11 @@ pub trait MutVisitor: Sized {
95
95
}
96
96
97
97
fn flat_map_foreign_item ( & mut self , ni : P < ForeignItem > ) -> SmallVec < [ P < ForeignItem > ; 1 ] > {
98
- noop_flat_map_item ( ni, self )
98
+ noop_flat_map_item ( ni, None , self )
99
99
}
100
100
101
101
fn flat_map_item ( & mut self , i : P < Item > ) -> SmallVec < [ P < Item > ; 1 ] > {
102
- noop_flat_map_item ( i, self )
102
+ noop_flat_map_item ( i, None , self )
103
103
}
104
104
105
105
fn visit_fn_header ( & mut self , header : & mut FnHeader ) {
@@ -113,15 +113,19 @@ pub trait MutVisitor: Sized {
113
113
fn flat_map_assoc_item (
114
114
& mut self ,
115
115
i : P < AssocItem > ,
116
- _ctxt : AssocCtxt ,
116
+ ctxt : AssocCtxt ,
117
117
) -> SmallVec < [ P < AssocItem > ; 1 ] > {
118
- noop_flat_map_item ( i, self )
118
+ noop_flat_map_item ( i, Some ( ctxt ) , self )
119
119
}
120
120
121
121
fn visit_fn_decl ( & mut self , d : & mut P < FnDecl > ) {
122
122
noop_visit_fn_decl ( d, self ) ;
123
123
}
124
124
125
+ fn visit_fn ( & mut self , fk : FnKind < ' _ > ) {
126
+ noop_visit_fn ( fk, self )
127
+ }
128
+
125
129
fn visit_coroutine_kind ( & mut self , a : & mut CoroutineKind ) {
126
130
noop_visit_coroutine_kind ( a, self ) ;
127
131
}
@@ -379,13 +383,6 @@ fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, ctxt: BoundKind, vis:
379
383
visit_vec ( bounds, |bound| vis. visit_param_bound ( bound, ctxt) ) ;
380
384
}
381
385
382
- // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
383
- fn visit_fn_sig < T : MutVisitor > ( FnSig { header, decl, span } : & mut FnSig , vis : & mut T ) {
384
- vis. visit_fn_header ( header) ;
385
- vis. visit_fn_decl ( decl) ;
386
- vis. visit_span ( span) ;
387
- }
388
-
389
386
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
390
387
fn visit_attr_args < T : MutVisitor > ( args : & mut AttrArgs , vis : & mut T ) {
391
388
match args {
@@ -880,6 +877,26 @@ fn noop_visit_coroutine_kind<T: MutVisitor>(coroutine_kind: &mut CoroutineKind,
880
877
}
881
878
}
882
879
880
+ fn noop_visit_fn < T : MutVisitor > ( kind : FnKind < ' _ > , vis : & mut T ) {
881
+ match kind {
882
+ FnKind :: Fn ( _ctxt, FnSig { header, decl, span } , generics, body) => {
883
+ // Identifier and visibility are visited as a part of the item.
884
+ vis. visit_fn_header ( header) ;
885
+ vis. visit_generics ( generics) ;
886
+ vis. visit_fn_decl ( decl) ;
887
+ if let Some ( body) = body {
888
+ vis. visit_block ( body) ;
889
+ }
890
+ vis. visit_span ( span) ;
891
+ }
892
+ FnKind :: Closure ( binder, decl, body) => {
893
+ vis. visit_closure_binder ( binder) ;
894
+ vis. visit_fn_decl ( decl) ;
895
+ vis. visit_expr ( body) ;
896
+ }
897
+ }
898
+ }
899
+
883
900
fn noop_visit_fn_decl < T : MutVisitor > ( decl : & mut P < FnDecl > , vis : & mut T ) {
884
901
let FnDecl { inputs, output } = decl. deref_mut ( ) ;
885
902
inputs. flat_map_in_place ( |param| vis. flat_map_param ( param) ) ;
@@ -1062,11 +1079,12 @@ pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) {
1062
1079
}
1063
1080
1064
1081
pub fn noop_visit_item_kind ( kind : & mut impl NoopVisitItemKind , vis : & mut impl MutVisitor ) {
1065
- kind. noop_visit ( vis)
1082
+ kind. noop_visit ( None , vis)
1066
1083
}
1067
1084
1068
1085
impl NoopVisitItemKind for ItemKind {
1069
- fn noop_visit ( & mut self , vis : & mut impl MutVisitor ) {
1086
+ fn noop_visit ( & mut self , ctxt : Option < AssocCtxt > , vis : & mut impl MutVisitor ) {
1087
+ assert_eq ! ( ctxt, None ) ;
1070
1088
match self {
1071
1089
ItemKind :: ExternCrate ( _orig_name) => { }
1072
1090
ItemKind :: Use ( use_tree) => vis. visit_use_tree ( use_tree) ,
@@ -1079,9 +1097,7 @@ impl NoopVisitItemKind for ItemKind {
1079
1097
}
1080
1098
ItemKind :: Fn ( box Fn { defaultness, generics, sig, body } ) => {
1081
1099
visit_defaultness ( defaultness, vis) ;
1082
- vis. visit_generics ( generics) ;
1083
- visit_fn_sig ( sig, vis) ;
1084
- visit_opt ( body, |body| vis. visit_block ( body) ) ;
1100
+ vis. visit_fn ( FnKind :: Fn ( FnCtxt :: Free , sig, generics, body) ) ;
1085
1101
}
1086
1102
ItemKind :: Mod ( safety, mod_kind) => {
1087
1103
visit_safety ( safety, vis) ;
@@ -1180,16 +1196,15 @@ impl NoopVisitItemKind for ItemKind {
1180
1196
}
1181
1197
1182
1198
impl NoopVisitItemKind for AssocItemKind {
1183
- fn noop_visit ( & mut self , visitor : & mut impl MutVisitor ) {
1199
+ fn noop_visit ( & mut self , ctxt : Option < AssocCtxt > , visitor : & mut impl MutVisitor ) {
1200
+ let ctxt = ctxt. unwrap ( ) ;
1184
1201
match self {
1185
1202
AssocItemKind :: Const ( item) => {
1186
1203
visit_const_item ( item, visitor) ;
1187
1204
}
1188
1205
AssocItemKind :: Fn ( box Fn { defaultness, generics, sig, body } ) => {
1189
1206
visit_defaultness ( defaultness, visitor) ;
1190
- visitor. visit_generics ( generics) ;
1191
- visit_fn_sig ( sig, visitor) ;
1192
- visit_opt ( body, |body| visitor. visit_block ( body) ) ;
1207
+ visitor. visit_fn ( FnKind :: Fn ( FnCtxt :: Assoc ( ctxt) , sig, generics, body) ) ;
1193
1208
}
1194
1209
AssocItemKind :: Type ( box TyAlias {
1195
1210
defaultness,
@@ -1272,31 +1287,31 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
1272
1287
// Mutates one item into possibly many items.
1273
1288
pub fn noop_flat_map_item < K : NoopVisitItemKind > (
1274
1289
mut item : P < Item < K > > ,
1290
+ ctxt : Option < AssocCtxt > ,
1275
1291
visitor : & mut impl MutVisitor ,
1276
1292
) -> SmallVec < [ P < Item < K > > ; 1 ] > {
1277
1293
let Item { ident, attrs, id, kind, vis, span, tokens } = item. deref_mut ( ) ;
1278
1294
visitor. visit_id ( id) ;
1279
1295
visit_attrs ( attrs, visitor) ;
1280
1296
visitor. visit_vis ( vis) ;
1281
1297
visitor. visit_ident ( ident) ;
1282
- kind. noop_visit ( visitor) ;
1298
+ kind. noop_visit ( ctxt , visitor) ;
1283
1299
visit_lazy_tts ( tokens, visitor) ;
1284
1300
visitor. visit_span ( span) ;
1285
1301
smallvec ! [ item]
1286
1302
}
1287
1303
1288
1304
impl NoopVisitItemKind for ForeignItemKind {
1289
- fn noop_visit ( & mut self , visitor : & mut impl MutVisitor ) {
1305
+ fn noop_visit ( & mut self , ctxt : Option < AssocCtxt > , visitor : & mut impl MutVisitor ) {
1306
+ assert_eq ! ( ctxt, None ) ;
1290
1307
match self {
1291
1308
ForeignItemKind :: Static ( box StaticItem { ty, mutability : _, expr, safety : _ } ) => {
1292
1309
visitor. visit_ty ( ty) ;
1293
1310
visit_opt ( expr, |expr| visitor. visit_expr ( expr) ) ;
1294
1311
}
1295
1312
ForeignItemKind :: Fn ( box Fn { defaultness, generics, sig, body } ) => {
1296
1313
visit_defaultness ( defaultness, visitor) ;
1297
- visitor. visit_generics ( generics) ;
1298
- visit_fn_sig ( sig, visitor) ;
1299
- visit_opt ( body, |body| visitor. visit_block ( body) ) ;
1314
+ visitor. visit_fn ( FnKind :: Fn ( FnCtxt :: Foreign , sig, generics, body) ) ;
1300
1315
}
1301
1316
ForeignItemKind :: TyAlias ( box TyAlias {
1302
1317
defaultness,
@@ -1506,12 +1521,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
1506
1521
fn_decl_span,
1507
1522
fn_arg_span,
1508
1523
} ) => {
1509
- vis. visit_closure_binder ( binder) ;
1510
1524
visit_constness ( constness, vis) ;
1511
1525
coroutine_kind. as_mut ( ) . map ( |coroutine_kind| vis. visit_coroutine_kind ( coroutine_kind) ) ;
1512
1526
vis. visit_capture_by ( capture_clause) ;
1513
- vis. visit_fn_decl ( fn_decl) ;
1514
- vis. visit_expr ( body) ;
1527
+ vis. visit_fn ( FnKind :: Closure ( binder, fn_decl, body) ) ;
1515
1528
vis. visit_span ( fn_decl_span) ;
1516
1529
vis. visit_span ( fn_arg_span) ;
1517
1530
}
@@ -1768,3 +1781,12 @@ impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNo
1768
1781
crate :: ast_traits:: AstNodeWrapper :: new ( N :: dummy ( ) , T :: dummy ( ) )
1769
1782
}
1770
1783
}
1784
+
1785
+ #[ derive( Debug ) ]
1786
+ pub enum FnKind < ' a > {
1787
+ /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
1788
+ Fn ( FnCtxt , & ' a mut FnSig , & ' a mut Generics , & ' a mut Option < P < Block > > ) ,
1789
+
1790
+ /// E.g., `|x, y| body`.
1791
+ Closure ( & ' a mut ClosureBinder , & ' a mut P < FnDecl > , & ' a mut P < Expr > ) ,
1792
+ }
0 commit comments