-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Changes required to help facilitate a refactoring tool #27493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
f4ea392
ff6dd5c
251696e
8b98256
ed9f8f8
fdba872
fc9ecae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -397,7 +397,7 @@ enum PatternBindingMode { | |
} | ||
|
||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] | ||
enum Namespace { | ||
pub enum Namespace { | ||
TypeNS, | ||
ValueNS | ||
} | ||
|
@@ -445,18 +445,38 @@ enum NameDefinition { | |
|
||
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { | ||
fn visit_item(&mut self, item: &Item) { | ||
if let Some(ref callback) = self.callback { | ||
if callback(ast_map::Node::NodeItem(item), &mut self.resolved) { | ||
return; | ||
} | ||
} | ||
self.resolve_item(item); | ||
} | ||
fn visit_arm(&mut self, arm: &Arm) { | ||
self.resolve_arm(arm); | ||
} | ||
fn visit_block(&mut self, block: &Block) { | ||
if let Some(ref callback) = self.callback { | ||
if callback(ast_map::Node::NodeBlock(block), &mut self.resolved) { | ||
return; | ||
} | ||
} | ||
self.resolve_block(block); | ||
} | ||
fn visit_expr(&mut self, expr: &Expr) { | ||
if let Some(ref callback) = self.callback { | ||
if callback(ast_map::Node::NodeExpr(expr), &mut self.resolved) { | ||
return; | ||
} | ||
} | ||
self.resolve_expr(expr); | ||
} | ||
fn visit_local(&mut self, local: &Local) { | ||
if let Some(ref callback) = self.callback { | ||
if callback(ast_map::Node::NodeLocal(&*local.pat), &mut self.resolved) { | ||
return; | ||
} | ||
} | ||
self.resolve_local(local); | ||
} | ||
fn visit_ty(&mut self, ty: &Ty) { | ||
|
@@ -475,6 +495,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { | |
visit::walk_poly_trait_ref(self, tref, m); | ||
} | ||
fn visit_variant(&mut self, variant: &ast::Variant, generics: &Generics) { | ||
if let Some(ref callback) = self.callback { | ||
if callback(ast_map::Node::NodeVariant(variant), &mut self.resolved) { | ||
return; | ||
} | ||
} | ||
if let Some(ref dis_expr) = variant.node.disr_expr { | ||
// resolve the discriminator expr as a constant | ||
self.with_constant_rib(|this| { | ||
|
@@ -498,6 +523,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { | |
} | ||
} | ||
fn visit_foreign_item(&mut self, foreign_item: &ast::ForeignItem) { | ||
if let Some(ref callback) = self.callback { | ||
if callback(ast_map::Node::NodeForeignItem(foreign_item), &mut self.resolved) { | ||
return; | ||
} | ||
} | ||
let type_parameters = match foreign_item.node { | ||
ForeignItemFn(_, ref generics) => { | ||
HasTypeParameters(generics, FnSpace, ItemRibKind) | ||
|
@@ -1110,6 +1140,13 @@ pub struct Resolver<'a, 'tcx:'a> { | |
|
||
used_imports: HashSet<(NodeId, Namespace)>, | ||
used_crates: HashSet<CrateNum>, | ||
|
||
// Callback function for intercepting walks | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think some more docs are in order. For example, what is the purpose of this boolean flag? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's to allow the walker to fall out while preserving the ribs (to call resolve_path afterwards). I've added a few more comments now. |
||
callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>, | ||
// The intention is that the callback modifies this flag. | ||
// Once set, the resolver falls out of the walk, preserving the ribs. | ||
resolved: bool, | ||
|
||
} | ||
|
||
#[derive(PartialEq)] | ||
|
@@ -1171,6 +1208,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
emit_errors: true, | ||
make_glob_map: make_glob_map == MakeGlobMap::Yes, | ||
glob_map: HashMap::new(), | ||
|
||
callback: None, | ||
resolved: false, | ||
|
||
} | ||
} | ||
|
||
|
@@ -2207,7 +2248,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
f(self); | ||
|
||
match type_parameters { | ||
HasTypeParameters(..) => { self.type_ribs.pop(); } | ||
HasTypeParameters(..) => { if !self.resolved { self.type_ribs.pop(); } } | ||
NoTypeParameters => { } | ||
} | ||
} | ||
|
@@ -2217,7 +2258,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
{ | ||
self.label_ribs.push(Rib::new(NormalRibKind)); | ||
f(self); | ||
self.label_ribs.pop(); | ||
if !self.resolved { | ||
self.label_ribs.pop(); | ||
} | ||
} | ||
|
||
fn with_constant_rib<F>(&mut self, f: F) where | ||
|
@@ -2226,8 +2269,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
self.value_ribs.push(Rib::new(ConstantItemRibKind)); | ||
self.type_ribs.push(Rib::new(ConstantItemRibKind)); | ||
f(self); | ||
self.type_ribs.pop(); | ||
self.value_ribs.pop(); | ||
if !self.resolved { | ||
self.type_ribs.pop(); | ||
self.value_ribs.pop(); | ||
} | ||
} | ||
|
||
fn resolve_function(&mut self, | ||
|
@@ -2258,8 +2303,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
|
||
debug!("(resolving function) leaving function"); | ||
|
||
self.label_ribs.pop(); | ||
self.value_ribs.pop(); | ||
if !self.resolved { | ||
self.label_ribs.pop(); | ||
self.value_ribs.pop(); | ||
} | ||
} | ||
|
||
fn resolve_trait_reference(&mut self, | ||
|
@@ -2362,7 +2409,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
self_type_rib.bindings.insert(name, DlDef(self_def)); | ||
self.type_ribs.push(self_type_rib); | ||
f(self); | ||
self.type_ribs.pop(); | ||
if !self.resolved { | ||
self.type_ribs.pop(); | ||
} | ||
} | ||
|
||
fn resolve_implementation(&mut self, | ||
|
@@ -2531,7 +2580,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
visit::walk_expr_opt(self, &arm.guard); | ||
self.visit_expr(&*arm.body); | ||
|
||
self.value_ribs.pop(); | ||
if !self.resolved { | ||
self.value_ribs.pop(); | ||
} | ||
} | ||
|
||
fn resolve_block(&mut self, block: &Block) { | ||
|
@@ -2573,9 +2624,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
visit::walk_block(self, block); | ||
|
||
// Move back up. | ||
self.current_module = orig_module; | ||
|
||
self.value_ribs.pop(); | ||
if !self.resolved { | ||
self.current_module = orig_module; | ||
self.value_ribs.pop(); | ||
} | ||
debug!("(resolving block) leaving block"); | ||
} | ||
|
||
|
@@ -3017,12 +3069,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { | |
/// doesn't skip straight to the containing module. | ||
/// Skips `path_depth` trailing segments, which is also reflected in the | ||
/// returned value. See `middle::def::PathResolution` for more info. | ||
fn resolve_path(&mut self, | ||
id: NodeId, | ||
path: &Path, | ||
path_depth: usize, | ||
namespace: Namespace, | ||
check_ribs: bool) -> Option<PathResolution> { | ||
pub fn resolve_path(&mut self, | ||
id: NodeId, | ||
path: &Path, | ||
path_depth: usize, | ||
namespace: Namespace, | ||
check_ribs: bool) -> Option<PathResolution> { | ||
let span = path.span; | ||
let segments = &path.segments[..path.segments.len()-path_depth]; | ||
|
||
|
@@ -3961,16 +4013,7 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session, | |
make_glob_map: MakeGlobMap) | ||
-> CrateMap { | ||
let krate = ast_map.krate(); | ||
let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map); | ||
|
||
build_reduced_graph::build_reduced_graph(&mut resolver, krate); | ||
session.abort_if_errors(); | ||
|
||
resolve_imports::resolve_imports(&mut resolver); | ||
session.abort_if_errors(); | ||
|
||
record_exports::record(&mut resolver); | ||
session.abort_if_errors(); | ||
let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None); | ||
|
||
resolver.resolve_crate(krate); | ||
session.abort_if_errors(); | ||
|
@@ -3991,4 +4034,34 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session, | |
} | ||
} | ||
|
||
/// Builds a name resolution walker to be used within this module, | ||
/// or used externally, with an optional callback function. | ||
/// | ||
/// The callback takes a &mut bool which allows callbacks to end a | ||
/// walk when set to true, passing through the rest of the walk, while | ||
/// preserving the ribs + current module. This allows resolve_path | ||
/// calls to be made with the correct scope info. The node in the | ||
/// callback corresponds to the current node in the walk. | ||
pub fn create_resolver<'a, 'tcx>(session: &'a Session, | ||
ast_map: &'a ast_map::Map<'tcx>, | ||
krate: &'a Crate, | ||
make_glob_map: MakeGlobMap, | ||
callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>) | ||
-> Resolver<'a, 'tcx> { | ||
let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map); | ||
|
||
resolver.callback = callback; | ||
|
||
build_reduced_graph::build_reduced_graph(&mut resolver, krate); | ||
session.abort_if_errors(); | ||
|
||
resolve_imports::resolve_imports(&mut resolver); | ||
session.abort_if_errors(); | ||
|
||
record_exports::record(&mut resolver); | ||
session.abort_if_errors(); | ||
|
||
resolver | ||
} | ||
|
||
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use a macro for this repeated idiom?