about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-04-01 08:15:59 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-04-10 14:39:57 +0200
commitcf3b7909fa8f1774fc9eac854ef9d9a5b91a1d3f (patch)
treeae10733caa36a1c80e598099d34cadb98f8e6f35
parent472b416592f494aa4fe0db50802ba49803cec26d (diff)
downloadrust-cf3b7909fa8f1774fc9eac854ef9d9a5b91a1d3f.tar.gz
rust-cf3b7909fa8f1774fc9eac854ef9d9a5b91a1d3f.zip
Make recursion_limit and type_length_limit thread-safe
-rw-r--r--src/librustc/middle/recursion_limit.rs11
-rw-r--r--src/librustc/session/mod.rs14
-rw-r--r--src/librustc/traits/project.rs6
-rw-r--r--src/librustc/traits/query/normalize.rs2
-rw-r--r--src/librustc/traits/select.rs2
-rw-r--r--src/librustc/ty/layout.rs2
-rw-r--r--src/librustc_driver/driver.rs2
-rw-r--r--src/librustc_mir/monomorphize/collector.rs4
-rw-r--r--src/librustc_traits/dropck_outlives.rs2
-rw-r--r--src/librustc_typeck/check/autoderef.rs4
10 files changed, 25 insertions, 24 deletions
diff --git a/src/librustc/middle/recursion_limit.rs b/src/librustc/middle/recursion_limit.rs
index 6c87f750376..077a20315a2 100644
--- a/src/librustc/middle/recursion_limit.rs
+++ b/src/librustc/middle/recursion_limit.rs
@@ -18,17 +18,17 @@
 use session::Session;
 use syntax::ast;
 
-use std::cell::Cell;
+use rustc_data_structures::sync::Once;
 
 pub fn update_limits(sess: &Session, krate: &ast::Crate) {
     update_limit(sess, krate, &sess.recursion_limit, "recursion_limit",
-                 "recursion limit");
+                 "recursion limit", 64);
     update_limit(sess, krate, &sess.type_length_limit, "type_length_limit",
-                 "type length limit");
+                 "type length limit", 1048576);
 }
 
-fn update_limit(sess: &Session, krate: &ast::Crate, limit: &Cell<usize>,
-                name: &str, description: &str) {
+fn update_limit(sess: &Session, krate: &ast::Crate, limit: &Once<usize>,
+                name: &str, description: &str, default: usize) {
     for attr in &krate.attrs {
         if !attr.check_name(name) {
             continue;
@@ -45,4 +45,5 @@ fn update_limit(sess: &Session, krate: &ast::Crate, limit: &Cell<usize>,
                   "malformed {} attribute, expected #![{}=\"N\"]",
                   description, name);
     }
+    limit.set(default);
 }
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 79c835744a3..afb62aca582 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -26,7 +26,7 @@ use util::nodemap::{FxHashMap, FxHashSet};
 use util::common::{duration_to_secs_str, ErrorReported};
 use util::common::ProfileQueriesMsg;
 
-use rustc_data_structures::sync::{Lrc, Lock, OneThread};
+use rustc_data_structures::sync::{Lrc, Lock, OneThread, Once};
 
 use syntax::ast::NodeId;
 use errors::{self, DiagnosticBuilder, DiagnosticId};
@@ -46,13 +46,13 @@ use rustc_back::target::{Target, TargetTriple};
 use rustc_data_structures::flock;
 use jobserver::Client;
 
+use std;
 use std::cell::{self, Cell, RefCell};
 use std::collections::HashMap;
 use std::env;
 use std::fmt;
 use std::io::Write;
 use std::path::{Path, PathBuf};
-use std::sync::{Once, ONCE_INIT};
 use std::time::Duration;
 use std::sync::mpsc;
 
@@ -105,10 +105,10 @@ pub struct Session {
 
     /// The maximum recursion limit for potentially infinitely recursive
     /// operations such as auto-dereference and monomorphization.
-    pub recursion_limit: Cell<usize>,
+    pub recursion_limit: Once<usize>,
 
     /// The maximum length of types during monomorphization.
-    pub type_length_limit: Cell<usize>,
+    pub type_length_limit: Once<usize>,
 
     /// The maximum number of stackframes allowed in const eval
     pub const_eval_stack_frame_limit: Cell<usize>,
@@ -1147,8 +1147,8 @@ pub fn build_session_(
         dependency_formats: RefCell::new(FxHashMap()),
         crate_disambiguator: RefCell::new(None),
         features: RefCell::new(None),
-        recursion_limit: Cell::new(64),
-        type_length_limit: Cell::new(1048576),
+        recursion_limit: Once::new(),
+        type_length_limit: Once::new(),
         const_eval_stack_frame_limit: Cell::new(100),
         const_eval_step_limit: Cell::new(1_000_000),
         next_node_id: Cell::new(NodeId::new(1)),
@@ -1188,7 +1188,7 @@ pub fn build_session_(
         // per-process.
         jobserver_from_env: unsafe {
             static mut GLOBAL_JOBSERVER: *mut Option<Client> = 0 as *mut _;
-            static INIT: Once = ONCE_INIT;
+            static INIT: std::sync::Once = std::sync::ONCE_INIT;
             INIT.call_once(|| {
                 GLOBAL_JOBSERVER = Box::into_raw(Box::new(Client::from_env()));
             });
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 2a62d0b5ee3..9f21ea14d0f 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -345,7 +345,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
                     Reveal::UserFacing => ty,
 
                     Reveal::All => {
-                        let recursion_limit = self.tcx().sess.recursion_limit.get();
+                        let recursion_limit = *self.tcx().sess.recursion_limit.get();
                         if self.depth >= recursion_limit {
                             let obligation = Obligation::with_depth(
                                 self.cause.clone(),
@@ -566,7 +566,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
                     found cache entry: in-progress");
 
             // But for now, let's classify this as an overflow:
-            let recursion_limit = selcx.tcx().sess.recursion_limit.get();
+            let recursion_limit = *selcx.tcx().sess.recursion_limit.get();
             let obligation = Obligation::with_depth(cause.clone(),
                                                     recursion_limit,
                                                     param_env,
@@ -848,7 +848,7 @@ fn project_type<'cx, 'gcx, 'tcx>(
     debug!("project(obligation={:?})",
            obligation);
 
-    let recursion_limit = selcx.tcx().sess.recursion_limit.get();
+    let recursion_limit = *selcx.tcx().sess.recursion_limit.get();
     if obligation.recursion_depth >= recursion_limit {
         debug!("project: overflow!");
         selcx.infcx().report_overflow_error(&obligation, true);
diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs
index 63f50cff4c2..5e0a4ca3305 100644
--- a/src/librustc/traits/query/normalize.rs
+++ b/src/librustc/traits/query/normalize.rs
@@ -109,7 +109,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx
                     Reveal::UserFacing => ty,
 
                     Reveal::All => {
-                        let recursion_limit = self.tcx().sess.recursion_limit.get();
+                        let recursion_limit = *self.tcx().sess.recursion_limit.get();
                         if self.anon_depth >= recursion_limit {
                             let obligation = Obligation::with_depth(
                                 self.cause.clone(),
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 58c591bf935..51493f26194 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -997,7 +997,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     {
         // Watch out for overflow. This intentionally bypasses (and does
         // not update) the cache.
-        let recursion_limit = self.infcx.tcx.sess.recursion_limit.get();
+        let recursion_limit = *self.infcx.tcx.sess.recursion_limit.get();
         if stack.obligation.recursion_depth >= recursion_limit {
             self.infcx().report_overflow_error(&stack.obligation, true);
         }
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 5f9c305d92f..91c61622407 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -898,7 +898,7 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 {
     let (param_env, ty) = query.into_parts();
 
-    let rec_limit = tcx.sess.recursion_limit.get();
+    let rec_limit = *tcx.sess.recursion_limit.get();
     let depth = tcx.layout_depth.get();
     if depth > rec_limit {
         tcx.sess.fatal(
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index c6ebc992680..8372cbdd5df 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -783,7 +783,7 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(sess: &'a Session,
         let features = sess.features_untracked();
         let cfg = syntax::ext::expand::ExpansionConfig {
             features: Some(&features),
-            recursion_limit: sess.recursion_limit.get(),
+            recursion_limit: *sess.recursion_limit.get(),
             trace_mac: sess.opts.debugging_opts.trace_macros,
             should_test: sess.opts.test,
             ..syntax::ext::expand::ExpansionConfig::default(crate_name.to_string())
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 209f6dbfa48..1189da10929 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -457,7 +457,7 @@ fn check_recursion_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // Code that needs to instantiate the same function recursively
     // more than the recursion limit is assumed to be causing an
     // infinite expansion.
-    if recursion_depth > tcx.sess.recursion_limit.get() {
+    if recursion_depth > *tcx.sess.recursion_limit.get() {
         let error = format!("reached the recursion limit while instantiating `{}`",
                             instance);
         if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
@@ -484,7 +484,7 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // which means that rustc basically hangs.
     //
     // Bail out in these cases to avoid that bad user experience.
-    let type_length_limit = tcx.sess.type_length_limit.get();
+    let type_length_limit = *tcx.sess.type_length_limit.get();
     if type_length > type_length_limit {
         // The instance name is already known to be too long for rustc. Use
         // `{:.64}` to avoid blasting the user's terminal with thousands of
diff --git a/src/librustc_traits/dropck_outlives.rs b/src/librustc_traits/dropck_outlives.rs
index 1fe2f87128a..5f4daf0d568 100644
--- a/src/librustc_traits/dropck_outlives.rs
+++ b/src/librustc_traits/dropck_outlives.rs
@@ -153,7 +153,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
         span, for_ty, depth, ty
     );
 
-    if depth >= tcx.sess.recursion_limit.get() {
+    if depth >= *tcx.sess.recursion_limit.get() {
         return Ok(DtorckConstraint {
             outlives: vec![],
             dtorck_types: vec![],
diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs
index 1d7c533178f..a87058d1fa5 100644
--- a/src/librustc_typeck/check/autoderef.rs
+++ b/src/librustc_typeck/check/autoderef.rs
@@ -56,9 +56,9 @@ impl<'a, 'gcx, 'tcx> Iterator for Autoderef<'a, 'gcx, 'tcx> {
             return Some((self.cur_ty, 0));
         }
 
-        if self.steps.len() >= tcx.sess.recursion_limit.get() {
+        if self.steps.len() >= *tcx.sess.recursion_limit.get() {
             // We've reached the recursion limit, error gracefully.
-            let suggested_limit = tcx.sess.recursion_limit.get() * 2;
+            let suggested_limit = *tcx.sess.recursion_limit.get() * 2;
             let msg = format!("reached the recursion limit while auto-dereferencing {:?}",
                               self.cur_ty);
             let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg.clone());