Make layout_depth thread-safe
This commit is contained in:
parent
7360d6dd67
commit
e3e4420906
3 changed files with 23 additions and 17 deletions
|
@ -62,7 +62,6 @@ use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
use rustc_data_structures::sync::{Lrc, Lock};
|
use rustc_data_structures::sync::{Lrc, Lock};
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::cell::Cell;
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::hash_map::{self, Entry};
|
use std::collections::hash_map::{self, Entry};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
@ -915,9 +914,6 @@ pub struct GlobalCtxt<'tcx> {
|
||||||
/// Data layout specification for the current target.
|
/// Data layout specification for the current target.
|
||||||
pub data_layout: TargetDataLayout,
|
pub data_layout: TargetDataLayout,
|
||||||
|
|
||||||
/// Used to prevent layout from recursing too deeply.
|
|
||||||
pub layout_depth: Cell<usize>,
|
|
||||||
|
|
||||||
stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
|
stability_interner: Lock<FxHashSet<&'tcx attr::Stability>>,
|
||||||
|
|
||||||
pub interpret_interner: InterpretInterner<'tcx>,
|
pub interpret_interner: InterpretInterner<'tcx>,
|
||||||
|
@ -1292,7 +1288,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
crate_name: Symbol::intern(crate_name),
|
crate_name: Symbol::intern(crate_name),
|
||||||
data_layout,
|
data_layout,
|
||||||
layout_interner: Lock::new(FxHashSet()),
|
layout_interner: Lock::new(FxHashSet()),
|
||||||
layout_depth: Cell::new(0),
|
|
||||||
stability_interner: Lock::new(FxHashSet()),
|
stability_interner: Lock::new(FxHashSet()),
|
||||||
interpret_interner: Default::default(),
|
interpret_interner: Default::default(),
|
||||||
tx_to_llvm_workers: Lock::new(tx),
|
tx_to_llvm_workers: Lock::new(tx),
|
||||||
|
@ -1574,6 +1569,7 @@ impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> {
|
||||||
let new_icx = ty::tls::ImplicitCtxt {
|
let new_icx = ty::tls::ImplicitCtxt {
|
||||||
tcx,
|
tcx,
|
||||||
query: icx.query.clone(),
|
query: icx.query.clone(),
|
||||||
|
layout_depth: icx.layout_depth,
|
||||||
};
|
};
|
||||||
ty::tls::enter_context(&new_icx, |new_icx| {
|
ty::tls::enter_context(&new_icx, |new_icx| {
|
||||||
f(new_icx.tcx)
|
f(new_icx.tcx)
|
||||||
|
@ -1768,6 +1764,9 @@ pub mod tls {
|
||||||
/// The current query job, if any. This is updated by start_job in
|
/// The current query job, if any. This is updated by start_job in
|
||||||
/// ty::maps::plumbing when executing a query
|
/// ty::maps::plumbing when executing a query
|
||||||
pub query: Option<Lrc<maps::QueryJob<'gcx>>>,
|
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
|
// A thread local value which stores a pointer to the current ImplicitCtxt
|
||||||
|
@ -1853,6 +1852,7 @@ pub mod tls {
|
||||||
let icx = ImplicitCtxt {
|
let icx = ImplicitCtxt {
|
||||||
tcx,
|
tcx,
|
||||||
query: None,
|
query: None,
|
||||||
|
layout_depth: 0,
|
||||||
};
|
};
|
||||||
enter_context(&icx, |_| {
|
enter_context(&icx, |_| {
|
||||||
f(tcx)
|
f(tcx)
|
||||||
|
|
|
@ -896,21 +896,26 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
|
query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
|
||||||
-> Result<&'tcx LayoutDetails, LayoutError<'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();
|
if icx.layout_depth > rec_limit {
|
||||||
let depth = tcx.layout_depth.get();
|
tcx.sess.fatal(
|
||||||
if depth > rec_limit {
|
&format!("overflow representing the type `{}`", ty));
|
||||||
tcx.sess.fatal(
|
}
|
||||||
&format!("overflow representing the type `{}`", ty));
|
|
||||||
}
|
|
||||||
|
|
||||||
tcx.layout_depth.set(depth+1);
|
// Update the ImplicitCtxt to increase the layout_depth
|
||||||
let cx = LayoutCx { tcx, param_env };
|
let icx = ty::tls::ImplicitCtxt {
|
||||||
let layout = cx.layout_raw_uncached(ty);
|
layout_depth: icx.layout_depth + 1,
|
||||||
tcx.layout_depth.set(depth);
|
..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) {
|
pub fn provide(providers: &mut ty::maps::Providers) {
|
||||||
|
|
|
@ -522,6 +522,7 @@ macro_rules! define_maps {
|
||||||
let icx = ty::tls::ImplicitCtxt {
|
let icx = ty::tls::ImplicitCtxt {
|
||||||
tcx,
|
tcx,
|
||||||
query: Some(job.clone()),
|
query: Some(job.clone()),
|
||||||
|
layout_depth: icx.layout_depth,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use the ImplicitCtxt while we execute the query
|
// Use the ImplicitCtxt while we execute the query
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue