Update variances_of
This commit is contained in:
parent
f024196dd5
commit
d2ff829433
7 changed files with 29 additions and 26 deletions
|
@ -102,6 +102,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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -330,15 +330,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 {
|
||||
|
|
|
@ -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>>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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(&[])
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue