Skip to content

Commit afd5307

Browse files
committed
Move ty::tls to seperate file
1 parent e098eb1 commit afd5307

File tree

2 files changed

+171
-172
lines changed

2 files changed

+171
-172
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 2 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
33
#![allow(rustc::usage_of_ty_tykind)]
44

5+
pub mod tls;
6+
57
use crate::arena::Arena;
68
use crate::dep_graph::{DepGraph, DepKindStruct};
79
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};
@@ -1188,178 +1190,6 @@ CloneLiftImpls! { for<'tcx> {
11881190
Constness, traits::WellFormedLoc, ImplPolarity, crate::mir::ReturnConstraint,
11891191
} }
11901192

1191-
pub mod tls {
1192-
use super::{ptr_eq, GlobalCtxt, TyCtxt};
1193-
1194-
use crate::dep_graph::TaskDepsRef;
1195-
use crate::ty::query;
1196-
use rustc_data_structures::sync::{self, Lock};
1197-
use rustc_errors::Diagnostic;
1198-
use std::mem;
1199-
use thin_vec::ThinVec;
1200-
1201-
#[cfg(not(parallel_compiler))]
1202-
use std::cell::Cell;
1203-
1204-
#[cfg(parallel_compiler)]
1205-
use rustc_rayon_core as rayon_core;
1206-
1207-
/// This is the implicit state of rustc. It contains the current
1208-
/// `TyCtxt` and query. It is updated when creating a local interner or
1209-
/// executing a new query. Whenever there's a `TyCtxt` value available
1210-
/// you should also have access to an `ImplicitCtxt` through the functions
1211-
/// in this module.
1212-
#[derive(Clone)]
1213-
pub struct ImplicitCtxt<'a, 'tcx> {
1214-
/// The current `TyCtxt`.
1215-
pub tcx: TyCtxt<'tcx>,
1216-
1217-
/// The current query job, if any. This is updated by `JobOwner::start` in
1218-
/// `ty::query::plumbing` when executing a query.
1219-
pub query: Option<query::QueryJobId>,
1220-
1221-
/// Where to store diagnostics for the current query job, if any.
1222-
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
1223-
pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
1224-
1225-
/// Used to prevent queries from calling too deeply.
1226-
pub query_depth: usize,
1227-
1228-
/// The current dep graph task. This is used to add dependencies to queries
1229-
/// when executing them.
1230-
pub task_deps: TaskDepsRef<'a>,
1231-
}
1232-
1233-
impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
1234-
pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
1235-
let tcx = TyCtxt { gcx };
1236-
ImplicitCtxt {
1237-
tcx,
1238-
query: None,
1239-
diagnostics: None,
1240-
query_depth: 0,
1241-
task_deps: TaskDepsRef::Ignore,
1242-
}
1243-
}
1244-
}
1245-
1246-
/// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
1247-
/// to `value` during the call to `f`. It is restored to its previous value after.
1248-
/// This is used to set the pointer to the new `ImplicitCtxt`.
1249-
#[cfg(parallel_compiler)]
1250-
#[inline]
1251-
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1252-
rayon_core::tlv::with(value, f)
1253-
}
1254-
1255-
/// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
1256-
/// This is used to get the pointer to the current `ImplicitCtxt`.
1257-
#[cfg(parallel_compiler)]
1258-
#[inline]
1259-
pub fn get_tlv() -> usize {
1260-
rayon_core::tlv::get()
1261-
}
1262-
1263-
#[cfg(not(parallel_compiler))]
1264-
thread_local! {
1265-
/// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
1266-
static TLV: Cell<usize> = const { Cell::new(0) };
1267-
}
1268-
1269-
/// Sets TLV to `value` during the call to `f`.
1270-
/// It is restored to its previous value after.
1271-
/// This is used to set the pointer to the new `ImplicitCtxt`.
1272-
#[cfg(not(parallel_compiler))]
1273-
#[inline]
1274-
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
1275-
let old = get_tlv();
1276-
let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old)));
1277-
TLV.with(|tlv| tlv.set(value));
1278-
f()
1279-
}
1280-
1281-
/// Gets the pointer to the current `ImplicitCtxt`.
1282-
#[cfg(not(parallel_compiler))]
1283-
#[inline]
1284-
fn get_tlv() -> usize {
1285-
TLV.with(|tlv| tlv.get())
1286-
}
1287-
1288-
/// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
1289-
#[inline]
1290-
pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
1291-
where
1292-
F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
1293-
{
1294-
set_tlv(context as *const _ as usize, || f(&context))
1295-
}
1296-
1297-
/// Allows access to the current `ImplicitCtxt` in a closure if one is available.
1298-
#[inline]
1299-
pub fn with_context_opt<F, R>(f: F) -> R
1300-
where
1301-
F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
1302-
{
1303-
let context = get_tlv();
1304-
if context == 0 {
1305-
f(None)
1306-
} else {
1307-
// We could get an `ImplicitCtxt` pointer from another thread.
1308-
// Ensure that `ImplicitCtxt` is `Sync`.
1309-
sync::assert_sync::<ImplicitCtxt<'_, '_>>();
1310-
1311-
unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
1312-
}
1313-
}
1314-
1315-
/// Allows access to the current `ImplicitCtxt`.
1316-
/// Panics if there is no `ImplicitCtxt` available.
1317-
#[inline]
1318-
pub fn with_context<F, R>(f: F) -> R
1319-
where
1320-
F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
1321-
{
1322-
with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
1323-
}
1324-
1325-
/// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
1326-
/// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
1327-
/// as the `TyCtxt` passed in.
1328-
/// This will panic if you pass it a `TyCtxt` which is different from the current
1329-
/// `ImplicitCtxt`'s `tcx` field.
1330-
#[inline]
1331-
pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
1332-
where
1333-
F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
1334-
{
1335-
with_context(|context| unsafe {
1336-
assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
1337-
let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
1338-
f(context)
1339-
})
1340-
}
1341-
1342-
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1343-
/// Panics if there is no `ImplicitCtxt` available.
1344-
#[inline]
1345-
pub fn with<F, R>(f: F) -> R
1346-
where
1347-
F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
1348-
{
1349-
with_context(|context| f(context.tcx))
1350-
}
1351-
1352-
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
1353-
/// The closure is passed None if there is no `ImplicitCtxt` available.
1354-
#[inline]
1355-
pub fn with_opt<F, R>(f: F) -> R
1356-
where
1357-
F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
1358-
{
1359-
with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
1360-
}
1361-
}
1362-
13631193
macro_rules! sty_debug_print {
13641194
($fmt: expr, $ctxt: expr, $($variant: ident),*) => {{
13651195
// Curious inner module to allow variant names to be used as
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
use super::{ptr_eq, GlobalCtxt, TyCtxt};
2+
3+
use crate::dep_graph::TaskDepsRef;
4+
use crate::ty::query;
5+
use rustc_data_structures::sync::{self, Lock};
6+
use rustc_errors::Diagnostic;
7+
use std::mem;
8+
use thin_vec::ThinVec;
9+
10+
#[cfg(not(parallel_compiler))]
11+
use std::cell::Cell;
12+
13+
#[cfg(parallel_compiler)]
14+
use rustc_rayon_core as rayon_core;
15+
16+
/// This is the implicit state of rustc. It contains the current
17+
/// `TyCtxt` and query. It is updated when creating a local interner or
18+
/// executing a new query. Whenever there's a `TyCtxt` value available
19+
/// you should also have access to an `ImplicitCtxt` through the functions
20+
/// in this module.
21+
#[derive(Clone)]
22+
pub struct ImplicitCtxt<'a, 'tcx> {
23+
/// The current `TyCtxt`.
24+
pub tcx: TyCtxt<'tcx>,
25+
26+
/// The current query job, if any. This is updated by `JobOwner::start` in
27+
/// `ty::query::plumbing` when executing a query.
28+
pub query: Option<query::QueryJobId>,
29+
30+
/// Where to store diagnostics for the current query job, if any.
31+
/// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
32+
pub diagnostics: Option<&'a Lock<ThinVec<Diagnostic>>>,
33+
34+
/// Used to prevent queries from calling too deeply.
35+
pub query_depth: usize,
36+
37+
/// The current dep graph task. This is used to add dependencies to queries
38+
/// when executing them.
39+
pub task_deps: TaskDepsRef<'a>,
40+
}
41+
42+
impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
43+
pub fn new(gcx: &'tcx GlobalCtxt<'tcx>) -> Self {
44+
let tcx = TyCtxt { gcx };
45+
ImplicitCtxt {
46+
tcx,
47+
query: None,
48+
diagnostics: None,
49+
query_depth: 0,
50+
task_deps: TaskDepsRef::Ignore,
51+
}
52+
}
53+
}
54+
55+
/// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
56+
/// to `value` during the call to `f`. It is restored to its previous value after.
57+
/// This is used to set the pointer to the new `ImplicitCtxt`.
58+
#[cfg(parallel_compiler)]
59+
#[inline]
60+
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
61+
rayon_core::tlv::with(value, f)
62+
}
63+
64+
/// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
65+
/// This is used to get the pointer to the current `ImplicitCtxt`.
66+
#[cfg(parallel_compiler)]
67+
#[inline]
68+
pub fn get_tlv() -> usize {
69+
rayon_core::tlv::get()
70+
}
71+
72+
#[cfg(not(parallel_compiler))]
73+
thread_local! {
74+
/// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
75+
static TLV: Cell<usize> = const { Cell::new(0) };
76+
}
77+
78+
/// Sets TLV to `value` during the call to `f`.
79+
/// It is restored to its previous value after.
80+
/// This is used to set the pointer to the new `ImplicitCtxt`.
81+
#[cfg(not(parallel_compiler))]
82+
#[inline]
83+
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
84+
let old = get_tlv();
85+
let _reset = rustc_data_structures::OnDrop(move || TLV.with(|tlv| tlv.set(old)));
86+
TLV.with(|tlv| tlv.set(value));
87+
f()
88+
}
89+
90+
/// Gets the pointer to the current `ImplicitCtxt`.
91+
#[cfg(not(parallel_compiler))]
92+
#[inline]
93+
fn get_tlv() -> usize {
94+
TLV.with(|tlv| tlv.get())
95+
}
96+
97+
/// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
98+
#[inline]
99+
pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> R
100+
where
101+
F: FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
102+
{
103+
set_tlv(context as *const _ as usize, || f(&context))
104+
}
105+
106+
/// Allows access to the current `ImplicitCtxt` in a closure if one is available.
107+
#[inline]
108+
pub fn with_context_opt<F, R>(f: F) -> R
109+
where
110+
F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R,
111+
{
112+
let context = get_tlv();
113+
if context == 0 {
114+
f(None)
115+
} else {
116+
// We could get an `ImplicitCtxt` pointer from another thread.
117+
// Ensure that `ImplicitCtxt` is `Sync`.
118+
sync::assert_sync::<ImplicitCtxt<'_, '_>>();
119+
120+
unsafe { f(Some(&*(context as *const ImplicitCtxt<'_, '_>))) }
121+
}
122+
}
123+
124+
/// Allows access to the current `ImplicitCtxt`.
125+
/// Panics if there is no `ImplicitCtxt` available.
126+
#[inline]
127+
pub fn with_context<F, R>(f: F) -> R
128+
where
129+
F: for<'a, 'tcx> FnOnce(&ImplicitCtxt<'a, 'tcx>) -> R,
130+
{
131+
with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
132+
}
133+
134+
/// Allows access to the current `ImplicitCtxt` whose tcx field is the same as the tcx argument
135+
/// passed in. This means the closure is given an `ImplicitCtxt` with the same `'tcx` lifetime
136+
/// as the `TyCtxt` passed in.
137+
/// This will panic if you pass it a `TyCtxt` which is different from the current
138+
/// `ImplicitCtxt`'s `tcx` field.
139+
#[inline]
140+
pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
141+
where
142+
F: FnOnce(&ImplicitCtxt<'_, 'tcx>) -> R,
143+
{
144+
with_context(|context| unsafe {
145+
assert!(ptr_eq(context.tcx.gcx, tcx.gcx));
146+
let context: &ImplicitCtxt<'_, '_> = mem::transmute(context);
147+
f(context)
148+
})
149+
}
150+
151+
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
152+
/// Panics if there is no `ImplicitCtxt` available.
153+
#[inline]
154+
pub fn with<F, R>(f: F) -> R
155+
where
156+
F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> R,
157+
{
158+
with_context(|context| f(context.tcx))
159+
}
160+
161+
/// Allows access to the `TyCtxt` in the current `ImplicitCtxt`.
162+
/// The closure is passed None if there is no `ImplicitCtxt` available.
163+
#[inline]
164+
pub fn with_opt<F, R>(f: F) -> R
165+
where
166+
F: for<'tcx> FnOnce(Option<TyCtxt<'tcx>>) -> R,
167+
{
168+
with_context_opt(|opt_context| f(opt_context.map(|context| context.tcx)))
169+
}

0 commit comments

Comments
 (0)