From 1e3302d85f6c9635c14535bb59d17964a9479c2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Wed, 22 May 2019 13:10:38 -0700
Subject: [PATCH 01/35] Suggest dereferencing on assignment to mutable borrow

---
 src/librustc_typeck/check/demand.rs           | 34 ++++++++++++++++---
 .../ui/suggestions/mut-ref-reassignment.rs    |  5 +++
 .../suggestions/mut-ref-reassignment.stderr   | 16 +++++++++
 3 files changed, 50 insertions(+), 5 deletions(-)
 create mode 100644 src/test/ui/suggestions/mut-ref-reassignment.rs
 create mode 100644 src/test/ui/suggestions/mut-ref-reassignment.stderr

diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs
index 8d68179b495c6..a4e687b8f9080 100644
--- a/src/librustc_typeck/check/demand.rs
+++ b/src/librustc_typeck/check/demand.rs
@@ -306,11 +306,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     /// In addition of this check, it also checks between references mutability state. If the
     /// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
     /// `&mut`!".
-    pub fn check_ref(&self,
-                 expr: &hir::Expr,
-                 checked_ty: Ty<'tcx>,
-                 expected: Ty<'tcx>)
-                 -> Option<(Span, &'static str, String)> {
+    pub fn check_ref(
+        &self,
+        expr: &hir::Expr,
+        checked_ty: Ty<'tcx>,
+        expected: Ty<'tcx>,
+    ) -> Option<(Span, &'static str, String)> {
         let cm = self.sess().source_map();
         let sp = expr.span;
         if !cm.span_to_filename(sp).is_real() {
@@ -397,6 +398,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         } else {
                             String::new()
                         };
+                        if let Some(hir::Node::Expr(hir::Expr {
+                            node: hir::ExprKind::Assign(left_expr, _),
+                            ..
+                        })) = self.tcx.hir().find_by_hir_id(
+                            self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id),
+                        ) {
+                            if mutability == hir::Mutability::MutMutable {
+                                // Found the following case:
+                                // fn foo(opt: &mut Option<String>){ opt = None }
+                                //                                   ---   ^^^^
+                                //                                   |     |
+                                //    consider dereferencing here: `*opt`  |
+                                // expected mutable reference, found enum `Option`
+                                if let Ok(src) = cm.span_to_snippet(left_expr.span) {
+                                    return Some((
+                                        left_expr.span,
+                                        "consider dereferencing here to assign to the mutable \
+                                         borrowed piece of memory",
+                                        format!("*{}", src),
+                                    ));
+                                }
+                            }
+                        }
                         return Some(match mutability {
                             hir::Mutability::MutMutable => (
                                 sp,
diff --git a/src/test/ui/suggestions/mut-ref-reassignment.rs b/src/test/ui/suggestions/mut-ref-reassignment.rs
new file mode 100644
index 0000000000000..b9deaa96dbfc3
--- /dev/null
+++ b/src/test/ui/suggestions/mut-ref-reassignment.rs
@@ -0,0 +1,5 @@
+fn change_opt(opt: &mut Option<String>){
+    opt = None //~ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/mut-ref-reassignment.stderr b/src/test/ui/suggestions/mut-ref-reassignment.stderr
new file mode 100644
index 0000000000000..d90c13b388279
--- /dev/null
+++ b/src/test/ui/suggestions/mut-ref-reassignment.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/mut-ref-reassignment.rs:2:11
+   |
+LL |     opt = None
+   |           ^^^^ expected mutable reference, found enum `std::option::Option`
+   |
+   = note: expected type `&mut std::option::Option<std::string::String>`
+              found type `std::option::Option<_>`
+help: consider dereferencing here to assign to the mutable borrowed piece of memory
+   |
+LL |     *opt = None
+   |     ^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From f44b264447f0d1b42676e7ea99a04d140749f65b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 23 May 2019 16:30:16 +0200
Subject: [PATCH 02/35] fix dangling reference in Vec::append

---
 src/liballoc/tests/vec.rs | 5 +++--
 src/liballoc/vec.rs       | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs
index 545332bcd6a2f..3307bdf94f985 100644
--- a/src/liballoc/tests/vec.rs
+++ b/src/liballoc/tests/vec.rs
@@ -1,5 +1,3 @@
-#![cfg(not(miri))]
-
 use std::borrow::Cow;
 use std::mem::size_of;
 use std::{usize, isize};
@@ -763,6 +761,7 @@ fn from_into_inner() {
     it.next().unwrap();
     let vec = it.collect::<Vec<_>>();
     assert_eq!(vec, [2, 3]);
+    #[cfg(not(miri))] // Miri does not support comparing dangling pointers
     assert!(ptr != vec.as_ptr());
 }
 
@@ -971,6 +970,7 @@ fn test_reserve_exact() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support signalling OOM
 fn test_try_reserve() {
 
     // These are the interesting cases:
@@ -1073,6 +1073,7 @@ fn test_try_reserve() {
 }
 
 #[test]
+#[cfg(not(miri))] // Miri does not support signalling OOM
 fn test_try_reserve_exact() {
 
     // This is exactly the same as test_try_reserve with the method changed.
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 073d3ab593703..dc661a267e2a6 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -1094,7 +1094,7 @@ impl<T> Vec<T> {
         let count = (*other).len();
         self.reserve(count);
         let len = self.len();
-        ptr::copy_nonoverlapping(other as *const T, self.get_unchecked_mut(len), count);
+        ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count);
         self.len += count;
     }
 

From 3cbf5864a6b7088eb28da30b9ccf61ba8d90054f Mon Sep 17 00:00:00 2001
From: Andy Russell <arussell123@gmail.com>
Date: Wed, 22 May 2019 16:56:51 -0400
Subject: [PATCH 03/35] tweak discriminant on non-nullary enum diagnostic

Adds notes pointing at the non-nullary variants, and uses "custom
discriminant" language to be consistent with the Reference.
---
 src/libsyntax/parse/diagnostics.rs            | 47 +++++++++++++++++--
 src/libsyntax/parse/parser.rs                 | 14 +-----
 src/test/ui/parser/issue-17383.rs             |  2 +-
 src/test/ui/parser/issue-17383.stderr         |  7 ++-
 .../ui/parser/tag-variant-disr-non-nullary.rs |  3 +-
 .../tag-variant-disr-non-nullary.stderr       | 16 ++++---
 6 files changed, 63 insertions(+), 26 deletions(-)

diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index d48fcbbd6720d..8ac5beb21b530 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -1,16 +1,19 @@
 use crate::ast;
-use crate::ast::{BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind};
-use crate::parse::parser::{BlockMode, PathStyle, TokenType, SemiColonMode};
+use crate::ast::{
+    BlockCheckMode, Expr, ExprKind, Item, ItemKind, Pat, PatKind, QSelf, Ty, TyKind, VariantData,
+};
+use crate::parse::parser::{BlockMode, PathStyle, SemiColonMode, TokenType};
 use crate::parse::token;
 use crate::parse::PResult;
 use crate::parse::Parser;
 use crate::print::pprust;
 use crate::ptr::P;
+use crate::source_map::Spanned;
 use crate::symbol::kw;
 use crate::ThinVec;
 use errors::{Applicability, DiagnosticBuilder};
-use syntax_pos::Span;
 use log::debug;
+use syntax_pos::Span;
 
 pub trait RecoverQPath: Sized + 'static {
     const PATH_STYLE: PathStyle = PathStyle::Expr;
@@ -79,6 +82,44 @@ impl<'a> Parser<'a> {
         }
     }
 
+    crate fn maybe_report_invalid_custom_discriminants(
+        &mut self,
+        discriminant_spans: Vec<Span>,
+        variants: &[Spanned<ast::Variant_>],
+    ) {
+        let has_fields = variants.iter().any(|variant| match variant.node.data {
+            VariantData::Tuple(..) | VariantData::Struct(..) => true,
+            VariantData::Unit(..) => false,
+        });
+
+        if !discriminant_spans.is_empty() && has_fields {
+            let mut err = self.struct_span_err(
+                discriminant_spans.clone(),
+                "custom discriminant values are not allowed in enums with fields",
+            );
+            for sp in discriminant_spans {
+                err.span_label(sp, "invalid custom discriminant");
+            }
+            for variant in variants.iter() {
+                if let VariantData::Struct(fields, ..) | VariantData::Tuple(fields, ..) =
+                    &variant.node.data
+                {
+                    let fields = if fields.len() > 1 {
+                        "fields"
+                    } else {
+                        "a field"
+                    };
+                    err.span_label(
+                        variant.span,
+                        &format!("variant with {fields} defined here", fields = fields),
+                    );
+
+                }
+            }
+            err.emit();
+        }
+    }
+
     crate fn maybe_recover_from_bad_type_plus(
         &mut self,
         allow_plus: bool,
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 7600d6078a106..8f8473c483de5 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -7464,7 +7464,6 @@ impl<'a> Parser<'a> {
     /// Parses the part of an enum declaration following the `{`.
     fn parse_enum_def(&mut self, _generics: &ast::Generics) -> PResult<'a, EnumDef> {
         let mut variants = Vec::new();
-        let mut all_nullary = true;
         let mut any_disr = vec![];
         while self.token != token::CloseDelim(token::Brace) {
             let variant_attrs = self.parse_outer_attributes()?;
@@ -7476,11 +7475,9 @@ impl<'a> Parser<'a> {
             let ident = self.parse_ident()?;
             if self.check(&token::OpenDelim(token::Brace)) {
                 // Parse a struct variant.
-                all_nullary = false;
                 let (fields, recovered) = self.parse_record_struct_body()?;
                 struct_def = VariantData::Struct(fields, recovered);
             } else if self.check(&token::OpenDelim(token::Paren)) {
-                all_nullary = false;
                 struct_def = VariantData::Tuple(
                     self.parse_tuple_struct_body()?,
                     ast::DUMMY_NODE_ID,
@@ -7524,16 +7521,7 @@ impl<'a> Parser<'a> {
             }
         }
         self.expect(&token::CloseDelim(token::Brace))?;
-        if !any_disr.is_empty() && !all_nullary {
-            let mut err = self.struct_span_err(
-                any_disr.clone(),
-                "discriminator values can only be used with a field-less enum",
-            );
-            for sp in any_disr {
-                err.span_label(sp, "only valid in field-less enums");
-            }
-            err.emit();
-        }
+        self.maybe_report_invalid_custom_discriminants(any_disr, &variants);
 
         Ok(ast::EnumDef { variants })
     }
diff --git a/src/test/ui/parser/issue-17383.rs b/src/test/ui/parser/issue-17383.rs
index 04cd43d0b1071..f95005cd91483 100644
--- a/src/test/ui/parser/issue-17383.rs
+++ b/src/test/ui/parser/issue-17383.rs
@@ -1,6 +1,6 @@
 enum X {
     A = 3,
-    //~^ ERROR discriminator values can only be used with a field-less enum
+    //~^ ERROR custom discriminant values are not allowed in enums with fields
     B(usize)
 }
 
diff --git a/src/test/ui/parser/issue-17383.stderr b/src/test/ui/parser/issue-17383.stderr
index 57caa3372a629..37abd0ff5e1f4 100644
--- a/src/test/ui/parser/issue-17383.stderr
+++ b/src/test/ui/parser/issue-17383.stderr
@@ -1,8 +1,11 @@
-error: discriminator values can only be used with a field-less enum
+error: custom discriminant values are not allowed in enums with fields
   --> $DIR/issue-17383.rs:2:9
    |
 LL |     A = 3,
-   |         ^ only valid in field-less enums
+   |         ^ invalid custom discriminant
+LL |
+LL |     B(usize)
+   |     -------- variant with a field defined here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.rs b/src/test/ui/parser/tag-variant-disr-non-nullary.rs
index 83a3b727982b5..305edc4ad5a04 100644
--- a/src/test/ui/parser/tag-variant-disr-non-nullary.rs
+++ b/src/test/ui/parser/tag-variant-disr-non-nullary.rs
@@ -1,11 +1,12 @@
 enum Color {
     Red = 0xff0000,
-    //~^ ERROR discriminator values can only be used with a field-less enum
+    //~^ ERROR custom discriminant values are not allowed in enums with fields
     Green = 0x00ff00,
     Blue = 0x0000ff,
     Black = 0x000000,
     White = 0xffffff,
     Other(usize),
+    Other2(usize, usize),
 }
 
 fn main() {}
diff --git a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr
index 884e9672cb12d..2d3b283953124 100644
--- a/src/test/ui/parser/tag-variant-disr-non-nullary.stderr
+++ b/src/test/ui/parser/tag-variant-disr-non-nullary.stderr
@@ -1,17 +1,21 @@
-error: discriminator values can only be used with a field-less enum
+error: custom discriminant values are not allowed in enums with fields
   --> $DIR/tag-variant-disr-non-nullary.rs:2:11
    |
 LL |     Red = 0xff0000,
-   |           ^^^^^^^^ only valid in field-less enums
+   |           ^^^^^^^^ invalid custom discriminant
 LL |
 LL |     Green = 0x00ff00,
-   |             ^^^^^^^^ only valid in field-less enums
+   |             ^^^^^^^^ invalid custom discriminant
 LL |     Blue = 0x0000ff,
-   |            ^^^^^^^^ only valid in field-less enums
+   |            ^^^^^^^^ invalid custom discriminant
 LL |     Black = 0x000000,
-   |             ^^^^^^^^ only valid in field-less enums
+   |             ^^^^^^^^ invalid custom discriminant
 LL |     White = 0xffffff,
-   |             ^^^^^^^^ only valid in field-less enums
+   |             ^^^^^^^^ invalid custom discriminant
+LL |     Other(usize),
+   |     ------------ variant with a field defined here
+LL |     Other2(usize, usize),
+   |     -------------------- variant with fields defined here
 
 error: aborting due to previous error
 

From 6116f19f7baa3c1f7ed4659aa3b9b5ec5ff8ac3e Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 23 May 2019 17:58:25 +0200
Subject: [PATCH 04/35] Box::into_unique: do the reborrow-to-raw *after*
 destroying the Box

---
 src/liballoc/boxed.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 024594517d988..0e40e4f371abf 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -253,15 +253,15 @@ impl<T: ?Sized> Box<T> {
     #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")]
     #[inline]
     #[doc(hidden)]
-    pub fn into_unique(mut b: Box<T>) -> Unique<T> {
+    pub fn into_unique(b: Box<T>) -> Unique<T> {
+        let mut unique = b.0;
+        mem::forget(b);
         // Box is kind-of a library type, but recognized as a "unique pointer" by
         // Stacked Borrows.  This function here corresponds to "reborrowing to
         // a raw pointer", but there is no actual reborrow here -- so
         // without some care, the pointer we are returning here still carries
         // the `Uniq` tag.  We round-trip through a mutable reference to avoid that.
-        let unique = unsafe { b.0.as_mut() as *mut T };
-        mem::forget(b);
-        unsafe { Unique::new_unchecked(unique) }
+        unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) }
     }
 
     /// Consumes and leaks the `Box`, returning a mutable reference,

From 8d4e7fde479e018d3caf37d1d12f47710183252e Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 23 May 2019 18:13:02 +0200
Subject: [PATCH 05/35] adjust comment

---
 src/liballoc/boxed.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 0e40e4f371abf..97c2d8e7a8e79 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -260,7 +260,8 @@ impl<T: ?Sized> Box<T> {
         // Stacked Borrows.  This function here corresponds to "reborrowing to
         // a raw pointer", but there is no actual reborrow here -- so
         // without some care, the pointer we are returning here still carries
-        // the `Uniq` tag.  We round-trip through a mutable reference to avoid that.
+        // the tag of `b`, with `Unique` permission.
+        // We round-trip through a mutable reference to avoid that.
         unsafe { Unique::new_unchecked(unique.as_mut() as *mut T) }
     }
 

From 4ba144d5dd095390e10bd0000ae80c208fb2d74c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 15:06:42 +0100
Subject: [PATCH 06/35] Update associated_item_def_ids

---
 src/librustc/query/mod.rs            |  2 +-
 src/librustc/ty/mod.rs               | 29 ++++++++++++++--------------
 src/librustc_metadata/Cargo.toml     |  1 +
 src/librustc_metadata/cstore_impl.rs |  5 +++--
 4 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 8825c94cdb81c..07b5df38d7f6d 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -262,7 +262,7 @@ rustc_queries! {
 
     Other {
         /// Maps from an impl/trait `DefId to a list of the `DefId`s of its items.
-        query associated_item_def_ids(_: DefId) -> Lrc<Vec<DefId>> {}
+        query associated_item_def_ids(_: DefId) -> &'tcx [DefId] {}
 
         /// Maps from a trait item to the trait item "descriptor".
         query associated_item(_: DefId) -> ty::AssociatedItem {}
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index a2c89489b95dc..8e64fa3ac0104 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -3106,7 +3106,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
 pub struct AssociatedItemsIterator<'a, 'gcx: 'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
-    def_ids: Lrc<Vec<DefId>>,
+    def_ids: &'gcx [DefId],
     next_index: usize,
 }
 
@@ -3183,26 +3183,27 @@ fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn associated_item_def_ids<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      def_id: DefId)
-                                     -> Lrc<Vec<DefId>> {
+                                     -> &'tcx [DefId] {
     let id = tcx.hir().as_local_hir_id(def_id).unwrap();
     let item = tcx.hir().expect_item_by_hir_id(id);
-    let vec: Vec<_> = match item.node {
+    match item.node {
         hir::ItemKind::Trait(.., ref trait_item_refs) => {
-            trait_item_refs.iter()
-                           .map(|trait_item_ref| trait_item_ref.id)
-                           .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
-                           .collect()
+            tcx.arena.alloc_from_iter(
+                trait_item_refs.iter()
+                               .map(|trait_item_ref| trait_item_ref.id)
+                               .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
+            )
         }
         hir::ItemKind::Impl(.., ref impl_item_refs) => {
-            impl_item_refs.iter()
-                          .map(|impl_item_ref| impl_item_ref.id)
-                          .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
-                          .collect()
+            tcx.arena.alloc_from_iter(
+                impl_item_refs.iter()
+                              .map(|impl_item_ref| impl_item_ref.id)
+                              .map(|id| tcx.hir().local_def_id_from_hir_id(id.hir_id))
+            )
         }
-        hir::ItemKind::TraitAlias(..) => vec![],
+        hir::ItemKind::TraitAlias(..) => &[],
         _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait")
-    };
-    Lrc::new(vec)
+    }
 }
 
 fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span {
diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml
index e234f4f880703..76aba33b6a404 100644
--- a/src/librustc_metadata/Cargo.toml
+++ b/src/librustc_metadata/Cargo.toml
@@ -13,6 +13,7 @@ crate-type = ["dylib"]
 flate2 = "1.0"
 log = "0.4"
 memmap = "0.6"
+smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 rustc = { path = "../librustc" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 errors = { path = "../librustc_errors", package = "rustc_errors" }
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 49f93c4014dc0..533a1c1c3009e 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -21,6 +21,7 @@ use rustc::hir::map::definitions::DefPathTable;
 use rustc::util::nodemap::DefIdMap;
 use rustc_data_structures::svh::Svh;
 
+use smallvec::SmallVec;
 use std::any::Any;
 use rustc_data_structures::sync::Lrc;
 use std::sync::Arc;
@@ -108,10 +109,10 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     }
     variances_of => { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) }
     associated_item_def_ids => {
-        let mut result = vec![];
+        let mut result = SmallVec::<[_; 8]>::new();
         cdata.each_child_of_item(def_id.index,
           |child| result.push(child.res.def_id()), tcx.sess);
-        Lrc::new(result)
+        tcx.arena.alloc_slice(&result)
     }
     associated_item => { cdata.get_associated_item(def_id.index) }
     impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) }

From 8c936e422f0cbd5a90adf73f6b680736551bf9db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 15:19:12 +0100
Subject: [PATCH 07/35] Update inherent_impls

---
 src/librustc/arena.rs                         |  1 +
 src/librustc/query/mod.rs                     |  4 ++--
 src/librustc/ty/mod.rs                        |  2 +-
 src/librustc_metadata/cstore_impl.rs          |  2 +-
 src/librustc_metadata/decoder.rs              | 15 +++++++-----
 .../coherence/inherent_impls.rs               | 24 ++++++-------------
 6 files changed, 21 insertions(+), 27 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index b48d81f2ef8f4..a66a27d140772 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -58,6 +58,7 @@ macro_rules! arena_types {
                 rustc::infer::canonical::Canonical<'tcx,
                     rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
                 >,
+            [few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 07b5df38d7f6d..b2b555d84319c 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -277,7 +277,7 @@ rustc_queries! {
         /// Maps a `DefId` of a type to a list of its inherent impls.
         /// Contains implementations of methods that are inherent to a type.
         /// Methods in these implementations don't need to be exported.
-        query inherent_impls(_: DefId) -> Lrc<Vec<DefId>> {
+        query inherent_impls(_: DefId) -> &'tcx [DefId] {
             eval_always
         }
     }
@@ -383,7 +383,7 @@ rustc_queries! {
         /// Not meant to be used directly outside of coherence.
         /// (Defined only for `LOCAL_CRATE`.)
         query crate_inherent_impls(k: CrateNum)
-            -> Lrc<CrateInherentImpls> {
+            -> &'tcx CrateInherentImpls {
             eval_always
             desc { "all inherent impls defined in crate `{:?}`", k }
         }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 8e64fa3ac0104..535da8557ee90 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -3389,7 +3389,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
 /// (constructing this map requires touching the entire crate).
 #[derive(Clone, Debug, Default, HashStable)]
 pub struct CrateInherentImpls {
-    pub inherent_impls: DefIdMap<Lrc<Vec<DefId>>>,
+    pub inherent_impls: DefIdMap<Vec<DefId>>,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 533a1c1c3009e..d94c07ce072a5 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -135,7 +135,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         (cdata.mir_const_qualif(def_id.index), tcx.arena.alloc(BitSet::new_empty(0)))
     }
     fn_sig => { cdata.fn_sig(def_id.index, tcx) }
-    inherent_impls => { Lrc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
+    inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
     is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
     static_mutability => { cdata.static_mutability(def_id.index) }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index a89cfe42eaaf4..a2ea0fd6f553c 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1013,12 +1013,15 @@ impl<'a, 'tcx> CrateMetadata {
         None
     }
 
-    pub fn get_inherent_implementations_for_type(&self, id: DefIndex) -> Vec<DefId> {
-        self.entry(id)
-            .inherent_impls
-            .decode(self)
-            .map(|index| self.local_def_id(index))
-            .collect()
+    pub fn get_inherent_implementations_for_type(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, '_>,
+        id: DefIndex
+    ) -> &'tcx [DefId] {
+        tcx.arena.alloc_from_iter(self.entry(id)
+                                      .inherent_impls
+                                      .decode(self)
+                                      .map(|index| self.local_def_id(index)))
     }
 
     pub fn get_implementations_for_trait(&self,
diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs
index d167c7fcafbe4..644d95963e652 100644
--- a/src/librustc_typeck/coherence/inherent_impls.rs
+++ b/src/librustc_typeck/coherence/inherent_impls.rs
@@ -13,14 +13,13 @@ use rustc::hir;
 use rustc::hir::itemlikevisit::ItemLikeVisitor;
 use rustc::ty::{self, CrateInherentImpls, TyCtxt};
 
-use rustc_data_structures::sync::Lrc;
 use syntax::ast;
 use syntax_pos::Span;
 
 /// On-demand query: yields a map containing all types mapped to their inherent impls.
 pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                       crate_num: CrateNum)
-                                      -> Lrc<CrateInherentImpls> {
+                                      -> &'tcx CrateInherentImpls {
     assert_eq!(crate_num, LOCAL_CRATE);
 
     let krate = tcx.hir().krate();
@@ -29,13 +28,13 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         impls_map: Default::default(),
     };
     krate.visit_all_item_likes(&mut collect);
-    Lrc::new(collect.impls_map)
+    tcx.arena.alloc(collect.impls_map)
 }
 
 /// On-demand query: yields a vector of the inherent impls for a specific type.
 pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 ty_def_id: DefId)
-                                -> Lrc<Vec<DefId>> {
+                                -> &'tcx [DefId] {
     assert!(ty_def_id.is_local());
 
     // NB. Until we adopt the red-green dep-tracking algorithm (see
@@ -53,15 +52,11 @@ pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     //
     // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4
 
-    thread_local! {
-        static EMPTY_DEF_ID_VEC: Lrc<Vec<DefId>> = Lrc::new(vec![])
-    }
-
     let result = tcx.dep_graph.with_ignore(|| {
         let crate_map = tcx.crate_inherent_impls(ty_def_id.krate);
         match crate_map.inherent_impls.get(&ty_def_id) {
-            Some(v) => v.clone(),
-            None => EMPTY_DEF_ID_VEC.with(|v| v.clone())
+            Some(v) => &v[..],
+            None => &[],
         }
     });
 
@@ -289,13 +284,8 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> {
             // type def ID, if there is a base type for this implementation and
             // the implementation does not have any associated traits.
             let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
-            let mut rc_vec = self.impls_map.inherent_impls
-                                           .entry(def_id)
-                                           .or_default();
-
-            // At this point, there should not be any clones of the
-            // `Lrc`, so we can still safely push into it in place:
-            Lrc::get_mut(&mut rc_vec).unwrap().push(impl_def_id);
+            let vec = self.impls_map.inherent_impls.entry(def_id).or_default();
+            vec.push(impl_def_id);
         } else {
             struct_span_err!(self.tcx.sess,
                              item.span,

From 99f6221bb6d8ec9cf98f0946ed93a345b4a0e4c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 20:15:09 +0100
Subject: [PATCH 08/35] Update borrowck

---
 src/librustc/arena.rs                 | 1 +
 src/librustc/query/mod.rs             | 2 +-
 src/librustc_borrowck/borrowck/mod.rs | 7 +++----
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index a66a27d140772..de0e780b261f3 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -59,6 +59,7 @@ macro_rules! arena_types {
                     rustc::infer::canonical::QueryResponse<'tcx, rustc::ty::Ty<'tcx>>
                 >,
             [few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
+            [decode] borrowck: rustc::middle::borrowck::BorrowCheckResult,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index b2b555d84319c..3594635f41a52 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -371,7 +371,7 @@ rustc_queries! {
     }
 
     BorrowChecking {
-        query borrowck(_: DefId) -> Lrc<BorrowCheckResult> {}
+        query borrowck(_: DefId) -> &'tcx BorrowCheckResult {}
 
         /// Borrow-checks the function body. If this is a closure, returns
         /// additional requirements that the closure's creator must verify.
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 65a550b1b8914..7dca47485bb92 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -32,7 +32,6 @@ use std::borrow::Cow;
 use std::cell::{Cell, RefCell};
 use std::fmt;
 use std::rc::Rc;
-use rustc_data_structures::sync::Lrc;
 use std::hash::{Hash, Hasher};
 use syntax::source_map::CompilerDesugaringKind;
 use syntax_pos::{MultiSpan, Span};
@@ -75,7 +74,7 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
 }
 
 fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
-    -> Lrc<BorrowCheckResult>
+    -> &'tcx BorrowCheckResult
 {
     assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck());
 
@@ -89,7 +88,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
             // those things (notably the synthesized constructors from
             // tuple structs/variants) do not have an associated body
             // and do not need borrowchecking.
-            return Lrc::new(BorrowCheckResult {
+            return tcx.arena.alloc(BorrowCheckResult {
                 used_mut_nodes: Default::default(),
                 signalled_any_error: SignalledError::NoErrorsSeen,
             })
@@ -136,7 +135,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
         check_loans::check_loans(&mut bccx, &loan_dfcx, &flowed_moves, &all_loans, body);
     }
 
-    Lrc::new(BorrowCheckResult {
+    tcx.arena.alloc(BorrowCheckResult {
         used_mut_nodes: bccx.used_mut_nodes.into_inner(),
         signalled_any_error: bccx.signalled_any_error.into_inner(),
     })

From 95dfd826667f52b9b67bfa531169b1a1285bc937 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 21:05:48 +0100
Subject: [PATCH 09/35] Update upstream_monomorphizations and
 upstream_monomorphizations_for

---
 src/librustc/arena.rs                          |  7 +++++++
 src/librustc/query/mod.rs                      |  4 ++--
 src/librustc_codegen_ssa/back/symbol_export.rs | 12 ++++--------
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index de0e780b261f3..e6808e0f3bfd8 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -60,6 +60,13 @@ macro_rules! arena_types {
                 >,
             [few] crate_inherent_impls: rustc::ty::CrateInherentImpls,
             [decode] borrowck: rustc::middle::borrowck::BorrowCheckResult,
+            [few] upstream_monomorphizations:
+                rustc::util::nodemap::DefIdMap<
+                    rustc_data_structures::fx::FxHashMap<
+                        rustc::ty::subst::SubstsRef<'tcx>,
+                        rustc::hir::def_id::CrateNum
+                    >
+                >,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 3594635f41a52..2e2cb2db8382c 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -681,11 +681,11 @@ rustc_queries! {
     Codegen {
         query upstream_monomorphizations(
             k: CrateNum
-        ) -> Lrc<DefIdMap<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>>> {
+        ) -> &'tcx DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>> {
             desc { "collecting available upstream monomorphizations `{:?}`", k }
         }
         query upstream_monomorphizations_for(_: DefId)
-            -> Option<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>> {}
+            -> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {}
     }
 
     Other {
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index a55f783df43a3..616049ea112a4 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -282,7 +282,7 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 fn upstream_monomorphizations_provider<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     cnum: CrateNum)
-    -> Lrc<DefIdMap<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>>>
+    -> &'tcx DefIdMap<FxHashMap<SubstsRef<'tcx>, CrateNum>>
 {
     debug_assert!(cnum == LOCAL_CRATE);
 
@@ -326,20 +326,16 @@ fn upstream_monomorphizations_provider<'a, 'tcx>(
         }
     }
 
-    Lrc::new(instances.into_iter()
-                      .map(|(key, value)| (key, Lrc::new(value)))
-                      .collect())
+    tcx.arena.alloc(instances)
 }
 
 fn upstream_monomorphizations_for_provider<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId)
-    -> Option<Lrc<FxHashMap<SubstsRef<'tcx>, CrateNum>>>
+    -> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>>
 {
     debug_assert!(!def_id.is_local());
-    tcx.upstream_monomorphizations(LOCAL_CRATE)
-       .get(&def_id)
-       .cloned()
+    tcx.upstream_monomorphizations(LOCAL_CRATE).get(&def_id)
 }
 
 fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) -> bool {

From 093940ddc44c4c7c97fbc35a3900fdc98a245dfc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 21:23:01 +0100
Subject: [PATCH 10/35] Update implementations_of_trait and
 all_trait_implementations

---
 src/librustc/query/mod.rs            |  4 ++--
 src/librustc_metadata/cstore_impl.rs | 10 ++--------
 src/librustc_metadata/decoder.rs     | 25 ++++++++++++++-----------
 3 files changed, 18 insertions(+), 21 deletions(-)

diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 2e2cb2db8382c..d6dbd49d1739d 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -724,12 +724,12 @@ rustc_queries! {
 
     TypeChecking {
         query implementations_of_trait(_: (CrateNum, DefId))
-            -> Lrc<Vec<DefId>> {
+            -> &'tcx [DefId] {
             no_force
             desc { "looking up implementations of a trait in a crate" }
         }
         query all_trait_implementations(_: CrateNum)
-            -> Lrc<Vec<DefId>> {
+            -> &'tcx [DefId] {
             desc { "looking up all (?) trait implementations" }
         }
     }
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index d94c07ce072a5..6b06a0712e18b 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -208,18 +208,12 @@ provide! { <'tcx> tcx, def_id, other, cdata,
 
     extra_filename => { cdata.root.extra_filename.clone() }
 
-
     implementations_of_trait => {
-        let mut result = vec![];
-        let filter = Some(other);
-        cdata.get_implementations_for_trait(filter, &mut result);
-        Lrc::new(result)
+        cdata.get_implementations_for_trait(tcx, Some(other))
     }
 
     all_trait_implementations => {
-        let mut result = vec![];
-        cdata.get_implementations_for_trait(None, &mut result);
-        Lrc::new(result)
+        cdata.get_implementations_for_trait(tcx, None)
     }
 
     visibility => { cdata.get_visibility(def_id.index) }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index a2ea0fd6f553c..c4037dcfac0ad 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1024,31 +1024,34 @@ impl<'a, 'tcx> CrateMetadata {
                                       .map(|index| self.local_def_id(index)))
     }
 
-    pub fn get_implementations_for_trait(&self,
-                                         filter: Option<DefId>,
-                                         result: &mut Vec<DefId>) {
+    pub fn get_implementations_for_trait(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, '_>,
+        filter: Option<DefId>,
+    ) -> &'tcx [DefId] {
         if self.proc_macros.is_some() {
             // proc-macro crates export no trait impls.
-            return
+            return &[]
         }
 
         // Do a reverse lookup beforehand to avoid touching the crate_num
         // hash map in the loop below.
         let filter = match filter.map(|def_id| self.reverse_translate_def_id(def_id)) {
             Some(Some(def_id)) => Some((def_id.krate.as_u32(), def_id.index)),
-            Some(None) => return,
+            Some(None) => return &[],
             None => None,
         };
 
         if let Some(filter) = filter {
-            if let Some(impls) = self.trait_impls
-                                     .get(&filter) {
-                result.extend(impls.decode(self).map(|idx| self.local_def_id(idx)));
+            if let Some(impls) = self.trait_impls.get(&filter) {
+                tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx)))
+            } else {
+                &[]
             }
         } else {
-            for impls in self.trait_impls.values() {
-                result.extend(impls.decode(self).map(|idx| self.local_def_id(idx)));
-            }
+            tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| {
+                impls.decode(self).map(|idx| self.local_def_id(idx))
+            }))
         }
     }
 

From 529aed81dea8bd808a72fd7e0d06468b0dd673fe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 22:26:57 +0100
Subject: [PATCH 11/35] Update resolve_lifetimes, named_region_map,
 is_late_bound_map and object_lifetime_defaults_map

---
 src/librustc/arena.rs                   |  1 +
 src/librustc/middle/resolve_lifetime.rs | 23 +++++++++--------------
 src/librustc/query/mod.rs               |  8 ++++----
 src/librustc/ty/context.rs              |  4 ++--
 4 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index e6808e0f3bfd8..02ed30dd3865b 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -67,6 +67,7 @@ macro_rules! arena_types {
                         rustc::hir::def_id::CrateNum
                     >
                 >,
+            [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
         ], $tcx);
     )
 }
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 419cc5936862c..775da1de313fa 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -15,7 +15,6 @@ use crate::rustc::lint;
 use crate::session::Session;
 use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
 use errors::{Applicability, DiagnosticBuilder};
-use rustc_data_structures::sync::Lrc;
 use rustc_macros::HashStable;
 use std::borrow::Cow;
 use std::cell::Cell;
@@ -211,10 +210,10 @@ struct NamedRegionMap {
 /// See [`NamedRegionMap`].
 #[derive(Default)]
 pub struct ResolveLifetimes {
-    defs: FxHashMap<LocalDefId, Lrc<FxHashMap<ItemLocalId, Region>>>,
-    late_bound: FxHashMap<LocalDefId, Lrc<FxHashSet<ItemLocalId>>>,
+    defs: FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Region>>,
+    late_bound: FxHashMap<LocalDefId, FxHashSet<ItemLocalId>>,
     object_lifetime_defaults:
-        FxHashMap<LocalDefId, Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>>,
+        FxHashMap<LocalDefId, FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>>,
 }
 
 impl_stable_hash_for!(struct crate::middle::resolve_lifetime::ResolveLifetimes {
@@ -347,7 +346,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
 
         named_region_map: |tcx, id| {
             let id = LocalDefId::from_def_id(DefId::local(id)); // (*)
-            tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id).cloned()
+            tcx.resolve_lifetimes(LOCAL_CRATE).defs.get(&id)
         },
 
         is_late_bound_map: |tcx, id| {
@@ -355,7 +354,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
             tcx.resolve_lifetimes(LOCAL_CRATE)
                 .late_bound
                 .get(&id)
-                .cloned()
         },
 
         object_lifetime_defaults_map: |tcx, id| {
@@ -363,7 +361,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
             tcx.resolve_lifetimes(LOCAL_CRATE)
                 .object_lifetime_defaults
                 .get(&id)
-                .cloned()
         },
 
         ..*providers
@@ -379,7 +376,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
 fn resolve_lifetimes<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     for_krate: CrateNum,
-) -> Lrc<ResolveLifetimes> {
+) -> &'tcx ResolveLifetimes {
     assert_eq!(for_krate, LOCAL_CRATE);
 
     let named_region_map = krate(tcx);
@@ -388,24 +385,22 @@ fn resolve_lifetimes<'tcx>(
 
     for (hir_id, v) in named_region_map.defs {
         let map = rl.defs.entry(hir_id.owner_local_def_id()).or_default();
-        Lrc::get_mut(map).unwrap().insert(hir_id.local_id, v);
+        map.insert(hir_id.local_id, v);
     }
     for hir_id in named_region_map.late_bound {
         let map = rl.late_bound
             .entry(hir_id.owner_local_def_id())
             .or_default();
-        Lrc::get_mut(map).unwrap().insert(hir_id.local_id);
+        map.insert(hir_id.local_id);
     }
     for (hir_id, v) in named_region_map.object_lifetime_defaults {
         let map = rl.object_lifetime_defaults
             .entry(hir_id.owner_local_def_id())
             .or_default();
-        Lrc::get_mut(map)
-            .unwrap()
-            .insert(hir_id.local_id, Lrc::new(v));
+        map.insert(hir_id.local_id, v);
     }
 
-    Lrc::new(rl)
+    tcx.arena.alloc(rl)
 }
 
 fn krate<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) -> NamedRegionMap {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index d6dbd49d1739d..8920952f00d92 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -754,19 +754,19 @@ rustc_queries! {
 
     BorrowChecking {
         // Lifetime resolution. See `middle::resolve_lifetimes`.
-        query resolve_lifetimes(_: CrateNum) -> Lrc<ResolveLifetimes> {
+        query resolve_lifetimes(_: CrateNum) -> &'tcx ResolveLifetimes {
             desc { "resolving lifetimes" }
         }
         query named_region_map(_: DefIndex) ->
-            Option<Lrc<FxHashMap<ItemLocalId, Region>>> {
+            Option<&'tcx FxHashMap<ItemLocalId, Region>> {
             desc { "looking up a named region" }
         }
         query is_late_bound_map(_: DefIndex) ->
-            Option<Lrc<FxHashSet<ItemLocalId>>> {
+            Option<&'tcx FxHashSet<ItemLocalId>> {
             desc { "testing if a region is late bound" }
         }
         query object_lifetime_defaults_map(_: DefIndex)
-            -> Option<Lrc<FxHashMap<ItemLocalId, Lrc<Vec<ObjectLifetimeDefault>>>>> {
+            -> Option<&'tcx FxHashMap<ItemLocalId, Vec<ObjectLifetimeDefault>>> {
             desc { "looking up lifetime defaults for a region" }
         }
     }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index b5a17684c0ff2..e7826b7a55907 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2982,10 +2982,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn object_lifetime_defaults(self, id: HirId)
-        -> Option<Lrc<Vec<ObjectLifetimeDefault>>>
+        -> Option<&'gcx [ObjectLifetimeDefault]>
     {
         self.object_lifetime_defaults_map(id.owner)
-            .and_then(|map| map.get(&id.local_id).cloned())
+            .and_then(|map| map.get(&id.local_id).map(|v| &**v))
     }
 }
 

From b1398a0de67ce647f490c04a69cab0f76c649f9e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 22:32:16 +0100
Subject: [PATCH 12/35] Update item_children

---
 src/librustc/query/mod.rs            | 2 +-
 src/librustc_metadata/cstore_impl.rs | 4 ++--
 src/librustdoc/clean/mod.rs          | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 8920952f00d92..4514121da9109 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -784,7 +784,7 @@ rustc_queries! {
             eval_always
             desc { "fetching what a crate is named" }
         }
-        query item_children(_: DefId) -> Lrc<Vec<Export<hir::HirId>>> {}
+        query item_children(_: DefId) -> &'tcx [Export<hir::HirId>] {}
         query extern_mod_stmt_cnum(_: DefId) -> Option<CrateNum> {}
 
         query get_lib_features(_: CrateNum) -> Lrc<LibFeatures> {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 6b06a0712e18b..aea2c816b6a9d 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -223,9 +223,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     }
     crate_name => { cdata.name }
     item_children => {
-        let mut result = vec![];
+        let mut result = SmallVec::<[_; 8]>::new();
         cdata.each_child_of_item(def_id.index, |child| result.push(child), tcx.sess);
-        Lrc::new(result)
+        tcx.arena.alloc_slice(&result)
     }
     defined_lib_features => { Lrc::new(cdata.get_lib_features()) }
     defined_lang_items => { Lrc::new(cdata.get_lang_items()) }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 1bbbe581c3ce1..9d4b55526d004 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -4434,7 +4434,7 @@ pub fn path_to_def(tcx: TyCtxt<'_, '_, '_>, path: &[Symbol]) -> Option<DefId> {
         loop {
             let segment = path_it.next()?;
 
-            for item in mem::replace(&mut items, Lrc::new(vec![])).iter() {
+            for item in mem::replace(&mut items, &[]).iter() {
                 if item.ident.name == *segment {
                     if path_it.peek().is_none() {
                         return match item.res {

From 28482db2479b24caef8f738a5973d2e410ed13bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 20:02:56 +0100
Subject: [PATCH 13/35] Update used_trait_imports

---
 src/librustc/arena.rs            | 2 +-
 src/librustc/query/mod.rs        | 2 +-
 src/librustc_typeck/check/mod.rs | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 02ed30dd3865b..a9b7aa4c10d40 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -14,7 +14,7 @@ macro_rules! arena_types {
                 rustc::hir::def_id::DefId,
                 rustc::ty::subst::SubstsRef<$tcx>
             )>,
-            [few] mir_keys: rustc::util::nodemap::DefIdSet,
+            [few, decode] mir_keys: rustc::util::nodemap::DefIdSet,
             [decode] specialization_graph: rustc::traits::specialization_graph::Graph,
             [] region_scope_tree: rustc::middle::region::ScopeTree,
             [] item_local_set: rustc::util::nodemap::ItemLocalSet,
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 4514121da9109..44a0cf550794e 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -359,7 +359,7 @@ rustc_queries! {
     }
 
     Other {
-        query used_trait_imports(_: DefId) -> Lrc<DefIdSet> {}
+        query used_trait_imports(_: DefId) -> &'tcx DefIdSet {}
     }
 
     TypeChecking {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a20a91b3e6f6d..6ff4fe9eff149 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -808,8 +808,8 @@ fn has_typeck_tables<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 fn used_trait_imports<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 def_id: DefId)
-                                -> Lrc<DefIdSet> {
-    tcx.typeck_tables_of(def_id).used_trait_imports.clone()
+                                -> &'tcx DefIdSet {
+    &*tcx.typeck_tables_of(def_id).used_trait_imports
 }
 
 fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

From ba5d9c094daf8d78178058e7a3498b66d47db950 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Wed, 24 Apr 2019 01:45:50 +0200
Subject: [PATCH 14/35] Optimize alloc_from_iter

---
 src/libarena/lib.rs | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index ce5e5f23a94b8..d6bec816e4ee6 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -486,9 +486,31 @@ impl DroplessArena {
         }
     }
 
+    #[inline]
+    unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
+        &self,
+        mut iter: I,
+        len: usize,
+        mem: *mut T,
+    ) -> &mut [T] {
+        let mut i = 0;
+        // Use a manual loop since LLVM manages to optimize it better for
+        // slice iterators
+        loop {
+            let value = iter.next();
+            if i >= len || value.is_none() {
+                // We only return as many items as the iterator gave us, even
+                // though it was supposed to give us `len`
+                return slice::from_raw_parts_mut(mem, i);
+            }
+            ptr::write(mem.offset(i as isize), value.unwrap());
+            i += 1;
+        }
+    }
+
     #[inline]
     pub fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] {
-        let mut iter = iter.into_iter();
+        let iter = iter.into_iter();
         assert!(mem::size_of::<T>() != 0);
         assert!(!mem::needs_drop::<T>());
 
@@ -505,10 +527,7 @@ impl DroplessArena {
                 let size = len.checked_mul(mem::size_of::<T>()).unwrap();
                 let mem = self.alloc_raw(size, mem::align_of::<T>()) as *mut _ as *mut T;
                 unsafe {
-                    for i in 0..len {
-                        ptr::write(mem.offset(i as isize), iter.next().unwrap())
-                    }
-                    slice::from_raw_parts_mut(mem, len)
+                    self.write_from_iter(iter, len, mem)
                 }
             }
             (_, _) => {

From ae8975c812c5f31102f1f840322e10696b369aa7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 18:13:27 +0100
Subject: [PATCH 15/35] Update GenericPredicates queries

---
 src/librustc/arena.rs                |  1 +
 src/librustc/query/mod.rs            | 10 ++---
 src/librustc/ty/context.rs           | 14 +++++++
 src/librustc/ty/mod.rs               |  2 +-
 src/librustc_metadata/cstore_impl.rs |  8 ++--
 src/librustc_privacy/lib.rs          |  6 +--
 src/librustc_typeck/astconv.rs       |  3 +-
 src/librustc_typeck/check/mod.rs     |  5 +--
 src/librustc_typeck/collect.rs       | 61 ++++++++++++----------------
 src/librustdoc/clean/auto_trait.rs   |  6 ++-
 src/librustdoc/clean/mod.rs          |  3 +-
 11 files changed, 64 insertions(+), 55 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index a9b7aa4c10d40..06e82f0ae9cb9 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -68,6 +68,7 @@ macro_rules! arena_types {
                     >
                 >,
             [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
+            [decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 44a0cf550794e..1b9c8e864d65c 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -61,7 +61,7 @@ rustc_queries! {
         /// predicate gets in the way of some checks, which are intended
         /// to operate over only the actual where-clauses written by the
         /// user.)
-        query predicates_of(_: DefId) -> Lrc<ty::GenericPredicates<'tcx>> {}
+        query predicates_of(_: DefId) -> &'tcx ty::GenericPredicates<'tcx> {}
 
         query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLibrary>> {
             desc { "looking up the native libraries of a linked crate" }
@@ -166,11 +166,11 @@ rustc_queries! {
         /// equal to the `explicit_predicates_of` predicates plus the
         /// `inferred_outlives_of` predicates.
         query predicates_defined_on(_: DefId)
-            -> Lrc<ty::GenericPredicates<'tcx>> {}
+            -> &'tcx ty::GenericPredicates<'tcx> {}
 
         /// Returns the predicates written explicitly by the user.
         query explicit_predicates_of(_: DefId)
-            -> Lrc<ty::GenericPredicates<'tcx>> {}
+            -> &'tcx ty::GenericPredicates<'tcx> {}
 
         /// Returns the inferred outlives predicates (e.g., for `struct
         /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`).
@@ -182,14 +182,14 @@ rustc_queries! {
         /// evaluate them even during type conversion, often before the
         /// full predicates are available (note that supertraits have
         /// additional acyclicity requirements).
-        query super_predicates_of(key: DefId) -> Lrc<ty::GenericPredicates<'tcx>> {
+        query super_predicates_of(key: DefId) -> &'tcx ty::GenericPredicates<'tcx> {
             desc { |tcx| "computing the supertraits of `{}`", tcx.def_path_str(key) }
         }
 
         /// To avoid cycles within the predicates of a single item we compute
         /// per-type-parameter predicates for resolving `T::AssocTy`.
         query type_param_predicates(key: (DefId, DefId))
-            -> Lrc<ty::GenericPredicates<'tcx>> {
+            -> &'tcx ty::GenericPredicates<'tcx> {
             no_force
             desc { |tcx| "computing the bounds for type parameter `{}`", {
                 let id = tcx.hir().as_local_hir_id(key.1).unwrap();
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index e7826b7a55907..d8d1170fc3a20 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -201,6 +201,10 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
     }
 }
 
+pub struct Common<'tcx> {
+    pub empty_predicates: ty::GenericPredicates<'tcx>,
+}
+
 pub struct CommonTypes<'tcx> {
     pub unit: Ty<'tcx>,
     pub bool: Ty<'tcx>,
@@ -1045,6 +1049,9 @@ pub struct GlobalCtxt<'tcx> {
 
     pub dep_graph: DepGraph,
 
+    /// Common objects.
+    pub common: Common<'tcx>,
+
     /// Common types, pre-interned for your convenience.
     pub types: CommonTypes<'tcx>,
 
@@ -1252,6 +1259,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             s.fatal(&err);
         });
         let interners = CtxtInterners::new(&arenas.interner);
+        let common = Common {
+            empty_predicates: ty::GenericPredicates {
+                parent: None,
+                predicates: vec![],
+            },
+        };
         let common_types = CommonTypes::new(&interners);
         let common_lifetimes = CommonLifetimes::new(&interners);
         let common_consts = CommonConsts::new(&interners, &common_types);
@@ -1308,6 +1321,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             global_arenas: &arenas.global,
             global_interners: interners,
             dep_graph,
+            common,
             types: common_types,
             lifetimes: common_lifetimes,
             consts: common_consts,
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 535da8557ee90..99c3293168754 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -2298,7 +2298,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
     }
 
     #[inline]
-    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Lrc<GenericPredicates<'gcx>> {
+    pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx GenericPredicates<'gcx> {
         tcx.predicates_of(self.did)
     }
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index aea2c816b6a9d..7ca1343a4873b 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -96,9 +96,11 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     generics_of => {
         tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess))
     }
-    predicates_of => { Lrc::new(cdata.get_predicates(def_id.index, tcx)) }
-    predicates_defined_on => { Lrc::new(cdata.get_predicates_defined_on(def_id.index, tcx)) }
-    super_predicates_of => { Lrc::new(cdata.get_super_predicates(def_id.index, tcx)) }
+    predicates_of => { tcx.arena.alloc(cdata.get_predicates(def_id.index, tcx)) }
+    predicates_defined_on => {
+        tcx.arena.alloc(cdata.get_predicates_defined_on(def_id.index, tcx))
+    }
+    super_predicates_of => { tcx.arena.alloc(cdata.get_super_predicates(def_id.index, tcx)) }
     trait_def => {
         tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess))
     }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 1df42a9504275..4fd6dd00cee4c 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -67,7 +67,7 @@ trait DefIdVisitor<'a, 'tcx: 'a> {
     fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> bool {
         self.skeleton().visit_trait(trait_ref)
     }
-    fn visit_predicates(&mut self, predicates: Lrc<ty::GenericPredicates<'tcx>>) -> bool {
+    fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool {
         self.skeleton().visit_predicates(predicates)
     }
 }
@@ -89,8 +89,8 @@ impl<'a, 'tcx, V> DefIdVisitorSkeleton<'_, 'a, 'tcx, V>
         (!self.def_id_visitor.shallow() && substs.visit_with(self))
     }
 
-    fn visit_predicates(&mut self, predicates: Lrc<ty::GenericPredicates<'tcx>>) -> bool {
-        let ty::GenericPredicates { parent: _, predicates } = &*predicates;
+    fn visit_predicates(&mut self, predicates: &ty::GenericPredicates<'tcx>) -> bool {
+        let ty::GenericPredicates { parent: _, predicates } = predicates;
         for (predicate, _span) in predicates {
             match predicate {
                 ty::Predicate::Trait(poly_predicate) => {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 4110a55840196..3a2b0178ce4d0 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -17,7 +17,6 @@ use rustc::ty::{GenericParamDef, GenericParamDefKind};
 use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
 use rustc::ty::wf::object_region_bounds;
 use rustc::mir::interpret::ConstValue;
-use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi;
 use crate::require_c_abi_if_c_variadic;
 use smallvec::SmallVec;
@@ -46,7 +45,7 @@ pub trait AstConv<'gcx, 'tcx> {
     /// Returns the set of bounds in scope for the type parameter with
     /// the given id.
     fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
-                                 -> Lrc<ty::GenericPredicates<'tcx>>;
+                                 -> &'tcx ty::GenericPredicates<'tcx>;
 
     /// What lifetime should we use when a lifetime is omitted (and not elided)?
     fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>)
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 6ff4fe9eff149..655bf5722ae5a 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -97,7 +97,6 @@ use crate::namespace::Namespace;
 use rustc::infer::{self, InferCtxt, InferOk, InferResult};
 use rustc::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc_data_structures::indexed_vec::Idx;
-use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi::Abi;
 use rustc::infer::opaque_types::OpaqueTypeDecl;
 use rustc::infer::type_variable::{TypeVariableOrigin};
@@ -1907,7 +1906,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx }
 
     fn get_type_parameter_bounds(&self, _: Span, def_id: DefId)
-                                 -> Lrc<ty::GenericPredicates<'tcx>>
+                                 -> &'tcx ty::GenericPredicates<'tcx>
     {
         let tcx = self.tcx;
         let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -1915,7 +1914,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
         let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
         let generics = tcx.generics_of(item_def_id);
         let index = generics.param_def_id_to_index[&def_id];
-        Lrc::new(ty::GenericPredicates {
+        tcx.arena.alloc(ty::GenericPredicates {
             parent: None,
             predicates: self.param_env.caller_bounds.iter().filter_map(|&predicate| {
                 match predicate {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 2a4d8f304b592..45380d757b97d 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -31,7 +31,6 @@ use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt};
 use rustc::ty::{ReprOptions, ToPredicate};
 use rustc::util::captures::Captures;
 use rustc::util::nodemap::FxHashMap;
-use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi;
 
 use syntax::ast;
@@ -178,7 +177,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
     }
 
     fn get_type_parameter_bounds(&self, span: Span, def_id: DefId)
-                                 -> Lrc<ty::GenericPredicates<'tcx>> {
+                                 -> &'tcx ty::GenericPredicates<'tcx> {
         self.tcx
             .at(span)
             .type_param_predicates((self.item_def_id, def_id))
@@ -243,7 +242,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
 fn type_param_predicates<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     (item_def_id, def_id): (DefId, DefId),
-) -> Lrc<ty::GenericPredicates<'tcx>> {
+) -> &'tcx ty::GenericPredicates<'tcx> {
     use rustc::hir::*;
 
     // In the AST, bounds can derive from two places. Either
@@ -264,16 +263,11 @@ fn type_param_predicates<'a, 'tcx>(
         tcx.generics_of(item_def_id).parent
     };
 
-    let mut result = parent.map_or_else(
-        || Lrc::new(ty::GenericPredicates {
-            parent: None,
-            predicates: vec![],
-        }),
-        |parent| {
-            let icx = ItemCtxt::new(tcx, parent);
-            icx.get_type_parameter_bounds(DUMMY_SP, def_id)
-        },
-    );
+    let result = parent.map_or(&tcx.common.empty_predicates, |parent| {
+        let icx = ItemCtxt::new(tcx, parent);
+        icx.get_type_parameter_bounds(DUMMY_SP, def_id)
+    });
+    let mut extend = None;
 
     let item_hir_id = tcx.hir().as_local_hir_id(item_def_id).unwrap();
     let ast_generics = match tcx.hir().get_by_hir_id(item_hir_id) {
@@ -298,9 +292,7 @@ fn type_param_predicates<'a, 'tcx>(
                     // Implied `Self: Trait` and supertrait bounds.
                     if param_id == item_hir_id {
                         let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id);
-                        Lrc::make_mut(&mut result)
-                            .predicates
-                            .push((identity_trait_ref.to_predicate(), item.span));
+                        extend = Some((identity_trait_ref.to_predicate(), item.span));
                     }
                     generics
                 }
@@ -317,11 +309,12 @@ fn type_param_predicates<'a, 'tcx>(
     };
 
     let icx = ItemCtxt::new(tcx, item_def_id);
-    Lrc::make_mut(&mut result)
-        .predicates
-        .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty,
-            OnlySelfBounds(true)));
-    result
+    let mut result = (*result).clone();
+    result.predicates.extend(extend.into_iter());
+    result.predicates
+          .extend(icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty,
+                  OnlySelfBounds(true)));
+    tcx.arena.alloc(result)
 }
 
 impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
@@ -690,7 +683,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
 fn super_predicates_of<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     trait_def_id: DefId,
-) -> Lrc<ty::GenericPredicates<'tcx>> {
+) -> &'tcx ty::GenericPredicates<'tcx> {
     debug!("super_predicates(trait_def_id={:?})", trait_def_id);
     let trait_hir_id = tcx.hir().as_local_hir_id(trait_def_id).unwrap();
 
@@ -734,7 +727,7 @@ fn super_predicates_of<'a, 'tcx>(
         }
     }
 
-    Lrc::new(ty::GenericPredicates {
+    tcx.arena.alloc(ty::GenericPredicates {
         parent: None,
         predicates: superbounds,
     })
@@ -1842,7 +1835,7 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx>(
 fn predicates_defined_on<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
-) -> Lrc<ty::GenericPredicates<'tcx>> {
+) -> &'tcx ty::GenericPredicates<'tcx> {
     debug!("predicates_defined_on({:?})", def_id);
     let mut result = tcx.explicit_predicates_of(def_id);
     debug!(
@@ -1858,9 +1851,9 @@ fn predicates_defined_on<'a, 'tcx>(
             def_id,
             inferred_outlives,
         );
-        Lrc::make_mut(&mut result)
-            .predicates
-            .extend(inferred_outlives.iter().map(|&p| (p, span)));
+        let mut predicates = (*result).clone();
+        predicates.predicates.extend(inferred_outlives.iter().map(|&p| (p, span)));
+        result = tcx.arena.alloc(predicates);
     }
     debug!("predicates_defined_on({:?}) = {:?}", def_id, result);
     result
@@ -1872,7 +1865,7 @@ fn predicates_defined_on<'a, 'tcx>(
 fn predicates_of<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
-) -> Lrc<ty::GenericPredicates<'tcx>> {
+) -> &'tcx ty::GenericPredicates<'tcx> {
     let mut result = tcx.predicates_defined_on(def_id);
 
     if tcx.is_trait(def_id) {
@@ -1889,9 +1882,9 @@ fn predicates_of<'a, 'tcx>(
         // used, and adding the predicate into this list ensures
         // that this is done.
         let span = tcx.def_span(def_id);
-        Lrc::make_mut(&mut result)
-            .predicates
-            .push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span));
+        let mut predicates = (*result).clone();
+        predicates.predicates.push((ty::TraitRef::identity(tcx, def_id).to_predicate(), span));
+        result = tcx.arena.alloc(predicates);
     }
     debug!("predicates_of(def_id={:?}) = {:?}", def_id, result);
     result
@@ -1902,7 +1895,7 @@ fn predicates_of<'a, 'tcx>(
 fn explicit_predicates_of<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     def_id: DefId,
-) -> Lrc<ty::GenericPredicates<'tcx>> {
+) -> &'tcx ty::GenericPredicates<'tcx> {
     use rustc::hir::*;
     use rustc_data_structures::fx::FxHashSet;
 
@@ -2017,7 +2010,7 @@ fn explicit_predicates_of<'a, 'tcx>(
 
                     if impl_trait_fn.is_some() {
                         // impl Trait
-                        return Lrc::new(ty::GenericPredicates {
+                        return tcx.arena.alloc(ty::GenericPredicates {
                             parent: None,
                             predicates: bounds.predicates(tcx, opaque_ty),
                         });
@@ -2228,7 +2221,7 @@ fn explicit_predicates_of<'a, 'tcx>(
         );
     }
 
-    let result = Lrc::new(ty::GenericPredicates {
+    let result = tcx.arena.alloc(ty::GenericPredicates {
         parent: generics.parent,
         predicates,
     });
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 11e8192521d79..8e2460a14b87a 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -104,8 +104,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     // Instead, we generate `impl !Send for Foo<T>`, which better
                     // expresses the fact that `Foo<T>` never implements `Send`,
                     // regardless of the choice of `T`.
-                    let params = (self.cx.tcx.generics_of(param_env_def_id), &Default::default())
-                        .clean(self.cx).params;
+                    let params = (
+                        self.cx.tcx.generics_of(param_env_def_id),
+                        &&self.cx.tcx.common.empty_predicates,
+                    ).clean(self.cx).params;
 
                     Generics {
                         params,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 9d4b55526d004..9c3f522d8470f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -10,7 +10,6 @@ mod auto_trait;
 mod blanket_impl;
 
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use rustc_data_structures::sync::Lrc;
 use rustc_target::spec::abi::Abi;
 use rustc_typeck::hir_ty_to_ty;
 use rustc::infer::region_constraints::{RegionConstraintData, Constraint};
@@ -1687,7 +1686,7 @@ impl Clean<Generics> for hir::Generics {
 }
 
 impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
-                                    &'a Lrc<ty::GenericPredicates<'tcx>>) {
+                                    &'a &'tcx ty::GenericPredicates<'tcx>) {
     fn clean(&self, cx: &DocContext<'_>) -> Generics {
         use self::WherePredicate as WP;
 

From e77096b08ccb276a938fafa7eadb87f9dac309d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 5 Apr 2019 13:22:13 +0200
Subject: [PATCH 16/35] Remove subtle Default impl for Value

---
 src/librustc/ty/query/values.rs               |  6 -----
 .../incremental/cyclic-trait-hierarchy.rs     |  1 -
 .../cycle-projection-based-on-where-clause.rs |  1 -
 ...le-projection-based-on-where-clause.stderr | 11 ++-------
 src/test/ui/issues/issue-20772.rs             |  1 -
 src/test/ui/issues/issue-20772.stderr         | 13 ++--------
 src/test/ui/issues/issue-21177.rs             |  1 -
 src/test/ui/issues/issue-21177.stderr         | 11 ++-------
 src/test/ui/issues/issue-23302-3.rs           |  1 -
 src/test/ui/issues/issue-23302-3.stderr       | 24 +++----------------
 10 files changed, 9 insertions(+), 61 deletions(-)

diff --git a/src/librustc/ty/query/values.rs b/src/librustc/ty/query/values.rs
index 2fb318a47befd..01d431b0ef0e7 100644
--- a/src/librustc/ty/query/values.rs
+++ b/src/librustc/ty/query/values.rs
@@ -14,12 +14,6 @@ impl<'tcx, T> Value<'tcx> for T {
     }
 }
 
-impl<'tcx, T: Default> Value<'tcx> for T {
-    default fn from_cycle_error<'a>(_: TyCtxt<'a, 'tcx, 'tcx>) -> T {
-        T::default()
-    }
-}
-
 impl<'tcx> Value<'tcx> for Ty<'tcx> {
     fn from_cycle_error<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
         tcx.types.err
diff --git a/src/test/incremental/cyclic-trait-hierarchy.rs b/src/test/incremental/cyclic-trait-hierarchy.rs
index 4102eb32580f0..27287d06d54b1 100644
--- a/src/test/incremental/cyclic-trait-hierarchy.rs
+++ b/src/test/incremental/cyclic-trait-hierarchy.rs
@@ -7,7 +7,6 @@ pub trait T2 { }
 #[cfg(cfail2)]
 pub trait T2: T1 { }
 //[cfail2]~^ ERROR cycle detected when computing the supertraits of `T2`
-//[cfail2]~| ERROR cycle detected when computing the supertraits of `T2`
 
 pub trait T1: T2 { }
 
diff --git a/src/test/ui/cycle-projection-based-on-where-clause.rs b/src/test/ui/cycle-projection-based-on-where-clause.rs
index 336b67852cd01..d3609acfdff63 100644
--- a/src/test/ui/cycle-projection-based-on-where-clause.rs
+++ b/src/test/ui/cycle-projection-based-on-where-clause.rs
@@ -16,7 +16,6 @@ struct A<T>
     where T : Trait,
           T : Add<T::Item>
     //~^ ERROR cycle detected
-    //~| ERROR associated type `Item` not found for `T`
 {
     data: T
 }
diff --git a/src/test/ui/cycle-projection-based-on-where-clause.stderr b/src/test/ui/cycle-projection-based-on-where-clause.stderr
index e5a5e2897cd0a..59815138e2e36 100644
--- a/src/test/ui/cycle-projection-based-on-where-clause.stderr
+++ b/src/test/ui/cycle-projection-based-on-where-clause.stderr
@@ -11,13 +11,6 @@ note: cycle used when processing `A`
 LL |           T : Add<T::Item>
    |                   ^^^^^^^
 
-error[E0220]: associated type `Item` not found for `T`
-  --> $DIR/cycle-projection-based-on-where-clause.rs:17:19
-   |
-LL |           T : Add<T::Item>
-   |                   ^^^^^^^ associated type `Item` not found
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0220, E0391.
-For more information about an error, try `rustc --explain E0220`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/issues/issue-20772.rs b/src/test/ui/issues/issue-20772.rs
index 36551e7014f10..1500bc831528a 100644
--- a/src/test/ui/issues/issue-20772.rs
+++ b/src/test/ui/issues/issue-20772.rs
@@ -1,6 +1,5 @@
 trait T : Iterator<Item=Self::Item>
 //~^ ERROR cycle detected
-//~| ERROR associated type `Item` not found for `Self`
 {}
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-20772.stderr b/src/test/ui/issues/issue-20772.stderr
index 3b5dd975ce9e9..d64636310a368 100644
--- a/src/test/ui/issues/issue-20772.stderr
+++ b/src/test/ui/issues/issue-20772.stderr
@@ -3,7 +3,6 @@ error[E0391]: cycle detected when computing the supertraits of `T`
    |
 LL | / trait T : Iterator<Item=Self::Item>
 LL | |
-LL | |
 LL | | {}
    | |__^
    |
@@ -13,17 +12,9 @@ note: cycle used when collecting item types in top-level module
    |
 LL | / trait T : Iterator<Item=Self::Item>
 LL | |
-LL | |
 LL | | {}
    | |__^
 
-error[E0220]: associated type `Item` not found for `Self`
-  --> $DIR/issue-20772.rs:1:25
-   |
-LL | trait T : Iterator<Item=Self::Item>
-   |                         ^^^^^^^^^^ associated type `Item` not found
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0220, E0391.
-For more information about an error, try `rustc --explain E0220`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/issues/issue-21177.rs b/src/test/ui/issues/issue-21177.rs
index 9d153696b885e..258e362d1317c 100644
--- a/src/test/ui/issues/issue-21177.rs
+++ b/src/test/ui/issues/issue-21177.rs
@@ -5,6 +5,5 @@ trait Trait {
 
 fn foo<T: Trait<A = T::B>>() { }
 //~^ ERROR cycle detected
-//~| ERROR associated type `B` not found for `T`
 
 fn main() { }
diff --git a/src/test/ui/issues/issue-21177.stderr b/src/test/ui/issues/issue-21177.stderr
index 6841fe85dd792..00d9a3c46a723 100644
--- a/src/test/ui/issues/issue-21177.stderr
+++ b/src/test/ui/issues/issue-21177.stderr
@@ -11,13 +11,6 @@ note: cycle used when processing `foo`
 LL | fn foo<T: Trait<A = T::B>>() { }
    |                     ^^^^
 
-error[E0220]: associated type `B` not found for `T`
-  --> $DIR/issue-21177.rs:6:21
-   |
-LL | fn foo<T: Trait<A = T::B>>() { }
-   |                     ^^^^ associated type `B` not found
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0220, E0391.
-For more information about an error, try `rustc --explain E0220`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/issues/issue-23302-3.rs b/src/test/ui/issues/issue-23302-3.rs
index e17c5eea2a445..da75f33079886 100644
--- a/src/test/ui/issues/issue-23302-3.rs
+++ b/src/test/ui/issues/issue-23302-3.rs
@@ -1,5 +1,4 @@
 const A: i32 = B; //~ ERROR cycle detected
-//~^ ERROR cycle detected
 
 const B: i32 = A;
 
diff --git a/src/test/ui/issues/issue-23302-3.stderr b/src/test/ui/issues/issue-23302-3.stderr
index 94624640809b7..a7d643987f710 100644
--- a/src/test/ui/issues/issue-23302-3.stderr
+++ b/src/test/ui/issues/issue-23302-3.stderr
@@ -10,36 +10,18 @@ note: ...which requires checking which parts of `A` are promotable to static...
 LL | const A: i32 = B;
    |                ^
 note: ...which requires const checking if rvalue is promotable to static `B`...
-  --> $DIR/issue-23302-3.rs:4:1
+  --> $DIR/issue-23302-3.rs:3:1
    |
 LL | const B: i32 = A;
    | ^^^^^^^^^^^^^^^^^
 note: ...which requires checking which parts of `B` are promotable to static...
-  --> $DIR/issue-23302-3.rs:4:16
+  --> $DIR/issue-23302-3.rs:3:16
    |
 LL | const B: i32 = A;
    |                ^
    = note: ...which again requires const checking if rvalue is promotable to static `A`, completing the cycle
    = note: cycle used when running analysis passes on this crate
 
-error[E0391]: cycle detected when processing `A`
-  --> $DIR/issue-23302-3.rs:1:16
-   |
-LL | const A: i32 = B;
-   |                ^
-   |
-note: ...which requires processing `B`...
-  --> $DIR/issue-23302-3.rs:4:16
-   |
-LL | const B: i32 = A;
-   |                ^
-   = note: ...which again requires processing `A`, completing the cycle
-note: cycle used when processing `A`
-  --> $DIR/issue-23302-3.rs:1:1
-   |
-LL | const A: i32 = B;
-   | ^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0391`.

From 42145659fde86af0e9563c92949cf8f39db3f505 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sun, 19 May 2019 17:27:28 +0200
Subject: [PATCH 17/35] Add a comment for arena_types!

---
 src/librustc/arena.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 06e82f0ae9cb9..51588953a2fbb 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -6,6 +6,15 @@ use std::cell::RefCell;
 use std::marker::PhantomData;
 use smallvec::SmallVec;
 
+/// This declares a list of types which can be allocated by `Arena`.
+///
+/// The `few` modifier will cause allocation to use the shared arena and recording the destructor.
+/// This is faster and more memory efficient if there's only a few allocations of the type.
+/// Leaving `few` out will cause the type to get its own dedicated `TypedArena` which is
+/// faster and more memory efficient if there is lots of allocations.
+///
+/// Specifying the `decode` modifier will add decode impls for &T and &[T] where T is the type
+/// listed. These impls will appear in the implement_ty_decoder! macro.
 #[macro_export]
 macro_rules! arena_types {
     ($macro:path, $args:tt, $tcx:lifetime) => (

From ad2b35bb31400f61a3ce2cee5fc9f8b43dda1065 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sun, 19 May 2019 18:02:08 +0200
Subject: [PATCH 18/35] Make ArenaField private

---
 src/librustc/arena.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 51588953a2fbb..d2797e652407b 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -139,7 +139,7 @@ pub trait ArenaAllocatable {}
 
 impl<T: Copy> ArenaAllocatable for T {}
 
-pub unsafe trait ArenaField<'tcx>: Sized {
+unsafe trait ArenaField<'tcx>: Sized {
     /// Returns a specific arena to allocate from.
     /// If None is returned, the DropArena will be used.
     fn arena<'a>(arena: &'a Arena<'tcx>) -> Option<&'a TypedArena<Self>>;

From 5bcc80be102cd2b47a0e9cde334c8d1063eea58d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sun, 19 May 2019 18:02:55 +0200
Subject: [PATCH 19/35] Update Cargo.lock

---
 Cargo.lock | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Cargo.lock b/Cargo.lock
index b651faac90281..392f3e8e4bdce 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2877,6 +2877,7 @@ dependencies = [
  "rustc_errors 0.0.0",
  "rustc_target 0.0.0",
  "serialize 0.0.0",
+ "smallvec 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "syntax 0.0.0",
  "syntax_ext 0.0.0",

From 9dcc60b08171c1c10379595df8b6a379b0007c0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 21:01:50 +0100
Subject: [PATCH 20/35] Update lint_levels

---
 src/librustc/arena.rs     | 1 +
 src/librustc/lint/mod.rs  | 6 +++---
 src/librustc/query/mod.rs | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index d2797e652407b..a52b883c3c314 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -78,6 +78,7 @@ macro_rules! arena_types {
                 >,
             [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
             [decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
+            [few] lint_levels: rustc::lint::LintLevelMap,
         ], $tcx);
     )
 }
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 512e4d434434c..2a684f4b0bb45 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -21,7 +21,7 @@
 pub use self::Level::*;
 pub use self::LintSource::*;
 
-use rustc_data_structures::sync::{self, Lrc};
+use rustc_data_structures::sync;
 
 use crate::hir::def_id::{CrateNum, LOCAL_CRATE};
 use crate::hir::intravisit;
@@ -767,7 +767,7 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool {
 }
 
 fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
-    -> Lrc<LintLevelMap>
+    -> &'tcx LintLevelMap
 {
     assert_eq!(cnum, LOCAL_CRATE);
     let mut builder = LintLevelMapBuilder {
@@ -784,7 +784,7 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
     intravisit::walk_crate(&mut builder, krate);
     builder.levels.pop(push);
 
-    Lrc::new(builder.levels.build_map())
+    tcx.arena.alloc(builder.levels.build_map())
 }
 
 struct LintLevelMapBuilder<'a, 'tcx: 'a> {
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 1b9c8e864d65c..4cbda01e13f86 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -67,7 +67,7 @@ rustc_queries! {
             desc { "looking up the native libraries of a linked crate" }
         }
 
-        query lint_levels(_: CrateNum) -> Lrc<lint::LintLevelMap> {
+        query lint_levels(_: CrateNum) -> &'tcx lint::LintLevelMap {
             eval_always
             desc { "computing the lint levels for items in this crate" }
         }

From 10ef70bb68707eda2f0c999a5a06231adcbf967c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 22:45:46 +0100
Subject: [PATCH 21/35] Update stability_index, all_crate_nums and
 features_query

---
 src/librustc/arena.rs                |  2 ++
 src/librustc/query/mod.rs            |  6 +++---
 src/librustc/ty/context.rs           | 12 ++++++------
 src/librustc_metadata/cstore_impl.rs |  2 +-
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index a52b883c3c314..b9126b619cd66 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -79,6 +79,8 @@ macro_rules! arena_types {
             [few] resolve_lifetimes: rustc::middle::resolve_lifetime::ResolveLifetimes,
             [decode] generic_predicates: rustc::ty::GenericPredicates<'tcx>,
             [few] lint_levels: rustc::lint::LintLevelMap,
+            [few] stability_index: rustc::middle::stability::Index<'tcx>,
+            [few] features: syntax::feature_gate::Features,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 4cbda01e13f86..759ee41f0e0b8 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -838,11 +838,11 @@ rustc_queries! {
             eval_always
         }
 
-        query stability_index(_: CrateNum) -> Lrc<stability::Index<'tcx>> {
+        query stability_index(_: CrateNum) -> &'tcx stability::Index<'tcx> {
             eval_always
             desc { "calculating the stability index for the local crate" }
         }
-        query all_crate_nums(_: CrateNum) -> Lrc<Vec<CrateNum>> {
+        query all_crate_nums(_: CrateNum) -> &'tcx [CrateNum] {
             eval_always
             desc { "fetching all foreign CrateNum instances" }
         }
@@ -1062,7 +1062,7 @@ rustc_queries! {
             desc { |tcx| "estimating size for `{}`", tcx.def_path_str(def.def_id()) }
         }
 
-        query features_query(_: CrateNum) -> Lrc<feature_gate::Features> {
+        query features_query(_: CrateNum) -> &'tcx feature_gate::Features {
             eval_always
             desc { "looking up enabled feature gates" }
         }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index d8d1170fc3a20..ad5fb53370a3a 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1420,15 +1420,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         else { None }
     }
 
-    pub fn stability(self) -> Lrc<stability::Index<'tcx>> {
+    pub fn stability(self) -> &'gcx stability::Index<'gcx> {
         self.stability_index(LOCAL_CRATE)
     }
 
-    pub fn crates(self) -> Lrc<Vec<CrateNum>> {
+    pub fn crates(self) -> &'gcx [CrateNum] {
         self.all_crate_nums(LOCAL_CRATE)
     }
 
-    pub fn features(self) -> Lrc<feature_gate::Features> {
+    pub fn features(self) -> &'gcx feature_gate::Features {
         self.features_query(LOCAL_CRATE)
     }
 
@@ -3083,7 +3083,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
 
     providers.stability_index = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        Lrc::new(stability::Index::new(tcx))
+        tcx.arena.alloc(stability::Index::new(tcx))
     };
     providers.lookup_stability = |tcx, id| {
         assert_eq!(id.krate, LOCAL_CRATE);
@@ -3101,7 +3101,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     };
     providers.all_crate_nums = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        Lrc::new(tcx.cstore.crates_untracked())
+        tcx.arena.alloc_slice(&tcx.cstore.crates_untracked())
     };
     providers.postorder_cnums = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
@@ -3113,7 +3113,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     };
     providers.features_query = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        Lrc::new(tcx.sess.features_untracked().clone())
+        tcx.arena.alloc(tcx.sess.features_untracked().clone())
     };
     providers.is_panic_runtime = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 7ca1343a4873b..bdb29006a0e0f 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -322,7 +322,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
             // which is to say, its not deterministic in general. But
             // we believe that libstd is consistently assigned crate
             // num 1, so it should be enough to resolve #46112.
-            let mut crates: Vec<CrateNum> = (*tcx.crates()).clone();
+            let mut crates: Vec<CrateNum> = (*tcx.crates()).to_owned();
             crates.sort();
 
             for &cnum in crates.iter() {

From 5751fcc3b129a31981e9e24ee0ad063b9c7574ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Fri, 30 Nov 2018 22:58:06 +0100
Subject: [PATCH 22/35] Update all_traits

---
 src/librustc/arena.rs                       | 1 +
 src/librustc/query/mod.rs                   | 2 +-
 src/librustc_typeck/check/method/suggest.rs | 3 +--
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index b9126b619cd66..8716f3e22cc7d 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -81,6 +81,7 @@ macro_rules! arena_types {
             [few] lint_levels: rustc::lint::LintLevelMap,
             [few] stability_index: rustc::middle::stability::Index<'tcx>,
             [few] features: syntax::feature_gate::Features,
+            [few] all_traits: Vec<rustc::hir::def_id::DefId>,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 759ee41f0e0b8..9bbc91e455616 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -850,7 +850,7 @@ rustc_queries! {
         /// A vector of every trait accessible in the whole crate
         /// (i.e., including those from subcrates). This is used only for
         /// error reporting.
-        query all_traits(_: CrateNum) -> Lrc<Vec<DefId>> {
+        query all_traits(_: CrateNum) -> &'tcx [DefId] {
             desc { "fetching all foreign and local traits" }
         }
     }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 77d2ffab8efb4..dfe21edee41f3 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -6,7 +6,6 @@ use crate::middle::lang_items::FnOnceTraitLangItem;
 use crate::namespace::Namespace;
 use crate::util::nodemap::FxHashSet;
 use errors::{Applicability, DiagnosticBuilder};
-use rustc_data_structures::sync::Lrc;
 use rustc::hir::{self, ExprKind, Node, QPath};
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
@@ -844,7 +843,7 @@ fn compute_all_traits<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Vec<DefId>
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
     providers.all_traits = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        Lrc::new(compute_all_traits(tcx))
+        &tcx.arena.alloc(compute_all_traits(tcx))[..]
     }
 }
 

From fb578794b0da323c963906555a5afe126f2d8644 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 15:34:04 +0100
Subject: [PATCH 23/35] Update privacy_access_levels

---
 src/librustc/arena.rs             | 1 +
 src/librustc/query/mod.rs         | 2 +-
 src/librustc_privacy/lib.rs       | 5 ++---
 src/librustc_save_analysis/lib.rs | 3 +--
 4 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 8716f3e22cc7d..a31c57c1f6809 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -82,6 +82,7 @@ macro_rules! arena_types {
             [few] stability_index: rustc::middle::stability::Index<'tcx>,
             [few] features: syntax::feature_gate::Features,
             [few] all_traits: Vec<rustc::hir::def_id::DefId>,
+            [few] privacy_access_levels: rustc::middle::privacy::AccessLevels,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 9bbc91e455616..6114f9da59480 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -437,7 +437,7 @@ rustc_queries! {
         query check_match(_: DefId) -> () {}
 
         /// Performs part of the privacy check and computes "access levels".
-        query privacy_access_levels(_: CrateNum) -> Lrc<AccessLevels> {
+        query privacy_access_levels(_: CrateNum) -> &'tcx AccessLevels {
             eval_always
             desc { "privacy access levels" }
         }
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 4fd6dd00cee4c..65b6a89aa0b4d 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -24,7 +24,6 @@ use rustc::ty::query::Providers;
 use rustc::ty::subst::InternalSubsts;
 use rustc::util::nodemap::HirIdSet;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::sync::Lrc;
 use syntax::ast::Ident;
 use syntax::attr;
 use syntax::symbol::{kw, sym};
@@ -1851,7 +1850,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
 fn privacy_access_levels<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     krate: CrateNum,
-) -> Lrc<AccessLevels> {
+) -> &'tcx AccessLevels {
     assert_eq!(krate, LOCAL_CRATE);
 
     // Build up a set of all exported items in the AST. This is a set of all
@@ -1872,7 +1871,7 @@ fn privacy_access_levels<'tcx>(
     }
     visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public));
 
-    Lrc::new(visitor.access_levels)
+    tcx.arena.alloc(visitor.access_levels)
 }
 
 fn check_private_in_public<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, krate: CrateNum) {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index d34f5633946bf..45ace5b37665a 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -24,7 +24,6 @@ use rustc::session::config::{CrateType, Input, OutputType};
 use rustc::ty::{self, DefIdTree, TyCtxt};
 use rustc::{bug, span_bug};
 use rustc_codegen_utils::link::{filename_for_metadata, out_filename};
-use rustc_data_structures::sync::Lrc;
 
 use std::cell::Cell;
 use std::default::Default;
@@ -1120,7 +1119,7 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>(
         // fallback in case the access levels couldn't have been correctly computed.
         let access_levels = match tcx.sess.compile_status() {
             Ok(..) => tcx.privacy_access_levels(LOCAL_CRATE),
-            Err(..) => Lrc::new(AccessLevels::default()),
+            Err(..) => tcx.arena.alloc(AccessLevels::default()),
         };
 
         let save_ctxt = SaveContext {

From 5f808f6588c3e66d9e578d039dd77f0eb0ea053b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 16:17:59 +0100
Subject: [PATCH 24/35] Update in_scope_traits_map

---
 src/librustc/query/mod.rs  |  2 +-
 src/librustc/ty/context.rs | 16 +++++++---------
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 6114f9da59480..99deadd9cb040 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -637,7 +637,7 @@ rustc_queries! {
             desc { "computing whether impls specialize one another" }
         }
         query in_scope_traits_map(_: DefIndex)
-            -> Option<Lrc<FxHashMap<ItemLocalId, Lrc<StableVec<TraitCandidate>>>>> {
+            -> Option<&'tcx FxHashMap<ItemLocalId, StableVec<TraitCandidate>>> {
             eval_always
             desc { "traits in scope at a block" }
         }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ad5fb53370a3a..2f3e35e081cc4 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1064,8 +1064,8 @@ pub struct GlobalCtxt<'tcx> {
     /// Map indicating what traits are in scope for places where this
     /// is relevant; generated by resolve.
     trait_map: FxHashMap<DefIndex,
-                         Lrc<FxHashMap<ItemLocalId,
-                                       Lrc<StableVec<TraitCandidate>>>>>,
+                         FxHashMap<ItemLocalId,
+                                   StableVec<TraitCandidate>>>,
 
     /// Export map produced by name resolution.
     export_map: FxHashMap<DefId, Lrc<Vec<Export<hir::HirId>>>>,
@@ -1305,13 +1305,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             None
         };
 
-        let mut trait_map: FxHashMap<_, Lrc<FxHashMap<_, _>>> = FxHashMap::default();
+        let mut trait_map: FxHashMap<_, FxHashMap<_, _>> = FxHashMap::default();
         for (k, v) in resolutions.trait_map {
             let hir_id = hir.node_to_hir_id(k);
             let map = trait_map.entry(hir_id.owner).or_default();
-            Lrc::get_mut(map).unwrap()
-                             .insert(hir_id.local_id,
-                                     Lrc::new(StableVec::new(v)));
+            map.insert(hir_id.local_id, StableVec::new(v));
         }
 
         GlobalCtxt {
@@ -2979,9 +2977,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         lint::struct_lint_level(self.sess, lint, level, src, None, msg)
     }
 
-    pub fn in_scope_traits(self, id: HirId) -> Option<Lrc<StableVec<TraitCandidate>>> {
+    pub fn in_scope_traits(self, id: HirId) -> Option<&'gcx StableVec<TraitCandidate>> {
         self.in_scope_traits_map(id.owner)
-            .and_then(|map| map.get(&id.local_id).cloned())
+            .and_then(|map| map.get(&id.local_id))
     }
 
     pub fn named_region(self, id: HirId) -> Option<resolve_lifetime::Region> {
@@ -3054,7 +3052,7 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
 }
 
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
-    providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id).cloned();
+    providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id);
     providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
     providers.crate_name = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);

From 9b648f7088cc6336a70ce65d86af10930212253c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 16:23:32 +0100
Subject: [PATCH 25/35] Update upvars and module_exports

---
 src/librustc/query/mod.rs        |  4 ++--
 src/librustc/ty/context.rs       | 12 ++++++------
 src/librustc_metadata/encoder.rs |  2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 99deadd9cb040..4de259a5b9d74 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -644,7 +644,7 @@ rustc_queries! {
     }
 
     Other {
-        query module_exports(_: DefId) -> Option<Lrc<Vec<Export<hir::HirId>>>> {
+        query module_exports(_: DefId) -> Option<&'tcx [Export<hir::HirId>]> {
             eval_always
         }
     }
@@ -822,7 +822,7 @@ rustc_queries! {
             desc { "generating a postorder list of CrateNums" }
         }
 
-        query upvars(_: DefId) -> Option<Lrc<Vec<hir::Upvar>>> {
+        query upvars(_: DefId) -> Option<&'tcx [hir::Upvar]> {
             eval_always
         }
         query maybe_unused_trait_import(_: DefId) -> bool {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 2f3e35e081cc4..87f6f9f070ed1 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1068,7 +1068,7 @@ pub struct GlobalCtxt<'tcx> {
                                    StableVec<TraitCandidate>>>,
 
     /// Export map produced by name resolution.
-    export_map: FxHashMap<DefId, Lrc<Vec<Export<hir::HirId>>>>,
+    export_map: FxHashMap<DefId, Vec<Export<hir::HirId>>>,
 
     hir_map: hir_map::Map<'tcx>,
 
@@ -1081,7 +1081,7 @@ pub struct GlobalCtxt<'tcx> {
     // Records the captured variables referenced by every closure
     // expression. Do not track deps for this, just recompute it from
     // scratch every time.
-    upvars: FxHashMap<DefId, Lrc<Vec<hir::Upvar>>>,
+    upvars: FxHashMap<DefId, Vec<hir::Upvar>>,
 
     maybe_unused_trait_imports: FxHashSet<DefId>,
     maybe_unused_extern_crates: Vec<(DefId, Span)>,
@@ -1328,13 +1328,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                 let exports: Vec<_> = v.into_iter().map(|e| {
                     e.map_id(|id| hir.node_to_hir_id(id))
                 }).collect();
-                (k, Lrc::new(exports))
+                (k, exports)
             }).collect(),
             upvars: resolutions.upvars.into_iter().map(|(k, v)| {
                 let vars: Vec<_> = v.into_iter().map(|e| {
                     e.map_id(|id| hir.node_to_hir_id(id))
                 }).collect();
-                (hir.local_def_id(k), Lrc::new(vars))
+                (hir.local_def_id(k), vars)
             }).collect(),
             maybe_unused_trait_imports:
                 resolutions.maybe_unused_trait_imports
@@ -3053,7 +3053,7 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
 
 pub fn provide(providers: &mut ty::query::Providers<'_>) {
     providers.in_scope_traits_map = |tcx, id| tcx.gcx.trait_map.get(&id);
-    providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).cloned();
+    providers.module_exports = |tcx, id| tcx.gcx.export_map.get(&id).map(|v| &v[..]);
     providers.crate_name = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);
         tcx.crate_name
@@ -3066,7 +3066,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         assert_eq!(id, LOCAL_CRATE);
         Lrc::new(middle::lang_items::collect(tcx))
     };
-    providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).cloned();
+    providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).map(|v| &v[..]);
     providers.maybe_unused_trait_import = |tcx, id| {
         tcx.maybe_unused_trait_imports.contains(&id)
     };
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index d81e34a07aba9..1a9d996131dc0 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -673,7 +673,7 @@ impl EncodeContext<'_, 'tcx> {
 
         let data = ModData {
             reexports: match tcx.module_exports(def_id) {
-                Some(ref exports) => self.lazy_seq_ref(&exports[..]),
+                Some(exports) => self.lazy_seq_ref(exports),
                 _ => LazySeq::empty(),
             },
         };

From 46f251129695f9e768bb444dd20a6cce8f2bfbc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 16:30:42 +0100
Subject: [PATCH 26/35] Update wasm_import_module_map and
 target_features_whitelist

---
 src/librustc/arena.rs                                     | 8 ++++++++
 src/librustc/query/mod.rs                                 | 4 ++--
 src/librustc_codegen_llvm/attributes.rs                   | 7 +++----
 .../hotplug_codegen_backend/the_backend.rs                | 4 ++--
 4 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index a31c57c1f6809..a24ef9523d417 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -83,6 +83,14 @@ macro_rules! arena_types {
             [few] features: syntax::feature_gate::Features,
             [few] all_traits: Vec<rustc::hir::def_id::DefId>,
             [few] privacy_access_levels: rustc::middle::privacy::AccessLevels,
+            [few] target_features_whitelist: rustc_data_structures::fx::FxHashMap<
+                String,
+                Option<syntax::symbol::Symbol>
+            >,
+            [few] wasm_import_module_map: rustc_data_structures::fx::FxHashMap<
+                rustc::hir::def_id::DefId,
+                String
+            >,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 4de259a5b9d74..ae4e22e6e4905 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -155,7 +155,7 @@ rustc_queries! {
     }
 
     Linking {
-        query wasm_import_module_map(_: CrateNum) -> Lrc<FxHashMap<DefId, String>> {
+        query wasm_import_module_map(_: CrateNum) -> &'tcx FxHashMap<DefId, String> {
             desc { "wasm import module map" }
         }
     }
@@ -1050,7 +1050,7 @@ rustc_queries! {
     }
 
     Other {
-        query target_features_whitelist(_: CrateNum) -> Lrc<FxHashMap<String, Option<Symbol>>> {
+        query target_features_whitelist(_: CrateNum) -> &'tcx FxHashMap<String, Option<Symbol>> {
             eval_always
             desc { "looking up the whitelist of target features" }
         }
diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs
index f26684d9ef04a..9d0e7dde34d13 100644
--- a/src/librustc_codegen_llvm/attributes.rs
+++ b/src/librustc_codegen_llvm/attributes.rs
@@ -10,7 +10,6 @@ use rustc::ty::{self, TyCtxt, PolyFnSig};
 use rustc::ty::layout::HasTyCtxt;
 use rustc::ty::query::Providers;
 use rustc_data_structures::small_c_str::SmallCStr;
-use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_target::spec::PanicStrategy;
 use rustc_codegen_ssa::traits::*;
@@ -320,11 +319,11 @@ pub fn provide(providers: &mut Providers<'_>) {
         if tcx.sess.opts.actually_rustdoc {
             // rustdoc needs to be able to document functions that use all the features, so
             // whitelist them all
-            Lrc::new(llvm_util::all_known_features()
+            tcx.arena.alloc(llvm_util::all_known_features()
                 .map(|(a, b)| (a.to_string(), b))
                 .collect())
         } else {
-            Lrc::new(llvm_util::target_feature_whitelist(tcx.sess)
+            tcx.arena.alloc(llvm_util::target_feature_whitelist(tcx.sess)
                 .iter()
                 .map(|&(a, b)| (a.to_string(), b))
                 .collect())
@@ -364,7 +363,7 @@ pub fn provide_extern(providers: &mut Providers<'_>) {
             }));
         }
 
-        Lrc::new(ret)
+        tcx.arena.alloc(ret)
     };
 }
 
diff --git a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
index 4e43aa96e1d85..1bab3f01aba04 100644
--- a/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
+++ b/src/test/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs
@@ -47,8 +47,8 @@ impl CodegenBackend for TheBackend {
     fn provide(&self, providers: &mut Providers) {
         rustc_codegen_utils::symbol_names::provide(providers);
 
-        providers.target_features_whitelist = |_tcx, _cnum| {
-            Default::default() // Just a dummy
+        providers.target_features_whitelist = |tcx, _cnum| {
+            tcx.arena.alloc(Default::default()) // Just a dummy
         };
         providers.is_reachable_non_generic = |_tcx, _defid| true;
         providers.exported_symbols = |_tcx, _crate| Arc::new(Vec::new());

From 3f87975d656aa9847b3fc9e7310e9308cebfdf8d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 16:57:29 +0100
Subject: [PATCH 27/35] Update get_lib_features, defined_lib_features,
 get_lang_items, defined_lang_items, missing_lang_items, postorder_cnums and
 maybe_unused_extern_crates

---
 src/librustc/arena.rs                |  2 ++
 src/librustc/middle/cstore.rs        |  4 ++--
 src/librustc/middle/stability.rs     |  4 ++--
 src/librustc/query/mod.rs            | 14 ++++++------
 src/librustc/ty/context.rs           | 12 +++++-----
 src/librustc_metadata/cstore_impl.rs |  6 ++---
 src/librustc_metadata/decoder.rs     | 34 ++++++++++++++++------------
 7 files changed, 42 insertions(+), 34 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index a24ef9523d417..53349773a360c 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -91,6 +91,8 @@ macro_rules! arena_types {
                 rustc::hir::def_id::DefId,
                 String
             >,
+            [few] get_lib_features: rustc::middle::lib_features::LibFeatures,
+            [few] defined_lib_features: rustc::middle::lang_items::LanguageItems,
         ], $tcx);
     )
 }
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index d22de6c647699..6f9abcd624f99 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -256,8 +256,8 @@ pub fn used_crates(tcx: TyCtxt<'_, '_, '_>, prefer: LinkagePreference)
             Some((cnum, path))
         })
         .collect::<Vec<_>>();
-    let mut ordering = tcx.postorder_cnums(LOCAL_CRATE);
-    Lrc::make_mut(&mut ordering).reverse();
+    let mut ordering = tcx.postorder_cnums(LOCAL_CRATE).to_owned();
+    ordering.reverse();
     libs.sort_by_cached_key(|&(a, _)| {
         ordering.iter().position(|x| *x == a)
     });
diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs
index abcf164cda6d4..ac0e99137cbc3 100644
--- a/src/librustc/middle/stability.rs
+++ b/src/librustc/middle/stability.rs
@@ -883,7 +883,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     remaining_lib_features.remove(&Symbol::intern("test"));
 
     let check_features =
-        |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &Vec<_>| {
+        |remaining_lib_features: &mut FxHashMap<_, _>, defined_features: &[_]| {
             for &(feature, since) in defined_features {
                 if let Some(since) = since {
                     if let Some(span) = remaining_lib_features.get(&feature) {
@@ -908,7 +908,7 @@ pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
             if remaining_lib_features.is_empty() {
                 break;
             }
-            check_features(&mut remaining_lib_features, &tcx.defined_lib_features(cnum));
+            check_features(&mut remaining_lib_features, tcx.defined_lib_features(cnum));
         }
     }
 
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index ae4e22e6e4905..84e88acbbded7 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -787,22 +787,22 @@ rustc_queries! {
         query item_children(_: DefId) -> &'tcx [Export<hir::HirId>] {}
         query extern_mod_stmt_cnum(_: DefId) -> Option<CrateNum> {}
 
-        query get_lib_features(_: CrateNum) -> Lrc<LibFeatures> {
+        query get_lib_features(_: CrateNum) -> &'tcx LibFeatures {
             eval_always
             desc { "calculating the lib features map" }
         }
         query defined_lib_features(_: CrateNum)
-            -> Lrc<Vec<(Symbol, Option<Symbol>)>> {
+            -> &'tcx [(Symbol, Option<Symbol>)] {
             desc { "calculating the lib features defined in a crate" }
         }
-        query get_lang_items(_: CrateNum) -> Lrc<LanguageItems> {
+        query get_lang_items(_: CrateNum) -> &'tcx LanguageItems {
             eval_always
             desc { "calculating the lang items map" }
         }
-        query defined_lang_items(_: CrateNum) -> Lrc<Vec<(DefId, usize)>> {
+        query defined_lang_items(_: CrateNum) -> &'tcx [(DefId, usize)] {
             desc { "calculating the lang items defined in a crate" }
         }
-        query missing_lang_items(_: CrateNum) -> Lrc<Vec<LangItem>> {
+        query missing_lang_items(_: CrateNum) -> &'tcx [LangItem] {
             desc { "calculating the missing lang items in a crate" }
         }
         query visible_parent_map(_: CrateNum)
@@ -817,7 +817,7 @@ rustc_queries! {
             eval_always
             desc { "looking at the source for a crate" }
         }
-        query postorder_cnums(_: CrateNum) -> Lrc<Vec<CrateNum>> {
+        query postorder_cnums(_: CrateNum) -> &'tcx [CrateNum] {
             eval_always
             desc { "generating a postorder list of CrateNums" }
         }
@@ -829,7 +829,7 @@ rustc_queries! {
             eval_always
         }
         query maybe_unused_extern_crates(_: CrateNum)
-            -> Lrc<Vec<(DefId, Span)>> {
+            -> &'tcx [(DefId, Span)] {
             eval_always
             desc { "looking up all possibly unused extern crates" }
         }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 87f6f9f070ed1..d83b2ce842a88 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -1376,11 +1376,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.sess.consider_optimizing(&cname, msg)
     }
 
-    pub fn lib_features(self) -> Lrc<middle::lib_features::LibFeatures> {
+    pub fn lib_features(self) -> &'gcx middle::lib_features::LibFeatures {
         self.get_lib_features(LOCAL_CRATE)
     }
 
-    pub fn lang_items(self) -> Lrc<middle::lang_items::LanguageItems> {
+    pub fn lang_items(self) -> &'gcx middle::lang_items::LanguageItems {
         self.get_lang_items(LOCAL_CRATE)
     }
 
@@ -3060,11 +3060,11 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     };
     providers.get_lib_features = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);
-        Lrc::new(middle::lib_features::collect(tcx))
+        tcx.arena.alloc(middle::lib_features::collect(tcx))
     };
     providers.get_lang_items = |tcx, id| {
         assert_eq!(id, LOCAL_CRATE);
-        Lrc::new(middle::lang_items::collect(tcx))
+        tcx.arena.alloc(middle::lang_items::collect(tcx))
     };
     providers.upvars = |tcx, id| tcx.gcx.upvars.get(&id).map(|v| &v[..]);
     providers.maybe_unused_trait_import = |tcx, id| {
@@ -3072,7 +3072,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     };
     providers.maybe_unused_extern_crates = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        Lrc::new(tcx.maybe_unused_extern_crates.clone())
+        &tcx.maybe_unused_extern_crates[..]
     };
     providers.names_imported_by_glob_use = |tcx, id| {
         assert_eq!(id.krate, LOCAL_CRATE);
@@ -3103,7 +3103,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
     };
     providers.postorder_cnums = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
-        Lrc::new(tcx.cstore.postorder_cnums_untracked())
+        tcx.arena.alloc_slice(&tcx.cstore.postorder_cnums_untracked())
     };
     providers.output_filenames = |tcx, cnum| {
         assert_eq!(cnum, LOCAL_CRATE);
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index bdb29006a0e0f..2469732a749de 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -229,9 +229,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         cdata.each_child_of_item(def_id.index, |child| result.push(child), tcx.sess);
         tcx.arena.alloc_slice(&result)
     }
-    defined_lib_features => { Lrc::new(cdata.get_lib_features()) }
-    defined_lang_items => { Lrc::new(cdata.get_lang_items()) }
-    missing_lang_items => { Lrc::new(cdata.get_missing_lang_items()) }
+    defined_lib_features => { cdata.get_lib_features(tcx) }
+    defined_lang_items => { cdata.get_lang_items(tcx) }
+    missing_lang_items => { cdata.get_missing_lang_items(tcx) }
 
     missing_extern_crate_item => {
         let r = match *cdata.extern_crate.borrow() {
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index c4037dcfac0ad..ea79161a6d90f 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -708,26 +708,30 @@ impl<'a, 'tcx> CrateMetadata {
     }
 
     /// Iterates over all the stability attributes in the given crate.
-    pub fn get_lib_features(&self) -> Vec<(ast::Name, Option<ast::Name>)> {
+    pub fn get_lib_features(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, '_>,
+    ) -> &'tcx [(ast::Name, Option<ast::Name>)] {
         // FIXME: For a proc macro crate, not sure whether we should return the "host"
         // features or an empty Vec. Both don't cause ICEs.
-        self.root
+        tcx.arena.alloc_from_iter(self.root
             .lib_features
-            .decode(self)
-            .collect()
+            .decode(self))
     }
 
     /// Iterates over the language items in the given crate.
-    pub fn get_lang_items(&self) -> Vec<(DefId, usize)> {
+    pub fn get_lang_items(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, '_>,
+    ) -> &'tcx [(DefId, usize)] {
         if self.proc_macros.is_some() {
             // Proc macro crates do not export any lang-items to the target.
-            vec![]
+            &[]
         } else {
-            self.root
+            tcx.arena.alloc_from_iter(self.root
                 .lang_items
                 .decode(self)
-                .map(|(def_index, index)| (self.local_def_id(def_index), index))
-                .collect()
+                .map(|(def_index, index)| (self.local_def_id(def_index), index)))
         }
     }
 
@@ -1102,15 +1106,17 @@ impl<'a, 'tcx> CrateMetadata {
             .collect()
     }
 
-    pub fn get_missing_lang_items(&self) -> Vec<lang_items::LangItem> {
+    pub fn get_missing_lang_items(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, '_>,
+    ) -> &'tcx [lang_items::LangItem] {
         if self.proc_macros.is_some() {
             // Proc macro crates do not depend on any target weak lang-items.
-            vec![]
+            &[]
         } else {
-            self.root
+            tcx.arena.alloc_from_iter(self.root
                 .lang_items_missing
-                .decode(self)
-                .collect()
+                .decode(self))
         }
     }
 

From 2f74d90ef3e4f6d38d4ae331a8f277fe92b3dbce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 17:02:51 +0100
Subject: [PATCH 28/35] Update visible_parent_map

---
 src/librustc/arena.rs                | 1 +
 src/librustc/query/mod.rs            | 2 +-
 src/librustc_metadata/cstore_impl.rs | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 53349773a360c..df40d12477d96 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -93,6 +93,7 @@ macro_rules! arena_types {
             >,
             [few] get_lib_features: rustc::middle::lib_features::LibFeatures,
             [few] defined_lib_features: rustc::middle::lang_items::LanguageItems,
+            [few] visible_parent_map: rustc::util::nodemap::DefIdMap<rustc::hir::def_id::DefId>,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 84e88acbbded7..ad328479533eb 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -806,7 +806,7 @@ rustc_queries! {
             desc { "calculating the missing lang items in a crate" }
         }
         query visible_parent_map(_: CrateNum)
-            -> Lrc<DefIdMap<DefId>> {
+            -> &'tcx DefIdMap<DefId> {
             desc { "calculating the visible parent map" }
         }
         query missing_extern_crate_item(_: CrateNum) -> bool {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 2469732a749de..72ff80db73cf5 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -371,7 +371,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
                 }
             }
 
-            Lrc::new(visible_parent_map)
+            tcx.arena.alloc(visible_parent_map)
         },
 
         ..*providers

From 469831f4da99c9db5c3555c74313cbcf5e9f351d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 17:14:40 +0100
Subject: [PATCH 29/35] Update foreign_modules and dllimport_foreign_items

---
 src/librustc/arena.rs                | 2 ++
 src/librustc/query/mod.rs            | 4 ++--
 src/librustc_codegen_ssa/base.rs     | 3 +--
 src/librustc_metadata/cstore_impl.rs | 4 ++--
 src/librustc_metadata/decoder.rs     | 9 ++++++---
 5 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index df40d12477d96..98678b1f28c36 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -94,6 +94,8 @@ macro_rules! arena_types {
             [few] get_lib_features: rustc::middle::lib_features::LibFeatures,
             [few] defined_lib_features: rustc::middle::lang_items::LanguageItems,
             [few] visible_parent_map: rustc::util::nodemap::DefIdMap<rustc::hir::def_id::DefId>,
+            [few] foreign_module: rustc::middle::cstore::ForeignModule,
+            [few] foreign_modules: Vec<rustc::middle::cstore::ForeignModule>,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index ad328479533eb..ff8acf5126e9e 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -689,7 +689,7 @@ rustc_queries! {
     }
 
     Other {
-        query foreign_modules(_: CrateNum) -> Lrc<Vec<ForeignModule>> {
+        query foreign_modules(_: CrateNum) -> &'tcx [ForeignModule] {
             desc { "looking up the foreign modules of a linked crate" }
         }
 
@@ -736,7 +736,7 @@ rustc_queries! {
 
     Other {
         query dllimport_foreign_items(_: CrateNum)
-            -> Lrc<FxHashSet<DefId>> {
+            -> &'tcx FxHashSet<DefId> {
             desc { "dllimport_foreign_items" }
         }
         query is_dllimport_foreign_item(_: DefId) -> bool {}
diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs
index 3cd47dfbb29fb..0b037f872475d 100644
--- a/src/librustc_codegen_ssa/base.rs
+++ b/src/librustc_codegen_ssa/base.rs
@@ -33,7 +33,6 @@ use rustc_mir::monomorphize::Instance;
 use rustc_mir::monomorphize::partitioning::{CodegenUnit, CodegenUnitExt};
 use rustc::util::nodemap::FxHashMap;
 use rustc_data_structures::indexed_vec::Idx;
-use rustc_data_structures::sync::Lrc;
 use rustc_codegen_utils::{symbol_names_test, check_for_rustc_errors_attr};
 use rustc::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
 use crate::mir::place::PlaceRef;
@@ -916,7 +915,7 @@ pub fn provide_both(providers: &mut Providers<'_>) {
             .map(|id| &module_map[&id])
             .flat_map(|module| module.foreign_items.iter().cloned())
             .collect();
-        Lrc::new(dllimports)
+        tcx.arena.alloc(dllimports)
     };
 
     providers.is_dllimport_foreign_item = |tcx, def_id| {
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 72ff80db73cf5..f0dde17beeeb1 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -193,7 +193,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         Lrc::new(reachable_non_generics)
     }
     native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
-    foreign_modules => { Lrc::new(cdata.get_foreign_modules(tcx.sess)) }
+    foreign_modules => { cdata.get_foreign_modules(tcx) }
     plugin_registrar_fn => {
         cdata.root.plugin_registrar_fn.map(|index| {
             DefId { krate: def_id.krate, index }
@@ -285,7 +285,7 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) {
         },
         foreign_modules: |tcx, cnum| {
             assert_eq!(cnum, LOCAL_CRATE);
-            Lrc::new(foreign_modules::collect(tcx))
+            &tcx.arena.alloc(foreign_modules::collect(tcx))[..]
         },
         link_args: |tcx, cnum| {
             assert_eq!(cnum, LOCAL_CRATE);
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index ea79161a6d90f..b287db498fcac 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1085,12 +1085,15 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    pub fn get_foreign_modules(&self, sess: &Session) -> Vec<ForeignModule> {
+    pub fn get_foreign_modules(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, '_>,
+    ) -> &'tcx [ForeignModule] {
         if self.proc_macros.is_some() {
             // Proc macro crates do not have any *target* foreign modules.
-            vec![]
+            &[]
         } else {
-            self.root.foreign_modules.decode((self, sess)).collect()
+            tcx.arena.alloc_from_iter(self.root.foreign_modules.decode((self, tcx.sess)))
         }
     }
 

From a58999c19e58d21734622d3e1b4b2de4c0bc7a5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Sat, 1 Dec 2018 17:27:12 +0100
Subject: [PATCH 30/35] Update dylib_dependency_formats, extern_crate and
 reachable_non_generics

---
 src/librustc/arena.rs                          |  3 +++
 src/librustc/query/mod.rs                      |  6 +++---
 src/librustc/ty/print/pretty.rs                |  4 ++--
 src/librustc_codegen_ssa/back/symbol_export.rs |  7 +++----
 src/librustc_metadata/cstore_impl.rs           |  8 ++++----
 src/librustc_metadata/decoder.rs               | 10 ++++++----
 src/librustc_save_analysis/lib.rs              |  4 ++--
 7 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 98678b1f28c36..6312a6cfcd651 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -96,6 +96,9 @@ macro_rules! arena_types {
             [few] visible_parent_map: rustc::util::nodemap::DefIdMap<rustc::hir::def_id::DefId>,
             [few] foreign_module: rustc::middle::cstore::ForeignModule,
             [few] foreign_modules: Vec<rustc::middle::cstore::ForeignModule>,
+            [few] reachable_non_generics: rustc::util::nodemap::DefIdMap<
+                rustc::middle::exported_symbols::SymbolExportLevel
+            >,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index ff8acf5126e9e..68d3cb65729d2 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -590,7 +590,7 @@ rustc_queries! {
 
     Other {
         query dylib_dependency_formats(_: CrateNum)
-                                        -> Lrc<Vec<(CrateNum, LinkagePreference)>> {
+                                        -> &'tcx [(CrateNum, LinkagePreference)] {
             desc { "dylib dependency formats of crate" }
         }
     }
@@ -625,7 +625,7 @@ rustc_queries! {
             desc { "test whether a crate has #![no_builtins]" }
         }
 
-        query extern_crate(_: DefId) -> Lrc<Option<ExternCrate>> {
+        query extern_crate(_: DefId) -> Option<&'tcx ExternCrate> {
             eval_always
             desc { "getting crate's ExternCrateData" }
         }
@@ -671,7 +671,7 @@ rustc_queries! {
         // Does not include external symbols that don't have a corresponding DefId,
         // like the compiler-generated `main` function and so on.
         query reachable_non_generics(_: CrateNum)
-            -> Lrc<DefIdMap<SymbolExportLevel>> {
+            -> &'tcx DefIdMap<SymbolExportLevel> {
             desc { "looking up the exported symbols of a crate" }
         }
         query is_reachable_non_generic(_: DefId) -> bool {}
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index 7a8d5d3bb9a67..06db4b9b65bca 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -253,8 +253,8 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
             // 2. for an extern inferred from a path or an indirect crate,
             //    where there is no explicit `extern crate`, we just prepend
             //    the crate name.
-            match *self.tcx().extern_crate(def_id) {
-                Some(ExternCrate {
+            match self.tcx().extern_crate(def_id) {
+                Some(&ExternCrate {
                     src: ExternCrateSource::Extern(def_id),
                     direct: true,
                     span,
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 616049ea112a4..fb7ef87646296 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -1,4 +1,3 @@
-use rustc_data_structures::sync::Lrc;
 use std::sync::Arc;
 
 use rustc::ty::Instance;
@@ -49,12 +48,12 @@ pub fn crates_export_threshold(crate_types: &[config::CrateType]) -> SymbolExpor
 
 fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                              cnum: CrateNum)
-                                             -> Lrc<DefIdMap<SymbolExportLevel>>
+                                             -> &'tcx DefIdMap<SymbolExportLevel>
 {
     assert_eq!(cnum, LOCAL_CRATE);
 
     if !tcx.sess.opts.output_types.should_codegen() {
-        return Default::default();
+        return tcx.arena.alloc(Default::default());
     }
 
     // Check to see if this crate is a "special runtime crate". These
@@ -155,7 +154,7 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         reachable_non_generics.insert(id, SymbolExportLevel::C);
     }
 
-    Lrc::new(reachable_non_generics)
+    tcx.arena.alloc(reachable_non_generics)
 }
 
 fn is_reachable_non_generic_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index f0dde17beeeb1..fae4c244d6e14 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -163,7 +163,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     }
     is_mir_available => { cdata.is_item_mir_available(def_id.index) }
 
-    dylib_dependency_formats => { Lrc::new(cdata.get_dylib_dependency_formats()) }
+    dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
     is_panic_runtime => { cdata.root.panic_runtime }
     is_compiler_builtins => { cdata.root.compiler_builtins }
     has_global_allocator => { cdata.root.has_global_allocator }
@@ -172,8 +172,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
     is_profiler_runtime => { cdata.root.profiler_runtime }
     panic_strategy => { cdata.root.panic_strategy }
     extern_crate => {
-        let r = Lrc::new(*cdata.extern_crate.lock());
-        r
+        let r = *cdata.extern_crate.lock();
+        r.map(|c| &*tcx.arena.alloc(c))
     }
     is_no_builtins => { cdata.root.no_builtins }
     impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
@@ -190,7 +190,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
             })
             .collect();
 
-        Lrc::new(reachable_non_generics)
+        tcx.arena.alloc(reachable_non_generics)
     }
     native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess)) }
     foreign_modules => { cdata.get_foreign_modules(tcx) }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index b287db498fcac..958c81989ffd6 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -1097,16 +1097,18 @@ impl<'a, 'tcx> CrateMetadata {
         }
     }
 
-    pub fn get_dylib_dependency_formats(&self) -> Vec<(CrateNum, LinkagePreference)> {
-        self.root
+    pub fn get_dylib_dependency_formats(
+        &self,
+        tcx: TyCtxt<'_, 'tcx, '_>,
+    ) -> &'tcx [(CrateNum, LinkagePreference)] {
+        tcx.arena.alloc_from_iter(self.root
             .dylib_dependency_formats
             .decode(self)
             .enumerate()
             .flat_map(|(i, link)| {
                 let cnum = CrateNum::new(i + 1);
                 link.map(|link| (self.cnum_map[cnum], link))
-            })
-            .collect()
+            }))
     }
 
     pub fn get_missing_lang_items(
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 45ace5b37665a..55471dbc00be5 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -109,8 +109,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         let mut result = Vec::with_capacity(self.tcx.crates().len());
 
         for &n in self.tcx.crates().iter() {
-            let span = match *self.tcx.extern_crate(n.as_def_id()) {
-                Some(ExternCrate { span, .. }) => span,
+            let span = match self.tcx.extern_crate(n.as_def_id()) {
+                Some(&ExternCrate { span, .. }) => span,
                 None => {
                     debug!("Skipping crate {}, no data", n);
                     continue;

From d46e732e393a01884115e4506968606bd4da0d17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com>
Date: Tue, 21 May 2019 00:40:32 +0200
Subject: [PATCH 31/35] Update crate_variances and inferred_outlives_crate

---
 src/librustc/arena.rs               | 2 ++
 src/librustc/query/mod.rs           | 4 ++--
 src/librustc_typeck/outlives/mod.rs | 5 ++---
 src/librustc_typeck/variance/mod.rs | 5 ++---
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 6312a6cfcd651..c179b05683d1c 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -99,6 +99,8 @@ macro_rules! arena_types {
             [few] reachable_non_generics: rustc::util::nodemap::DefIdMap<
                 rustc::middle::exported_symbols::SymbolExportLevel
             >,
+            [few] crate_variances: rustc::ty::CrateVariancesMap<'tcx>,
+            [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>,
         ], $tcx);
     )
 }
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index 68d3cb65729d2..c03cd7e268ef5 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -244,7 +244,7 @@ rustc_queries! {
         query static_mutability(_: DefId) -> Option<hir::Mutability> {}
 
         /// Gets a map with the variance of every item; use `item_variance` instead.
-        query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap<'tcx>> {
+        query crate_variances(_: CrateNum) -> &'tcx ty::CrateVariancesMap<'tcx> {
             desc { "computing the variances for items in this crate" }
         }
 
@@ -255,7 +255,7 @@ rustc_queries! {
     TypeChecking {
         /// Maps from thee `DefId` of a type to its (inferred) outlives.
         query inferred_outlives_crate(_: CrateNum)
-            -> Lrc<ty::CratePredicatesMap<'tcx>> {
+            -> &'tcx ty::CratePredicatesMap<'tcx> {
             desc { "computing the inferred outlives predicates for items in this crate" }
         }
     }
diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs
index a6b5b99982ec6..57787a75e4aef 100644
--- a/src/librustc_typeck/outlives/mod.rs
+++ b/src/librustc_typeck/outlives/mod.rs
@@ -4,7 +4,6 @@ use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::ty::query::Providers;
 use rustc::ty::subst::UnpackedKind;
 use rustc::ty::{self, CratePredicatesMap, TyCtxt};
-use rustc_data_structures::sync::Lrc;
 use syntax::symbol::sym;
 
 mod explicit;
@@ -74,7 +73,7 @@ fn inferred_outlives_of<'a, 'tcx>(
 fn inferred_outlives_crate<'tcx>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     crate_num: CrateNum,
-) -> Lrc<CratePredicatesMap<'tcx>> {
+) -> &'tcx CratePredicatesMap<'tcx> {
     assert_eq!(crate_num, LOCAL_CRATE);
 
     // Compute a map from each struct/enum/union S to the **explicit**
@@ -120,7 +119,7 @@ fn inferred_outlives_crate<'tcx>(
             (def_id, &*predicates)
         }).collect();
 
-    Lrc::new(ty::CratePredicatesMap {
+    tcx.arena.alloc(ty::CratePredicatesMap {
         predicates,
     })
 }
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index 88ee1d79f5435..47c4a9b39c865 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -9,7 +9,6 @@ use hir::Node;
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc::ty::{self, CrateVariancesMap, TyCtxt};
 use rustc::ty::query::Providers;
-use rustc_data_structures::sync::Lrc;
 
 /// Defines the `TermsContext` basically houses an arena where we can
 /// allocate terms.
@@ -36,12 +35,12 @@ pub fn provide(providers: &mut Providers<'_>) {
 }
 
 fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
-                             -> Lrc<CrateVariancesMap<'tcx>> {
+                             -> &'tcx CrateVariancesMap<'tcx> {
     assert_eq!(crate_num, LOCAL_CRATE);
     let mut arena = arena::TypedArena::default();
     let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &mut arena);
     let constraints_cx = constraints::add_constraints_from_crate(terms_cx);
-    Lrc::new(solve::solve_constraints(constraints_cx))
+    tcx.arena.alloc(solve::solve_constraints(constraints_cx))
 }
 
 fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)

From 7fbbcfaafd08023cc2296481425e16a02ccd3f1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 23 May 2019 10:32:01 -0700
Subject: [PATCH 32/35] Add regression test for negative case

---
 .../ui/suggestions/mut-ref-reassignment.rs    | 14 ++++++-
 .../suggestions/mut-ref-reassignment.stderr   | 37 +++++++++++++++++--
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/test/ui/suggestions/mut-ref-reassignment.rs b/src/test/ui/suggestions/mut-ref-reassignment.rs
index b9deaa96dbfc3..1428324934de2 100644
--- a/src/test/ui/suggestions/mut-ref-reassignment.rs
+++ b/src/test/ui/suggestions/mut-ref-reassignment.rs
@@ -1,5 +1,17 @@
-fn change_opt(opt: &mut Option<String>){
+fn suggestion(opt: &mut Option<String>) {
+    opt = None; //~ ERROR mismatched types
+}
+
+fn no_suggestion(opt: &mut Result<String, ()>) {
     opt = None //~ ERROR mismatched types
 }
 
+fn suggestion2(opt: &mut Option<String>) {
+    opt = Some(String::new())//~ ERROR mismatched types
+}
+
+fn no_suggestion2(opt: &mut Option<String>) {
+    opt = Some(42)//~ ERROR mismatched types
+}
+
 fn main() {}
diff --git a/src/test/ui/suggestions/mut-ref-reassignment.stderr b/src/test/ui/suggestions/mut-ref-reassignment.stderr
index d90c13b388279..66b78a1b14015 100644
--- a/src/test/ui/suggestions/mut-ref-reassignment.stderr
+++ b/src/test/ui/suggestions/mut-ref-reassignment.stderr
@@ -1,16 +1,47 @@
 error[E0308]: mismatched types
   --> $DIR/mut-ref-reassignment.rs:2:11
    |
-LL |     opt = None
+LL |     opt = None;
    |           ^^^^ expected mutable reference, found enum `std::option::Option`
    |
    = note: expected type `&mut std::option::Option<std::string::String>`
               found type `std::option::Option<_>`
 help: consider dereferencing here to assign to the mutable borrowed piece of memory
    |
-LL |     *opt = None
+LL |     *opt = None;
    |     ^^^^
 
-error: aborting due to previous error
+error[E0308]: mismatched types
+  --> $DIR/mut-ref-reassignment.rs:6:11
+   |
+LL |     opt = None
+   |           ^^^^ expected mutable reference, found enum `std::option::Option`
+   |
+   = note: expected type `&mut std::result::Result<std::string::String, ()>`
+              found type `std::option::Option<_>`
+
+error[E0308]: mismatched types
+  --> $DIR/mut-ref-reassignment.rs:10:11
+   |
+LL |     opt = Some(String::new())
+   |           ^^^^^^^^^^^^^^^^^^^ expected mutable reference, found enum `std::option::Option`
+   |
+   = note: expected type `&mut std::option::Option<std::string::String>`
+              found type `std::option::Option<std::string::String>`
+help: consider dereferencing here to assign to the mutable borrowed piece of memory
+   |
+LL |     *opt = Some(String::new())
+   |     ^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/mut-ref-reassignment.rs:14:11
+   |
+LL |     opt = Some(42)
+   |           ^^^^^^^^ expected mutable reference, found enum `std::option::Option`
+   |
+   = note: expected type `&mut std::option::Option<std::string::String>`
+              found type `std::option::Option<{integer}>`
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0308`.

From 49f01d823fc936919a4f093c45ad858d27fda2e9 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 23 May 2019 21:39:27 +0100
Subject: [PATCH 33/35] Fix missing overflowing literal lint in for loop

---
 src/librustc/lint/mod.rs | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 512e4d434434c..fc2fff6a81fe0 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -35,7 +35,7 @@ use crate::util::nodemap::NodeMap;
 use errors::{DiagnosticBuilder, DiagnosticId};
 use std::{hash, ptr};
 use syntax::ast;
-use syntax::source_map::{MultiSpan, ExpnFormat};
+use syntax::source_map::{MultiSpan, ExpnFormat, CompilerDesugaringKind};
 use syntax::early_buffered_lints::BufferedEarlyLintId;
 use syntax::edition::Edition;
 use syntax::symbol::{Symbol, sym};
@@ -887,21 +887,22 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
     };
 
     match info.format {
-        ExpnFormat::MacroAttribute(..) => return true, // definitely a plugin
-        ExpnFormat::CompilerDesugaring(_) => return true, // well, it's "external"
-        ExpnFormat::MacroBang(..) => {} // check below
-    }
-
-    let def_site = match info.def_site {
-        Some(span) => span,
-        // no span for the def_site means it's an external macro
-        None => return true,
-    };
+        ExpnFormat::MacroAttribute(..) => true, // definitely a plugin
+        ExpnFormat::CompilerDesugaring(CompilerDesugaringKind::ForLoop) => false,
+        ExpnFormat::CompilerDesugaring(_) => true, // well, it's "external"
+        ExpnFormat::MacroBang(..) => {
+            let def_site = match info.def_site {
+                Some(span) => span,
+                // no span for the def_site means it's an external macro
+                None => return true,
+            };
 
-    match sess.source_map().span_to_snippet(def_site) {
-        Ok(code) => !code.starts_with("macro_rules"),
-        // no snippet = external macro or compiler-builtin expansion
-        Err(_) => true,
+            match sess.source_map().span_to_snippet(def_site) {
+                Ok(code) => !code.starts_with("macro_rules"),
+                // no snippet = external macro or compiler-builtin expansion
+                Err(_) => true,
+            }
+        }
     }
 }
 

From 3e4cefe1bda1b37eedad1d6c3d4166dd8d41c5a2 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 23 May 2019 21:39:36 +0100
Subject: [PATCH 34/35] Update unreachable loop patterns test

---
 src/test/ui/unreachable/unreachable-loop-patterns.rs     | 1 +
 src/test/ui/unreachable/unreachable-loop-patterns.stderr | 8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.rs b/src/test/ui/unreachable/unreachable-loop-patterns.rs
index 3c878410f7710..56ab1a270a75d 100644
--- a/src/test/ui/unreachable/unreachable-loop-patterns.rs
+++ b/src/test/ui/unreachable/unreachable-loop-patterns.rs
@@ -19,4 +19,5 @@ impl Iterator for Void {
 fn main() {
     for _ in unimplemented!() as Void {}
     //~^ ERROR unreachable pattern
+    //~^^ ERROR unreachable pattern
 }
diff --git a/src/test/ui/unreachable/unreachable-loop-patterns.stderr b/src/test/ui/unreachable/unreachable-loop-patterns.stderr
index d2f255c3e104d..254d1178d142e 100644
--- a/src/test/ui/unreachable/unreachable-loop-patterns.stderr
+++ b/src/test/ui/unreachable/unreachable-loop-patterns.stderr
@@ -10,5 +10,11 @@ note: lint level defined here
 LL | #![deny(unreachable_patterns)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error: unreachable pattern
+  --> $DIR/unreachable-loop-patterns.rs:20:14
+   |
+LL |     for _ in unimplemented!() as Void {}
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 

From 12de24ce81fbbcc1a2b170a719cc792dfa559c81 Mon Sep 17 00:00:00 2001
From: varkor <github@varkor.com>
Date: Thu, 23 May 2019 21:48:26 +0100
Subject: [PATCH 35/35] Add test for denying overflowing literal in loop

---
 src/test/ui/lint/deny-overflowing-literals.rs     | 3 +++
 src/test/ui/lint/deny-overflowing-literals.stderr | 8 +++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/test/ui/lint/deny-overflowing-literals.rs b/src/test/ui/lint/deny-overflowing-literals.rs
index b887f66e94bd6..21c8ba7d6ce4e 100644
--- a/src/test/ui/lint/deny-overflowing-literals.rs
+++ b/src/test/ui/lint/deny-overflowing-literals.rs
@@ -1,4 +1,7 @@
 fn main() {
     let x: u8 = 256;
     //~^ error: literal out of range for `u8`
+
+    for _ in 0..256u8 {}
+    //~^ error: range endpoint is out of range for `u8`
 }
diff --git a/src/test/ui/lint/deny-overflowing-literals.stderr b/src/test/ui/lint/deny-overflowing-literals.stderr
index 1263a7bb7fd1b..c97872b5222e8 100644
--- a/src/test/ui/lint/deny-overflowing-literals.stderr
+++ b/src/test/ui/lint/deny-overflowing-literals.stderr
@@ -6,5 +6,11 @@ LL |     let x: u8 = 256;
    |
    = note: #[deny(overflowing_literals)] on by default
 
-error: aborting due to previous error
+error: range endpoint is out of range for `u8`
+  --> $DIR/deny-overflowing-literals.rs:5:14
+   |
+LL |     for _ in 0..256u8 {}
+   |              ^^^^^^^^ help: use an inclusive range instead: `0..=255u8`
+
+error: aborting due to 2 previous errors