diff options
| author | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2015-07-01 23:07:26 +0300 |
|---|---|---|
| committer | Ariel Ben-Yehuda <arielb1@mail.tau.ac.il> | 2015-07-01 23:08:40 +0300 |
| commit | 2fc85718615a4261eba5ef0e696e1d995cdfd375 (patch) | |
| tree | 48aa7e1b48ec5dc1ff3a56cbc3b9b5a346ad2e2a /src | |
| parent | 40db46c6ba0d59e5ad9aa056a73055d2d3b83d04 (diff) | |
| download | rust-2fc85718615a4261eba5ef0e696e1d995cdfd375.tar.gz rust-2fc85718615a4261eba5ef0e696e1d995cdfd375.zip | |
Fix deadlocks with RUST_LOG=rustc::middle::ty
These are RefCell deadlocks that cause the rustc task to die with the stderr lock held, causing a real deadlock. Fixes #26717.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/astencode.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/ty.rs | 50 | ||||
| -rw-r--r-- | src/librustc/util/ppaux.rs | 11 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/coherence/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/collect.rs | 57 |
6 files changed, 68 insertions, 56 deletions
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index d2c79e1d820..a0efc50d0d7 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -1656,7 +1656,7 @@ fn decode_side_tables(dcx: &DecodeContext, 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); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 489ce7bc4cf..4ec59926eae 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3198,10 +3198,10 @@ pub trait ClosureTyper<'tcx> { 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), @@ -3430,12 +3430,12 @@ impl<'tcx> ctxt<'tcx> { 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()), @@ -3563,35 +3563,37 @@ impl<'tcx> ctxt<'tcx> { } 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> { @@ -5930,6 +5932,10 @@ impl<'tcx> ctxt<'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. @@ -6006,8 +6012,8 @@ impl<'tcx> ctxt<'tcx> { 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 } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index de2f33e8a4a..91b547e9679 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -680,8 +680,15 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { 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), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 7e87dc6540e..020aac2c197 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4007,7 +4007,7 @@ fn check_const<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, 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); } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fbabc287342..da7851b18f9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -214,7 +214,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { }; 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() diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ef9dcd56a57..4ac100f4c10 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -596,7 +596,7 @@ fn get_enum_variant_types<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, 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); } @@ -635,7 +635,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, 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 }); @@ -661,11 +661,11 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, 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()); @@ -841,9 +841,9 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { 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()); @@ -863,11 +863,11 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { 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), @@ -954,11 +954,11 @@ fn convert_item(ccx: &CrateCtxt, it: &ast::Item) { 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)); @@ -1099,26 +1099,25 @@ fn convert_struct<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // 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); } } |
