@@ -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
}
@@ -390,13 +394,6 @@ fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, ctxt: BoundKind, vis:
390
394
visit_vec ( bounds, |bound| vis. visit_param_bound ( bound, ctxt) ) ;
391
395
}
392
396
393
- // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
394
- fn visit_fn_sig < T : MutVisitor > ( FnSig { header, decl, span } : & mut FnSig , vis : & mut T ) {
395
- vis. visit_fn_header ( header) ;
396
- vis. visit_fn_decl ( decl) ;
397
- vis. visit_span ( span) ;
398
- }
399
-
400
397
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
401
398
fn visit_attr_args < T : MutVisitor > ( args : & mut AttrArgs , vis : & mut T ) {
402
399
match args {
@@ -891,6 +888,26 @@ fn noop_visit_coroutine_kind<T: MutVisitor>(coroutine_kind: &mut CoroutineKind,
891
888
}
892
889
}
893
890
891
+ fn noop_visit_fn < T : MutVisitor > ( kind : FnKind < ' _ > , vis : & mut T ) {
892
+ match kind {
893
+ FnKind :: Fn ( _ctxt, FnSig { header, decl, span } , generics, body) => {
894
+ // Identifier and visibility are visited as a part of the item.
895
+ vis. visit_fn_header ( header) ;
896
+ vis. visit_generics ( generics) ;
897
+ vis. visit_fn_decl ( decl) ;
898
+ if let Some ( body) = body {
899
+ vis. visit_block ( body) ;
900
+ }
901
+ vis. visit_span ( span) ;
902
+ }
903
+ FnKind :: Closure ( binder, decl, body) => {
904
+ vis. visit_closure_binder ( binder) ;
905
+ vis. visit_fn_decl ( decl) ;
906
+ vis. visit_expr ( body) ;
907
+ }
908
+ }
909
+ }
910
+
894
911
fn noop_visit_fn_decl < T : MutVisitor > ( decl : & mut P < FnDecl > , vis : & mut T ) {
895
912
let FnDecl { inputs, output } = decl. deref_mut ( ) ;
896
913
inputs. flat_map_in_place ( |param| vis. flat_map_param ( param) ) ;
@@ -1073,11 +1090,12 @@ pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) {
1073
1090
}
1074
1091
1075
1092
pub fn noop_visit_item_kind ( kind : & mut impl NoopVisitItemKind , vis : & mut impl MutVisitor ) {
1076
- kind. noop_visit ( vis)
1093
+ kind. noop_visit ( None , vis)
1077
1094
}
1078
1095
1079
1096
impl NoopVisitItemKind for ItemKind {
1080
- fn noop_visit ( & mut self , vis : & mut impl MutVisitor ) {
1097
+ fn noop_visit ( & mut self , ctxt : Option < AssocCtxt > , vis : & mut impl MutVisitor ) {
1098
+ assert_eq ! ( ctxt, None ) ;
1081
1099
match self {
1082
1100
ItemKind :: ExternCrate ( _orig_name) => { }
1083
1101
ItemKind :: Use ( use_tree) => vis. visit_use_tree ( use_tree) ,
@@ -1090,9 +1108,7 @@ impl NoopVisitItemKind for ItemKind {
1090
1108
}
1091
1109
ItemKind :: Fn ( box Fn { defaultness, generics, sig, body } ) => {
1092
1110
visit_defaultness ( defaultness, vis) ;
1093
- vis. visit_generics ( generics) ;
1094
- visit_fn_sig ( sig, vis) ;
1095
- visit_opt ( body, |body| vis. visit_block ( body) ) ;
1111
+ vis. visit_fn ( FnKind :: Fn ( FnCtxt :: Free , sig, generics, body) ) ;
1096
1112
}
1097
1113
ItemKind :: Mod ( safety, mod_kind) => {
1098
1114
visit_safety ( safety, vis) ;
@@ -1191,16 +1207,15 @@ impl NoopVisitItemKind for ItemKind {
1191
1207
}
1192
1208
1193
1209
impl NoopVisitItemKind for AssocItemKind {
1194
- fn noop_visit ( & mut self , visitor : & mut impl MutVisitor ) {
1210
+ fn noop_visit ( & mut self , ctxt : Option < AssocCtxt > , visitor : & mut impl MutVisitor ) {
1211
+ let ctxt = ctxt. unwrap ( ) ;
1195
1212
match self {
1196
1213
AssocItemKind :: Const ( item) => {
1197
1214
visit_const_item ( item, visitor) ;
1198
1215
}
1199
1216
AssocItemKind :: Fn ( box Fn { defaultness, generics, sig, body } ) => {
1200
1217
visit_defaultness ( defaultness, visitor) ;
1201
- visitor. visit_generics ( generics) ;
1202
- visit_fn_sig ( sig, visitor) ;
1203
- visit_opt ( body, |body| visitor. visit_block ( body) ) ;
1218
+ visitor. visit_fn ( FnKind :: Fn ( FnCtxt :: Assoc ( ctxt) , sig, generics, body) ) ;
1204
1219
}
1205
1220
AssocItemKind :: Type ( box TyAlias {
1206
1221
defaultness,
@@ -1283,31 +1298,31 @@ pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
1283
1298
// Mutates one item into possibly many items.
1284
1299
pub fn noop_flat_map_item < K : NoopVisitItemKind > (
1285
1300
mut item : P < Item < K > > ,
1301
+ ctxt : Option < AssocCtxt > ,
1286
1302
visitor : & mut impl MutVisitor ,
1287
1303
) -> SmallVec < [ P < Item < K > > ; 1 ] > {
1288
1304
let Item { ident, attrs, id, kind, vis, span, tokens } = item. deref_mut ( ) ;
1289
1305
visitor. visit_id ( id) ;
1290
1306
visit_attrs ( attrs, visitor) ;
1291
1307
visitor. visit_vis ( vis) ;
1292
1308
visitor. visit_ident ( ident) ;
1293
- kind. noop_visit ( visitor) ;
1309
+ kind. noop_visit ( ctxt , visitor) ;
1294
1310
visit_lazy_tts ( tokens, visitor) ;
1295
1311
visitor. visit_span ( span) ;
1296
1312
smallvec ! [ item]
1297
1313
}
1298
1314
1299
1315
impl NoopVisitItemKind for ForeignItemKind {
1300
- fn noop_visit ( & mut self , visitor : & mut impl MutVisitor ) {
1316
+ fn noop_visit ( & mut self , ctxt : Option < AssocCtxt > , visitor : & mut impl MutVisitor ) {
1317
+ assert_eq ! ( ctxt, None ) ;
1301
1318
match self {
1302
1319
ForeignItemKind :: Static ( box StaticItem { ty, mutability : _, expr, safety : _ } ) => {
1303
1320
visitor. visit_ty ( ty) ;
1304
1321
visit_opt ( expr, |expr| visitor. visit_expr ( expr) ) ;
1305
1322
}
1306
1323
ForeignItemKind :: Fn ( box Fn { defaultness, generics, sig, body } ) => {
1307
1324
visit_defaultness ( defaultness, visitor) ;
1308
- visitor. visit_generics ( generics) ;
1309
- visit_fn_sig ( sig, visitor) ;
1310
- visit_opt ( body, |body| visitor. visit_block ( body) ) ;
1325
+ visitor. visit_fn ( FnKind :: Fn ( FnCtxt :: Foreign , sig, generics, body) ) ;
1311
1326
}
1312
1327
ForeignItemKind :: TyAlias ( box TyAlias {
1313
1328
defaultness,
@@ -1517,12 +1532,10 @@ pub fn noop_visit_expr<T: MutVisitor>(
1517
1532
fn_decl_span,
1518
1533
fn_arg_span,
1519
1534
} ) => {
1520
- vis. visit_closure_binder ( binder) ;
1521
1535
visit_constness ( constness, vis) ;
1522
1536
coroutine_kind. as_mut ( ) . map ( |coroutine_kind| vis. visit_coroutine_kind ( coroutine_kind) ) ;
1523
1537
vis. visit_capture_by ( capture_clause) ;
1524
- vis. visit_fn_decl ( fn_decl) ;
1525
- vis. visit_expr ( body) ;
1538
+ vis. visit_fn ( FnKind :: Closure ( binder, fn_decl, body) ) ;
1526
1539
vis. visit_span ( fn_decl_span) ;
1527
1540
vis. visit_span ( fn_arg_span) ;
1528
1541
}
@@ -1779,3 +1792,12 @@ impl<N: DummyAstNode, T: DummyAstNode> DummyAstNode for crate::ast_traits::AstNo
1779
1792
crate :: ast_traits:: AstNodeWrapper :: new ( N :: dummy ( ) , T :: dummy ( ) )
1780
1793
}
1781
1794
}
1795
+
1796
+ #[ derive( Debug ) ]
1797
+ pub enum FnKind < ' a > {
1798
+ /// E.g., `fn foo()`, `fn foo(&self)`, or `extern "Abi" fn foo()`.
1799
+ Fn ( FnCtxt , & ' a mut FnSig , & ' a mut Generics , & ' a mut Option < P < Block > > ) ,
1800
+
1801
+ /// E.g., `|x, y| body`.
1802
+ Closure ( & ' a mut ClosureBinder , & ' a mut P < FnDecl > , & ' a mut P < Expr > ) ,
1803
+ }
0 commit comments