use arena::TypedArena;
use dep_graph::DepTrackingMapConfig;
-use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace};
use rustc::ty::{self, TyCtxt};
use rustc::ty::maps::ItemVariances;
use std::fmt;
use util::nodemap::NodeMap;
use self::VarianceTerm::*;
-use self::ParamKind::*;
pub type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
match *self {
ConstantTerm(c1) => write!(f, "{:?}", c1),
TransformTerm(v1, v2) => write!(f, "({:?} \u{00D7} {:?})", v1, v2),
- InferredTerm(id) => write!(f, "[{}]", { let InferredIndex(i) = id; i })
+ InferredTerm(id) => {
+ write!(f, "[{}]", {
+ let InferredIndex(i) = id;
+ i
+ })
+ }
}
}
}
pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub arena: &'a TypedArena<VarianceTerm<'a>>,
- pub empty_variances: Rc<ty::ItemVariances>,
+ pub empty_variances: Rc<Vec<ty::Variance>>,
// For marker types, UnsafeCell, and other lang items where
// variance is hardcoded, records the item-id and the hardcoded
pub inferred_map: NodeMap<InferredIndex>,
// Maps from an InferredIndex to the info for that variable.
- pub inferred_infos: Vec<InferredInfo<'a>> ,
-}
-
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum ParamKind {
- TypeParam,
- RegionParam,
+ pub inferred_infos: Vec<InferredInfo<'a>>,
}
pub struct InferredInfo<'a> {
pub item_id: ast::NodeId,
- pub kind: ParamKind,
- pub space: ParamSpace,
pub index: usize,
pub param_id: ast::NodeId,
pub term: VarianceTermPtr<'a>,
pub initial_variance: ty::Variance,
}
-pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
- tcx: TyCtxt<'a, 'tcx, 'tcx>,
- arena: &'a mut TypedArena<VarianceTerm<'a>>)
- -> TermsContext<'a, 'tcx>
-{
+pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ arena: &'a mut TypedArena<VarianceTerm<'a>>)
+ -> TermsContext<'a, 'tcx> {
let mut terms_cx = TermsContext {
tcx: tcx,
arena: arena,
// cache and share the variance struct used for items with
// no type/region parameters
- empty_variances: Rc::new(ty::ItemVariances {
- types: VecPerParamSpace::empty(),
- regions: VecPerParamSpace::empty()
- })
+ empty_variances: Rc::new(vec![]),
};
// See README.md for a discussion on dep-graph management.
- tcx.visit_all_items_in_krate(|def_id| ItemVariances::to_dep_node(&def_id),
- &mut terms_cx);
+ tcx.visit_all_items_in_krate(|def_id| ItemVariances::to_dep_node(&def_id), &mut terms_cx);
terms_cx
}
-fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId,Vec<ty::Variance>)> {
+fn lang_items(tcx: TyCtxt) -> Vec<(ast::NodeId, Vec<ty::Variance>)> {
let all = vec![
(tcx.lang_items.phantom_data(), vec![ty::Covariant]),
(tcx.lang_items.unsafe_cell_type(), vec![ty::Invariant]),
fn add_inferreds_for_item(&mut self,
item_id: ast::NodeId,
has_self: bool,
- generics: &hir::Generics)
- {
- /*!
- * Add "inferreds" for the generic parameters declared on this
- * item. This has a lot of annoying parameters because we are
- * trying to drive this from the AST, rather than the
- * ty::Generics, so that we can get span info -- but this
- * means we must accommodate syntactic distinctions.
- */
+ generics: &hir::Generics) {
+ //! Add "inferreds" for the generic parameters declared on this
+ //! item. This has a lot of annoying parameters because we are
+ //! trying to drive this from the AST, rather than the
+ //! ty::Generics, so that we can get span info -- but this
+ //! means we must accommodate syntactic distinctions.
+ //!
// NB: In the code below for writing the results back into the
// tcx, we rely on the fact that all inferreds for a particular
let inferreds_on_entry = self.num_inferred();
if has_self {
- self.add_inferred(item_id, TypeParam, SelfSpace, 0, item_id);
+ self.add_inferred(item_id, 0, item_id);
}
for (i, p) in generics.lifetimes.iter().enumerate() {
let id = p.lifetime.id;
- self.add_inferred(item_id, RegionParam, TypeSpace, i, id);
+ let i = has_self as usize + i;
+ self.add_inferred(item_id, i, id);
}
for (i, p) in generics.ty_params.iter().enumerate() {
- self.add_inferred(item_id, TypeParam, TypeSpace, i, p.id);
+ let i = has_self as usize + generics.lifetimes.len() + i;
+ self.add_inferred(item_id, i, p.id);
}
// If this item has no type or lifetime parameters,
// parameters".
if self.num_inferred() == inferreds_on_entry {
let item_def_id = self.tcx.map.local_def_id(item_id);
- let newly_added =
- self.tcx.item_variance_map.borrow_mut().insert(
- item_def_id,
- self.empty_variances.clone()).is_none();
+ let newly_added = self.tcx
+ .item_variance_map
+ .borrow_mut()
+ .insert(item_def_id, self.empty_variances.clone())
+ .is_none();
assert!(newly_added);
}
}
- fn add_inferred(&mut self,
- item_id: ast::NodeId,
- kind: ParamKind,
- space: ParamSpace,
- index: usize,
- param_id: ast::NodeId) {
+ fn add_inferred(&mut self, item_id: ast::NodeId, index: usize, param_id: ast::NodeId) {
let inf_index = InferredIndex(self.inferred_infos.len());
let term = self.arena.alloc(InferredTerm(inf_index));
- let initial_variance = self.pick_initial_variance(item_id, space, index);
- self.inferred_infos.push(InferredInfo { item_id: item_id,
- kind: kind,
- space: space,
- index: index,
- param_id: param_id,
- term: term,
- initial_variance: initial_variance });
+ let initial_variance = self.pick_initial_variance(item_id, index);
+ self.inferred_infos.push(InferredInfo {
+ item_id: item_id,
+ index: index,
+ param_id: param_id,
+ term: term,
+ initial_variance: initial_variance,
+ });
let newly_added = self.inferred_map.insert(param_id, inf_index).is_none();
assert!(newly_added);
debug!("add_inferred(item_path={}, \
item_id={}, \
- kind={:?}, \
- space={:?}, \
index={}, \
param_id={}, \
inf_index={:?}, \
initial_variance={:?})",
self.tcx.item_path_str(self.tcx.map.local_def_id(item_id)),
- item_id, kind, space, index, param_id, inf_index,
+ item_id,
+ index,
+ param_id,
+ inf_index,
initial_variance);
}
- fn pick_initial_variance(&self,
- item_id: ast::NodeId,
- space: ParamSpace,
- index: usize)
- -> ty::Variance
- {
- match space {
- SelfSpace | FnSpace => {
- ty::Bivariant
- }
-
- TypeSpace => {
- match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
- Some(&(_, ref variances)) => variances[index],
- None => ty::Bivariant
- }
- }
+ fn pick_initial_variance(&self, item_id: ast::NodeId, index: usize) -> ty::Variance {
+ match self.lang_items.iter().find(|&&(n, _)| n == item_id) {
+ Some(&(_, ref variances)) => variances[index],
+ None => ty::Bivariant,
}
}
impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
fn visit_item(&mut self, item: &hir::Item) {
- debug!("add_inferreds for item {}", self.tcx.map.node_to_string(item.id));
+ debug!("add_inferreds for item {}",
+ self.tcx.map.node_to_string(item.id));
match item.node {
hir::ItemEnum(_, ref generics) |
- hir::ItemStruct(_, ref generics) => {
+ hir::ItemStruct(_, ref generics) |
+ hir::ItemUnion(_, ref generics) => {
self.add_inferreds_for_item(item.id, false, generics);
}
- hir::ItemTrait(_, ref generics, _, _) => {
+ hir::ItemTrait(_, ref generics, ..) => {
// Note: all inputs for traits are ultimately
// constrained to be invariant. See `visit_item` in
// the impl for `ConstraintContext` in `constraints.rs`.
hir::ItemFn(..) |
hir::ItemMod(..) |
hir::ItemForeignMod(..) |
- hir::ItemTy(..) => {
- }
+ hir::ItemTy(..) => {}
}
}
}
-