]> git.lizzy.rs Git - rust.git/commitdiff
rustdoc: fix fallout from using ptr::P.
authorEduard Burtescu <edy.burt@gmail.com>
Sun, 18 May 2014 13:56:13 +0000 (16:56 +0300)
committerEduard Burtescu <edy.burt@gmail.com>
Sun, 14 Sep 2014 01:20:34 +0000 (04:20 +0300)
src/librustdoc/clean/mod.rs
src/librustdoc/core.rs
src/librustdoc/doctree.rs
src/librustdoc/test.rs
src/librustdoc/visit_ast.rs

index c1a91f26dbf802c9e725cc8e533aebd33fa5f8e1..e6fcbbe9b6ff35c800852f974919fe67c6485621 100644 (file)
@@ -20,6 +20,7 @@
 use syntax::codemap::Pos;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
+use syntax::ptr::P;
 
 use rustc::back::link;
 use rustc::driver::driver;
@@ -34,7 +35,6 @@
 
 use std::rc::Rc;
 use std::u32;
-use std::gc::{Gc, GC};
 
 use core::DocContext;
 use doctree;
@@ -67,7 +67,7 @@ fn clean(&self, cx: &DocContext) -> VecPerParamSpace<U> {
     }
 }
 
-impl<T: 'static + Clean<U>, U> Clean<U> for Gc<T> {
+impl<T: Clean<U>, U> Clean<U> for P<T> {
     fn clean(&self, cx: &DocContext) -> U {
         (**self).clean(cx)
     }
@@ -408,7 +408,7 @@ fn clean(&self, cx: &DocContext) -> Attribute {
 
 impl Clean<Attribute> for ast::Attribute {
     fn clean(&self, cx: &DocContext) -> Attribute {
-        self.desugar_doc().node.value.clean(cx)
+        self.with_desugared_doc(|a| a.node.value.clean(cx))
     }
 }
 
@@ -430,12 +430,12 @@ fn value_str(&self) -> Option<InternedString> {
             _ => None,
         }
     }
-    fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
+    fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }
 }
 impl<'a> attr::AttrMetaMethods for &'a Attribute {
     fn name(&self) -> InternedString { (**self).name() }
     fn value_str(&self) -> Option<InternedString> { (**self).value_str() }
-    fn meta_item_list<'a>(&'a self) -> Option<&'a [Gc<ast::MetaItem>]> { None }
+    fn meta_item_list<'a>(&'a self) -> Option<&'a [P<ast::MetaItem>]> { None }
 }
 
 #[deriving(Clone, Encodable, Decodable, PartialEq)]
@@ -758,10 +758,10 @@ fn clean(&self, cx: &DocContext) -> SelfTy {
         match *self {
             ast::SelfStatic => SelfStatic,
             ast::SelfValue(_) => SelfValue,
-            ast::SelfRegion(lt, mt, _) => {
+            ast::SelfRegion(ref lt, ref mt, _) => {
                 SelfBorrowed(lt.clean(cx), mt.clean(cx))
             }
-            ast::SelfExplicit(typ, _) => SelfExplicit(typ.clean(cx)),
+            ast::SelfExplicit(ref typ, _) => SelfExplicit(typ.clean(cx)),
         }
     }
 }
@@ -1189,11 +1189,11 @@ fn clean(&self, cx: &DocContext) -> Type {
             TyRptr(ref l, ref m) =>
                 BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx),
                              type_: box m.ty.clean(cx)},
-            TyBox(ty) => Managed(box ty.clean(cx)),
-            TyUniq(ty) => Unique(box ty.clean(cx)),
-            TyVec(ty) => Vector(box ty.clean(cx)),
-            TyFixedLengthVec(ty, ref e) => FixedVector(box ty.clean(cx),
-                                                       e.span.to_src(cx)),
+            TyBox(ref ty) => Managed(box ty.clean(cx)),
+            TyUniq(ref ty) => Unique(box ty.clean(cx)),
+            TyVec(ref ty) => Vector(box ty.clean(cx)),
+            TyFixedLengthVec(ref ty, ref e) => FixedVector(box ty.clean(cx),
+                                                           e.span.to_src(cx)),
             TyTup(ref tys) => Tuple(tys.clean(cx)),
             TyPath(ref p, ref tpbs, id) => {
                 resolve_type(cx, p.clean(cx), tpbs.clean(cx), id)
@@ -1799,7 +1799,7 @@ fn clean(&self, cx: &DocContext) -> Vec<Item> {
                                                          remaining,
                                                          b.clone());
                             let path = syntax::codemap::dummy_spanned(path);
-                            ret.push(convert(&ast::ViewItemUse(box(GC) path)));
+                            ret.push(convert(&ast::ViewItemUse(P(path))));
                         }
                     }
                     ast::ViewPathSimple(ident, _, id) => {
@@ -1985,8 +1985,8 @@ fn name_from_pat(p: &ast::Pat) -> String {
         },
         PatTup(ref elts) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
                                             .collect::<Vec<String>>().connect(", ")),
-        PatBox(p) => name_from_pat(&*p),
-        PatRegion(p) => name_from_pat(&*p),
+        PatBox(ref p) => name_from_pat(&**p),
+        PatRegion(ref p) => name_from_pat(&**p),
         PatLit(..) => {
             warn!("tried to get argument name from PatLit, \
                   which is silly in function arguments");
index a8cd9f18d60a52b152a1a3bdaba9cea57be42b74..ddb4b994ca38e157e4d326433f13b1909f64de43 100644 (file)
@@ -8,18 +8,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc;
-use rustc::{driver, middle};
+use rustc::driver::{config, driver, session};
 use rustc::middle::{privacy, ty};
 use rustc::lint;
 use rustc::back::link;
 
-use syntax::ast;
+use syntax::{ast, ast_map, codemap, diagnostic};
 use syntax::parse::token;
-use syntax;
+use syntax::ptr::P;
 
 use std::cell::RefCell;
-use std::gc::GC;
 use std::os;
 use std::collections::{HashMap, HashSet};
 use arena::TypedArena;
 
 /// Are we generating documentation (`Typed`) or tests (`NotTyped`)?
 pub enum MaybeTyped<'tcx> {
-    Typed(middle::ty::ctxt<'tcx>),
-    NotTyped(driver::session::Session)
+    Typed(ty::ctxt<'tcx>),
+    NotTyped(session::Session)
 }
 
 pub type ExternalPaths = RefCell<Option<HashMap<ast::DefId,
                                                 (Vec<String>, clean::TypeKind)>>>;
 
 pub struct DocContext<'tcx> {
-    pub krate: ast::Crate,
+    pub krate: &'tcx ast::Crate,
     pub maybe_typed: MaybeTyped<'tcx>,
     pub src: Path,
     pub external_paths: ExternalPaths,
@@ -49,7 +47,7 @@ pub struct DocContext<'tcx> {
 }
 
 impl<'tcx> DocContext<'tcx> {
-    pub fn sess<'a>(&'a self) -> &'a driver::session::Session {
+    pub fn sess<'a>(&'a self) -> &'a session::Session {
         match self.maybe_typed {
             Typed(ref tcx) => &tcx.sess,
             NotTyped(ref sess) => sess
@@ -80,64 +78,60 @@ pub struct CrateAnalysis {
 
 pub type Externs = HashMap<String, Vec<String>>;
 
-/// Parses, resolves, and typechecks the given crate
-fn get_ast_and_resolve<'tcx>(cpath: &Path, libs: Vec<Path>, cfgs: Vec<String>,
-                             externs: Externs, triple: Option<String>,
-                             type_arena: &'tcx TypedArena<ty::t_box_>)
-                             -> (DocContext<'tcx>, CrateAnalysis) {
-    use syntax::codemap::dummy_spanned;
-    use rustc::driver::driver::{FileInput,
-                                phase_1_parse_input,
-                                phase_2_configure_and_expand,
-                                phase_3_run_analysis_passes};
-    use rustc::driver::config::build_configuration;
+pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, externs: Externs,
+                cpath: &Path, triple: Option<String>)
+                -> (clean::Crate, CrateAnalysis) {
 
-    let input = FileInput(cpath.clone());
+    // Parse, resolve, and typecheck the given crate.
+
+    let input = driver::FileInput(cpath.clone());
 
     let warning_lint = lint::builtin::WARNINGS.name_lower();
 
-    let sessopts = driver::config::Options {
+    let sessopts = config::Options {
         maybe_sysroot: Some(os::self_exe_path().unwrap().dir_path()),
         addl_lib_search_paths: RefCell::new(libs),
-        crate_types: vec!(driver::config::CrateTypeRlib),
+        crate_types: vec!(config::CrateTypeRlib),
         lint_opts: vec!((warning_lint, lint::Allow)),
         externs: externs,
-        target_triple: triple.unwrap_or(driver::driver::host_triple().to_string()),
-        ..rustc::driver::config::basic_options().clone()
+        target_triple: triple.unwrap_or(driver::host_triple().to_string()),
+        ..config::basic_options().clone()
     };
 
 
-    let codemap = syntax::codemap::CodeMap::new();
-    let diagnostic_handler = syntax::diagnostic::default_handler(syntax::diagnostic::Auto, None);
+    let codemap = codemap::CodeMap::new();
+    let diagnostic_handler = diagnostic::default_handler(diagnostic::Auto, None);
     let span_diagnostic_handler =
-        syntax::diagnostic::mk_span_handler(diagnostic_handler, codemap);
+        diagnostic::mk_span_handler(diagnostic_handler, codemap);
 
-    let sess = driver::session::build_session_(sessopts,
-                                               Some(cpath.clone()),
-                                               span_diagnostic_handler);
+    let sess = session::build_session_(sessopts,
+                                       Some(cpath.clone()),
+                                       span_diagnostic_handler);
 
-    let mut cfg = build_configuration(&sess);
+    let mut cfg = config::build_configuration(&sess);
     for cfg_ in cfgs.move_iter() {
         let cfg_ = token::intern_and_get_ident(cfg_.as_slice());
-        cfg.push(box(GC) dummy_spanned(ast::MetaWord(cfg_)));
+        cfg.push(P(codemap::dummy_spanned(ast::MetaWord(cfg_))));
     }
 
-    let krate = phase_1_parse_input(&sess, cfg, &input);
+    let krate = driver::phase_1_parse_input(&sess, cfg, &input);
 
     let name = link::find_crate_name(Some(&sess), krate.attrs.as_slice(),
                                      &input);
 
-    let (krate, ast_map)
-        = phase_2_configure_and_expand(&sess, krate, name.as_slice(), None)
-            .expect("phase_2_configure_and_expand aborted in rustdoc!");
+    let krate = driver::phase_2_configure_and_expand(&sess, krate, name.as_slice(), None)
+                    .expect("phase_2_configure_and_expand aborted in rustdoc!");
+
+    let mut forest = ast_map::Forest::new(krate);
+    let ast_map = driver::assign_node_ids_and_map(&sess, &mut forest);
 
-    let driver::driver::CrateAnalysis {
+    let type_arena = TypedArena::new();
+    let driver::CrateAnalysis {
         exported_items, public_items, ty_cx, ..
-    } = phase_3_run_analysis_passes(sess, &krate, ast_map, type_arena, name);
+    } = driver::phase_3_run_analysis_passes(sess, ast_map, &type_arena, name);
 
-    debug!("crate: {:?}", krate);
-    (DocContext {
-        krate: krate,
+    let ctxt = DocContext {
+        krate: ty_cx.map.krate(),
         maybe_typed: Typed(ty_cx),
         src: cpath.clone(),
         external_traits: RefCell::new(Some(HashMap::new())),
@@ -145,26 +139,21 @@ fn get_ast_and_resolve<'tcx>(cpath: &Path, libs: Vec<Path>, cfgs: Vec<String>,
         external_paths: RefCell::new(Some(HashMap::new())),
         inlined: RefCell::new(Some(HashSet::new())),
         populated_crate_impls: RefCell::new(HashSet::new()),
-    }, CrateAnalysis {
+    };
+    debug!("crate: {:?}", ctxt.krate);
+
+    let analysis = CrateAnalysis {
         exported_items: exported_items,
         public_items: public_items,
         external_paths: RefCell::new(None),
         external_traits: RefCell::new(None),
         external_typarams: RefCell::new(None),
         inlined: RefCell::new(None),
-    })
-}
-
-pub fn run_core(libs: Vec<Path>, cfgs: Vec<String>, externs: Externs,
-                path: &Path, triple: Option<String>)
-                -> (clean::Crate, CrateAnalysis) {
-    let type_arena = TypedArena::new();
-    let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs, externs,
-                                               triple, &type_arena);
+    };
 
     let krate = {
         let mut v = RustdocVisitor::new(&ctxt, Some(&analysis));
-        v.visit(&ctxt.krate);
+        v.visit(ctxt.krate);
         v.clean(&ctxt)
     };
 
index 4d2cf852b8ab7cb3637abeac01ba8618b3af828f..72964609049bf5fa61a2aff488e5fb7c46009e5e 100644 (file)
@@ -16,8 +16,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::ast::{Ident, NodeId};
-
-use std::gc::Gc;
+use syntax::ptr::P;
 
 pub struct Module {
     pub name: Option<Ident>,
@@ -130,7 +129,7 @@ pub struct Function {
 }
 
 pub struct Typedef {
-    pub ty: ast::P<ast::Ty>,
+    pub ty: P<ast::Ty>,
     pub gen: ast::Generics,
     pub name: Ident,
     pub id: ast::NodeId,
@@ -141,9 +140,9 @@ pub struct Typedef {
 }
 
 pub struct Static {
-    pub type_: ast::P<ast::Ty>,
+    pub type_: P<ast::Ty>,
     pub mutability: ast::Mutability,
-    pub expr: Gc<ast::Expr>,
+    pub expr: P<ast::Expr>,
     pub name: Ident,
     pub attrs: Vec<ast::Attribute>,
     pub vis: ast::Visibility,
@@ -167,7 +166,7 @@ pub struct Trait {
 pub struct Impl {
     pub generics: ast::Generics,
     pub trait_: Option<ast::TraitRef>,
-    pub for_: ast::P<ast::Ty>,
+    pub for_: P<ast::Ty>,
     pub items: Vec<ast::ImplItem>,
     pub attrs: Vec<ast::Attribute>,
     pub whence: Span,
index 0eb0a9afd751cad7c1791d844ac8061e1f05ae82..b7c602d9d730f7bf14ecd8d338489b61f9f6e77c 100644 (file)
@@ -11,7 +11,6 @@
 use std::cell::RefCell;
 use std::char;
 use std::dynamic_lib::DynamicLibrary;
-use std::gc::GC;
 use std::io::{Command, TempDir};
 use std::io;
 use std::os;
@@ -28,6 +27,7 @@
 use syntax::codemap::{CodeMap, dummy_spanned};
 use syntax::diagnostic;
 use syntax::parse::token;
+use syntax::ptr::P;
 
 use core;
 use clean;
@@ -67,15 +67,15 @@ pub fn run(input: &str,
     let mut cfg = config::build_configuration(&sess);
     cfg.extend(cfgs.move_iter().map(|cfg_| {
         let cfg_ = token::intern_and_get_ident(cfg_.as_slice());
-        box(GC) dummy_spanned(ast::MetaWord(cfg_))
+        P(dummy_spanned(ast::MetaWord(cfg_)))
     }));
     let krate = driver::phase_1_parse_input(&sess, cfg, &input);
-    let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate,
-                                                          "rustdoc-test", None)
+    let krate = driver::phase_2_configure_and_expand(&sess, krate,
+                                                     "rustdoc-test", None)
         .expect("phase_2_configure_and_expand aborted in rustdoc!");
 
     let ctx = core::DocContext {
-        krate: krate,
+        krate: &krate,
         maybe_typed: core::NotTyped(sess),
         src: input_path,
         external_paths: RefCell::new(Some(HashMap::new())),
@@ -86,7 +86,7 @@ pub fn run(input: &str,
     };
 
     let mut v = RustdocVisitor::new(&ctx, None);
-    v.visit(&ctx.krate);
+    v.visit(ctx.krate);
     let mut krate = v.clean(&ctx);
     match crate_name {
         Some(name) => krate.name = name,
index 79576cac20af3b759b532b7bdb75eecd47028266..a9e0c9cb260f65f21ad9e276034bc69e456e1ea3 100644 (file)
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
 use syntax::codemap::Span;
+use syntax::ptr::P;
 
 use rustc::middle::stability;
 
-use std::gc::{Gc, GC};
-
 use core;
 use doctree::*;
 
@@ -57,13 +56,10 @@ fn stability(&self, id: ast::NodeId) -> Option<attr::Stability> {
     }
 
     pub fn visit(&mut self, krate: &ast::Crate) {
-        self.attrs = krate.attrs.iter().map(|x| (*x).clone()).collect();
+        self.attrs = krate.attrs.clone();
 
         self.module = self.visit_mod_contents(krate.span,
-                                              krate.attrs
-                                                   .iter()
-                                                   .map(|x| *x)
-                                                   .collect(),
+                                              krate.attrs.clone(),
                                               ast::Public,
                                               ast::CRATE_NODE_ID,
                                               &krate.module,
@@ -74,51 +70,50 @@ pub fn visit(&mut self, krate: &ast::Crate) {
         self.module.is_crate = true;
     }
 
-    pub fn visit_struct_def(&mut self, item: &ast::Item, sd: Gc<ast::StructDef>,
+    pub fn visit_struct_def(&mut self, item: &ast::Item,
+                            name: ast::Ident, sd: &ast::StructDef,
                             generics: &ast::Generics) -> Struct {
         debug!("Visiting struct");
         let struct_type = struct_type_from_def(&*sd);
         Struct {
             id: item.id,
             struct_type: struct_type,
-            name: item.ident,
+            name: name,
             vis: item.vis,
             stab: self.stability(item.id),
-            attrs: item.attrs.iter().map(|x| *x).collect(),
+            attrs: item.attrs.clone(),
             generics: generics.clone(),
-            fields: sd.fields.iter().map(|x| (*x).clone()).collect(),
+            fields: sd.fields.clone(),
             whence: item.span
         }
     }
 
-    pub fn visit_enum_def(&mut self, it: &ast::Item, def: &ast::EnumDef,
+    pub fn visit_enum_def(&mut self, it: &ast::Item,
+                          name: ast::Ident, def: &ast::EnumDef,
                           params: &ast::Generics) -> Enum {
         debug!("Visiting enum");
-        let mut vars: Vec<Variant> = Vec::new();
-        for x in def.variants.iter() {
-            vars.push(Variant {
-                name: x.node.name,
-                attrs: x.node.attrs.iter().map(|x| *x).collect(),
-                vis: x.node.vis,
-                stab: self.stability(x.node.id),
-                id: x.node.id,
-                kind: x.node.kind.clone(),
-                whence: x.span,
-            });
-        }
         Enum {
-            name: it.ident,
-            variants: vars,
+            name: name,
+            variants: def.variants.iter().map(|v| Variant {
+                name: v.node.name,
+                attrs: v.node.attrs.clone(),
+                vis: v.node.vis,
+                stab: self.stability(v.node.id),
+                id: v.node.id,
+                kind: v.node.kind.clone(),
+                whence: v.span,
+            }).collect(),
             vis: it.vis,
             stab: self.stability(it.id),
             generics: params.clone(),
-            attrs: it.attrs.iter().map(|x| *x).collect(),
+            attrs: it.attrs.clone(),
             id: it.id,
             whence: it.span,
         }
     }
 
-    pub fn visit_fn(&mut self, item: &ast::Item, fd: &ast::FnDecl,
+    pub fn visit_fn(&mut self, item: &ast::Item,
+                    name: ast::Ident, fd: &ast::FnDecl,
                     fn_style: &ast::FnStyle, _abi: &abi::Abi,
                     gen: &ast::Generics) -> Function {
         debug!("Visiting fn");
@@ -126,9 +121,9 @@ pub fn visit_fn(&mut self, item: &ast::Item, fd: &ast::FnDecl,
             id: item.id,
             vis: item.vis,
             stab: self.stability(item.id),
-            attrs: item.attrs.iter().map(|x| *x).collect(),
+            attrs: item.attrs.clone(),
             decl: fd.clone(),
-            name: item.ident,
+            name: name,
             whence: item.span,
             generics: gen.clone(),
             fn_style: *fn_style,
@@ -150,7 +145,7 @@ pub fn visit_mod_contents(&mut self, span: Span, attrs: Vec<ast::Attribute> ,
         om.stab = self.stability(id);
         om.id = id;
         for i in m.items.iter() {
-            self.visit_item(&**i, &mut om);
+            self.visit_item(&**i, None, &mut om);
         }
         om
     }
@@ -169,7 +164,7 @@ pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) {
         });
         let item = match item.node {
             ast::ViewItemUse(ref vpath) => {
-                match self.visit_view_path(*vpath, om, please_inline) {
+                match self.visit_view_path(&**vpath, om, please_inline) {
                     None => return,
                     Some(path) => {
                         ast::ViewItem {
@@ -184,9 +179,9 @@ pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) {
         om.view_items.push(item);
     }
 
-    fn visit_view_path(&mut self, path: Gc<ast::ViewPath>,
+    fn visit_view_path(&mut self, path: &ast::ViewPath,
                        om: &mut Module,
-                       please_inline: bool) -> Option<Gc<ast::ViewPath>> {
+                       please_inline: bool) -> Option<P<ast::ViewPath>> {
         match path.node {
             ast::ViewPathSimple(dst, _, id) => {
                 if self.resolve_id(id, Some(dst), false, om, please_inline) {
@@ -203,10 +198,10 @@ fn visit_view_path(&mut self, path: Gc<ast::ViewPath>,
                 }
 
                 if mine.len() == 0 { return None }
-                return Some(box(GC) ::syntax::codemap::Spanned {
+                return Some(P(::syntax::codemap::Spanned {
                     node: ast::ViewPathList(p.clone(), mine, b.clone()),
                     span: path.span,
-                })
+                }))
             }
 
             // these are feature gated anyway
@@ -216,7 +211,7 @@ fn visit_view_path(&mut self, path: Gc<ast::ViewPath>,
                 }
             }
         }
-        return Some(path);
+        Some(P(path.clone()))
     }
 
     fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
@@ -236,15 +231,6 @@ fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
 
         match tcx.map.get(def.node) {
             ast_map::NodeItem(it) => {
-                let it = match renamed {
-                    Some(ident) => {
-                        box(GC) ast::Item {
-                            ident: ident,
-                            ..(*it).clone()
-                        }
-                    }
-                    None => it,
-                };
                 if glob {
                     match it.node {
                         ast::ItemMod(ref m) => {
@@ -252,13 +238,13 @@ fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
                                 self.visit_view_item(vi, om);
                             }
                             for i in m.items.iter() {
-                                self.visit_item(&**i, om);
+                                self.visit_item(&**i, None, om);
                             }
                         }
                         _ => { fail!("glob not mapped to a module"); }
                     }
                 } else {
-                    self.visit_item(&*it, om);
+                    self.visit_item(it, renamed, om);
                 }
                 true
             }
@@ -266,47 +252,46 @@ fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
         }
     }
 
-    pub fn visit_item(&mut self, item: &ast::Item, om: &mut Module) {
+    pub fn visit_item(&mut self, item: &ast::Item,
+                      renamed: Option<ast::Ident>, om: &mut Module) {
         debug!("Visiting item {:?}", item);
+        let name = renamed.unwrap_or(item.ident);
         match item.node {
             ast::ItemMod(ref m) => {
                 om.mods.push(self.visit_mod_contents(item.span,
-                                                     item.attrs
-                                                         .iter()
-                                                         .map(|x| *x)
-                                                         .collect(),
+                                                     item.attrs.clone(),
                                                      item.vis,
                                                      item.id,
                                                      m,
-                                                     Some(item.ident)));
+                                                     Some(name)));
             },
             ast::ItemEnum(ref ed, ref gen) =>
-                om.enums.push(self.visit_enum_def(item, ed, gen)),
-            ast::ItemStruct(sd, ref gen) =>
-                om.structs.push(self.visit_struct_def(item, sd, gen)),
+                om.enums.push(self.visit_enum_def(item, name, ed, gen)),
+            ast::ItemStruct(ref sd, ref gen) =>
+                om.structs.push(self.visit_struct_def(item, name, &**sd, gen)),
             ast::ItemFn(ref fd, ref pur, ref abi, ref gen, _) =>
-                om.fns.push(self.visit_fn(item, &**fd, pur, abi, gen)),
-            ast::ItemTy(ty, ref gen) => {
+                om.fns.push(self.visit_fn(item, name, &**fd, pur, abi, gen)),
+            ast::ItemTy(ref ty, ref gen) => {
                 let t = Typedef {
-                    ty: ty,
+                    ty: ty.clone(),
                     gen: gen.clone(),
-                    name: item.ident,
+                    name: name,
                     id: item.id,
-                    attrs: item.attrs.iter().map(|x| *x).collect(),
+                    attrs: item.attrs.clone(),
                     whence: item.span,
                     vis: item.vis,
                     stab: self.stability(item.id),
                 };
                 om.typedefs.push(t);
             },
-            ast::ItemStatic(ty, ref mut_, ref exp) => {
+            ast::ItemStatic(ref ty, ref mut_, ref exp) => {
                 let s = Static {
-                    type_: ty,
+                    type_: ty.clone(),
                     mutability: mut_.clone(),
                     expr: exp.clone(),
                     id: item.id,
-                    name: item.ident,
-                    attrs: item.attrs.iter().map(|x| *x).collect(),
+                    name: name,
+                    attrs: item.attrs.clone(),
                     whence: item.span,
                     vis: item.vis,
                     stab: self.stability(item.id),
@@ -315,25 +300,25 @@ pub fn visit_item(&mut self, item: &ast::Item, om: &mut Module) {
             },
             ast::ItemTrait(ref gen, _, ref b, ref items) => {
                 let t = Trait {
-                    name: item.ident,
-                    items: items.iter().map(|x| (*x).clone()).collect(),
+                    name: name,
+                    items: items.clone(),
                     generics: gen.clone(),
                     bounds: b.iter().map(|x| (*x).clone()).collect(),
                     id: item.id,
-                    attrs: item.attrs.iter().map(|x| *x).collect(),
+                    attrs: item.attrs.clone(),
                     whence: item.span,
                     vis: item.vis,
                     stab: self.stability(item.id),
                 };
                 om.traits.push(t);
             },
-            ast::ItemImpl(ref gen, ref tr, ty, ref items) => {
+            ast::ItemImpl(ref gen, ref tr, ref ty, ref items) => {
                 let i = Impl {
                     generics: gen.clone(),
                     trait_: tr.clone(),
-                    for_: ty,
-                    items: items.iter().map(|x| *x).collect(),
-                    attrs: item.attrs.iter().map(|x| *x).collect(),
+                    for_: ty.clone(),
+                    items: items.clone(),
+                    attrs: item.attrs.clone(),
                     id: item.id,
                     whence: item.span,
                     vis: item.vis,
@@ -354,7 +339,7 @@ pub fn visit_item(&mut self, item: &ast::Item, om: &mut Module) {
     fn visit_macro(&self, item: &ast::Item) -> Macro {
         Macro {
             id: item.id,
-            attrs: item.attrs.iter().map(|x| *x).collect(),
+            attrs: item.attrs.clone(),
             name: item.ident,
             whence: item.span,
             stab: self.stability(item.id),