@@ -397,7 +397,7 @@ enum PatternBindingMode {
397
397
}
398
398
399
399
#[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
400
- enum Namespace {
400
+ pub enum Namespace {
401
401
TypeNS ,
402
402
ValueNS
403
403
}
@@ -445,18 +445,38 @@ enum NameDefinition {
445
445
446
446
impl < ' a , ' v , ' tcx > Visitor < ' v > for Resolver < ' a , ' tcx > {
447
447
fn visit_item ( & mut self , item : & Item ) {
448
+ if let Some ( ref callback) = self . callback {
449
+ if callback ( ast_map:: Node :: NodeItem ( item) , & mut self . resolved ) {
450
+ return ;
451
+ }
452
+ }
448
453
self . resolve_item ( item) ;
449
454
}
450
455
fn visit_arm ( & mut self , arm : & Arm ) {
451
456
self . resolve_arm ( arm) ;
452
457
}
453
458
fn visit_block ( & mut self , block : & Block ) {
459
+ if let Some ( ref callback) = self . callback {
460
+ if callback ( ast_map:: Node :: NodeBlock ( block) , & mut self . resolved ) {
461
+ return ;
462
+ }
463
+ }
454
464
self . resolve_block ( block) ;
455
465
}
456
466
fn visit_expr ( & mut self , expr : & Expr ) {
467
+ if let Some ( ref callback) = self . callback {
468
+ if callback ( ast_map:: Node :: NodeExpr ( expr) , & mut self . resolved ) {
469
+ return ;
470
+ }
471
+ }
457
472
self . resolve_expr ( expr) ;
458
473
}
459
474
fn visit_local ( & mut self , local : & Local ) {
475
+ if let Some ( ref callback) = self . callback {
476
+ if callback ( ast_map:: Node :: NodeLocal ( & * local. pat ) , & mut self . resolved ) {
477
+ return ;
478
+ }
479
+ }
460
480
self . resolve_local ( local) ;
461
481
}
462
482
fn visit_ty ( & mut self , ty : & Ty ) {
@@ -475,6 +495,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
475
495
visit:: walk_poly_trait_ref ( self , tref, m) ;
476
496
}
477
497
fn visit_variant ( & mut self , variant : & ast:: Variant , generics : & Generics ) {
498
+ if let Some ( ref callback) = self . callback {
499
+ if callback ( ast_map:: Node :: NodeVariant ( variant) , & mut self . resolved ) {
500
+ return ;
501
+ }
502
+ }
478
503
if let Some ( ref dis_expr) = variant. node . disr_expr {
479
504
// resolve the discriminator expr as a constant
480
505
self . with_constant_rib ( |this| {
@@ -498,6 +523,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
498
523
}
499
524
}
500
525
fn visit_foreign_item ( & mut self , foreign_item : & ast:: ForeignItem ) {
526
+ if let Some ( ref callback) = self . callback {
527
+ if callback ( ast_map:: Node :: NodeForeignItem ( foreign_item) , & mut self . resolved ) {
528
+ return ;
529
+ }
530
+ }
501
531
let type_parameters = match foreign_item. node {
502
532
ForeignItemFn ( _, ref generics) => {
503
533
HasTypeParameters ( generics, FnSpace , ItemRibKind )
@@ -1110,6 +1140,13 @@ pub struct Resolver<'a, 'tcx:'a> {
1110
1140
1111
1141
used_imports : HashSet < ( NodeId , Namespace ) > ,
1112
1142
used_crates : HashSet < CrateNum > ,
1143
+
1144
+ // Callback function for intercepting walks
1145
+ callback : Option < Box < Fn ( ast_map:: Node , & mut bool ) -> bool > > ,
1146
+ // The intention is that the callback modifies this flag.
1147
+ // Once set, the resolver falls out of the walk, preserving the ribs.
1148
+ resolved : bool ,
1149
+
1113
1150
}
1114
1151
1115
1152
#[ derive( PartialEq ) ]
@@ -1171,6 +1208,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1171
1208
emit_errors : true ,
1172
1209
make_glob_map : make_glob_map == MakeGlobMap :: Yes ,
1173
1210
glob_map : HashMap :: new ( ) ,
1211
+
1212
+ callback : None ,
1213
+ resolved : false ,
1214
+
1174
1215
}
1175
1216
}
1176
1217
@@ -2207,7 +2248,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2207
2248
f ( self ) ;
2208
2249
2209
2250
match type_parameters {
2210
- HasTypeParameters ( ..) => { self . type_ribs . pop ( ) ; }
2251
+ HasTypeParameters ( ..) => { if ! self . resolved { self . type_ribs . pop ( ) ; } }
2211
2252
NoTypeParameters => { }
2212
2253
}
2213
2254
}
@@ -2217,7 +2258,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2217
2258
{
2218
2259
self . label_ribs . push ( Rib :: new ( NormalRibKind ) ) ;
2219
2260
f ( self ) ;
2220
- self . label_ribs . pop ( ) ;
2261
+ if !self . resolved {
2262
+ self . label_ribs . pop ( ) ;
2263
+ }
2221
2264
}
2222
2265
2223
2266
fn with_constant_rib < F > ( & mut self , f : F ) where
@@ -2226,8 +2269,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2226
2269
self . value_ribs . push ( Rib :: new ( ConstantItemRibKind ) ) ;
2227
2270
self . type_ribs . push ( Rib :: new ( ConstantItemRibKind ) ) ;
2228
2271
f ( self ) ;
2229
- self . type_ribs . pop ( ) ;
2230
- self . value_ribs . pop ( ) ;
2272
+ if !self . resolved {
2273
+ self . type_ribs . pop ( ) ;
2274
+ self . value_ribs . pop ( ) ;
2275
+ }
2231
2276
}
2232
2277
2233
2278
fn resolve_function ( & mut self ,
@@ -2258,8 +2303,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2258
2303
2259
2304
debug ! ( "(resolving function) leaving function" ) ;
2260
2305
2261
- self . label_ribs . pop ( ) ;
2262
- self . value_ribs . pop ( ) ;
2306
+ if !self . resolved {
2307
+ self . label_ribs . pop ( ) ;
2308
+ self . value_ribs . pop ( ) ;
2309
+ }
2263
2310
}
2264
2311
2265
2312
fn resolve_trait_reference ( & mut self ,
@@ -2362,7 +2409,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2362
2409
self_type_rib. bindings . insert ( name, DlDef ( self_def) ) ;
2363
2410
self . type_ribs . push ( self_type_rib) ;
2364
2411
f ( self ) ;
2365
- self . type_ribs . pop ( ) ;
2412
+ if !self . resolved {
2413
+ self . type_ribs . pop ( ) ;
2414
+ }
2366
2415
}
2367
2416
2368
2417
fn resolve_implementation ( & mut self ,
@@ -2531,7 +2580,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2531
2580
visit:: walk_expr_opt ( self , & arm. guard ) ;
2532
2581
self . visit_expr ( & * arm. body ) ;
2533
2582
2534
- self . value_ribs . pop ( ) ;
2583
+ if !self . resolved {
2584
+ self . value_ribs . pop ( ) ;
2585
+ }
2535
2586
}
2536
2587
2537
2588
fn resolve_block ( & mut self , block : & Block ) {
@@ -2575,7 +2626,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2575
2626
// Move back up.
2576
2627
self . current_module = orig_module;
2577
2628
2578
- self . value_ribs . pop ( ) ;
2629
+ if !self . resolved {
2630
+ self . value_ribs . pop ( ) ;
2631
+ }
2579
2632
debug ! ( "(resolving block) leaving block" ) ;
2580
2633
}
2581
2634
@@ -3017,12 +3070,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3017
3070
/// doesn't skip straight to the containing module.
3018
3071
/// Skips `path_depth` trailing segments, which is also reflected in the
3019
3072
/// returned value. See `middle::def::PathResolution` for more info.
3020
- fn resolve_path ( & mut self ,
3021
- id : NodeId ,
3022
- path : & Path ,
3023
- path_depth : usize ,
3024
- namespace : Namespace ,
3025
- check_ribs : bool ) -> Option < PathResolution > {
3073
+ pub fn resolve_path ( & mut self ,
3074
+ id : NodeId ,
3075
+ path : & Path ,
3076
+ path_depth : usize ,
3077
+ namespace : Namespace ,
3078
+ check_ribs : bool ) -> Option < PathResolution > {
3026
3079
let span = path. span ;
3027
3080
let segments = & path. segments [ ..path. segments . len ( ) -path_depth] ;
3028
3081
@@ -3991,4 +4044,27 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
3991
4044
}
3992
4045
}
3993
4046
4047
+ pub fn create_resolver < ' a , ' tcx > ( session : & ' a Session ,
4048
+ ast_map : & ' a ast_map:: Map < ' tcx > ,
4049
+ _: & LanguageItems ,
4050
+ krate : & ' a Crate ,
4051
+ make_glob_map : MakeGlobMap ,
4052
+ callback : Option < Box < Fn ( ast_map:: Node , & mut bool ) -> bool > > )
4053
+ -> Resolver < ' a , ' tcx > {
4054
+ let mut resolver = Resolver :: new ( session, ast_map, krate. span , make_glob_map) ;
4055
+
4056
+ resolver. callback = callback;
4057
+
4058
+ build_reduced_graph:: build_reduced_graph ( & mut resolver, krate) ;
4059
+ session. abort_if_errors ( ) ;
4060
+
4061
+ resolve_imports:: resolve_imports ( & mut resolver) ;
4062
+ session. abort_if_errors ( ) ;
4063
+
4064
+ record_exports:: record ( & mut resolver) ;
4065
+ session. abort_if_errors ( ) ;
4066
+
4067
+ resolver
4068
+ }
4069
+
3994
4070
__build_diagnostic_array ! { librustc_resolve, DIAGNOSTICS }
0 commit comments