]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/middle/save/mod.rs
rollup merge of #17355 : gamazeps/issue17210
[rust.git] / src / librustc / middle / save / mod.rs
index 7350413643c8da460fb03b10e250c2b47f7fff9b..0f4ed202ec20750c9b80030fd92db4b841d4d188 100644 (file)
@@ -35,7 +35,6 @@
 use middle::typeck;
 
 use std::cell::Cell;
-use std::gc::Gc;
 use std::io;
 use std::io::File;
 use std::io::fs;
@@ -54,6 +53,7 @@
 use syntax::visit;
 use syntax::visit::Visitor;
 use syntax::print::pprust::{path_to_string,ty_to_string};
+use syntax::ptr::P;
 
 use middle::save::span_utils::SpanUtils;
 use middle::save::recorder::Recorder;
@@ -71,7 +71,7 @@ fn escape(s: String) -> String {
 
 // If the expression is a macro expansion or other generated code, run screaming and don't index.
 fn generated_code(span: Span) -> bool {
-    span.expn_info.is_some() || span  == DUMMY_SP
+    span.expn_id != NO_EXPANSION || span  == DUMMY_SP
 }
 
 struct DxrVisitor<'l, 'tcx: 'l> {
@@ -83,9 +83,18 @@ struct DxrVisitor<'l, 'tcx: 'l> {
 
     span: SpanUtils<'l>,
     fmt: FmtStrs<'l>,
+
+    cur_scope: NodeId
 }
 
 impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
+    fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) {
+        let parent_scope = self.cur_scope;
+        self.cur_scope = scope_id;
+        f(self);
+        self.cur_scope = parent_scope;
+    }
+
     fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
         // the current crate
         self.fmt.crate_str(krate.span, name);
@@ -136,19 +145,19 @@ fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
         result
     }
 
-    fn write_sub_paths(&mut self, path: &ast::Path, scope_id: NodeId) {
+    fn write_sub_paths(&mut self, path: &ast::Path) {
         let sub_paths = self.process_path_prefixes(path);
         for &(ref span, ref qualname) in sub_paths.iter() {
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
                                      qualname.as_slice(),
-                                     scope_id);
+                                     self.cur_scope);
         }
     }
 
     // As write_sub_paths, but does not process the last ident in the path (assuming it
     // will be processed elsewhere).
-    fn write_sub_paths_truncated(&mut self, path: &ast::Path, scope_id: NodeId) {
+    fn write_sub_paths_truncated(&mut self, path: &ast::Path) {
         let sub_paths = self.process_path_prefixes(path);
         let len = sub_paths.len();
         if len <= 1 {
@@ -160,13 +169,13 @@ fn write_sub_paths_truncated(&mut self, path: &ast::Path, scope_id: NodeId) {
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
                                      qualname.as_slice(),
-                                     scope_id);
+                                     self.cur_scope);
         }
     }
 
     // As write_sub_paths, but expects a path of the form module_path::trait::method
     // Where trait could actually be a struct too.
-    fn write_sub_path_trait_truncated(&mut self, path: &ast::Path, scope_id: NodeId) {
+    fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
         let sub_paths = self.process_path_prefixes(path);
         let len = sub_paths.len();
         if len <= 1 {
@@ -189,7 +198,7 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path, scope_id: NodeId)
             self.fmt.sub_mod_ref_str(path.span,
                                      *span,
                                      qualname.as_slice(),
-                                     scope_id);
+                                     self.cur_scope);
         }
     }
 
@@ -217,14 +226,13 @@ fn lookup_def_kind(&self, ref_id: NodeId, span: Span) -> Option<recorder::Row> {
             def::DefMod(_) |
             def::DefForeignMod(_) => Some(recorder::ModRef),
             def::DefStruct(_) => Some(recorder::StructRef),
-            def::DefTy(_) |
+            def::DefTy(..) |
+            def::DefAssociatedTy(..) |
             def::DefTrait(_) => Some(recorder::TypeRef),
             def::DefStatic(_, _) |
-            def::DefBinding(_, _) |
-            def::DefArg(_, _) |
-            def::DefLocal(_, _) |
+            def::DefLocal(_) |
             def::DefVariant(_, _, _) |
-            def::DefUpvar(_, _, _, _) => Some(recorder::VarRef),
+            def::DefUpvar(..) => Some(recorder::VarRef),
 
             def::DefFn(_, _) => Some(recorder::FnRef),
 
@@ -243,11 +251,11 @@ fn lookup_def_kind(&self, ref_id: NodeId, span: Span) -> Option<recorder::Row> {
         }
     }
 
-    fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisitorEnv) {
+    fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str) {
         for arg in formals.iter() {
             assert!(self.collected_paths.len() == 0 && !self.collecting);
             self.collecting = true;
-            self.visit_pat(&*arg.pat, e);
+            self.visit_pat(&*arg.pat);
             self.collecting = false;
             let span_utils = self.span;
             for &(id, ref p, _, _) in self.collected_paths.iter() {
@@ -266,7 +274,7 @@ fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisi
         }
     }
 
-    fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
+    fn process_method(&mut self, method: &ast::Method) {
         if generated_code(method.span) {
             return;
         }
@@ -280,9 +288,9 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                 NodeItem(item) => {
                     scope_id = item.id;
                     match item.node {
-                        ast::ItemImpl(_, _, ty, _) => {
+                        ast::ItemImpl(_, _, ref ty, _) => {
                             let mut result = String::from_str("<");
-                            result.push_str(ty_to_string(&*ty).as_slice());
+                            result.push_str(ty_to_string(&**ty).as_slice());
 
                             match ty::trait_of_item(&self.analysis.ty_cx,
                                                     ast_util::local_def(method.id)) {
@@ -346,11 +354,12 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                     ty::MethodTraitItemId(def_id) => {
                         method.id != 0 && def_id.node == 0
                     }
+                    ty::TypeTraitItemId(_) => false,
                 }
             });
         let decl_id = match decl_id {
             None => None,
-            Some(ty::MethodTraitItemId(def_id)) => Some(def_id),
+            Some(id) => Some(id.def_id()),
         };
 
         let sub_span = self.span.sub_span_after_keyword(method.span, keywords::Fn);
@@ -361,27 +370,24 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
                             decl_id,
                             scope_id);
 
-        self.process_formals(&method.pe_fn_decl().inputs, qualname, e);
+        self.process_formals(&method.pe_fn_decl().inputs, qualname);
 
         // walk arg and return types
         for arg in method.pe_fn_decl().inputs.iter() {
-            self.visit_ty(&*arg.ty, e);
+            self.visit_ty(&*arg.ty);
         }
-        self.visit_ty(&*method.pe_fn_decl().output, e);
+        self.visit_ty(&*method.pe_fn_decl().output);
         // walk the fn body
-        self.visit_block(&*method.pe_body(),
-                         DxrVisitorEnv::new_nested(method.id));
+        self.nest(method.id, |v| v.visit_block(&*method.pe_body()));
 
         self.process_generic_params(method.pe_generics(),
                                     method.span,
                                     qualname,
-                                    method.id,
-                                    e);
+                                    method.id);
     }
 
     fn process_trait_ref(&mut self,
                          trait_ref: &ast::TraitRef,
-                         e: DxrVisitorEnv,
                          impl_id: Option<NodeId>) {
         match self.lookup_type_ref(trait_ref.ref_id) {
             Some(id) => {
@@ -390,16 +396,16 @@ fn process_trait_ref(&mut self,
                                  trait_ref.path.span,
                                  sub_span,
                                  id,
-                                 e.cur_scope);
+                                 self.cur_scope);
                 match impl_id {
                     Some(impl_id) => self.fmt.impl_str(trait_ref.path.span,
                                                        sub_span,
                                                        impl_id,
                                                        id,
-                                                       e.cur_scope),
+                                                       self.cur_scope),
                     None => (),
                 }
-                visit::walk_path(self, &trait_ref.path, e);
+                visit::walk_path(self, &trait_ref.path);
             },
             None => ()
         }
@@ -436,8 +442,7 @@ fn process_struct_field_def(&mut self,
     fn process_generic_params(&mut self, generics:&ast::Generics,
                               full_span: Span,
                               prefix: &str,
-                              id: NodeId,
-                              e: DxrVisitorEnv) {
+                              id: NodeId) {
         // We can't only use visit_generics since we don't have spans for param
         // bindings, so we reparse the full_span to get those sub spans.
         // However full span is the entire enum/fn/struct block, so we only want
@@ -456,15 +461,14 @@ fn process_generic_params(&mut self, generics:&ast::Generics,
                                  name.as_slice(),
                                  "");
         }
-        self.visit_generics(generics, e);
+        self.visit_generics(generics);
     }
 
     fn process_fn(&mut self,
                   item: &ast::Item,
-                  e: DxrVisitorEnv,
-                  decl: ast::P<ast::FnDecl>,
+                  decl: &ast::FnDecl,
                   ty_params: &ast::Generics,
-                  body: ast::P<ast::Block>) {
+                  body: &ast::Block) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
         let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Fn);
@@ -472,26 +476,25 @@ fn process_fn(&mut self,
                         sub_span,
                         item.id,
                         qualname.as_slice(),
-                        e.cur_scope);
+                        self.cur_scope);
 
-        self.process_formals(&decl.inputs, qualname.as_slice(), e);
+        self.process_formals(&decl.inputs, qualname.as_slice());
 
         // walk arg and return types
         for arg in decl.inputs.iter() {
-            self.visit_ty(&*arg.ty, e);
+            self.visit_ty(&*arg.ty);
         }
-        self.visit_ty(&*decl.output, e);
+        self.visit_ty(&*decl.output);
 
         // walk the body
-        self.visit_block(&*body, DxrVisitorEnv::new_nested(item.id));
+        self.nest(item.id, |v| v.visit_block(&*body));
 
-        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
     }
 
     fn process_static(&mut self,
                       item: &ast::Item,
-                      e: DxrVisitorEnv,
-                      typ: ast::P<ast::Ty>,
+                      typ: &ast::Ty,
                       mt: ast::Mutability,
                       expr: &ast::Expr)
     {
@@ -511,16 +514,15 @@ fn process_static(&mut self,
                             qualname.as_slice(),
                             value.as_slice(),
                             ty_to_string(&*typ).as_slice(),
-                            e.cur_scope);
+                            self.cur_scope);
 
         // walk type and init value
-        self.visit_ty(&*typ, e);
-        self.visit_expr(expr, e);
+        self.visit_ty(&*typ);
+        self.visit_expr(expr);
     }
 
     fn process_struct(&mut self,
                       item: &ast::Item,
-                      e: DxrVisitorEnv,
                       def: &ast::StructDef,
                       ty_params: &ast::Generics) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@@ -535,20 +537,19 @@ fn process_struct(&mut self,
                             item.id,
                             ctor_id,
                             qualname.as_slice(),
-                            e.cur_scope);
+                            self.cur_scope);
 
         // fields
         for field in def.fields.iter() {
             self.process_struct_field_def(field, qualname.as_slice(), item.id);
-            self.visit_ty(&*field.node.ty, e);
+            self.visit_ty(&*field.node.ty);
         }
 
-        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
     }
 
     fn process_enum(&mut self,
                     item: &ast::Item,
-                    e: DxrVisitorEnv,
                     enum_definition: &ast::EnumDef,
                     ty_params: &ast::Generics) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@@ -557,7 +558,7 @@ fn process_enum(&mut self,
                                                 Some(sub_span),
                                                 item.id,
                                                 qualname.as_slice(),
-                                                e.cur_scope),
+                                                self.cur_scope),
             None => self.sess.span_bug(item.span,
                                        format!("Could not find subspan for enum {}",
                                                qualname).as_slice()),
@@ -578,7 +579,7 @@ fn process_enum(&mut self,
                                                val.as_slice(),
                                                item.id);
                     for arg in args.iter() {
-                        self.visit_ty(&*arg.ty, e);
+                        self.visit_ty(&*arg.ty);
                     }
                 }
                 ast::StructVariantKind(ref struct_def) => {
@@ -597,21 +598,20 @@ fn process_enum(&mut self,
 
                     for field in struct_def.fields.iter() {
                         self.process_struct_field_def(field, qualname.as_slice(), variant.node.id);
-                        self.visit_ty(&*field.node.ty, e);
+                        self.visit_ty(&*field.node.ty);
                     }
                 }
             }
         }
 
-        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
     }
 
     fn process_impl(&mut self,
                     item: &ast::Item,
-                    e: DxrVisitorEnv,
                     type_parameters: &ast::Generics,
                     trait_ref: &Option<ast::TraitRef>,
-                    typ: ast::P<ast::Ty>,
+                    typ: &ast::Ty,
                     impl_items: &Vec<ast::ImplItem>) {
         match typ.node {
             ast::TyPath(ref path, _, id) => {
@@ -622,29 +622,32 @@ fn process_impl(&mut self,
                                          path.span,
                                          sub_span,
                                          id,
-                                         e.cur_scope);
+                                         self.cur_scope);
                         self.fmt.impl_str(path.span,
                                           sub_span,
                                           item.id,
                                           id,
-                                          e.cur_scope);
+                                          self.cur_scope);
                     },
                     None => ()
                 }
             },
-            _ => self.visit_ty(&*typ, e),
+            _ => self.visit_ty(&*typ),
         }
 
         match *trait_ref {
-            Some(ref trait_ref) => self.process_trait_ref(trait_ref, e, Some(item.id)),
+            Some(ref trait_ref) => self.process_trait_ref(trait_ref, Some(item.id)),
             None => (),
         }
 
-        self.process_generic_params(type_parameters, item.span, "", item.id, e);
+        self.process_generic_params(type_parameters, item.span, "", item.id);
         for impl_item in impl_items.iter() {
             match *impl_item {
-                ast::MethodImplItem(method) => {
-                    visit::walk_method_helper(self, &*method, e)
+                ast::MethodImplItem(ref method) => {
+                    visit::walk_method_helper(self, &**method)
+                }
+                ast::TypeImplItem(ref typedef) => {
+                    visit::walk_ty(self, &*typedef.typ)
                 }
             }
         }
@@ -652,7 +655,6 @@ fn process_impl(&mut self,
 
     fn process_trait(&mut self,
                      item: &ast::Item,
-                     e: DxrVisitorEnv,
                      generics: &ast::Generics,
                      trait_refs: &OwnedSlice<ast::TyParamBound>,
                      methods: &Vec<ast::TraitItem>) {
@@ -663,7 +665,7 @@ fn process_trait(&mut self,
                            sub_span,
                            item.id,
                            qualname.as_slice(),
-                           e.cur_scope);
+                           self.cur_scope);
 
         // super-traits
         for super_bound in trait_refs.iter() {
@@ -683,7 +685,7 @@ fn process_trait(&mut self,
                                      trait_ref.path.span,
                                      sub_span,
                                      id,
-                                     e.cur_scope);
+                                     self.cur_scope);
                     self.fmt.inherit_str(trait_ref.path.span,
                                          sub_span,
                                          id,
@@ -694,15 +696,14 @@ fn process_trait(&mut self,
         }
 
         // walk generics and methods
-        self.process_generic_params(generics, item.span, qualname.as_slice(), item.id, e);
+        self.process_generic_params(generics, item.span, qualname.as_slice(), item.id);
         for method in methods.iter() {
-            self.visit_trait_item(method, e)
+            self.visit_trait_item(method)
         }
     }
 
     fn process_mod(&mut self,
                    item: &ast::Item,  // The module in question, represented as an item.
-                   e: DxrVisitorEnv,
                    m: &ast::Mod) {
         let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
 
@@ -714,15 +715,14 @@ fn process_mod(&mut self,
                          sub_span,
                          item.id,
                          qualname.as_slice(),
-                         e.cur_scope,
+                         self.cur_scope,
                          filename.as_slice());
 
-        visit::walk_mod(self, m, DxrVisitorEnv::new_nested(item.id));
+        self.nest(item.id, |v| visit::walk_mod(v, m));
     }
 
     fn process_path(&mut self,
                     ex: &ast::Expr,
-                    e: DxrVisitorEnv,
                     path: &ast::Path) {
         if generated_code(path.span) {
             return
@@ -737,25 +737,19 @@ fn process_path(&mut self,
         let def = def_map.get(&ex.id);
         let sub_span = self.span.span_for_last_ident(ex.span);
         match *def {
-            def::DefLocal(id, _) |
-            def::DefArg(id, _) |
-            def::DefUpvar(id, _, _, _) |
-            def::DefBinding(id, _) => self.fmt.ref_str(recorder::VarRef,
-                                                       ex.span,
-                                                       sub_span,
-                                                       ast_util::local_def(id),
-                                                       e.cur_scope),
-            def::DefStatic(def_id,_) |
-            def::DefVariant(_, def_id, _) => self.fmt.ref_str(recorder::VarRef,
-                                                              ex.span,
-                                                              sub_span,
-                                                              def_id,
-                                                              e.cur_scope),
+            def::DefUpvar(..) |
+            def::DefLocal(..) |
+            def::DefStatic(..) |
+            def::DefVariant(..) => self.fmt.ref_str(recorder::VarRef,
+                                                    ex.span,
+                                                    sub_span,
+                                                    def.def_id(),
+                                                    self.cur_scope),
             def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef,
                                                        ex.span,
                                                        sub_span,
                                                        def_id,
-                                                        e.cur_scope),
+                                                        self.cur_scope),
             def::DefStaticMethod(declid, provenence, _) => {
                 let sub_span = self.span.sub_span_for_meth_name(ex.span);
                 let defid = if declid.krate == ast::LOCAL_CRATE {
@@ -767,12 +761,7 @@ fn process_path(&mut self,
                                                  def_id)
                                     .iter()
                                     .find(|mr| {
-                                        match **mr {
-                                            ty::MethodTraitItem(ref mr) => {
-                                                mr.ident.name == ti.ident()
-                                                                   .name
-                                            }
-                                        }
+                                        mr.ident().name == ti.ident().name
                                     })
                                     .unwrap()
                                     .def_id())
@@ -785,18 +774,13 @@ fn process_path(&mut self,
                             Some(impl_items.get(&def_id)
                                            .iter()
                                            .find(|mr| {
-                                            match **mr {
-                                                ty::MethodTraitItemId(mr) => {
-                                                    ty::impl_or_trait_item(
-                                                            &self.analysis
-                                                                 .ty_cx,
-                                                            mr).ident()
-                                                               .name ==
-                                                        ti.ident().name
-                                                    }
-                                                }
-                                            }).unwrap()
-                                              .def_id())
+                                            ty::impl_or_trait_item(
+                                                &self.analysis.ty_cx,
+                                                mr.def_id()).ident().name ==
+                                                ti.ident().name
+                                            })
+                                           .unwrap()
+                                           .def_id())
                         }
                     }
                 } else {
@@ -806,12 +790,12 @@ fn process_path(&mut self,
                                        sub_span,
                                        defid,
                                        Some(declid),
-                                       e.cur_scope);
+                                       self.cur_scope);
             },
             def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
                                                           sub_span,
                                                           def_id,
-                                                          e.cur_scope),
+                                                          self.cur_scope),
             _ => self.sess.span_bug(ex.span,
                                     format!("Unexpected def kind while looking up path in '{}'",
                                             self.span.snippet(ex.span)).as_slice()),
@@ -819,25 +803,23 @@ fn process_path(&mut self,
         // modules or types in the path prefix
         match *def {
             def::DefStaticMethod(_, _, _) => {
-                self.write_sub_path_trait_truncated(path, e.cur_scope);
+                self.write_sub_path_trait_truncated(path);
             },
-            def::DefLocal(_, _) |
-            def::DefArg(_, _) |
+            def::DefLocal(_) |
             def::DefStatic(_,_) |
             def::DefStruct(_) |
-            def::DefFn(_, _) => self.write_sub_paths_truncated(path, e.cur_scope),
+            def::DefFn(_, _) => self.write_sub_paths_truncated(path),
             _ => {},
         }
 
-        visit::walk_path(self, path, e);
+        visit::walk_path(self, path);
     }
 
     fn process_struct_lit(&mut self,
                           ex: &ast::Expr,
-                          e: DxrVisitorEnv,
                           path: &ast::Path,
                           fields: &Vec<ast::Field>,
-                          base: Option<Gc<ast::Expr>>) {
+                          base: &Option<P<ast::Expr>>) {
         if generated_code(path.span) {
             return
         }
@@ -851,12 +833,12 @@ fn process_struct_lit(&mut self,
                                  path.span,
                                  sub_span,
                                  id,
-                                 e.cur_scope);
+                                 self.cur_scope);
             },
             None => ()
         }
 
-        self.write_sub_paths_truncated(path, e.cur_scope);
+        self.write_sub_paths_truncated(path);
 
         for field in fields.iter() {
             match struct_def {
@@ -873,22 +855,21 @@ fn process_struct_lit(&mut self,
                                              field.ident.span,
                                              sub_span,
                                              f.id,
-                                             e.cur_scope);
+                                             self.cur_scope);
                         }
                     }
                 }
                 None => {}
             }
 
-            self.visit_expr(&*field.expr, e)
+            self.visit_expr(&*field.expr)
         }
-        visit::walk_expr_opt(self, base, e)
+        visit::walk_expr_opt(self, base)
     }
 
     fn process_method_call(&mut self,
                            ex: &ast::Expr,
-                           e: DxrVisitorEnv,
-                           args: &Vec<Gc<ast::Expr>>) {
+                           args: &Vec<P<ast::Expr>>) {
         let method_map = self.analysis.ty_cx.method_map.borrow();
         let method_callee = method_map.get(&typeck::MethodCall::expr(ex.id));
         let (def_id, decl_id) = match method_callee.origin {
@@ -899,7 +880,7 @@ fn process_method_call(&mut self,
                     match ty::trait_item_of_item(&self.analysis.ty_cx,
                                                  def_id) {
                         None => None,
-                        Some(ty::MethodTraitItemId(decl_id)) => Some(decl_id),
+                        Some(decl_id) => Some(decl_id.def_id()),
                     };
 
                 // This incantation is required if the method referenced is a
@@ -910,44 +891,37 @@ fn process_method_call(&mut self,
                     ty::MethodTraitItem(method) => {
                         method.provided_source.unwrap_or(def_id)
                     }
+                    ty::TypeTraitItem(_) => def_id,
                 };
                 (Some(def_id), decl_id)
             }
-            typeck::MethodParam(mp) => {
+            typeck::MethodTypeParam(ref mp) => {
                 // method invoked on a type parameter
                 let trait_item = ty::trait_item(&self.analysis.ty_cx,
-                                                mp.trait_id,
+                                                mp.trait_ref.def_id,
                                                 mp.method_num);
-                match trait_item {
-                    ty::MethodTraitItem(method) => {
-                        (None, Some(method.def_id))
-                    }
-                }
-            },
-            typeck::MethodObject(mo) => {
+                (None, Some(trait_item.def_id()))
+            }
+            typeck::MethodTraitObject(ref mo) => {
                 // method invoked on a trait instance
                 let trait_item = ty::trait_item(&self.analysis.ty_cx,
-                                                mo.trait_id,
+                                                mo.trait_ref.def_id,
                                                 mo.method_num);
-                match trait_item {
-                    ty::MethodTraitItem(method) => {
-                        (None, Some(method.def_id))
-                    }
-                }
-            },
+                (None, Some(trait_item.def_id()))
+            }
         };
         let sub_span = self.span.sub_span_for_meth_name(ex.span);
         self.fmt.meth_call_str(ex.span,
                                sub_span,
                                def_id,
                                decl_id,
-                               e.cur_scope);
+                               self.cur_scope);
 
         // walk receiver and args
-        visit::walk_exprs(self, args.as_slice(), e);
+        visit::walk_exprs(self, args.as_slice());
     }
 
-    fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
+    fn process_pat(&mut self, p:&ast::Pat) {
         if generated_code(p.span) {
             return
         }
@@ -955,7 +929,7 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
         match p.node {
             ast::PatStruct(ref path, ref fields, _) => {
                 self.collected_paths.push((p.id, path.clone(), false, recorder::StructRef));
-                visit::walk_path(self, path, e);
+                visit::walk_path(self, path);
                 let struct_def = match self.lookup_type_ref(p.id) {
                     Some(sd) => sd,
                     None => {
@@ -976,7 +950,7 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
                                ).as_slice());
                 }
                 for (field, &span) in fields.iter().zip(field_spans.iter()) {
-                    self.visit_pat(&*field.pat, e);
+                    self.visit_pat(&*field.pat);
                     if span.is_none() {
                         continue;
                     }
@@ -987,7 +961,7 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
                                              p.span,
                                              span,
                                              f.id,
-                                             e.cur_scope);
+                                             self.cur_scope);
                             break;
                         }
                     }
@@ -995,7 +969,7 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
             }
             ast::PatEnum(ref path, _) => {
                 self.collected_paths.push((p.id, path.clone(), false, recorder::VarRef));
-                visit::walk_pat(self, p, e);
+                visit::walk_pat(self, p);
             }
             ast::PatIdent(bm, ref path1, ref optional_subpattern) => {
                 let immut = match bm {
@@ -1015,44 +989,43 @@ fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) {
                 self.collected_paths.push((p.id, path, immut, recorder::VarRef));
                 match *optional_subpattern {
                     None => {}
-                    Some(subpattern) => self.visit_pat(&*subpattern, e),
+                    Some(ref subpattern) => self.visit_pat(&**subpattern)
                 }
             }
-            _ => visit::walk_pat(self, p, e)
+            _ => visit::walk_pat(self, p)
         }
     }
 }
 
-impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
-    fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) {
+impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
+    fn visit_item(&mut self, item: &ast::Item) {
         if generated_code(item.span) {
             return
         }
 
         match item.node {
-            ast::ItemFn(decl, _, _, ref ty_params, body) =>
-                self.process_fn(item, e, decl, ty_params, body),
-            ast::ItemStatic(typ, mt, expr) =>
-                self.process_static(item, e, typ, mt, &*expr),
-            ast::ItemStruct(def, ref ty_params) => self.process_struct(item, e, &*def, ty_params),
-            ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, e, def, ty_params),
+            ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
+                self.process_fn(item, &**decl, ty_params, &**body),
+            ast::ItemStatic(ref typ, mt, ref expr) =>
+                self.process_static(item, &**typ, mt, &**expr),
+            ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, &**def, ty_params),
+            ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
             ast::ItemImpl(ref ty_params,
                           ref trait_ref,
-                          typ,
+                          ref typ,
                           ref impl_items) => {
                 self.process_impl(item,
-                                  e,
                                   ty_params,
                                   trait_ref,
-                                  typ,
+                                  &**typ,
                                   impl_items)
             }
             ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
-                self.process_trait(item, e, generics, trait_refs, methods),
-            ast::ItemMod(ref m) => self.process_mod(item, e, m),
-            ast::ItemTy(ty, ref ty_params) => {
+                self.process_trait(item, generics, trait_refs, methods),
+            ast::ItemMod(ref m) => self.process_mod(item, m),
+            ast::ItemTy(ref ty, ref ty_params) => {
                 let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
-                let value = ty_to_string(&*ty);
+                let value = ty_to_string(&**ty);
                 let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
                 self.fmt.typedef_str(item.span,
                                      sub_span,
@@ -1060,27 +1033,27 @@ fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) {
                                      qualname.as_slice(),
                                      value.as_slice());
 
-                self.visit_ty(&*ty, e);
-                self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
+                self.visit_ty(&**ty);
+                self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
             },
             ast::ItemMac(_) => (),
-            _ => visit::walk_item(self, item, e),
+            _ => visit::walk_item(self, item),
         }
     }
 
-    fn visit_generics(&mut self, generics: &ast::Generics, e: DxrVisitorEnv) {
+    fn visit_generics(&mut self, generics: &ast::Generics) {
         for param in generics.ty_params.iter() {
             for bound in param.bounds.iter() {
                 match *bound {
                     ast::TraitTyParamBound(ref trait_ref) => {
-                        self.process_trait_ref(trait_ref, e, None);
+                        self.process_trait_ref(trait_ref, None);
                     }
                     _ => {}
                 }
             }
             match param.default {
-                Some(ty) => self.visit_ty(&*ty, e),
-                None => (),
+                Some(ref ty) => self.visit_ty(&**ty),
+                None => {}
             }
         }
     }
@@ -1088,23 +1061,22 @@ fn visit_generics(&mut self, generics: &ast::Generics, e: DxrVisitorEnv) {
     // We don't actually index functions here, that is done in visit_item/ItemFn.
     // Here we just visit methods.
     fn visit_fn(&mut self,
-                fk: &visit::FnKind,
-                fd: &ast::FnDecl,
-                b: &ast::Block,
+                fk: visit::FnKind<'v>,
+                fd: &'v ast::FnDecl,
+                b: &'v ast::Block,
                 s: Span,
-                _: NodeId,
-                e: DxrVisitorEnv) {
+                _: NodeId) {
         if generated_code(s) {
             return;
         }
 
-        match *fk {
-            visit::FkMethod(_, _, method) => self.process_method(method, e),
-            _ => visit::walk_fn(self, fk, fd, b, s, e),
+        match fk {
+            visit::FkMethod(_, _, method) => self.process_method(method),
+            _ => visit::walk_fn(self, fk, fd, b, s),
         }
     }
 
-    fn visit_trait_item(&mut self, tm: &ast::TraitItem, e: DxrVisitorEnv) {
+    fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
         match *tm {
             ast::RequiredMethod(ref method_type) => {
                 if generated_code(method_type.span) {
@@ -1137,21 +1109,21 @@ fn visit_trait_item(&mut self, tm: &ast::TraitItem, e: DxrVisitorEnv) {
 
                 // walk arg and return types
                 for arg in method_type.decl.inputs.iter() {
-                    self.visit_ty(&*arg.ty, e);
+                    self.visit_ty(&*arg.ty);
                 }
-                self.visit_ty(&*method_type.decl.output, e);
+                self.visit_ty(&*method_type.decl.output);
 
                 self.process_generic_params(&method_type.generics,
                                             method_type.span,
                                             qualname,
-                                            method_type.id,
-                                            e);
+                                            method_type.id);
             }
-            ast::ProvidedMethod(method) => self.process_method(&*method, e),
+            ast::ProvidedMethod(ref method) => self.process_method(&**method),
+            ast::TypeTraitItem(_) => {}
         }
     }
 
-    fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
+    fn visit_view_item(&mut self, i: &ast::ViewItem) {
         if generated_code(i.span) {
             return
         }
@@ -1168,7 +1140,7 @@ fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
                                                                    path.span,
                                                                    sub_span,
                                                                    def_id,
-                                                                   e.cur_scope),
+                                                                   self.cur_scope),
                                     None => {},
                                 }
                                 Some(def_id)
@@ -1189,11 +1161,11 @@ fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
                                                id,
                                                mod_id,
                                                get_ident(ident).get(),
-                                               e.cur_scope);
-                        self.write_sub_paths_truncated(path, e.cur_scope);
+                                               self.cur_scope);
+                        self.write_sub_paths_truncated(path);
                     }
                     ast::ViewPathGlob(ref path, _) => {
-                        self.write_sub_paths(path, e.cur_scope);
+                        self.write_sub_paths(path);
                     }
                     ast::ViewPathList(ref path, ref list, _) => {
                         for plid in list.iter() {
@@ -1206,7 +1178,7 @@ fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
                                                     self.fmt.ref_str(
                                                         kind, plid.span,
                                                         Some(plid.span),
-                                                        def_id, e.cur_scope);
+                                                        def_id, self.cur_scope);
                                                 }
                                                 None => ()
                                             },
@@ -1217,7 +1189,7 @@ fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
                             }
                         }
 
-                        self.write_sub_paths(path, e.cur_scope);
+                        self.write_sub_paths(path);
                     }
                 }
             },
@@ -1239,12 +1211,12 @@ fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) {
                                           cnum,
                                           name,
                                           s.as_slice(),
-                                          e.cur_scope);
+                                          self.cur_scope);
             },
         }
     }
 
-    fn visit_ty(&mut self, t: &ast::Ty, e: DxrVisitorEnv) {
+    fn visit_ty(&mut self, t: &ast::Ty) {
         if generated_code(t.span) {
             return
         }
@@ -1258,42 +1230,42 @@ fn visit_ty(&mut self, t: &ast::Ty, e: DxrVisitorEnv) {
                                          t.span,
                                          sub_span,
                                          id,
-                                         e.cur_scope);
+                                         self.cur_scope);
                     },
                     None => ()
                 }
 
-                self.write_sub_paths_truncated(path, e.cur_scope);
+                self.write_sub_paths_truncated(path);
 
-                visit::walk_path(self, path, e);
+                visit::walk_path(self, path);
             },
-            _ => visit::walk_ty(self, t, e),
+            _ => visit::walk_ty(self, t),
         }
     }
 
-    fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
+    fn visit_expr(&mut self, ex: &ast::Expr) {
         if generated_code(ex.span) {
             return
         }
 
         match ex.node {
-            ast::ExprCall(_f, ref _args) => {
+            ast::ExprCall(ref _f, ref _args) => {
                 // Don't need to do anything for function calls,
                 // because just walking the callee path does what we want.
-                visit::walk_expr(self, ex, e);
+                visit::walk_expr(self, ex);
             },
-            ast::ExprPath(ref path) => self.process_path(ex, e, path),
-            ast::ExprStruct(ref path, ref fields, base) =>
-                self.process_struct_lit(ex, e, path, fields, base),
-            ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, e, args),
-            ast::ExprField(sub_ex, ident, _) => {
+            ast::ExprPath(ref path) => self.process_path(ex, path),
+            ast::ExprStruct(ref path, ref fields, ref base) =>
+                self.process_struct_lit(ex, path, fields, base),
+            ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
+            ast::ExprField(ref sub_ex, ident, _) => {
                 if generated_code(sub_ex.span) {
                     return
                 }
 
-                self.visit_expr(&*sub_ex, e);
+                self.visit_expr(&**sub_ex);
 
-                let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
+                let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex);
                 let t_box = ty::get(t);
                 match t_box.sty {
                     ty::ty_struct(def_id, _) => {
@@ -1305,7 +1277,7 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                                                  ex.span,
                                                  sub_span,
                                                  f.id,
-                                                 e.cur_scope);
+                                                 self.cur_scope);
                                 break;
                             }
                         }
@@ -1314,14 +1286,14 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                                             "Expected struct type, but not ty_struct"),
                 }
             },
-            ast::ExprTupField(sub_ex, idx, _) => {
+            ast::ExprTupField(ref sub_ex, idx, _) => {
                 if generated_code(sub_ex.span) {
                     return
                 }
 
-                self.visit_expr(&*sub_ex, e);
+                self.visit_expr(&**sub_ex);
 
-                let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
+                let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex);
                 let t_box = ty::get(t);
                 match t_box.sty {
                     ty::ty_struct(def_id, _) => {
@@ -1333,7 +1305,7 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                                                  ex.span,
                                                  sub_span,
                                                  f.id,
-                                                 e.cur_scope);
+                                                 self.cur_scope);
                                 break;
                             }
                         }
@@ -1342,47 +1314,47 @@ fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) {
                                             "Expected struct type, but not ty_struct"),
                 }
             },
-            ast::ExprFnBlock(_, decl, body) => {
+            ast::ExprFnBlock(_, ref decl, ref body) => {
                 if generated_code(body.span) {
                     return
                 }
 
                 let id = String::from_str("$").append(ex.id.to_string().as_slice());
-                self.process_formals(&decl.inputs, id.as_slice(), e);
+                self.process_formals(&decl.inputs, id.as_slice());
 
                 // walk arg and return types
                 for arg in decl.inputs.iter() {
-                    self.visit_ty(&*arg.ty, e);
+                    self.visit_ty(&*arg.ty);
                 }
-                self.visit_ty(&*decl.output, e);
+                self.visit_ty(&*decl.output);
 
                 // walk the body
-                self.visit_block(&*body, DxrVisitorEnv::new_nested(ex.id));
+                self.nest(ex.id, |v| v.visit_block(&**body));
             },
             _ => {
-                visit::walk_expr(self, ex, e)
+                visit::walk_expr(self, ex)
             },
         }
     }
 
-    fn visit_mac(&mut self, _: &ast::Mac, _: DxrVisitorEnv) {
+    fn visit_mac(&mut self, _: &ast::Mac) {
         // Just stop, macros are poison to us.
     }
 
-    fn visit_pat(&mut self, p: &ast::Pat, e: DxrVisitorEnv) {
-        self.process_pat(p, e);
+    fn visit_pat(&mut self, p: &ast::Pat) {
+        self.process_pat(p);
         if !self.collecting {
             self.collected_paths.clear();
         }
     }
 
-    fn visit_arm(&mut self, arm: &ast::Arm, e: DxrVisitorEnv) {
+    fn visit_arm(&mut self, arm: &ast::Arm) {
         assert!(self.collected_paths.len() == 0 && !self.collecting);
         self.collecting = true;
 
         for pattern in arm.pats.iter() {
             // collect paths from the arm's patterns
-            self.visit_pat(&**pattern, e);
+            self.visit_pat(&**pattern);
         }
         self.collecting = false;
         // process collected paths
@@ -1401,36 +1373,37 @@ fn visit_arm(&mut self, arm: &ast::Arm, e: DxrVisitorEnv) {
             }
             let def = def_map.get(&id);
             match *def {
-                def::DefBinding(id, _)  => self.fmt.variable_str(p.span,
-                                                                 sub_span,
-                                                                 id,
-                                                                 path_to_string(p).as_slice(),
-                                                                 value.as_slice(),
-                                                                 ""),
+                def::DefLocal(id)  => self.fmt.variable_str(p.span,
+                                                            sub_span,
+                                                            id,
+                                                            path_to_string(p).as_slice(),
+                                                            value.as_slice(),
+                                                            ""),
                 def::DefVariant(_,id,_) => self.fmt.ref_str(ref_kind,
                                                             p.span,
                                                             sub_span,
                                                             id,
-                                                            e.cur_scope),
+                                                            self.cur_scope),
                 // FIXME(nrc) what is this doing here?
                 def::DefStatic(_, _) => {}
-                _ => error!("unexpected defintion kind when processing collected paths: {:?}", *def)
+                _ => error!("unexpected definition kind when processing collected paths: {:?}",
+                            *def)
             }
         }
         self.collected_paths.clear();
-        visit::walk_expr_opt(self, arm.guard, e);
-        self.visit_expr(&*arm.body, e);
+        visit::walk_expr_opt(self, &arm.guard);
+        self.visit_expr(&*arm.body);
     }
 
-    fn visit_stmt(&mut self, s:&ast::Stmt, e:DxrVisitorEnv) {
+    fn visit_stmt(&mut self, s: &ast::Stmt) {
         if generated_code(s.span) {
             return
         }
 
-        visit::walk_stmt(self, s, e)
+        visit::walk_stmt(self, s)
     }
 
-    fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
+    fn visit_local(&mut self, l: &ast::Local) {
         if generated_code(l.span) {
             return
         }
@@ -1439,7 +1412,7 @@ fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
         // pattern and collect them all.
         assert!(self.collected_paths.len() == 0 && !self.collecting);
         self.collecting = true;
-        self.visit_pat(&*l.pat, e);
+        self.visit_pat(&*l.pat);
         self.collecting = false;
 
         let value = self.span.snippet(l.span);
@@ -1462,22 +1435,8 @@ fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) {
         self.collected_paths.clear();
 
         // Just walk the initialiser and type (don't want to walk the pattern again).
-        self.visit_ty(&*l.ty, e);
-        visit::walk_expr_opt(self, l.init, e);
-    }
-}
-
-#[deriving(Clone)]
-struct DxrVisitorEnv {
-    cur_scope: NodeId,
-}
-
-impl DxrVisitorEnv {
-    fn new() -> DxrVisitorEnv {
-        DxrVisitorEnv{cur_scope: 0}
-    }
-    fn new_nested(new_mod: NodeId) -> DxrVisitorEnv {
-        DxrVisitorEnv{cur_scope: new_mod}
+        self.visit_ty(&*l.ty);
+        visit::walk_expr_opt(self, &l.init);
     }
 }
 
@@ -1532,25 +1491,28 @@ pub fn process_crate(sess: &Session,
     };
     root_path.pop();
 
-    let mut visitor = DxrVisitor{ sess: sess,
-                                  analysis: analysis,
-                                  collected_paths: vec!(),
-                                  collecting: false,
-                                  fmt: FmtStrs::new(box Recorder {
-                                                        out: output_file as Box<Writer+'static>,
-                                                        dump_spans: false,
-                                                    },
-                                                    SpanUtils {
-                                                        sess: sess,
-                                                        err_count: Cell::new(0)
-                                                    },
-                                                    cratename.clone()),
-                                  span: SpanUtils {
-                                      sess: sess,
-                                      err_count: Cell::new(0)
-                                  }};
+    let mut visitor = DxrVisitor {
+        sess: sess,
+        analysis: analysis,
+        collected_paths: vec!(),
+        collecting: false,
+        fmt: FmtStrs::new(box Recorder {
+                            out: output_file as Box<Writer+'static>,
+                            dump_spans: false,
+                        },
+                        SpanUtils {
+                            sess: sess,
+                            err_count: Cell::new(0)
+                        },
+                        cratename.clone()),
+        span: SpanUtils {
+            sess: sess,
+            err_count: Cell::new(0)
+        },
+        cur_scope: 0
+    };
 
     visitor.dump_crate_info(cratename.as_slice(), krate);
 
-    visit::walk_crate(&mut visitor, krate, DxrVisitorEnv::new());
+    visit::walk_crate(&mut visitor, krate);
 }