Skip to content

Commit 535fdfc

Browse files
authored
Rollup merge of rust-lang#60287 - Zoxc:the-arena-variances_of, r=eddyb
Use references for variances_of Based on rust-lang#60280. cc @varkor r? @eddyb
2 parents 96ee0ba + d2ff829 commit 535fdfc

File tree

7 files changed

+44
-29
lines changed

7 files changed

+44
-29
lines changed

src/librustc/arena.rs

+8
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ impl<'tcx> Arena<'tcx> {
144144
}
145145
}
146146

147+
#[inline]
148+
pub fn alloc_slice<T: Copy>(&self, value: &[T]) -> &mut [T] {
149+
if value.len() == 0 {
150+
return &mut []
151+
}
152+
self.dropless.alloc_slice(value)
153+
}
154+
147155
pub fn alloc_from_iter<
148156
T: ArenaAllocatable,
149157
I: IntoIterator<Item = T>

src/librustc/query/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,13 +245,13 @@ rustc_queries! {
245245

246246
/// Get a map with the variance of every item; use `item_variance`
247247
/// instead.
248-
query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap> {
248+
query crate_variances(_: CrateNum) -> Lrc<ty::CrateVariancesMap<'tcx>> {
249249
desc { "computing the variances for items in this crate" }
250250
}
251251

252252
/// Maps from def-id of a type or region parameter to its
253253
/// (inferred) variance.
254-
query variances_of(_: DefId) -> Lrc<Vec<ty::Variance>> {}
254+
query variances_of(_: DefId) -> &'tcx [ty::Variance] {}
255255
}
256256

257257
TypeChecking {

src/librustc/ty/mod.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -332,15 +332,11 @@ pub enum Variance {
332332
/// `tcx.variances_of()` to get the variance for a *particular*
333333
/// item.
334334
#[derive(HashStable)]
335-
pub struct CrateVariancesMap {
335+
pub struct CrateVariancesMap<'tcx> {
336336
/// For each item with generics, maps to a vector of the variance
337337
/// of its generics. If an item has no generics, it will have no
338338
/// entry.
339-
pub variances: FxHashMap<DefId, Lrc<Vec<ty::Variance>>>,
340-
341-
/// An empty vector, useful for cloning.
342-
#[stable_hasher(ignore)]
343-
pub empty_variance: Lrc<Vec<ty::Variance>>,
339+
pub variances: FxHashMap<DefId, &'tcx [ty::Variance]>,
344340
}
345341

346342
impl Variance {

src/librustc/ty/relate.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub trait TypeRelation<'a, 'gcx: 'a+'tcx, 'tcx: 'a> : Sized {
6060
b_subst);
6161

6262
let opt_variances = self.tcx().variances_of(item_def_id);
63-
relate_substs(self, Some(&opt_variances), a_subst, b_subst)
63+
relate_substs(self, Some(opt_variances), a_subst, b_subst)
6464
}
6565

6666
/// Switch variance for the purpose of relating `a` and `b`.
@@ -122,7 +122,7 @@ impl<'tcx> Relate<'tcx> for ty::TypeAndMut<'tcx> {
122122
}
123123

124124
pub fn relate_substs<'a, 'gcx, 'tcx, R>(relation: &mut R,
125-
variances: Option<&Vec<ty::Variance>>,
125+
variances: Option<&[ty::Variance]>,
126126
a_subst: SubstsRef<'tcx>,
127127
b_subst: SubstsRef<'tcx>)
128128
-> RelateResult<'tcx, SubstsRef<'tcx>>

src/librustc_metadata/cstore_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
106106
let _ = cdata;
107107
tcx.calculate_dtor(def_id, &mut |_,_| Ok(()))
108108
}
109-
variances_of => { Lrc::new(cdata.get_item_variances(def_id.index)) }
109+
variances_of => { tcx.arena.alloc_from_iter(cdata.get_item_variances(def_id.index)) }
110110
associated_item_def_ids => {
111111
let mut result = vec![];
112112
cdata.each_child_of_item(def_id.index,

src/librustc_typeck/variance/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ pub fn provide(providers: &mut Providers<'_>) {
3636
}
3737

3838
fn crate_variances<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum)
39-
-> Lrc<CrateVariancesMap> {
39+
-> Lrc<CrateVariancesMap<'tcx>> {
4040
assert_eq!(crate_num, LOCAL_CRATE);
4141
let mut arena = arena::TypedArena::default();
4242
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)
4545
}
4646

4747
fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
48-
-> Lrc<Vec<ty::Variance>> {
48+
-> &'tcx [ty::Variance] {
4949
let id = tcx.hir().as_local_hir_id(item_def_id).expect("expected local def-id");
5050
let unsupported = || {
5151
// Variance not relevant.
@@ -88,6 +88,6 @@ fn variances_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId)
8888

8989
let crate_map = tcx.crate_variances(LOCAL_CRATE);
9090
crate_map.variances.get(&item_def_id)
91-
.unwrap_or(&crate_map.empty_variance)
92-
.clone()
91+
.map(|p| *p)
92+
.unwrap_or(&[])
9393
}

src/librustc_typeck/variance/solve.rs

+25-14
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use rustc::hir::def_id::DefId;
99
use rustc::ty;
1010
use rustc_data_structures::fx::FxHashMap;
11-
use rustc_data_structures::sync::Lrc;
1211

1312
use super::constraints::*;
1413
use super::terms::*;
@@ -23,7 +22,9 @@ struct SolveContext<'a, 'tcx: 'a> {
2322
solutions: Vec<ty::Variance>,
2423
}
2524

26-
pub fn solve_constraints(constraints_cx: ConstraintContext<'_, '_>) -> ty::CrateVariancesMap {
25+
pub fn solve_constraints<'tcx>(
26+
constraints_cx: ConstraintContext<'_, 'tcx>
27+
) -> ty::CrateVariancesMap<'tcx> {
2728
let ConstraintContext { terms_cx, constraints, .. } = constraints_cx;
2829

2930
let mut solutions = vec![ty::Bivariant; terms_cx.inferred_terms.len()];
@@ -41,9 +42,8 @@ pub fn solve_constraints(constraints_cx: ConstraintContext<'_, '_>) -> ty::Crate
4142
};
4243
solutions_cx.solve();
4344
let variances = solutions_cx.create_map();
44-
let empty_variance = Lrc::new(Vec::new());
4545

46-
ty::CrateVariancesMap { variances, empty_variance }
46+
ty::CrateVariancesMap { variances }
4747
}
4848

4949
impl<'a, 'tcx> SolveContext<'a, 'tcx> {
@@ -78,7 +78,23 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
7878
}
7979
}
8080

81-
fn create_map(&self) -> FxHashMap<DefId, Lrc<Vec<ty::Variance>>> {
81+
fn enforce_const_invariance(&self, generics: &ty::Generics, variances: &mut [ty::Variance]) {
82+
let tcx = self.terms_cx.tcx;
83+
84+
// Make all const parameters invariant.
85+
for param in generics.params.iter() {
86+
if let ty::GenericParamDefKind::Const = param.kind {
87+
variances[param.index as usize] = ty::Invariant;
88+
}
89+
}
90+
91+
// Make all the const parameters in the parent invariant (recursively).
92+
if let Some(def_id) = generics.parent {
93+
self.enforce_const_invariance(tcx.generics_of(def_id), variances);
94+
}
95+
}
96+
97+
fn create_map(&self) -> FxHashMap<DefId, &'tcx [ty::Variance]> {
8298
let tcx = self.terms_cx.tcx;
8399

84100
let solutions = &self.solutions;
@@ -87,26 +103,21 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
87103
let generics = tcx.generics_of(def_id);
88104
let count = generics.count();
89105

90-
let mut variances = solutions[start..(start + count)].to_vec();
91-
debug!("id={} variances={:?}", id, variances);
106+
let variances = tcx.arena.alloc_slice(&solutions[start..(start + count)]);
92107

93108
// Const parameters are always invariant.
94-
for (idx, param) in generics.params.iter().enumerate() {
95-
if let ty::GenericParamDefKind::Const = param.kind {
96-
variances[idx] = ty::Invariant;
97-
}
98-
}
109+
self.enforce_const_invariance(generics, variances);
99110

100111
// Functions are permitted to have unused generic parameters: make those invariant.
101112
if let ty::FnDef(..) = tcx.type_of(def_id).sty {
102-
for variance in &mut variances {
113+
for variance in variances.iter_mut() {
103114
if *variance == ty::Bivariant {
104115
*variance = ty::Invariant;
105116
}
106117
}
107118
}
108119

109-
(def_id, Lrc::new(variances))
120+
(def_id, &*variances)
110121
}).collect()
111122
}
112123

0 commit comments

Comments
 (0)