c::tag_table_tcache => {
let type_scheme = val_dsr.read_type_scheme(dcx);
let lid = ast::DefId { krate: ast::LOCAL_CRATE, node: id };
- dcx.tcx.tcache.borrow_mut().insert(lid, type_scheme);
+ dcx.tcx.register_item_type(lid, type_scheme);
}
c::tag_table_param_defs => {
let bounds = val_dsr.read_type_param_def(dcx);
impl<'tcx> CommonTypes<'tcx> {
fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
- interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
+ interner: &RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>)
-> CommonTypes<'tcx>
{
- let mut mk = |sty| ctxt::intern_ty(arena, interner, sty);
+ let mk = |sty| ctxt::intern_ty(arena, interner, sty);
CommonTypes {
bool: mk(TyBool),
char: mk(TyChar),
f: F) -> (Session, R)
where F: FnOnce(&ctxt<'tcx>) -> R
{
- let mut interner = FnvHashMap();
- let common_types = CommonTypes::new(&arenas.type_, &mut interner);
+ let interner = RefCell::new(FnvHashMap());
+ let common_types = CommonTypes::new(&arenas.type_, &interner);
tls::enter(ctxt {
arenas: arenas,
- interner: RefCell::new(interner),
+ interner: interner,
substs_interner: RefCell::new(FnvHashMap()),
bare_fn_interner: RefCell::new(FnvHashMap()),
region_interner: RefCell::new(FnvHashMap()),
}
fn intern_ty(type_arena: &'tcx TypedArena<TyS<'tcx>>,
- interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
+ interner: &RefCell<FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>>,
st: TypeVariants<'tcx>)
-> Ty<'tcx> {
- match interner.get(&st) {
- Some(ty) => return *ty,
- _ => ()
- }
+ let ty: Ty /* don't be &mut TyS */ = {
+ let mut interner = interner.borrow_mut();
+ match interner.get(&st) {
+ Some(ty) => return *ty,
+ _ => ()
+ }
- let flags = FlagComputation::for_sty(&st);
+ let flags = FlagComputation::for_sty(&st);
+
+ let ty = match () {
+ () => type_arena.alloc(TyS { sty: st,
+ flags: Cell::new(flags.flags),
+ region_depth: flags.depth, }),
+ };
- let ty = match () {
- () => type_arena.alloc(TyS { sty: st,
- flags: Cell::new(flags.flags),
- region_depth: flags.depth, }),
+ interner.insert(InternedTy { ty: ty }, ty);
+ ty
};
debug!("Interned type: {:?} Pointer: {:?}",
ty, ty as *const TyS);
-
- interner.insert(InternedTy { ty: ty }, ty);
-
ty
}
// Interns a type/name combination, stores the resulting box in cx.interner,
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
- let mut interner = self.interner.borrow_mut();
- ctxt::intern_ty(&self.arenas.type_, &mut *interner, st)
+ ctxt::intern_ty(&self.arenas.type_, &self.interner, st)
}
pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> {
.clone()
}
+ // Register a given item type
+ pub fn register_item_type(&self, did: ast::DefId, ty: TypeScheme<'tcx>) {
+ self.tcache.borrow_mut().insert(did, ty);
+ }
// If the given item is in an external crate, looks up its type and adds it to
// the type cache. Returns the type parameters and type.
if id.krate == ast::LOCAL_CRATE {
self.node_id_to_type(id.node)
} else {
- let mut tcache = self.tcache.borrow_mut();
- tcache.entry(id).or_insert_with(|| csearch::get_field_type(self, struct_id, id)).ty
+ memoized(&self.tcache, id,
+ |id| csearch::get_field_type(self, struct_id, id)).ty
}
}
TyError => write!(f, "[type error]"),
TyParam(ref param_ty) => write!(f, "{}", param_ty),
TyEnum(did, substs) | TyStruct(did, substs) => {
- parameterized(f, substs, did, &[],
- |tcx| tcx.lookup_item_type(did).generics)
+ ty::tls::with(|tcx| {
+ if did.krate == ast::LOCAL_CRATE &&
+ !tcx.tcache.borrow().contains_key(&did) {
+ write!(f, "{}<..>", tcx.item_path_str(did))
+ } else {
+ parameterized(f, substs, did, &[],
+ |tcx| tcx.lookup_item_type(did).generics)
+ }
+ })
}
TyTrait(ref data) => write!(f, "{}", data),
ty::TyProjection(ref data) => write!(f, "{}", data),
let inh = static_inherited_fields(ccx, &tables);
let rty = ccx.tcx.node_id_to_type(id);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
- let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty;
+ let declty = fcx.ccx.tcx.lookup_item_type(local_def(id)).ty;
check_const_with_ty(&fcx, sp, e, declty);
}
};
debug!("new_polytype={:?}", new_polytype);
- tcx.tcache.borrow_mut().insert(new_did, new_polytype);
+ tcx.register_item_type(new_did, new_polytype);
tcx.predicates.borrow_mut().insert(new_did, new_method_ty.predicates.clone());
tcx.impl_or_trait_items
.borrow_mut()
ty: result_ty
};
- tcx.tcache.borrow_mut().insert(variant_def_id, variant_scheme.clone());
+ tcx.register_item_type(variant_def_id, variant_scheme.clone());
tcx.predicates.borrow_mut().insert(variant_def_id, enum_predicates.clone());
write_ty_to_tcx(tcx, variant.node.id, result_ty);
}
ccx.tcx.mk_bare_fn(ty_method.fty.clone()));
debug!("method {} (id {}) has type {:?}",
ident, id, fty);
- ccx.tcx.tcache.borrow_mut().insert(def_id,TypeScheme {
+ ccx.tcx.register_item_type(def_id, TypeScheme {
generics: ty_method.generics.clone(),
ty: fty
});
write_ty_to_tcx(ccx.tcx, v.node.id, tt);
/* add the field to the tcache */
- ccx.tcx.tcache.borrow_mut().insert(local_def(v.node.id),
- ty::TypeScheme {
- generics: struct_generics.clone(),
- ty: tt
- });
+ ccx.tcx.register_item_type(local_def(v.node.id),
+ ty::TypeScheme {
+ generics: struct_generics.clone(),
+ ty: tt
+ });
ccx.tcx.predicates.borrow_mut().insert(local_def(v.node.id),
struct_predicates.clone());
let selfty = ccx.icx(&ty_predicates).to_ty(&ExplicitRscope, &**selfty);
write_ty_to_tcx(tcx, it.id, selfty);
- tcx.tcache.borrow_mut().insert(local_def(it.id),
- TypeScheme { generics: ty_generics.clone(),
- ty: selfty });
+ tcx.register_item_type(local_def(it.id),
+ TypeScheme { generics: ty_generics.clone(),
+ ty: selfty });
tcx.predicates.borrow_mut().insert(local_def(it.id),
ty_predicates.clone());
if let ast::ConstImplItem(ref ty, ref expr) = impl_item.node {
let ty = ccx.icx(&ty_predicates)
.to_ty(&ExplicitRscope, &*ty);
- tcx.tcache.borrow_mut().insert(local_def(impl_item.id),
- TypeScheme {
- generics: ty_generics.clone(),
- ty: ty,
- });
+ tcx.register_item_type(local_def(impl_item.id),
+ TypeScheme {
+ generics: ty_generics.clone(),
+ ty: ty,
+ });
convert_associated_const(ccx, ImplContainer(local_def(it.id)),
impl_item.ident, impl_item.id,
impl_item.vis.inherit_from(parent_visibility),
ast::ConstTraitItem(ref ty, ref default) => {
let ty = ccx.icx(&trait_predicates)
.to_ty(&ExplicitRscope, ty);
- tcx.tcache.borrow_mut().insert(local_def(trait_item.id),
- TypeScheme {
- generics: trait_def.generics.clone(),
- ty: ty,
- });
+ tcx.register_item_type(local_def(trait_item.id),
+ TypeScheme {
+ generics: trait_def.generics.clone(),
+ ty: ty,
+ });
convert_associated_const(ccx, TraitContainer(local_def(it.id)),
trait_item.ident, trait_item.id,
ast::Public, ty, default.as_ref().map(|d| &**d));
// Enum-like.
write_ty_to_tcx(tcx, ctor_id, selfty);
- tcx.tcache.borrow_mut().insert(local_def(ctor_id), scheme);
+ tcx.register_item_type(local_def(ctor_id), scheme);
tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates);
} else if struct_def.fields[0].node.kind.is_unnamed() {
// Tuple-like.
let inputs: Vec<_> =
struct_def.fields
.iter()
- .map(|field| tcx.tcache.borrow().get(&local_def(field.node.id))
- .unwrap()
- .ty)
+ .map(|field| tcx.lookup_item_type(
+ local_def(field.node.id)).ty)
.collect();
let ctor_fn_ty = tcx.mk_ctor_fn(local_def(ctor_id),
&inputs[..],
selfty);
write_ty_to_tcx(tcx, ctor_id, ctor_fn_ty);
- tcx.tcache.borrow_mut().insert(local_def(ctor_id),
- TypeScheme {
- generics: scheme.generics,
- ty: ctor_fn_ty
- });
+ tcx.register_item_type(local_def(ctor_id),
+ TypeScheme {
+ generics: scheme.generics,
+ ty: ctor_fn_ty
+ });
tcx.predicates.borrow_mut().insert(local_def(ctor_id), predicates);
}
}