Skip to content

Commit f4ea392

Browse files
committed
Introduce callback to resolver
Sets a flag to pass through the rest of the walker.
1 parent ea5cc76 commit f4ea392

File tree

1 file changed

+92
-16
lines changed

1 file changed

+92
-16
lines changed

src/librustc_resolve/lib.rs

Lines changed: 92 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ enum PatternBindingMode {
397397
}
398398

399399
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
400-
enum Namespace {
400+
pub enum Namespace {
401401
TypeNS,
402402
ValueNS
403403
}
@@ -445,18 +445,38 @@ enum NameDefinition {
445445

446446
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
447447
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+
}
448453
self.resolve_item(item);
449454
}
450455
fn visit_arm(&mut self, arm: &Arm) {
451456
self.resolve_arm(arm);
452457
}
453458
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+
}
454464
self.resolve_block(block);
455465
}
456466
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+
}
457472
self.resolve_expr(expr);
458473
}
459474
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+
}
460480
self.resolve_local(local);
461481
}
462482
fn visit_ty(&mut self, ty: &Ty) {
@@ -475,6 +495,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
475495
visit::walk_poly_trait_ref(self, tref, m);
476496
}
477497
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+
}
478503
if let Some(ref dis_expr) = variant.node.disr_expr {
479504
// resolve the discriminator expr as a constant
480505
self.with_constant_rib(|this| {
@@ -498,6 +523,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
498523
}
499524
}
500525
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+
}
501531
let type_parameters = match foreign_item.node {
502532
ForeignItemFn(_, ref generics) => {
503533
HasTypeParameters(generics, FnSpace, ItemRibKind)
@@ -1110,6 +1140,13 @@ pub struct Resolver<'a, 'tcx:'a> {
11101140

11111141
used_imports: HashSet<(NodeId, Namespace)>,
11121142
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+
11131150
}
11141151

11151152
#[derive(PartialEq)]
@@ -1171,6 +1208,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
11711208
emit_errors: true,
11721209
make_glob_map: make_glob_map == MakeGlobMap::Yes,
11731210
glob_map: HashMap::new(),
1211+
1212+
callback: None,
1213+
resolved: false,
1214+
11741215
}
11751216
}
11761217

@@ -2207,7 +2248,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
22072248
f(self);
22082249

22092250
match type_parameters {
2210-
HasTypeParameters(..) => { self.type_ribs.pop(); }
2251+
HasTypeParameters(..) => { if !self.resolved { self.type_ribs.pop(); } }
22112252
NoTypeParameters => { }
22122253
}
22132254
}
@@ -2217,7 +2258,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
22172258
{
22182259
self.label_ribs.push(Rib::new(NormalRibKind));
22192260
f(self);
2220-
self.label_ribs.pop();
2261+
if !self.resolved {
2262+
self.label_ribs.pop();
2263+
}
22212264
}
22222265

22232266
fn with_constant_rib<F>(&mut self, f: F) where
@@ -2226,8 +2269,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
22262269
self.value_ribs.push(Rib::new(ConstantItemRibKind));
22272270
self.type_ribs.push(Rib::new(ConstantItemRibKind));
22282271
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+
}
22312276
}
22322277

22332278
fn resolve_function(&mut self,
@@ -2258,8 +2303,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
22582303

22592304
debug!("(resolving function) leaving function");
22602305

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+
}
22632310
}
22642311

22652312
fn resolve_trait_reference(&mut self,
@@ -2362,7 +2409,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
23622409
self_type_rib.bindings.insert(name, DlDef(self_def));
23632410
self.type_ribs.push(self_type_rib);
23642411
f(self);
2365-
self.type_ribs.pop();
2412+
if !self.resolved {
2413+
self.type_ribs.pop();
2414+
}
23662415
}
23672416

23682417
fn resolve_implementation(&mut self,
@@ -2531,7 +2580,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
25312580
visit::walk_expr_opt(self, &arm.guard);
25322581
self.visit_expr(&*arm.body);
25332582

2534-
self.value_ribs.pop();
2583+
if !self.resolved {
2584+
self.value_ribs.pop();
2585+
}
25352586
}
25362587

25372588
fn resolve_block(&mut self, block: &Block) {
@@ -2575,7 +2626,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
25752626
// Move back up.
25762627
self.current_module = orig_module;
25772628

2578-
self.value_ribs.pop();
2629+
if !self.resolved {
2630+
self.value_ribs.pop();
2631+
}
25792632
debug!("(resolving block) leaving block");
25802633
}
25812634

@@ -3017,12 +3070,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
30173070
/// doesn't skip straight to the containing module.
30183071
/// Skips `path_depth` trailing segments, which is also reflected in the
30193072
/// 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> {
30263079
let span = path.span;
30273080
let segments = &path.segments[..path.segments.len()-path_depth];
30283081

@@ -3991,4 +4044,27 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
39914044
}
39924045
}
39934046

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+
39944070
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }

0 commit comments

Comments
 (0)