about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-05-01 08:29:09 +0200
committerGitHub <noreply@github.com>2019-05-01 08:29:09 +0200
commita8b854bde0145f0ca052f067a4b86b778ecc17ab (patch)
tree3d3952464c2929f290246105934b7cbaeb5b7e0a
parent834bd1959cc06bbae08e7de65f09f326d1702a95 (diff)
parentd2ff829433222f563425f3f7b13d20002e0708fd (diff)
downloadrust-a8b854bde0145f0ca052f067a4b86b778ecc17ab.tar.gz
rust-a8b854bde0145f0ca052f067a4b86b778ecc17ab.zip
Rollup merge of #60287 - Zoxc:the-arena-variances_of, r=eddyb
Use references for variances_of

Based on https://github.com/rust-lang/rust/pull/60280.

cc @varkor
r? @eddyb
-rw-r--r--src/librustc/arena.rs8
-rw-r--r--src/librustc/query/mod.rs4
-rw-r--r--src/librustc/ty/mod.rs8
-rw-r--r--src/librustc/ty/relate.rs4
-rw-r--r--src/librustc_metadata/cstore_impl.rs2
-rw-r--r--src/librustc_typeck/variance/mod.rs8
-rw-r--r--src/librustc_typeck/variance/solve.rs21
7 files changed, 29 insertions, 26 deletions
diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs
index 1cc6500d038..b48d81f2ef8 100644
--- a/src/librustc/arena.rs
+++ b/src/librustc/arena.rs
@@ -144,6 +144,14 @@ impl<'tcx> Arena<'tcx> {
         }
     }
 
+    #[inline]
+    pub fn alloc_slice<T: Copy>(&self, value: &[T]) -> &mut [T] {
+        if value.len() == 0 {
+            return &mut []
+        }
+        self.dropless.alloc_slice(value)
+    }
+
     pub fn alloc_from_iter<
         T: ArenaAllocatable,
         I: IntoIterator<Item = T>
diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs
index eaf9fd1bc76..b96ef1b7a86 100644
--- a/src/librustc/query/mod.rs
+++ b/src/librustc/query/mod.rs
@@ -245,13 +245,13 @@ rustc_queries! {
 
         /// Get a map with the variance of every item; use `item_variance`
         /// instead.
-        query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap> {
+        query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap<'tcx>> {
             desc { "computing the variances for items in this crate" }
         }
 
         /// Maps from def-id of a type or region parameter to its
         /// (inferred) variance.
-        query variances_of(_: DefId) -> Lrc<Vec<ty::Variance>> {}
+        query variances_of(_: DefId) -> &'tcx [ty::Variance] {}
     }
 
     TypeChecking {
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 69532b9b2c4..6b938ea2fcc 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -332,15 +332,11 @@ pub enum Variance {
 /// `tcx.variances_of()` to get the variance for a *particular*
 /// item.
 #[derive(HashStable)]
-pub struct CrateVariancesMap {
+pub struct CrateVariancesMap<'tcx> {
     /// For each item with generics, maps to a vector of the variance
     /// of its generics. If an item has no generics, it will have no
     /// entry.
-    pub variances: FxHashMap<DefId, Lrc<Vec<ty::Variance>>>,
-
-    /// An empty vector, useful for cloning.
-    #[stable_hasher(ignore)]
-    pub empty_variance: Lrc<Vec<ty::Variance>>,
+    pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>,
 }
 
 impl Variance {
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 1f5a39cbef1..2638a1c7c88 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -60,7 +60,7 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
                b_subst);
 
         let opt_variances = self.tcx().variances_of(item_def_id);
-        relate_substs(self, Some(&opt_variances), a_subst, b_subst)
+        relate_substs(self, Some(opt_variances), a_subst, b_subst)
     }
 
     /// Switch variance for the purpose of relating `a` and `b`.
@@ -122,7 +122,7 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
 }
 
 pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
-                                        variances: Option<&Vec<ty::Variance>>,
+                                        variances: Option<&[ty::Variance]>,
                                         a_subst: SubstsRef<'tcx>,
                                         b_subst: SubstsRef<'tcx>)
                                         -> RelateResult<'tcx, SubstsRef<'tcx>>
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 53f06baaa9d..b3439e4c970 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -106,7 +106,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         let _ = cdata;
         tcx.calculate_dtor(def_id, &mut |_,_| Ok(()))
     }
-    variances_of => { Lrc::new(cdata.get_item_variances(def_id.index)) }
+    variances_of => { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) }
     associated_item_def_ids => {
         let mut result = vec![];
         cdata.each_child_of_item(def_id.index,
diff --git a/src/librustc_typeck/variance/mod.rs b/src/librustc_typeck/variance/mod.rs
index 9b9a6bace96..88ee1d79f54 100644
--- a/src/librustc_typeck/variance/mod.rs
+++ b/src/librustc_typeck/variance/mod.rs
@@ -36,7 +36,7 @@ pub fn provide(providers: &mut Providers<'_>) {
 }
 
 fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
-                             -> Lrc<CrateVariancesMap> {
+                             -> Lrc<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);
@@ -45,7 +45,7 @@ fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
 }
 
 fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
-                          -> Lrc<Vec<ty::Variance>> {
+                          -> &'tcx [ty::Variance] {
     let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id");
     let unsupported = || {
         // Variance not relevant.
@@ -88,6 +88,6 @@ fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
 
     let crate_map = tcx.crate_variances(LOCAL_CRATE);
     crate_map.variances.get(&item_def_id)
-                       .unwrap_or(&crate_map.empty_variance)
-                       .clone()
+                       .map(|p| *p)
+                       .unwrap_or(&[])
 }
diff --git a/src/librustc_typeck/variance/solve.rs b/src/librustc_typeck/variance/solve.rs
index 51a1d088ddc..8edf3c52ccc 100644
--- a/src/librustc_typeck/variance/solve.rs
+++ b/src/librustc_typeck/variance/solve.rs
@@ -8,7 +8,6 @@
 use rustc::hir::def_id::DefId;
 use rustc::ty;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::Lrc;
 
 use super::constraints::*;
 use super::terms::*;
@@ -23,7 +22,9 @@ struct SolveContext<'a, 'tcx: 'a> {
     solutions: Vec<ty::Variance>,
 }
 
-pub fn solve_constraints(constraints_cx: ConstraintContext<'_, '_>) -> ty::CrateVariancesMap {
+pub fn solve_constraints<'tcx>(
+    constraints_cx: ConstraintContext<'_, 'tcx>
+) -> ty::CrateVariancesMap<'tcx> {
     let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
 
     let mut solutions = vec![ty::Bivariant; terms_cx.inferred_terms.len()];
@@ -41,9 +42,8 @@ pub fn solve_constraints(constraints_cx: ConstraintContext<'_, '_>) -> ty::Crate
     };
     solutions_cx.solve();
     let variances = solutions_cx.create_map();
-    let empty_variance = Lrc::new(Vec::new());
 
-    ty::CrateVariancesMap { variances, empty_variance }
+    ty::CrateVariancesMap { variances }
 }
 
 impl<'a, 'tcx> SolveContext<'a, 'tcx> {
@@ -78,7 +78,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
         }
     }
 
-    fn enforce_const_invariance(&self, generics: &ty::Generics, variances: &mut Vec<ty::Variance>) {
+    fn enforce_const_invariance(&self, generics: &ty::Generics, variances: &mut [ty::Variance]) {
         let tcx = self.terms_cx.tcx;
 
         // Make all const parameters invariant.
@@ -94,7 +94,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
         }
     }
 
-    fn create_map(&self) -> FxHashMap<DefId, Lrc<Vec<ty::Variance>>> {
+    fn create_map(&self) -> FxHashMap<DefId, &'tcx [ty::Variance]> {
         let tcx = self.terms_cx.tcx;
 
         let solutions = &self.solutions;
@@ -103,22 +103,21 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
             let generics = tcx.generics_of(def_id);
             let count = generics.count();
 
-            let mut variances = solutions[start..(start + count)].to_vec();
-            debug!("id={} variances={:?}", id, variances);
+            let variances = tcx.arena.alloc_slice(&solutions[start..(start + count)]);
 
             // Const parameters are always invariant.
-            self.enforce_const_invariance(generics, &mut variances);
+            self.enforce_const_invariance(generics, variances);
 
             // Functions are permitted to have unused generic parameters: make those invariant.
             if let ty::FnDef(..) = tcx.type_of(def_id).sty {
-                for variance in &mut variances {
+                for variance in variances.iter_mut() {
                     if *variance == ty::Bivariant {
                         *variance = ty::Invariant;
                     }
                 }
             }
 
-            (def_id, Lrc::new(variances))
+            (def_id, &*variances)
         }).collect()
     }