fn with_scope<F>(&mut self, id: NodeId, f: F)
        where F: FnOnce(&mut Resolver)
    {
        let module = self.module_map.get(&id).cloned(); // clones a reference
        if let Some(module) = module {
            // Move down in the graph.
            let orig_module = ::std::mem::replace(&mut self.current_module, module);
            self.value_ribs.push(Rib::new(ModuleRibKind(module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(module)));

            f(self);

            self.current_module = orig_module;
            self.value_ribs.pop();
            self.type_ribs.pop();
        } else {
            f(self);
        }
    }
// AST resolution
//
// We maintain a list of value ribs and type ribs.
//
// Simultaneously, we keep track of the current position in the module
// graph in the `current_module` pointer. When we go to resolve a name in
// the value or type namespaces, we first look through all the ribs and
// then query the module graph. When we resolve a name in the module
// namespace, we can skip all the ribs (since nested modules are not
// allowed within blocks in Rust) and jump straight to the current module
// graph node.
//
// Named implementations are handled separately. When we find a method
// call, we consult the module node to find all of the implementations in
// scope. This information is lazily cached in the module node. We then
// generate a fake "implementation scope" containing all the
// implementations thus found, for compatibility with old resolve pass.
AST resolution
We maintain a list of value ribs and type ribs.

Simultaneously, we keep track of the current position in the module
graph in the `current_module` pointer. When we go to resolve a name in
the value or type namespaces, we first look through all the ribs and
then query the module graph. When we resolve a name in the module
namespace, we can skip all the ribs (since nested modules are not
allowed within blocks in Rust) and jump straight to the current module
graph node.

Named implementations are handled separately. When we find a method
call, we consult the module node to find all of the implementations in
scope. This information is lazily cached in the module node. We then
generate a fake "implementation scope" containing all the
implementations thus found, for compatibility with old resolve pass.
AST resolution We maintain a list of value ribs and type ribs . Simultaneously we keep track of the current position in the module graph in the ` current_module ` pointer . When we go to resolve a name in the value or type namespaces we first look through all the ribs and then query the module graph . When we resolve a name in the module namespace we can skip all the ribs ( since nested modules are not allowed within blocks in Rust ) and jump straight to the current module graph node . Named implementations are handled separately . When we find a method call we consult the module node to find all of the implementations in scope . This information is lazily cached in the module node . We then generate a fake " implementation scope " containing all the implementations thus found for compatibility with old resolve pass .
fn with_scope<F>(&mut self, id: NodeId, f: F)
        where F: FnOnce(&mut Resolver)
    {
        let module = self.module_map.get(&id).cloned(); // clones a reference
        if let Some(module) = module {
            // Move down in the graph.
            let orig_module = ::std::mem::replace(&mut self.current_module, module);
            self.value_ribs.push(Rib::new(ModuleRibKind(module)));
            self.type_ribs.push(Rib::new(ModuleRibKind(module)));
            f(self);
            self.current_module = orig_module;
            self.value_ribs.pop();
            self.type_ribs.pop();
        } else {
            f(self);
        }
    }
fn with_scope < F > ( & mut self , id : NodeId , f : F ) where F : FnOnce ( & mut Resolver ) { let module = self . module_map . get ( & id ) . cloned ( ) ; // clones a reference if let Some ( module ) = module { // Move down in the graph. let orig_module = :: std :: mem :: replace ( & mut self . current_module , module ) ; self . value_ribs . push ( Rib :: new ( ModuleRibKind ( module ) ) ) ; self . type_ribs . push ( Rib :: new ( ModuleRibKind ( module ) ) ) ; f ( self ) ; self . current_module = orig_module ; self . value_ribs . pop ( ) ; self . type_ribs . pop ( ) ; } else { f ( self ) ; } }
AST resolution
We maintain a list of value ribs and type ribs.
AST resolution We maintain a list of value ribs and type ribs .
&mut self
id
NodeId
f
F
&mut self
id
NodeId
f
F