]> git.lizzy.rs Git - rust.git/commitdiff
Fix deadlocks with RUST_LOG=rustc::middle::ty
authorAriel Ben-Yehuda <arielb1@mail.tau.ac.il>
Wed, 1 Jul 2015 20:07:26 +0000 (23:07 +0300)
committerAriel Ben-Yehuda <arielb1@mail.tau.ac.il>
Wed, 1 Jul 2015 20:08:40 +0000 (23:08 +0300)
These are RefCell deadlocks that cause the rustc task to die with the stderr
lock held, causing a real deadlock.

Fixes #26717.

src/librustc/middle/astencode.rs
src/librustc/middle/ty.rs
src/librustc/util/ppaux.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/collect.rs

index d2c79e1d820bf98751cb81b562eda485f0f5006d..a0efc50d0d781143b87e088bd1d1e5e503f325aa 100644 (file)
@@ -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);
index 489ce7bc4cf78c102eb07846f8d5fd17dcec4f97..4ec59926eaef24ffc8c5c7795a6c6cc378a530a7 100644 (file)
@@ -3198,10 +3198,10 @@ fn closure_upvars(&self,
 
 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 @@ pub fn create_and_enter<F, R>(s: Session,
                                  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 @@ pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option<ast::Mutability
     }
 
     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 @@ pub fn enum_variant_with_id(&self,
                                    .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 @@ pub fn lookup_field_type_unsubstituted(&self,
         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
         }
     }
 
index de2f33e8a4ac9dd3233639804f2428759eec7e17..91b547e967952b2d8646da9dd5d4f98730b822b9 100644 (file)
@@ -680,8 +680,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
             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),
index 7e87dc6540ea517f122b631c29beef3ec5e7a7d0..020aac2c197af3631e9c7c8172e21a327cdcd553 100644 (file)
@@ -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);
 }
 
index fbabc287342e9e0ce9d5c59f1f6a18e17203580b..da7851b18f9d029bf6e1311747772a81beeb390a 100644 (file)
@@ -214,7 +214,7 @@ fn instantiate_default_methods(
             };
             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()
index ef9dcd56a578bdc1d8f04777a9f482e0965576dd..4ac100f4c1012b873de3fe88aaf18048d39ab0dc 100644 (file)
@@ -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);
             }
         }