about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-12 11:43:15 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2019-06-19 21:16:08 +0300
commit673c3fc23ad0c78fe26420b641957e4fdfea553b (patch)
treeb31611fff1cfcca26ccf8ff3a64227280f20ef18
parent887feeeaf7d40c25caa9532f2d9121cb79fca899 (diff)
rustc: disallow cloning HIR nodes.
-rw-r--r--src/librustc/hir/lowering.rs103
-rw-r--r--src/librustc/hir/map/mod.rs10
-rw-r--r--src/librustc/hir/mod.rs170
-rw-r--r--src/librustc/hir/print.rs61
-rw-r--r--src/librustc/traits/error_reporting.rs4
-rw-r--r--src/librustc_mir/borrow_check/conflict_errors.rs4
-rw-r--r--src/librustc_typeck/astconv.rs26
-rw-r--r--src/librustc_typeck/check/mod.rs14
-rw-r--r--src/librustc_typeck/collect.rs20
-rw-r--r--src/librustdoc/clean/mod.rs93
-rw-r--r--src/librustdoc/doctree.rs202
-rw-r--r--src/librustdoc/visit_ast.rs243
12 files changed, 476 insertions, 474 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 996af3672e8..c87ab686937 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -608,15 +608,7 @@ impl<'a> LoweringContext<'a> {
                 });
 
                 if let Some(hir_id) = item_hir_id {
-                    let item_generics = match self.lctx.items.get(&hir_id).unwrap().node {
-                        hir::ItemKind::Impl(_, _, _, ref generics, ..)
-                        | hir::ItemKind::Trait(_, _, ref generics, ..) => {
-                            generics.params.clone()
-                        }
-                        _ => HirVec::new(),
-                    };
-
-                    self.lctx.with_parent_impl_lifetime_defs(&item_generics, |this| {
+                    self.lctx.with_parent_item_lifetime_defs(hir_id, |this| {
                         let this = &mut ItemLowerer { lctx: this };
                         if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.node {
                             this.with_trait_impl_ref(opt_trait_ref, |this| {
@@ -1054,14 +1046,22 @@ impl<'a> LoweringContext<'a> {
     // This should only be used with generics that have already had their
     // in-band lifetimes added. In practice, this means that this function is
     // only used when lowering a child item of a trait or impl.
-    fn with_parent_impl_lifetime_defs<T, F>(&mut self,
-        params: &HirVec<hir::GenericParam>,
+    fn with_parent_item_lifetime_defs<T, F>(&mut self,
+        parent_hir_id: hir::HirId,
         f: F
     ) -> T where
         F: FnOnce(&mut LoweringContext<'_>) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
-        let lt_def_names = params.iter().filter_map(|param| match param.kind {
+
+        let parent_generics = match self.items.get(&parent_hir_id).unwrap().node {
+            hir::ItemKind::Impl(_, _, _, ref generics, ..)
+            | hir::ItemKind::Trait(_, _, ref generics, ..) => {
+                &generics.params[..]
+            }
+            _ => &[],
+        };
+        let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
             hir::GenericParamKind::Lifetime { .. } => Some(param.name.ident().modern()),
             _ => None,
         });
@@ -1113,8 +1113,7 @@ impl<'a> LoweringContext<'a> {
 
         lowered_generics.params = lowered_generics
             .params
-            .iter()
-            .cloned()
+            .into_iter()
             .chain(in_band_defs)
             .collect();
 
@@ -3114,8 +3113,8 @@ impl<'a> LoweringContext<'a> {
             &NodeMap::default(),
             itctx.reborrow(),
         );
-        let trait_ref = self.with_parent_impl_lifetime_defs(
-            &bound_generic_params,
+        let trait_ref = self.with_in_scope_lifetime_defs(
+            &p.bound_generic_params,
             |this| this.lower_trait_ref(&p.trait_ref, itctx),
         );
 
@@ -3602,8 +3601,7 @@ impl<'a> LoweringContext<'a> {
                 // Essentially a single `use` which imports two names is desugared into
                 // two imports.
                 for (res, &new_node_id) in resolutions.zip([id1, id2].iter()) {
-                    let vis = vis.clone();
-                    let ident = ident.clone();
+                    let ident = *ident;
                     let mut path = path.clone();
                     for seg in &mut path.segments {
                         seg.id = self.sess.next_node_id();
@@ -3616,19 +3614,7 @@ impl<'a> LoweringContext<'a> {
                         let path =
                             this.lower_path_extra(res, &path, ParamMode::Explicit, None);
                         let item = hir::ItemKind::Use(P(path), hir::UseKind::Single);
-                        let vis_kind = match vis.node {
-                            hir::VisibilityKind::Public => hir::VisibilityKind::Public,
-                            hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
-                            hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
-                            hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
-                                let path = this.renumber_segment_ids(path);
-                                hir::VisibilityKind::Restricted {
-                                    path,
-                                    hir_id: this.next_id(),
-                                }
-                            }
-                        };
-                        let vis = respan(vis.span, vis_kind);
+                        let vis = this.rebuild_vis(&vis);
 
                         this.insert_item(
                             hir::Item {
@@ -3692,8 +3678,6 @@ impl<'a> LoweringContext<'a> {
                 for &(ref use_tree, id) in trees {
                     let new_hir_id = self.lower_node_id(id);
 
-                    let mut vis = vis.clone();
-                    let mut ident = ident.clone();
                     let mut prefix = prefix.clone();
 
                     // Give the segments new node-ids since they are being cloned.
@@ -3707,6 +3691,9 @@ impl<'a> LoweringContext<'a> {
                     // own its own names, we have to adjust the owner before
                     // lowering the rest of the import.
                     self.with_hir_id_owner(id, |this| {
+                        let mut vis = this.rebuild_vis(&vis);
+                        let mut ident = *ident;
+
                         let item = this.lower_use_tree(use_tree,
                                                        &prefix,
                                                        id,
@@ -3714,20 +3701,6 @@ impl<'a> LoweringContext<'a> {
                                                        &mut ident,
                                                        attrs);
 
-                        let vis_kind = match vis.node {
-                            hir::VisibilityKind::Public => hir::VisibilityKind::Public,
-                            hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
-                            hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
-                            hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
-                                let path = this.renumber_segment_ids(path);
-                                hir::VisibilityKind::Restricted {
-                                    path: path,
-                                    hir_id: this.next_id(),
-                                }
-                            }
-                        };
-                        let vis = respan(vis.span, vis_kind);
-
                         this.insert_item(
                             hir::Item {
                                 hir_id: new_hir_id,
@@ -3773,15 +3746,35 @@ impl<'a> LoweringContext<'a> {
     /// Paths like the visibility path in `pub(super) use foo::{bar, baz}` are repeated
     /// many times in the HIR tree; for each occurrence, we need to assign distinct
     /// `NodeId`s. (See, e.g., #56128.)
-    fn renumber_segment_ids(&mut self, path: &P<hir::Path>) -> P<hir::Path> {
-        debug!("renumber_segment_ids(path = {:?})", path);
-        let mut path = path.clone();
-        for seg in path.segments.iter_mut() {
-            if seg.hir_id.is_some() {
-                seg.hir_id = Some(self.next_id());
-            }
+    fn rebuild_use_path(&mut self, path: &hir::Path) -> hir::Path {
+        debug!("rebuild_use_path(path = {:?})", path);
+        let segments = path.segments.iter().map(|seg| hir::PathSegment {
+            ident: seg.ident,
+            hir_id: seg.hir_id.map(|_| self.next_id()),
+            res: seg.res,
+            args: None,
+            infer_args: seg.infer_args,
+        }).collect();
+        hir::Path {
+            span: path.span,
+            res: path.res,
+            segments,
         }
-        path
+    }
+
+    fn rebuild_vis(&mut self, vis: &hir::Visibility) -> hir::Visibility {
+        let vis_kind = match vis.node {
+            hir::VisibilityKind::Public => hir::VisibilityKind::Public,
+            hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
+            hir::VisibilityKind::Inherited => hir::VisibilityKind::Inherited,
+            hir::VisibilityKind::Restricted { ref path, hir_id: _ } => {
+                hir::VisibilityKind::Restricted {
+                    path: P(self.rebuild_use_path(path)),
+                    hir_id: self.next_id(),
+                }
+            }
+        };
+        respan(vis.span, vis_kind)
     }
 
     fn lower_trait_item(&mut self, i: &TraitItem) -> hir::TraitItem {
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 85c86991f48..87da3273bd2 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -51,11 +51,11 @@ impl<'hir> Entry<'hir> {
         }
     }
 
-    fn fn_decl(&self) -> Option<&FnDecl> {
+    fn fn_decl(&self) -> Option<&'hir FnDecl> {
         match self.node {
             Node::Item(ref item) => {
                 match item.node {
-                    ItemKind::Fn(ref fn_decl, _, _, _) => Some(&fn_decl),
+                    ItemKind::Fn(ref fn_decl, _, _, _) => Some(fn_decl),
                     _ => None,
                 }
             }
@@ -76,7 +76,7 @@ impl<'hir> Entry<'hir> {
 
             Node::Expr(ref expr) => {
                 match expr.node {
-                    ExprKind::Closure(_, ref fn_decl, ..) => Some(&fn_decl),
+                    ExprKind::Closure(_, ref fn_decl, ..) => Some(fn_decl),
                     _ => None,
                 }
             }
@@ -412,9 +412,9 @@ impl<'hir> Map<'hir> {
         self.forest.krate.body(id)
     }
 
-    pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<FnDecl> {
+    pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option<&'hir FnDecl> {
         if let Some(entry) = self.find_entry(hir_id) {
-            entry.fn_decl().cloned()
+            entry.fn_decl()
         } else {
             bug!("no entry for hir_id `{}`", hir_id)
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index de8c75345fe..2b46170a6d2 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -155,7 +155,7 @@ pub const DUMMY_HIR_ID: HirId = HirId {
 
 pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Copy, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
 pub struct Lifetime {
     pub hir_id: HirId,
     pub span: Span,
@@ -295,7 +295,7 @@ impl Lifetime {
 /// A `Path` is essentially Rust's notion of a name; for instance,
 /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers,
 /// along with a bunch of supporting information.
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable)]
 pub struct Path {
     pub span: Span,
     /// The resolution for the path.
@@ -324,7 +324,7 @@ impl fmt::Display for Path {
 
 /// A segment of a path: an identifier, an optional lifetime, and a set of
 /// types.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct PathSegment {
     /// The identifier portion of this path segment.
     #[stable_hasher(project(name))]
@@ -393,13 +393,13 @@ impl PathSegment {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ConstArg {
     pub value: AnonConst,
     pub span: Span,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum GenericArg {
     Lifetime(Lifetime),
     Type(Ty),
@@ -431,7 +431,7 @@ impl GenericArg {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GenericArgs {
     /// The generic arguments for this path segment.
     pub args: HirVec<GenericArg>,
@@ -505,7 +505,7 @@ pub enum TraitBoundModifier {
 /// `typeck::collect::compute_bounds` matches these against
 /// the "special" built-in traits (see `middle::lang_items`) and
 /// detects `Copy`, `Send` and `Sync`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum GenericBound {
     Trait(PolyTraitRef, TraitBoundModifier),
     Outlives(Lifetime),
@@ -541,7 +541,7 @@ pub enum LifetimeParamKind {
     Error,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum GenericParamKind {
     /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`).
     Lifetime {
@@ -556,7 +556,7 @@ pub enum GenericParamKind {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GenericParam {
     pub hir_id: HirId,
     pub name: ParamName,
@@ -576,7 +576,7 @@ pub struct GenericParamCount {
 
 /// Represents lifetimes and type parameters attached to a declaration
 /// of a function, enum, trait, etc.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Generics {
     pub params: HirVec<GenericParam>,
     pub where_clause: WhereClause,
@@ -584,7 +584,7 @@ pub struct Generics {
 }
 
 impl Generics {
-    pub fn empty() -> Generics {
+    pub const fn empty() -> Generics {
         Generics {
             params: HirVec::new(),
             where_clause: WhereClause {
@@ -638,7 +638,7 @@ pub enum SyntheticTyParamKind {
 }
 
 /// A where-clause in a definition.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereClause {
     pub predicates: HirVec<WherePredicate>,
     // Only valid if predicates isn't empty.
@@ -656,7 +656,7 @@ impl WhereClause {
 }
 
 /// A single predicate in a where-clause.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum WherePredicate {
     /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`).
     BoundPredicate(WhereBoundPredicate),
@@ -677,7 +677,7 @@ impl WherePredicate {
 }
 
 /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereBoundPredicate {
     pub span: Span,
     /// Any generics from a `for` binding.
@@ -689,7 +689,7 @@ pub struct WhereBoundPredicate {
 }
 
 /// A lifetime predicate (e.g., `'a: 'b + 'c`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereRegionPredicate {
     pub span: Span,
     pub lifetime: Lifetime,
@@ -697,7 +697,7 @@ pub struct WhereRegionPredicate {
 }
 
 /// An equality predicate (e.g., `T = int`); currently unsupported.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct WhereEqPredicate {
     pub hir_id: HirId,
     pub span: Span,
@@ -705,7 +705,7 @@ pub struct WhereEqPredicate {
     pub rhs_ty: P<Ty>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct ModuleItems {
     // Use BTreeSets here so items are in the same order as in the
     // list of all items in Crate
@@ -720,7 +720,7 @@ pub struct ModuleItems {
 /// For more details, see the [rustc guide].
 ///
 /// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct Crate {
     pub module: Mod,
     pub attrs: HirVec<Attribute>,
@@ -815,7 +815,7 @@ impl Crate {
 /// A macro definition, in this crate or imported from another.
 ///
 /// Not parsed directly, but created on macro import or `macro_rules!` expansion.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct MacroDef {
     pub name: Name,
     pub vis: Visibility,
@@ -829,7 +829,7 @@ pub struct MacroDef {
 /// A block of statements `{ .. }`, which may have a label (in this case the
 /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
 /// the `rules` being anything but `DefaultBlock`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Block {
     /// Statements in a block.
     pub stmts: HirVec<Stmt>,
@@ -847,7 +847,7 @@ pub struct Block {
     pub targeted_by_break: bool,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable)]
 pub struct Pat {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -910,7 +910,7 @@ impl Pat {
 /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`
 /// are treated the same as` x: x, y: ref y, z: ref mut z`,
 /// except `is_shorthand` is true.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct FieldPat {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -925,7 +925,7 @@ pub struct FieldPat {
 /// Explicit binding annotations given in the HIR for a binding. Note
 /// that this is not the final binding *mode* that we infer after type
 /// inference.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum BindingAnnotation {
     /// No binding annotation given: this means that the final binding mode
     /// will depend on whether we have skipped through a `&` reference
@@ -952,7 +952,7 @@ pub enum RangeEnd {
     Excluded,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum PatKind {
     /// Represents a wildcard pattern (i.e., `_`).
     Wild,
@@ -997,8 +997,8 @@ pub enum PatKind {
     Slice(HirVec<P<Pat>>, Option<P<Pat>>, HirVec<P<Pat>>),
 }
 
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
-         RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
+         RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum Mutability {
     MutMutable,
     MutImmutable,
@@ -1014,7 +1014,7 @@ impl Mutability {
     }
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Hash, HashStable)]
 pub enum BinOpKind {
     /// The `+` operator (addition).
     Add,
@@ -1148,7 +1148,7 @@ impl Into<ast::BinOpKind> for BinOpKind {
 
 pub type BinOp = Spanned<BinOpKind>;
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, Hash, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Hash, HashStable)]
 pub enum UnOp {
     /// The `*` operator (deferencing).
     UnDeref,
@@ -1177,7 +1177,7 @@ impl UnOp {
 }
 
 /// A statement.
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct Stmt {
     pub hir_id: HirId,
     pub node: StmtKind,
@@ -1192,7 +1192,7 @@ impl fmt::Debug for Stmt {
 }
 
 /// The contents of a statement.
-#[derive(Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, HashStable)]
 pub enum StmtKind {
     /// A local (`let`) binding.
     Local(P<Local>),
@@ -1219,7 +1219,7 @@ impl StmtKind {
 }
 
 /// Represents a `let` statement (i.e., `let <pat>:<ty> = <expr>;`).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Local {
     pub pat: P<Pat>,
     /// Type annotation, if any (otherwise the type will be inferred).
@@ -1236,7 +1236,7 @@ pub struct Local {
 
 /// Represents a single arm of a `match` expression, e.g.
 /// `<pats> (if <guard>) => <body>`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Arm {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -1250,12 +1250,12 @@ pub struct Arm {
     pub body: P<Expr>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum Guard {
     If(P<Expr>),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Field {
     #[stable_hasher(ignore)]
     pub hir_id: HirId,
@@ -1265,7 +1265,7 @@ pub struct Field {
     pub is_shorthand: bool,
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum BlockCheckMode {
     DefaultBlock,
     UnsafeBlock(UnsafeSource),
@@ -1273,7 +1273,7 @@ pub enum BlockCheckMode {
     PopUnsafeBlock(UnsafeSource),
 }
 
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
@@ -1305,7 +1305,7 @@ pub struct BodyId {
 ///
 /// All bodies have an **owner**, which can be accessed via the HIR
 /// map using `body_owner_def_id()`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct Body {
     pub arguments: HirVec<Arg>,
     pub value: Expr,
@@ -1379,7 +1379,7 @@ pub struct AnonConst {
 }
 
 /// An expression
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct Expr {
     pub span: Span,
     pub node: ExprKind,
@@ -1490,7 +1490,7 @@ impl fmt::Debug for Expr {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ExprKind {
     /// A `box x` expression.
     Box(P<Expr>),
@@ -1598,7 +1598,7 @@ pub enum ExprKind {
 }
 
 /// Represents an optionally `Self`-qualified value/type path or associated extension.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum QPath {
     /// Path to a definition, optionally "fully-qualified" with a `Self`
     /// type, if the path points to an associated item in a trait.
@@ -1618,7 +1618,7 @@ pub enum QPath {
 }
 
 /// Hints at the original code for a let statement.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum LocalSource {
     /// A `match _ { .. }`.
     Normal,
@@ -1640,7 +1640,7 @@ pub enum LocalSource {
 }
 
 /// Hints at the original code for a `match _ { .. }`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
 pub enum MatchSource {
     /// A `match _ { .. }`.
     Normal,
@@ -1664,7 +1664,7 @@ pub enum MatchSource {
 }
 
 /// The loop type that yielded an `ExprKind::Loop`.
-#[derive(Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, PartialEq, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum LoopSource {
     /// A `loop { .. }` loop.
     Loop,
@@ -1674,7 +1674,7 @@ pub enum LoopSource {
     ForLoop,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum LoopIdError {
     OutsideLoopScope,
     UnlabeledCfInWhileCondition,
@@ -1692,7 +1692,7 @@ impl fmt::Display for LoopIdError {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Destination {
     // This is `Some(_)` iff there is an explicit user-specified `label
     pub label: Option<Label>,
@@ -1703,8 +1703,8 @@ pub struct Destination {
 }
 
 /// Whether a generator contains self-references, causing it to be `!Unpin`.
-#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
-         RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, HashStable,
+         RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum GeneratorMovability {
     /// May contain self-references, `!Unpin`.
     Static,
@@ -1713,7 +1713,7 @@ pub enum GeneratorMovability {
 }
 
 /// The yield kind that caused an `ExprKind::Yield`.
-#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub enum YieldSource {
     /// An `<expr>.await`.
     Await,
@@ -1730,7 +1730,7 @@ impl fmt::Display for YieldSource {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum CaptureClause {
     CaptureByValue,
     CaptureByRef,
@@ -1738,14 +1738,14 @@ pub enum CaptureClause {
 
 // N.B., if you change this, you'll probably want to change the corresponding
 // type structure in middle/ty.rs as well.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct MutTy {
     pub ty: P<Ty>,
     pub mutbl: Mutability,
 }
 
 /// Represents a method's signature in a trait declaration or implementation.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct MethodSig {
     pub header: FnHeader,
     pub decl: P<FnDecl>,
@@ -1763,7 +1763,7 @@ pub struct TraitItemId {
 /// possibly including a default implementation. A trait item is
 /// either required (meaning it doesn't have an implementation, just a
 /// signature) or provided (meaning it has a default implementation).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct TraitItem {
     pub ident: Ident,
     pub hir_id: HirId,
@@ -1774,7 +1774,7 @@ pub struct TraitItem {
 }
 
 /// Represents a trait method's body (or just argument names).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum TraitMethod {
     /// No default body in the trait, just a signature.
     Required(HirVec<Ident>),
@@ -1784,7 +1784,7 @@ pub enum TraitMethod {
 }
 
 /// Represents a trait method or associated constant or type
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum TraitItemKind {
     /// An associated constant with an optional value (otherwise `impl`s must contain a value).
     Const(P<Ty>, Option<BodyId>),
@@ -1804,7 +1804,7 @@ pub struct ImplItemId {
 }
 
 /// Represents anything within an `impl` block
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct ImplItem {
     pub ident: Ident,
     pub hir_id: HirId,
@@ -1817,7 +1817,7 @@ pub struct ImplItem {
 }
 
 /// Represents various kinds of content within an `impl`.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ImplItemKind {
     /// An associated constant of the given type, set to the constant result
     /// of the expression
@@ -1844,7 +1844,7 @@ pub enum ImplItemKind {
 ///    Binding(...),
 /// }
 /// ```
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct TypeBinding {
     pub hir_id: HirId,
     #[stable_hasher(project(name))]
@@ -1854,7 +1854,7 @@ pub struct TypeBinding {
 }
 
 // Represents the two kinds of type bindings.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum TypeBindingKind {
     /// E.g., `Foo<Bar: Send>`.
     Constraint {
@@ -1875,7 +1875,7 @@ impl TypeBinding {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable)]
+#[derive(RustcEncodable, RustcDecodable)]
 pub struct Ty {
     pub hir_id: HirId,
     pub node: TyKind,
@@ -1890,7 +1890,7 @@ impl fmt::Debug for Ty {
 }
 
 /// Not represented directly in the AST; referred to by name through a `ty_path`.
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, HashStable)]
 pub enum PrimTy {
     Int(IntTy),
     Uint(UintTy),
@@ -1900,7 +1900,7 @@ pub enum PrimTy {
     Char,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct BareFnTy {
     pub unsafety: Unsafety,
     pub abi: Abi,
@@ -1909,7 +1909,7 @@ pub struct BareFnTy {
     pub arg_names: HirVec<Ident>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ExistTy {
     pub generics: Generics,
     pub bounds: GenericBounds,
@@ -1929,7 +1929,7 @@ pub enum ExistTyOrigin {
 }
 
 /// The various kinds of types recognized by the compiler.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum TyKind {
     /// A variable length slice (i.e., `[T]`).
     Slice(P<Ty>),
@@ -1971,7 +1971,7 @@ pub enum TyKind {
     CVarArgs(Lifetime),
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct InlineAsmOutput {
     pub constraint: Symbol,
     pub is_rw: bool,
@@ -1994,14 +1994,14 @@ pub struct InlineAsm {
 }
 
 /// Represents an argument in a function header.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct Arg {
     pub pat: P<Pat>,
     pub hir_id: HirId,
 }
 
 /// Represents the header (not the body) of a function declaration.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct FnDecl {
     /// The types of the function's arguments.
     ///
@@ -2014,7 +2014,7 @@ pub struct FnDecl {
 }
 
 /// Represents what type of implicit self a function has, if any.
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ImplicitSelfKind {
     /// Represents a `fn x(self);`.
     Imm,
@@ -2119,7 +2119,7 @@ impl fmt::Debug for ImplPolarity {
 }
 
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum FunctionRetTy {
     /// Return type is not specified.
     ///
@@ -2149,7 +2149,7 @@ impl FunctionRetTy {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct Mod {
     /// A span from the first token past `{` to the last token until `}`.
     /// For `mod foo;`, the inner span ranges from the first token
@@ -2158,25 +2158,25 @@ pub struct Mod {
     pub item_ids: HirVec<ItemId>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ForeignMod {
     pub abi: Abi,
     pub items: HirVec<ForeignItem>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct GlobalAsm {
     pub asm: Symbol,
     #[stable_hasher(ignore)] // This is used for error reporting
     pub ctxt: SyntaxContext,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct EnumDef {
     pub variants: HirVec<Variant>,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct VariantKind {
     /// Name of the variant.
     #[stable_hasher(project(name))]
@@ -2215,7 +2215,7 @@ pub enum UseKind {
 /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the
 /// trait being referred to but just a unique `HirId` that serves as a key
 /// within the resolution map.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct TraitRef {
     pub path: Path,
     // Don't hash the ref_id. It is tracked via the thing it is used to access
@@ -2237,7 +2237,7 @@ impl TraitRef {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct PolyTraitRef {
     /// The `'a` in `<'a> Foo<&'a T>`.
     pub bound_generic_params: HirVec<GenericParam>,
@@ -2250,7 +2250,7 @@ pub struct PolyTraitRef {
 
 pub type Visibility = Spanned<VisibilityKind>;
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub enum VisibilityKind {
     Public,
     Crate(CrateSugar),
@@ -2285,7 +2285,7 @@ impl VisibilityKind {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct StructField {
     pub span: Span,
     #[stable_hasher(project(name))]
@@ -2305,7 +2305,7 @@ impl StructField {
 }
 
 /// Fields and constructor IDs of enum variants and structs.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum VariantData {
     /// A struct variant.
     ///
@@ -2350,7 +2350,7 @@ pub struct ItemId {
 /// An item
 ///
 /// The name might be a dummy name in case of anonymous items
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct Item {
     pub ident: Ident,
     pub hir_id: HirId,
@@ -2360,7 +2360,7 @@ pub struct Item {
     pub span: Span,
 }
 
-#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct FnHeader {
     pub unsafety: Unsafety,
     pub constness: Constness,
@@ -2377,7 +2377,7 @@ impl FnHeader {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ItemKind {
     /// An `extern crate` item, with optional *original* crate name if the crate was renamed.
     ///
@@ -2480,7 +2480,7 @@ impl ItemKind {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct TraitItemRef {
     pub id: TraitItemId,
     #[stable_hasher(project(name))]
@@ -2496,7 +2496,7 @@ pub struct TraitItemRef {
 /// type or method, and whether it is public). This allows other
 /// passes to find the impl they want without loading the ID (which
 /// means fewer edges in the incremental compilation graph).
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ImplItemRef {
     pub id: ImplItemId,
     #[stable_hasher(project(name))]
@@ -2515,7 +2515,7 @@ pub enum AssocItemKind {
     Existential,
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub struct ForeignItem {
     #[stable_hasher(project(name))]
     pub ident: Ident,
@@ -2527,7 +2527,7 @@ pub struct ForeignItem {
 }
 
 /// An item within an `extern` block.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
+#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
 pub enum ForeignItemKind {
     /// A foreign function.
     Fn(P<FnDecl>, HirVec<Ident>, Generics),
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index 8111ac44a87..8b1984e04f5 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -625,10 +625,10 @@ impl<'a> State<'a> {
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
                     } else {
-                        real_bounds.push(b.clone());
+                        real_bounds.push(b);
                     }
                 }
-                self.print_bounds(":", &real_bounds[..])?;
+                self.print_bounds(":", real_bounds)?;
                 self.s.word(";")?;
                 self.end()?; // end the outer ibox
             }
@@ -698,10 +698,10 @@ impl<'a> State<'a> {
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
                     } else {
-                        real_bounds.push(b.clone());
+                        real_bounds.push(b);
                     }
                 }
-                self.print_bounds(":", &real_bounds[..])?;
+                self.print_bounds(":", real_bounds)?;
                 self.print_where_clause(&generics.where_clause)?;
                 self.s.word(" ")?;
                 self.bopen()?;
@@ -724,11 +724,11 @@ impl<'a> State<'a> {
                         self.word_space("for ?")?;
                         self.print_trait_ref(&ptr.trait_ref)?;
                     } else {
-                        real_bounds.push(b.clone());
+                        real_bounds.push(b);
                     }
                 }
                 self.nbsp()?;
-                self.print_bounds("=", &real_bounds[..])?;
+                self.print_bounds("=", real_bounds)?;
                 self.print_where_clause(&generics.where_clause)?;
                 self.s.word(";")?;
             }
@@ -1998,31 +1998,34 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_bounds(&mut self, prefix: &'static str, bounds: &[hir::GenericBound])
-                        -> io::Result<()> {
-        if !bounds.is_empty() {
-            self.s.word(prefix)?;
-            let mut first = true;
-            for bound in bounds {
-                if !(first && prefix.is_empty()) {
-                    self.nbsp()?;
-                }
-                if first {
-                    first = false;
-                } else {
-                    self.word_space("+")?;
-                }
+    pub fn print_bounds<'b>(
+        &mut self,
+        prefix: &'static str,
+        bounds: impl IntoIterator<Item = &'b hir::GenericBound>,
+    ) -> io::Result<()> {
+        let mut first = true;
+        for bound in bounds {
+            if first {
+                self.s.word(prefix)?;
+            }
+            if !(first && prefix.is_empty()) {
+                self.nbsp()?;
+            }
+            if first {
+                first = false;
+            } else {
+                self.word_space("+")?;
+            }
 
-                match bound {
-                    GenericBound::Trait(tref, modifier) => {
-                        if modifier == &TraitBoundModifier::Maybe {
-                            self.s.word("?")?;
-                        }
-                        self.print_poly_trait_ref(tref)?;
-                    }
-                    GenericBound::Outlives(lt) => {
-                        self.print_lifetime(lt)?;
+            match bound {
+                GenericBound::Trait(tref, modifier) => {
+                    if modifier == &TraitBoundModifier::Maybe {
+                        self.s.word("?")?;
                     }
+                    self.print_poly_trait_ref(tref)?;
+                }
+                GenericBound::Outlives(lt) => {
+                    self.print_lifetime(lt)?;
                 }
             }
         }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 4b65d3b9d8e..2555833cd77 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1050,10 +1050,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 (self.tcx.sess.source_map().def_span(span), self.tcx.hir().body(id).arguments.iter()
                     .map(|arg| {
                         if let hir::Pat {
-                            node: hir::PatKind::Tuple(args, _),
+                            node: hir::PatKind::Tuple(ref args, _),
                             span,
                             ..
-                        } = arg.pat.clone().into_inner() {
+                        } = *arg.pat {
                             ArgKind::Tuple(
                                 Some(span),
                                 args.iter().map(|pat| {
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 6a70a23729c..dfaad95fa3c 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -1815,8 +1815,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 // as the HIR doesn't have full types for closure arguments.
                 let return_ty = *sig.output().skip_binder();
                 let mut return_span = fn_decl.output.span();
-                if let hir::FunctionRetTy::Return(ty) = fn_decl.output {
-                    if let hir::TyKind::Rptr(lifetime, _) = ty.into_inner().node {
+                if let hir::FunctionRetTy::Return(ty) = &fn_decl.output {
+                    if let hir::TyKind::Rptr(lifetime, _) = ty.node {
                         return_span = lifetime.span;
                     }
                 }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index b6d123c72ac..267f3798bd1 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -97,15 +97,15 @@ pub enum SizedByDefault {
     No,
 }
 
-struct ConvertedBinding<'tcx> {
+struct ConvertedBinding<'a, 'tcx> {
     item_name: ast::Ident,
-    kind: ConvertedBindingKind<'tcx>,
+    kind: ConvertedBindingKind<'a, 'tcx>,
     span: Span,
 }
 
-enum ConvertedBindingKind<'tcx> {
+enum ConvertedBindingKind<'a, 'tcx> {
     Equality(Ty<'tcx>),
-    Constraint(P<[hir::GenericBound]>),
+    Constraint(&'a [hir::GenericBound]),
 }
 
 #[derive(PartialEq)]
@@ -596,7 +596,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         generic_args: &'a hir::GenericArgs,
         infer_args: bool,
         self_ty: Option<Ty<'tcx>>)
-        -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'tcx>>, Option<Vec<Span>>)
+        -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, Option<Vec<Span>>)
     {
         // If the type is parameterized by this region, then replace this
         // region with the current anon region binding (in other words,
@@ -738,7 +738,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     hir::TypeBindingKind::Equality { ref ty } =>
                         ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty)),
                     hir::TypeBindingKind::Constraint { ref bounds } =>
-                        ConvertedBindingKind::Constraint(bounds.clone()),
+                        ConvertedBindingKind::Constraint(bounds),
                 };
                 ConvertedBinding {
                     item_name: binding.ident,
@@ -859,13 +859,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         ty::TraitRef::new(trait_def_id, substs)
     }
 
-    fn create_substs_for_ast_trait_ref(
+    fn create_substs_for_ast_trait_ref<'a>(
         &self,
         span: Span,
         trait_def_id: DefId,
         self_ty: Ty<'tcx>,
-        trait_segment: &hir::PathSegment,
-    ) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'tcx>>, Option<Vec<Span>>) {
+        trait_segment: &'a hir::PathSegment,
+    ) -> (SubstsRef<'tcx>, Vec<ConvertedBinding<'a, 'tcx>>, Option<Vec<Span>>) {
         debug!("create_substs_for_ast_trait_ref(trait_segment={:?})",
                trait_segment);
 
@@ -912,7 +912,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         for ab in ast_bounds {
             if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab {
                 if unbound.is_none() {
-                    unbound = Some(ptr.trait_ref.clone());
+                    unbound = Some(&ptr.trait_ref);
                 } else {
                     span_err!(
                         tcx.sess,
@@ -927,7 +927,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         let kind_id = tcx.lang_items().require(SizedTraitLangItem);
         match unbound {
-            Some(ref tpb) => {
+            Some(tpb) => {
                 // FIXME(#8559) currently requires the unbound to be built-in.
                 if let Ok(kind_id) = kind_id {
                     if tpb.path.res != Res::Def(DefKind::Trait, kind_id) {
@@ -1048,7 +1048,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         hir_ref_id: hir::HirId,
         trait_ref: ty::PolyTraitRef<'tcx>,
-        binding: &ConvertedBinding<'tcx>,
+        binding: &ConvertedBinding<'_, 'tcx>,
         bounds: &mut Bounds<'tcx>,
         speculative: bool,
         dup_bindings: &mut FxHashMap<DefId, Span>,
@@ -1165,7 +1165,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     }
                 }), binding.span));
             }
-            ConvertedBindingKind::Constraint(ref ast_bounds) => {
+            ConvertedBindingKind::Constraint(ast_bounds) => {
                 // "Desugar" a constraint like `T: Iterator<Item: Debug>` to
                 //
                 // `<T as Iterator>::Item: Debug`
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index fe742a74fff..0e83db48284 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3696,39 +3696,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
-    fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, ast::Ident)> {
+    fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, ast::Ident)> {
         let parent = self.tcx.hir().get_by_hir_id(self.tcx.hir().get_parent_item(blk_id));
         self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
     }
 
     /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
-    fn get_node_fn_decl(&self, node: Node<'_>) -> Option<(hir::FnDecl, ast::Ident, bool)> {
+    fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
         match node {
             Node::Item(&hir::Item {
                 ident, node: hir::ItemKind::Fn(ref decl, ..), ..
-            }) => decl.clone().and_then(|decl| {
+            }) => {
                 // This is less than ideal, it will not suggest a return type span on any
                 // method called `main`, regardless of whether it is actually the entry point,
                 // but it will still present it as the reason for the expected type.
                 Some((decl, ident, ident.name != sym::main))
-            }),
+            }
             Node::TraitItem(&hir::TraitItem {
                 ident, node: hir::TraitItemKind::Method(hir::MethodSig {
                     ref decl, ..
                 }, ..), ..
-            }) => decl.clone().and_then(|decl| Some((decl, ident, true))),
+            }) => Some((decl, ident, true)),
             Node::ImplItem(&hir::ImplItem {
                 ident, node: hir::ImplItemKind::Method(hir::MethodSig {
                     ref decl, ..
                 }, ..), ..
-            }) => decl.clone().and_then(|decl| Some((decl, ident, false))),
+            }) => Some((decl, ident, false)),
             _ => None,
         }
     }
 
     /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
     /// suggestion can be made, `None` otherwise.
-    pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(hir::FnDecl, bool)> {
+    pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl, bool)> {
         // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
         // `while` before reaching it, as block tail returns are not available in them.
         self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 5606d9c0ce8..52cda4ac3c6 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -165,7 +165,7 @@ impl ItemCtxt<'tcx> {
         ItemCtxt { tcx, item_def_id }
     }
 
-    pub fn to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
+    pub fn to_ty(&self, ast_ty: &'tcx hir::Ty) -> Ty<'tcx> {
         AstConv::ast_ty_to_ty(self, ast_ty)
     }
 }
@@ -338,7 +338,7 @@ impl ItemCtxt<'tcx> {
     /// bounds for a type parameter `X` if `X::Foo` is used.
     fn type_parameter_bounds_in_generics(
         &self,
-        ast_generics: &hir::Generics,
+        ast_generics: &'tcx hir::Generics,
         param_id: hir::HirId,
         ty: Ty<'tcx>,
         only_self_bounds: OnlySelfBounds,
@@ -1909,7 +1909,9 @@ fn explicit_predicates_of<'tcx>(
     let mut is_default_impl_trait = None;
 
     let icx = ItemCtxt::new(tcx, def_id);
-    let no_generics = hir::Generics::empty();
+
+    const NO_GENERICS: &hir::Generics = &hir::Generics::empty();
+
     let empty_trait_items = HirVec::new();
 
     let mut predicates = UniquePredicates::new();
@@ -1991,17 +1993,17 @@ fn explicit_predicates_of<'tcx>(
                     }
                 }
 
-                _ => &no_generics,
+                _ => NO_GENERICS,
             }
         }
 
         Node::ForeignItem(item) => match item.node {
-            ForeignItemKind::Static(..) => &no_generics,
+            ForeignItemKind::Static(..) => NO_GENERICS,
             ForeignItemKind::Fn(_, _, ref generics) => generics,
-            ForeignItemKind::Type => &no_generics,
+            ForeignItemKind::Type => NO_GENERICS,
         },
 
-        _ => &no_generics,
+        _ => NO_GENERICS,
     };
 
     let generics = tcx.generics_of(def_id);
@@ -2205,7 +2207,7 @@ fn explicit_predicates_of<'tcx>(
 fn predicates_from_bound<'tcx>(
     astconv: &dyn AstConv<'tcx>,
     param_ty: Ty<'tcx>,
-    bound: &hir::GenericBound,
+    bound: &'tcx hir::GenericBound,
 ) -> Vec<(ty::Predicate<'tcx>, Span)> {
     match *bound {
         hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => {
@@ -2227,7 +2229,7 @@ fn predicates_from_bound<'tcx>(
 fn compute_sig_of_foreign_fn_decl<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
-    decl: &hir::FnDecl,
+    decl: &'tcx hir::FnDecl,
     abi: abi::Abi,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9968118d2ec..b489ccf179c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -159,7 +159,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
 
         // Clean the crate, translating the entire libsyntax AST to one that is
         // understood by rustdoc.
-        let mut module = self.module.clean(cx);
+        let mut module = self.module.as_ref().unwrap().clean(cx);
         let mut masked_crates = FxHashSet::default();
 
         match module.inner {
@@ -600,7 +600,7 @@ pub struct Module {
     pub is_crate: bool,
 }
 
-impl Clean<Item> for doctree::Module {
+impl Clean<Item> for doctree::Module<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let name = if self.name.is_some() {
             self.name.expect("No name provided").clean(cx)
@@ -620,7 +620,7 @@ impl Clean<Item> for doctree::Module {
         items.extend(self.unions.iter().map(|x| x.clean(cx)));
         items.extend(self.enums.iter().map(|x| x.clean(cx)));
         items.extend(self.fns.iter().map(|x| x.clean(cx)));
-        items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx)));
+        items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
         items.extend(self.mods.iter().map(|x| x.clean(cx)));
         items.extend(self.typedefs.iter().map(|x| x.clean(cx)));
         items.extend(self.existentials.iter().map(|x| x.clean(cx)));
@@ -1920,10 +1920,10 @@ pub struct Function {
     pub ret_types: Vec<Type>,
 }
 
-impl Clean<Item> for doctree::Function {
+impl Clean<Item> for doctree::Function<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let (generics, decl) = enter_impl_trait(cx, || {
-            (self.generics.clean(cx), (&self.decl, self.body).clean(cx))
+            (self.generics.clean(cx), (self.decl, self.body).clean(cx))
         });
 
         let did = cx.tcx.hir().local_def_id_from_hir_id(self.id);
@@ -2128,7 +2128,7 @@ pub struct Trait {
     pub is_auto: bool,
 }
 
-impl Clean<Item> for doctree::Trait {
+impl Clean<Item> for doctree::Trait<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let attrs = self.attrs.clean(cx);
         let is_spotlight = attrs.has_doc_flag(sym::spotlight);
@@ -2143,7 +2143,7 @@ impl Clean<Item> for doctree::Trait {
             inner: TraitItem(Trait {
                 auto: self.is_auto.clean(cx),
                 unsafety: self.unsafety,
-                items: self.items.clean(cx),
+                items: self.items.iter().map(|ti| ti.clean(cx)).collect(),
                 generics: self.generics.clean(cx),
                 bounds: self.bounds.clean(cx),
                 is_spotlight,
@@ -2159,7 +2159,7 @@ pub struct TraitAlias {
     pub bounds: Vec<GenericBound>,
 }
 
-impl Clean<Item> for doctree::TraitAlias {
+impl Clean<Item> for doctree::TraitAlias<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let attrs = self.attrs.clean(cx);
         Item {
@@ -2853,11 +2853,11 @@ impl Clean<Type> for hir::Ty {
                                             _ => None,
                                         }
                                     });
-                                    if let Some(ty) = type_.cloned() {
+                                    if let Some(ty) = type_ {
                                         ty_substs.insert(ty_param_def_id, ty.clean(cx));
                                     } else if let Some(default) = default.clone() {
                                         ty_substs.insert(ty_param_def_id,
-                                                         default.into_inner().clean(cx));
+                                                         default.clean(cx));
                                     }
                                     indices.types += 1;
                                 }
@@ -2877,7 +2877,7 @@ impl Clean<Type> for hir::Ty {
                                             _ => None,
                                         }
                                     });
-                                    if let Some(ct) = const_.cloned() {
+                                    if let Some(ct) = const_ {
                                         ct_substs.insert(const_param_def_id, ct.clean(cx));
                                     }
                                     // FIXME(const_generics:defaults)
@@ -2891,20 +2891,20 @@ impl Clean<Type> for hir::Ty {
                 resolve_type(cx, path.clean(cx), self.hir_id)
             }
             TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref p)) => {
-                let mut segments: Vec<_> = p.segments.clone().into();
-                segments.pop();
-                let trait_path = hir::Path {
-                    span: p.span,
+                let segments = if p.is_global() { &p.segments[1..] } else { &p.segments };
+                let trait_segments = &segments[..segments.len() - 1];
+                let trait_path = self::Path {
+                    global: p.is_global(),
                     res: Res::Def(
                         DefKind::Trait,
                         cx.tcx.associated_item(p.res.def_id()).container.id(),
                     ),
-                    segments: segments.into(),
+                    segments: trait_segments.clean(cx),
                 };
                 Type::QPath {
                     name: p.segments.last().expect("segments were empty").ident.name.clean(cx),
                     self_type: box qself.clean(cx),
-                    trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id)
+                    trait_: box resolve_type(cx, trait_path, self.hir_id)
                 }
             }
             TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
@@ -3235,7 +3235,7 @@ pub struct Union {
     pub fields_stripped: bool,
 }
 
-impl Clean<Item> for doctree::Struct {
+impl Clean<Item> for doctree::Struct<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
@@ -3255,7 +3255,7 @@ impl Clean<Item> for doctree::Struct {
     }
 }
 
-impl Clean<Item> for doctree::Union {
+impl Clean<Item> for doctree::Union<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
@@ -3302,7 +3302,7 @@ pub struct Enum {
     pub variants_stripped: bool,
 }
 
-impl Clean<Item> for doctree::Enum {
+impl Clean<Item> for doctree::Enum<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
@@ -3326,7 +3326,7 @@ pub struct Variant {
     pub kind: VariantKind,
 }
 
-impl Clean<Item> for doctree::Variant {
+impl Clean<Item> for doctree::Variant<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
@@ -3631,7 +3631,7 @@ pub struct Typedef {
     pub generics: Generics,
 }
 
-impl Clean<Item> for doctree::Typedef {
+impl Clean<Item> for doctree::Typedef<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
@@ -3655,7 +3655,7 @@ pub struct Existential {
     pub generics: Generics,
 }
 
-impl Clean<Item> for doctree::Existential {
+impl Clean<Item> for doctree::Existential<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
@@ -3705,7 +3705,7 @@ pub struct Static {
     pub expr: String,
 }
 
-impl Clean<Item> for doctree::Static {
+impl Clean<Item> for doctree::Static<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
         Item {
@@ -3731,7 +3731,7 @@ pub struct Constant {
     pub expr: String,
 }
 
-impl Clean<Item> for doctree::Constant {
+impl Clean<Item> for doctree::Constant<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
@@ -3801,11 +3801,11 @@ pub fn get_auto_trait_and_blanket_impls(
         .chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id))
 }
 
-impl Clean<Vec<Item>> for doctree::Impl {
+impl Clean<Vec<Item>> for doctree::Impl<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
         let mut ret = Vec::new();
         let trait_ = self.trait_.clean(cx);
-        let items = self.items.clean(cx);
+        let items = self.items.iter().map(|ii| ii.clean(cx)).collect::<Vec<_>>();
 
         // If this impl block is an implementation of the Deref trait, then we
         // need to try inlining the target's inherent impl blocks as well.
@@ -3902,7 +3902,7 @@ fn build_deref_target_impls(cx: &DocContext<'_>,
     }
 }
 
-impl Clean<Vec<Item>> for doctree::ExternCrate {
+impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
 
         let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| {
@@ -3941,7 +3941,7 @@ impl Clean<Vec<Item>> for doctree::ExternCrate {
     }
 }
 
-impl Clean<Vec<Item>> for doctree::Import {
+impl Clean<Vec<Item>> for doctree::Import<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
         // We consider inlining the documentation of `pub use` statements, but we
         // forcefully don't inline if this is not public or if the
@@ -4017,22 +4017,11 @@ pub struct ImportSource {
     pub did: Option<DefId>,
 }
 
-impl Clean<Vec<Item>> for hir::ForeignMod {
-    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
-        let mut items = self.items.clean(cx);
-        for item in &mut items {
-            if let ForeignFunctionItem(ref mut f) = item.inner {
-                f.header.abi = self.abi;
-            }
-        }
-        items
-    }
-}
-
-impl Clean<Item> for hir::ForeignItem {
+impl Clean<Item> for doctree::ForeignItem<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
-        let inner = match self.node {
+        let inner = match self.kind {
             hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => {
+                let abi = cx.tcx.hir().get_foreign_abi(self.id);
                 let (generics, decl) = enter_impl_trait(cx, || {
                     (generics.clean(cx), (&**decl, &names[..]).clean(cx))
                 });
@@ -4042,7 +4031,7 @@ impl Clean<Item> for hir::ForeignItem {
                     generics,
                     header: hir::FnHeader {
                         unsafety: hir::Unsafety::Unsafe,
-                        abi: Abi::Rust,
+                        abi,
                         constness: hir::Constness::NotConst,
                         asyncness: hir::IsAsync::NotAsync,
                     },
@@ -4062,16 +4051,14 @@ impl Clean<Item> for hir::ForeignItem {
             }
         };
 
-        let local_did = cx.tcx.hir().local_def_id_from_hir_id(self.hir_id);
-
         Item {
-            name: Some(self.ident.clean(cx)),
+            name: Some(self.name.clean(cx)),
             attrs: self.attrs.clean(cx),
-            source: self.span.clean(cx),
-            def_id: local_did,
+            source: self.whence.clean(cx),
+            def_id: cx.tcx.hir().local_def_id_from_hir_id(self.id),
             visibility: self.vis.clean(cx),
-            stability: get_stability(cx, local_did),
-            deprecation: get_deprecation(cx, local_did),
+            stability: self.stab.clean(cx),
+            deprecation: self.depr.clean(cx),
             inner,
         }
     }
@@ -4246,7 +4233,7 @@ pub struct Macro {
     pub imported_from: Option<String>,
 }
 
-impl Clean<Item> for doctree::Macro {
+impl Clean<Item> for doctree::Macro<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         let name = self.name.clean(cx);
         Item {
@@ -4275,7 +4262,7 @@ pub struct ProcMacro {
     pub helpers: Vec<String>,
 }
 
-impl Clean<Item> for doctree::ProcMacro {
+impl Clean<Item> for doctree::ProcMacro<'_> {
     fn clean(&self, cx: &DocContext<'_>) -> Item {
         Item {
             name: Some(self.name.clean(cx)),
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 7a528e50e9c..51deb4e9b97 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -7,52 +7,55 @@ use syntax::ast::{Name, NodeId};
 use syntax::attr;
 use syntax::ext::base::MacroKind;
 use syntax::ptr::P;
-use syntax::source_map::Spanned;
 use syntax_pos::{self, Span};
 
 use rustc::hir;
 use rustc::hir::def_id::CrateNum;
 
-pub struct Module {
+pub struct Module<'hir> {
     pub name: Option<Name>,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub where_outer: Span,
     pub where_inner: Span,
-    pub extern_crates: Vec<ExternCrate>,
-    pub imports: Vec<Import>,
-    pub structs: Vec<Struct>,
-    pub unions: Vec<Union>,
-    pub enums: Vec<Enum>,
-    pub fns: Vec<Function>,
-    pub mods: Vec<Module>,
+    pub extern_crates: Vec<ExternCrate<'hir>>,
+    pub imports: Vec<Import<'hir>>,
+    pub structs: Vec<Struct<'hir>>,
+    pub unions: Vec<Union<'hir>>,
+    pub enums: Vec<Enum<'hir>>,
+    pub fns: Vec<Function<'hir>>,
+    pub mods: Vec<Module<'hir>>,
     pub id: NodeId,
-    pub typedefs: Vec<Typedef>,
-    pub existentials: Vec<Existential>,
-    pub statics: Vec<Static>,
-    pub constants: Vec<Constant>,
-    pub traits: Vec<Trait>,
-    pub vis: hir::Visibility,
+    pub typedefs: Vec<Typedef<'hir>>,
+    pub existentials: Vec<Existential<'hir>>,
+    pub statics: Vec<Static<'hir>>,
+    pub constants: Vec<Constant<'hir>>,
+    pub traits: Vec<Trait<'hir>>,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub impls: Vec<Impl>,
-    pub foreigns: Vec<hir::ForeignMod>,
-    pub macros: Vec<Macro>,
-    pub proc_macros: Vec<ProcMacro>,
-    pub trait_aliases: Vec<TraitAlias>,
+    pub impls: Vec<Impl<'hir>>,
+    pub foreigns: Vec<ForeignItem<'hir>>,
+    pub macros: Vec<Macro<'hir>>,
+    pub proc_macros: Vec<ProcMacro<'hir>>,
+    pub trait_aliases: Vec<TraitAlias<'hir>>,
     pub is_crate: bool,
 }
 
-impl Module {
-    pub fn new(name: Option<Name>) -> Module {
+impl Module<'hir> {
+    pub fn new(
+        name: Option<Name>,
+        attrs: &'hir hir::HirVec<ast::Attribute>,
+        vis: &'hir hir::Visibility,
+    ) -> Module<'hir> {
         Module {
             name       : name,
             id: ast::CRATE_NODE_ID,
-            vis: Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Inherited },
+            vis,
             stab: None,
             depr: None,
             where_outer: syntax_pos::DUMMY_SP,
             where_inner: syntax_pos::DUMMY_SP,
-            attrs      : hir::HirVec::new(),
+            attrs,
             extern_crates: Vec::new(),
             imports    :   Vec::new(),
             structs    :   Vec::new(),
@@ -85,167 +88,178 @@ pub enum StructType {
     Unit,
 }
 
-pub struct Struct {
-    pub vis: hir::Visibility,
+pub struct Struct<'hir> {
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub id: hir::HirId,
     pub struct_type: StructType,
     pub name: Name,
-    pub generics: hir::Generics,
-    pub attrs: hir::HirVec<ast::Attribute>,
-    pub fields: hir::HirVec<hir::StructField>,
+    pub generics: &'hir hir::Generics,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
+    pub fields: &'hir [hir::StructField],
     pub whence: Span,
 }
 
-pub struct Union {
-    pub vis: hir::Visibility,
+pub struct Union<'hir> {
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub id: hir::HirId,
     pub struct_type: StructType,
     pub name: Name,
-    pub generics: hir::Generics,
-    pub attrs: hir::HirVec<ast::Attribute>,
-    pub fields: hir::HirVec<hir::StructField>,
+    pub generics: &'hir hir::Generics,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
+    pub fields: &'hir [hir::StructField],
     pub whence: Span,
 }
 
-pub struct Enum {
-    pub vis: hir::Visibility,
+pub struct Enum<'hir> {
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
-    pub variants: hir::HirVec<Variant>,
-    pub generics: hir::Generics,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub variants: Vec<Variant<'hir>>,
+    pub generics: &'hir hir::Generics,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub id: hir::HirId,
     pub whence: Span,
     pub name: Name,
 }
 
-pub struct Variant {
+pub struct Variant<'hir> {
     pub name: Name,
     pub id: hir::HirId,
-    pub attrs: hir::HirVec<ast::Attribute>,
-    pub def: hir::VariantData,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
+    pub def: &'hir hir::VariantData,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub whence: Span,
 }
 
-pub struct Function {
-    pub decl: hir::FnDecl,
-    pub attrs: hir::HirVec<ast::Attribute>,
+pub struct Function<'hir> {
+    pub decl: &'hir hir::FnDecl,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub id: hir::HirId,
     pub name: Name,
-    pub vis: hir::Visibility,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub header: hir::FnHeader,
     pub whence: Span,
-    pub generics: hir::Generics,
+    pub generics: &'hir hir::Generics,
     pub body: hir::BodyId,
 }
 
-pub struct Typedef {
-    pub ty: P<hir::Ty>,
-    pub gen: hir::Generics,
+pub struct Typedef<'hir> {
+    pub ty: &'hir P<hir::Ty>,
+    pub gen: &'hir hir::Generics,
     pub name: Name,
     pub id: hir::HirId,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub whence: Span,
-    pub vis: hir::Visibility,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
 }
 
-pub struct Existential {
-    pub exist_ty: hir::ExistTy,
+pub struct Existential<'hir> {
+    pub exist_ty: &'hir hir::ExistTy,
     pub name: Name,
     pub id: hir::HirId,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub whence: Span,
-    pub vis: hir::Visibility,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
 }
 
 #[derive(Debug)]
-pub struct Static {
-    pub type_: P<hir::Ty>,
+pub struct Static<'hir> {
+    pub type_: &'hir P<hir::Ty>,
     pub mutability: hir::Mutability,
     pub expr: hir::BodyId,
     pub name: Name,
-    pub attrs: hir::HirVec<ast::Attribute>,
-    pub vis: hir::Visibility,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub id: hir::HirId,
     pub whence: Span,
 }
 
-pub struct Constant {
-    pub type_: P<hir::Ty>,
+pub struct Constant<'hir> {
+    pub type_: &'hir P<hir::Ty>,
     pub expr: hir::BodyId,
     pub name: Name,
-    pub attrs: hir::HirVec<ast::Attribute>,
-    pub vis: hir::Visibility,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub id: hir::HirId,
     pub whence: Span,
 }
 
-pub struct Trait {
+pub struct Trait<'hir> {
     pub is_auto: hir::IsAuto,
     pub unsafety: hir::Unsafety,
     pub name: Name,
-    pub items: hir::HirVec<hir::TraitItem>,
-    pub generics: hir::Generics,
-    pub bounds: hir::HirVec<hir::GenericBound>,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub items: Vec<&'hir hir::TraitItem>,
+    pub generics: &'hir hir::Generics,
+    pub bounds: &'hir hir::HirVec<hir::GenericBound>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub id: hir::HirId,
     pub whence: Span,
-    pub vis: hir::Visibility,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
 }
 
-pub struct TraitAlias {
+pub struct TraitAlias<'hir> {
     pub name: Name,
-    pub generics: hir::Generics,
-    pub bounds: hir::HirVec<hir::GenericBound>,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub generics: &'hir hir::Generics,
+    pub bounds: &'hir hir::HirVec<hir::GenericBound>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub id: hir::HirId,
     pub whence: Span,
-    pub vis: hir::Visibility,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
 }
 
 #[derive(Debug)]
-pub struct Impl {
+pub struct Impl<'hir> {
     pub unsafety: hir::Unsafety,
     pub polarity: hir::ImplPolarity,
     pub defaultness: hir::Defaultness,
-    pub generics: hir::Generics,
-    pub trait_: Option<hir::TraitRef>,
-    pub for_: P<hir::Ty>,
-    pub items: hir::HirVec<hir::ImplItem>,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub generics: &'hir hir::Generics,
+    pub trait_: &'hir Option<hir::TraitRef>,
+    pub for_: &'hir P<hir::Ty>,
+    pub items: Vec<&'hir hir::ImplItem>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub whence: Span,
-    pub vis: hir::Visibility,
+    pub vis: &'hir hir::Visibility,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
     pub id: hir::HirId,
 }
 
+pub struct ForeignItem<'hir> {
+    pub vis: &'hir hir::Visibility,
+    pub stab: Option<attr::Stability>,
+    pub depr: Option<attr::Deprecation>,
+    pub id: hir::HirId,
+    pub name: Name,
+    pub kind: &'hir hir::ForeignItemKind,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
+    pub whence: Span,
+}
+
 // For Macro we store the DefId instead of the NodeId, since we also create
 // these imported macro_rules (which only have a DUMMY_NODE_ID).
-pub struct Macro {
+pub struct Macro<'hir> {
     pub name: Name,
     pub def_id: hir::def_id::DefId,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub whence: Span,
     pub matchers: hir::HirVec<Span>,
     pub stab: Option<attr::Stability>,
@@ -253,31 +267,31 @@ pub struct Macro {
     pub imported_from: Option<Name>,
 }
 
-pub struct ExternCrate {
+pub struct ExternCrate<'hir> {
     pub name: Name,
     pub cnum: CrateNum,
     pub path: Option<String>,
-    pub vis: hir::Visibility,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub vis: &'hir hir::Visibility,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub whence: Span,
 }
 
-pub struct Import {
+pub struct Import<'hir> {
     pub name: Name,
     pub id: hir::HirId,
-    pub vis: hir::Visibility,
-    pub attrs: hir::HirVec<ast::Attribute>,
-    pub path: hir::Path,
+    pub vis: &'hir hir::Visibility,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
+    pub path: &'hir hir::Path,
     pub glob: bool,
     pub whence: Span,
 }
 
-pub struct ProcMacro {
+pub struct ProcMacro<'hir> {
     pub name: Name,
     pub id: hir::HirId,
     pub kind: MacroKind,
     pub helpers: Vec<Name>,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub attrs: &'hir hir::HirVec<ast::Attribute>,
     pub whence: Span,
     pub stab: Option<attr::Stability>,
     pub depr: Option<attr::Deprecation>,
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index ff76579d67d..c94149d3102 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -29,8 +29,7 @@ use crate::doctree::*;
 // framework from syntax?.
 
 pub struct RustdocVisitor<'a, 'tcx> {
-    pub module: Module,
-    pub attrs: hir::HirVec<ast::Attribute>,
+    pub module: Option<Module<'tcx>>,
     pub cx: &'a core::DocContext<'tcx>,
     view_item_stack: FxHashSet<hir::HirId>,
     inlining: bool,
@@ -47,8 +46,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         let mut stack = FxHashSet::default();
         stack.insert(hir::CRATE_HIR_ID);
         RustdocVisitor {
-            module: Module::new(None),
-            attrs: hir::HirVec::new(),
+            module: None,
             cx,
             view_item_stack: stack,
             inlining: false,
@@ -77,92 +75,91 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             .and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id))
     }
 
-    pub fn visit(&mut self, krate: &hir::Crate) {
-        self.attrs = krate.attrs.clone();
-
-        self.module = self.visit_mod_contents(krate.span,
-                                              krate.attrs.clone(),
-                                              Spanned { span: syntax_pos::DUMMY_SP,
+    pub fn visit(&mut self, krate: &'tcx hir::Crate) {
+        let mut module = self.visit_mod_contents(krate.span,
+                                              &krate.attrs,
+                                              &Spanned { span: syntax_pos::DUMMY_SP,
                                                         node: hir::VisibilityKind::Public },
                                               hir::CRATE_HIR_ID,
                                               &krate.module,
                                               None);
         // Attach the crate's exported macros to the top-level module:
-        let macro_exports: Vec<_> =
-            krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)).collect();
-        self.module.macros.extend(macro_exports);
-        self.module.is_crate = true;
+        module.macros.extend(
+            krate.exported_macros.iter().map(|def| self.visit_local_macro(def, None)),
+        );
+        module.is_crate = true;
+        self.module = Some(module);
 
         self.cx.renderinfo.borrow_mut().exact_paths = self.exact_paths.take().unwrap();
     }
 
-    pub fn visit_variant_data(&mut self, item: &hir::Item,
-                              name: ast::Name, sd: &hir::VariantData,
-                              generics: &hir::Generics) -> Struct {
+    pub fn visit_variant_data(&mut self, item: &'tcx hir::Item,
+                              name: ast::Name, sd: &'tcx hir::VariantData,
+                              generics: &'tcx hir::Generics) -> Struct<'tcx> {
         debug!("Visiting struct");
         let struct_type = struct_type_from_def(&*sd);
         Struct {
             id: item.hir_id,
             struct_type,
             name,
-            vis: item.vis.clone(),
+            vis: &item.vis,
             stab: self.stability(item.hir_id),
             depr: self.deprecation(item.hir_id),
-            attrs: item.attrs.clone(),
-            generics: generics.clone(),
-            fields: sd.fields().iter().cloned().collect(),
+            attrs: &item.attrs,
+            generics,
+            fields: sd.fields(),
             whence: item.span
         }
     }
 
-    pub fn visit_union_data(&mut self, item: &hir::Item,
-                            name: ast::Name, sd: &hir::VariantData,
-                            generics: &hir::Generics) -> Union {
+    pub fn visit_union_data(&mut self, item: &'tcx hir::Item,
+                            name: ast::Name, sd: &'tcx hir::VariantData,
+                            generics: &'tcx hir::Generics) -> Union<'tcx> {
         debug!("Visiting union");
         let struct_type = struct_type_from_def(&*sd);
         Union {
             id: item.hir_id,
             struct_type,
             name,
-            vis: item.vis.clone(),
+            vis: &item.vis,
             stab: self.stability(item.hir_id),
             depr: self.deprecation(item.hir_id),
-            attrs: item.attrs.clone(),
-            generics: generics.clone(),
-            fields: sd.fields().iter().cloned().collect(),
+            attrs: &item.attrs,
+            generics,
+            fields: sd.fields(),
             whence: item.span
         }
     }
 
-    pub fn visit_enum_def(&mut self, it: &hir::Item,
-                          name: ast::Name, def: &hir::EnumDef,
-                          params: &hir::Generics) -> Enum {
+    pub fn visit_enum_def(&mut self, it: &'tcx hir::Item,
+                          name: ast::Name, def: &'tcx hir::EnumDef,
+                          generics: &'tcx hir::Generics) -> Enum<'tcx> {
         debug!("Visiting enum");
         Enum {
             name,
             variants: def.variants.iter().map(|v| Variant {
                 name: v.node.ident.name,
                 id: v.node.id,
-                attrs: v.node.attrs.clone(),
+                attrs: &v.node.attrs,
                 stab: self.stability(v.node.id),
                 depr: self.deprecation(v.node.id),
-                def: v.node.data.clone(),
+                def: &v.node.data,
                 whence: v.span,
             }).collect(),
-            vis: it.vis.clone(),
+            vis: &it.vis,
             stab: self.stability(it.hir_id),
             depr: self.deprecation(it.hir_id),
-            generics: params.clone(),
-            attrs: it.attrs.clone(),
+            generics,
+            attrs: &it.attrs,
             id: it.hir_id,
             whence: it.span,
         }
     }
 
-    pub fn visit_fn(&mut self, om: &mut Module, item: &hir::Item,
-                    name: ast::Name, fd: &hir::FnDecl,
+    pub fn visit_fn(&mut self, om: &mut Module<'tcx>, item: &'tcx hir::Item,
+                    name: ast::Name, decl: &'tcx hir::FnDecl,
                     header: hir::FnHeader,
-                    gen: &hir::Generics,
+                    generics: &'tcx hir::Generics,
                     body: hir::BodyId) {
         debug!("Visiting fn");
         let macro_kind = item.attrs.iter().filter_map(|a| {
@@ -208,7 +205,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     id: item.hir_id,
                     kind,
                     helpers,
-                    attrs: item.attrs.clone(),
+                    attrs: &item.attrs,
                     whence: item.span,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
@@ -217,14 +214,14 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             None => {
                 om.fns.push(Function {
                     id: item.hir_id,
-                    vis: item.vis.clone(),
+                    vis: &item.vis,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
-                    attrs: item.attrs.clone(),
-                    decl: fd.clone(),
+                    attrs: &item.attrs,
+                    decl,
                     name,
                     whence: item.span,
-                    generics: gen.clone(),
+                    generics,
                     header,
                     body,
                 });
@@ -232,15 +229,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         }
     }
 
-    pub fn visit_mod_contents(&mut self, span: Span, attrs: hir::HirVec<ast::Attribute>,
-                              vis: hir::Visibility, id: hir::HirId,
-                              m: &hir::Mod,
-                              name: Option<ast::Name>) -> Module {
-        let mut om = Module::new(name);
+    pub fn visit_mod_contents(&mut self, span: Span, attrs: &'tcx hir::HirVec<ast::Attribute>,
+                              vis: &'tcx hir::Visibility, id: hir::HirId,
+                              m: &'tcx hir::Mod,
+                              name: Option<ast::Name>) -> Module<'tcx> {
+        let mut om = Module::new(name, attrs, vis);
         om.where_outer = span;
         om.where_inner = m.inner;
-        om.attrs = attrs;
-        om.vis = vis.clone();
         om.stab = self.stability(id);
         om.depr = self.deprecation(id);
         om.id = self.cx.tcx.hir().hir_to_node_id(id);
@@ -269,7 +264,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                           res: Res,
                           renamed: Option<ast::Ident>,
                           glob: bool,
-                          om: &mut Module,
+                          om: &mut Module<'tcx>,
                           please_inline: bool) -> bool {
 
         fn inherits_doc_hidden(cx: &core::DocContext<'_>, mut node: hir::HirId) -> bool {
@@ -359,14 +354,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 true
             }
             Node::ForeignItem(it) if !glob => {
-                // Generate a fresh `extern {}` block if we want to inline a foreign item.
-                om.foreigns.push(hir::ForeignMod {
-                    abi: tcx.hir().get_foreign_abi(it.hir_id),
-                    items: vec![hir::ForeignItem {
-                        ident: renamed.unwrap_or(it.ident),
-                        .. it.clone()
-                    }].into(),
-                });
+                let prev = mem::replace(&mut self.inlining, true);
+                self.visit_foreign_item(it, renamed, om);
+                self.inlining = prev;
                 true
             }
             Node::MacroDef(def) if !glob => {
@@ -379,8 +369,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         ret
     }
 
-    pub fn visit_item(&mut self, item: &hir::Item,
-                      renamed: Option<ast::Ident>, om: &mut Module) {
+    pub fn visit_item(&mut self, item: &'tcx hir::Item,
+                      renamed: Option<ast::Ident>, om: &mut Module<'tcx>) {
         debug!("Visiting item {:?}", item);
         let ident = renamed.unwrap_or(item.ident);
 
@@ -391,15 +381,9 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
 
         match item.node {
             hir::ItemKind::ForeignMod(ref fm) => {
-                // If inlining we only want to include public functions.
-                om.foreigns.push(if self.inlining {
-                    hir::ForeignMod {
-                        abi: fm.abi,
-                        items: fm.items.iter().filter(|i| i.vis.node.is_pub()).cloned().collect(),
-                    }
-                } else {
-                    fm.clone()
-                });
+                for item in &fm.items {
+                    self.visit_foreign_item(item, None, om);
+                }
             }
             // If we're inlining, skip private items.
             _ if self.inlining && !item.vis.node.is_pub() => {}
@@ -411,8 +395,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                                 .unwrap_or(LOCAL_CRATE),
                     name: ident.name,
                     path: orig_name.map(|x|x.to_string()),
-                    vis: item.vis.clone(),
-                    attrs: item.attrs.clone(),
+                    vis: &item.vis,
+                    attrs: &item.attrs,
                     whence: item.span,
                 })
             }
@@ -454,17 +438,17 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 om.imports.push(Import {
                     name: ident.name,
                     id: item.hir_id,
-                    vis: item.vis.clone(),
-                    attrs: item.attrs.clone(),
-                    path: (**path).clone(),
+                    vis: &item.vis,
+                    attrs: &item.attrs,
+                    path,
                     glob: is_glob,
                     whence: item.span,
                 });
             }
             hir::ItemKind::Mod(ref m) => {
                 om.mods.push(self.visit_mod_contents(item.span,
-                                                     item.attrs.clone(),
-                                                     item.vis.clone(),
+                                                     &item.attrs,
+                                                     &item.vis,
                                                      item.hir_id,
                                                      m,
                                                      Some(ident.name)));
@@ -479,13 +463,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 self.visit_fn(om, item, ident.name, &**fd, header, gen, body),
             hir::ItemKind::Ty(ref ty, ref gen) => {
                 let t = Typedef {
-                    ty: ty.clone(),
-                    gen: gen.clone(),
+                    ty,
+                    gen,
                     name: ident.name,
                     id: item.hir_id,
-                    attrs: item.attrs.clone(),
+                    attrs: &item.attrs,
                     whence: item.span,
-                    vis: item.vis.clone(),
+                    vis: &item.vis,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
                 };
@@ -493,75 +477,75 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             },
             hir::ItemKind::Existential(ref exist_ty) => {
                 let t = Existential {
-                    exist_ty: exist_ty.clone(),
+                    exist_ty,
                     name: ident.name,
                     id: item.hir_id,
-                    attrs: item.attrs.clone(),
+                    attrs: &item.attrs,
                     whence: item.span,
-                    vis: item.vis.clone(),
+                    vis: &item.vis,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
                 };
                 om.existentials.push(t);
             },
-            hir::ItemKind::Static(ref ty, ref mut_, ref exp) => {
+            hir::ItemKind::Static(ref type_, mutability, expr) => {
                 let s = Static {
-                    type_: ty.clone(),
-                    mutability: mut_.clone(),
-                    expr: exp.clone(),
+                    type_,
+                    mutability,
+                    expr,
                     id: item.hir_id,
                     name: ident.name,
-                    attrs: item.attrs.clone(),
+                    attrs: &item.attrs,
                     whence: item.span,
-                    vis: item.vis.clone(),
+                    vis: &item.vis,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
                 };
                 om.statics.push(s);
             },
-            hir::ItemKind::Const(ref ty, ref exp) => {
+            hir::ItemKind::Const(ref type_, expr) => {
                 let s = Constant {
-                    type_: ty.clone(),
-                    expr: exp.clone(),
+                    type_,
+                    expr,
                     id: item.hir_id,
                     name: ident.name,
-                    attrs: item.attrs.clone(),
+                    attrs: &item.attrs,
                     whence: item.span,
-                    vis: item.vis.clone(),
+                    vis: &item.vis,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
                 };
                 om.constants.push(s);
             },
-            hir::ItemKind::Trait(is_auto, unsafety, ref gen, ref b, ref item_ids) => {
+            hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
                 let items = item_ids.iter()
-                                    .map(|ti| self.cx.tcx.hir().trait_item(ti.id).clone())
+                                    .map(|ti| self.cx.tcx.hir().trait_item(ti.id))
                                     .collect();
                 let t = Trait {
                     is_auto,
                     unsafety,
                     name: ident.name,
                     items,
-                    generics: gen.clone(),
-                    bounds: b.iter().cloned().collect(),
+                    generics,
+                    bounds,
                     id: item.hir_id,
-                    attrs: item.attrs.clone(),
+                    attrs: &item.attrs,
                     whence: item.span,
-                    vis: item.vis.clone(),
+                    vis: &item.vis,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
                 };
                 om.traits.push(t);
             },
-            hir::ItemKind::TraitAlias(ref gen, ref b) => {
+            hir::ItemKind::TraitAlias(ref generics, ref bounds) => {
                 let t = TraitAlias {
                     name: ident.name,
-                    generics: gen.clone(),
-                    bounds: b.iter().cloned().collect(),
+                    generics,
+                    bounds,
                     id: item.hir_id,
-                    attrs: item.attrs.clone(),
+                    attrs: &item.attrs,
                     whence: item.span,
-                    vis: item.vis.clone(),
+                    vis: &item.vis,
                     stab: self.stability(item.hir_id),
                     depr: self.deprecation(item.hir_id),
                 };
@@ -571,28 +555,28 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             hir::ItemKind::Impl(unsafety,
                           polarity,
                           defaultness,
-                          ref gen,
-                          ref tr,
-                          ref ty,
+                          ref generics,
+                          ref trait_,
+                          ref for_,
                           ref item_ids) => {
                 // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick
                 // them up regardless of where they're located.
-                if !self.inlining && tr.is_none() {
+                if !self.inlining && trait_.is_none() {
                     let items = item_ids.iter()
-                                        .map(|ii| self.cx.tcx.hir().impl_item(ii.id).clone())
+                                        .map(|ii| self.cx.tcx.hir().impl_item(ii.id))
                                         .collect();
                     let i = Impl {
                         unsafety,
                         polarity,
                         defaultness,
-                        generics: gen.clone(),
-                        trait_: tr.clone(),
-                        for_: ty.clone(),
+                        generics,
+                        trait_,
+                        for_,
                         items,
-                        attrs: item.attrs.clone(),
+                        attrs: &item.attrs,
                         id: item.hir_id,
                         whence: item.span,
-                        vis: item.vis.clone(),
+                        vis: &item.vis,
                         stab: self.stability(item.hir_id),
                         depr: self.deprecation(item.hir_id),
                     };
@@ -602,12 +586,31 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         }
     }
 
+    fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem,
+                      renamed: Option<ast::Ident>, om: &mut Module<'tcx>) {
+        // If inlining we only want to include public functions.
+        if self.inlining && !item.vis.node.is_pub() {
+            return;
+        }
+
+        om.foreigns.push(ForeignItem {
+            id: item.hir_id,
+            name: renamed.unwrap_or(item.ident).name,
+            kind: &item.node,
+            vis: &item.vis,
+            stab: self.stability(item.hir_id),
+            depr: self.deprecation(item.hir_id),
+            attrs: &item.attrs,
+            whence: item.span
+        });
+    }
+
     // Convert each `exported_macro` into a doc item.
     fn visit_local_macro(
         &self,
-        def: &hir::MacroDef,
+        def: &'tcx hir::MacroDef,
         renamed: Option<ast::Name>
-    ) -> Macro {
+    ) -> Macro<'tcx> {
         debug!("visit_local_macro: {}", def.name);
         let tts = def.body.trees().collect::<Vec<_>>();
         // Extract the spans of all matchers. They represent the "interface" of the macro.
@@ -616,7 +619,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         Macro {
 
             def_id: self.cx.tcx.hir().local_def_id_from_hir_id(def.hir_id),
-            attrs: def.attrs.clone(),
+            attrs: &def.attrs,
             name: renamed.unwrap_or(def.name),
             whence: def.span,
             matchers,