about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-04-06 14:53:11 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-04-15 20:53:03 +0200
commite3e4420906b23bbcb266d93f5ac3ac75300cce21 (patch)
tree08f04833d706a55a4d9a66cf0baa5228f52fabb5
parent7360d6dd678d186d9c9b46311b75ba6840e61aa2 (diff)
downloadrust-e3e4420906b23bbcb266d93f5ac3ac75300cce21.tar.gz
rust-e3e4420906b23bbcb266d93f5ac3ac75300cce21.zip
Make layout_depth thread-safe
-rw-r--r--src/librustc/ty/context.rs10
-rw-r--r--src/librustc/ty/layout.rs29
-rw-r--r--src/librustc/ty/maps/plumbing.rs1
3 files changed, 23 insertions, 17 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ed3332f32d0..9da83199ec9 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -62,7 +62,6 @@ use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::{Lrc, Lock};
 use std::any::Any;
 use std::borrow::Borrow;
-use std::cell::Cell;
 use std::cmp::Ordering;
 use std::collections::hash_map::{self, Entry};
 use std::hash::{Hash, Hasher};
@@ -915,9 +914,6 @@ pub struct GlobalCtxt<'tcx> {
     /// Data layout specification for the current target.
     pub data_layout: TargetDataLayout,
 
-    /// Used to prevent layout from recursing too deeply.
-    pub layout_depth: Cell<usize>,
-
     stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
 
     pub interpret_interner: InterpretInterner<'tcx>,
@@ -1292,7 +1288,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             crate_name: Symbol::intern(crate_name),
             data_layout,
             layout_interner: Lock::new(FxHashSet()),
-            layout_depth: Cell::new(0),
             stability_interner: Lock::new(FxHashSet()),
             interpret_interner: Default::default(),
             tx_to_llvm_workers: Lock::new(tx),
@@ -1574,6 +1569,7 @@ impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> {
             let new_icx = ty::tls::ImplicitCtxt {
                 tcx,
                 query: icx.query.clone(),
+                layout_depth: icx.layout_depth,
             };
             ty::tls::enter_context(&new_icx, |new_icx| {
                 f(new_icx.tcx)
@@ -1768,6 +1764,9 @@ pub mod tls {
         /// The current query job, if any. This is updated by start_job in
         /// ty::maps::plumbing when executing a query
         pub query: Option<Lrc<maps::QueryJob<'gcx>>>,
+
+        /// Used to prevent layout from recursing too deeply.
+        pub layout_depth: usize,
     }
 
     // A thread local value which stores a pointer to the current ImplicitCtxt
@@ -1853,6 +1852,7 @@ pub mod tls {
             let icx = ImplicitCtxt {
                 tcx,
                 query: None,
+                layout_depth: 0,
             };
             enter_context(&icx, |_| {
                 f(tcx)
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 35ada4a7227..6bd833568d4 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -896,21 +896,26 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
                         -> Result<&'tcx LayoutDetails, LayoutError<'tcx>>
 {
-    let (param_env, ty) = query.into_parts();
+    ty::tls::with_related_context(tcx, move |icx| {
+        let rec_limit = *tcx.sess.recursion_limit.get();
+        let (param_env, ty) = query.into_parts();
 
-    let rec_limit = *tcx.sess.recursion_limit.get();
-    let depth = tcx.layout_depth.get();
-    if depth > rec_limit {
-        tcx.sess.fatal(
-            &format!("overflow representing the type `{}`", ty));
-    }
+        if icx.layout_depth > rec_limit {
+            tcx.sess.fatal(
+                &format!("overflow representing the type `{}`", ty));
+        }
 
-    tcx.layout_depth.set(depth+1);
-    let cx = LayoutCx { tcx, param_env };
-    let layout = cx.layout_raw_uncached(ty);
-    tcx.layout_depth.set(depth);
+        // Update the ImplicitCtxt to increase the layout_depth
+        let icx = ty::tls::ImplicitCtxt {
+            layout_depth: icx.layout_depth + 1,
+            ..icx.clone()
+        };
 
-    layout
+        ty::tls::enter_context(&icx, |_| {
+            let cx = LayoutCx { tcx, param_env };
+            cx.layout_raw_uncached(ty)
+        })
+    })
 }
 
 pub fn provide(providers: &mut ty::maps::Providers) {
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index efe7a56d800..185db623c6f 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -522,6 +522,7 @@ macro_rules! define_maps {
                         let icx = ty::tls::ImplicitCtxt {
                             tcx,
                             query: Some(job.clone()),
+                            layout_depth: icx.layout_depth,
                         };
 
                         // Use the ImplicitCtxt while we execute the query