Skip to content

Commit 4f7d0fd

Browse files
committed
Some cleanups and added comments
1 parent 29a4ec0 commit 4f7d0fd

File tree

4 files changed

+157
-86
lines changed

4 files changed

+157
-86
lines changed

src/librustc/ty/context.rs

+67-25
Original file line numberDiff line numberDiff line change
@@ -1489,10 +1489,13 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
14891489

14901490
impl<'gcx: 'tcx, 'tcx> GlobalCtxt<'gcx> {
14911491
/// Call the closure with a local `TyCtxt` using the given arena.
1492-
pub fn enter_local<F, R>(&self,
1493-
arena: &'tcx DroplessArena,
1494-
f: F) -> R
1495-
where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
1492+
pub fn enter_local<F, R>(
1493+
&self,
1494+
arena: &'tcx DroplessArena,
1495+
f: F
1496+
) -> R
1497+
where
1498+
F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
14961499
{
14971500
let interners = CtxtInterners::new(arena);
14981501
let tcx = TyCtxt {
@@ -1665,12 +1668,23 @@ pub mod tls {
16651668
use rustc_data_structures::OnDrop;
16661669
use rustc_data_structures::sync::Lrc;
16671670

1671+
/// This is the implicit state of rustc. It contains the current
1672+
/// TyCtxt and query. It is updated when creating a local interner or
1673+
/// executing a new query. Whenever there's a TyCtxt value available
1674+
/// you should also have access to an ImplicitCtxt through the functions
1675+
/// in this module.
16681676
#[derive(Clone)]
16691677
pub struct ImplicitCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
1678+
/// The current TyCtxt. Initially created by `enter_global` and updated
1679+
/// by `enter_local` with a new local interner
16701680
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
1681+
1682+
/// The current query job, if any. This is updated by start_job in
1683+
/// ty::maps::plumbing when executing a query
16711684
pub query: Option<Lrc<maps::QueryJob<'gcx>>>,
16721685
}
16731686

1687+
// A thread local value which stores a pointer to the current ImplicitCtxt
16741688
thread_local!(static TLV: Cell<usize> = Cell::new(0));
16751689

16761690
fn set_tlv<F: FnOnce() -> R, R>(value: usize, f: F) -> R {
@@ -1684,12 +1698,17 @@ pub mod tls {
16841698
TLV.with(|tlv| tlv.get())
16851699
}
16861700

1701+
/// This is a callback from libsyntax as it cannot access the implicit state
1702+
/// in librustc otherwise
16871703
fn span_debug(span: syntax_pos::Span, f: &mut fmt::Formatter) -> fmt::Result {
16881704
with(|tcx| {
16891705
write!(f, "{}", tcx.sess.codemap().span_to_string(span))
16901706
})
16911707
}
16921708

1709+
/// This is a callback from libsyntax as it cannot access the implicit state
1710+
/// in librustc otherwise. It is used to when diagnostic messages are
1711+
/// emitted and stores them in the current query, if there is one.
16931712
fn track_diagnostic(diagnostic: &Diagnostic) {
16941713
with_context(|context| {
16951714
if let Some(ref query) = context.query {
@@ -1698,6 +1717,7 @@ pub mod tls {
16981717
})
16991718
}
17001719

1720+
/// Sets up the callbacks from libsyntax on the current thread
17011721
pub fn with_thread_locals<F, R>(f: F) -> R
17021722
where F: FnOnce() -> R
17031723
{
@@ -1722,6 +1742,20 @@ pub mod tls {
17221742
})
17231743
}
17241744

1745+
/// Sets `context` as the new current ImplicitCtxt for the duration of the function `f`
1746+
pub fn enter_context<'a, 'gcx: 'tcx, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'gcx, 'tcx>,
1747+
f: F) -> R
1748+
where F: FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
1749+
{
1750+
set_tlv(context as *const _ as usize, || {
1751+
f(&context)
1752+
})
1753+
}
1754+
1755+
/// Enters GlobalCtxt by setting up libsyntax callbacks and
1756+
/// creating a initial TyCtxt and ImplicitCtxt.
1757+
/// This happens once per rustc session and TyCtxts only exists
1758+
/// inside the `f` function.
17251759
pub fn enter_global<'gcx, F, R>(gcx: &GlobalCtxt<'gcx>, f: F) -> R
17261760
where F: for<'a> FnOnce(TyCtxt<'a, 'gcx, 'gcx>) -> R
17271761
{
@@ -1740,15 +1774,7 @@ pub mod tls {
17401774
})
17411775
}
17421776

1743-
pub fn enter_context<'a, 'gcx: 'tcx, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'gcx, 'tcx>,
1744-
f: F) -> R
1745-
where F: FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
1746-
{
1747-
set_tlv(context as *const _ as usize, || {
1748-
f(&context)
1749-
})
1750-
}
1751-
1777+
/// Allows access to the current ImplicitCtxt in a closure if one is available
17521778
pub fn with_context_opt<F, R>(f: F) -> R
17531779
where F: for<'a, 'gcx, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'gcx, 'tcx>>) -> R
17541780
{
@@ -1760,46 +1786,62 @@ pub mod tls {
17601786
}
17611787
}
17621788

1763-
pub fn with_fully_related_context<'a, 'gcx, 'tcx, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx>, f: F) -> R
1764-
where F: for<'b> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx>) -> R
1789+
/// Allows access to the current ImplicitCtxt.
1790+
/// Panics if there is no ImplicitCtxt available
1791+
pub fn with_context<F, R>(f: F) -> R
1792+
where F: for<'a, 'gcx, 'tcx> FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
1793+
{
1794+
with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
1795+
}
1796+
1797+
/// Allows access to the current ImplicitCtxt whose tcx field has the same global
1798+
/// interner as the tcx argument passed in. This means the closure is given an ImplicitCtxt
1799+
/// with the same 'gcx lifetime as the TyCtxt passed in.
1800+
/// This will panic if you pass it a TyCtxt which has a different global interner from
1801+
/// the current ImplicitCtxt's tcx field.
1802+
pub fn with_related_context<'a, 'gcx, 'tcx1, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx1>, f: F) -> R
1803+
where F: for<'b, 'tcx2> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx2>) -> R
17651804
{
17661805
with_context(|context| {
17671806
unsafe {
17681807
let gcx = tcx.gcx as *const _ as usize;
1769-
let interners = tcx.interners as *const _ as usize;
17701808
assert!(context.tcx.gcx as *const _ as usize == gcx);
1771-
assert!(context.tcx.interners as *const _ as usize == interners);
17721809
let context: &ImplicitCtxt = mem::transmute(context);
17731810
f(context)
17741811
}
17751812
})
17761813
}
17771814

1778-
pub fn with_related_context<'a, 'gcx, 'tcx1, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx1>, f: F) -> R
1779-
where F: for<'b, 'tcx2> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx2>) -> R
1815+
/// Allows access to the current ImplicitCtxt whose tcx field has the same global
1816+
/// interner and local interner as the tcx argument passed in. This means the closure
1817+
/// is given an ImplicitCtxt with the same 'tcx and 'gcx lifetimes as the TyCtxt passed in.
1818+
/// This will panic if you pass it a TyCtxt which has a different global interner or
1819+
/// a different local interner from the current ImplicitCtxt's tcx field.
1820+
pub fn with_fully_related_context<'a, 'gcx, 'tcx, F, R>(tcx: TyCtxt<'a, 'gcx, 'tcx>, f: F) -> R
1821+
where F: for<'b> FnOnce(&ImplicitCtxt<'b, 'gcx, 'tcx>) -> R
17801822
{
17811823
with_context(|context| {
17821824
unsafe {
17831825
let gcx = tcx.gcx as *const _ as usize;
1826+
let interners = tcx.interners as *const _ as usize;
17841827
assert!(context.tcx.gcx as *const _ as usize == gcx);
1828+
assert!(context.tcx.interners as *const _ as usize == interners);
17851829
let context: &ImplicitCtxt = mem::transmute(context);
17861830
f(context)
17871831
}
17881832
})
17891833
}
17901834

1791-
pub fn with_context<F, R>(f: F) -> R
1792-
where F: for<'a, 'gcx, 'tcx> FnOnce(&ImplicitCtxt<'a, 'gcx, 'tcx>) -> R
1793-
{
1794-
with_context_opt(|opt_context| f(opt_context.expect("no ImplicitCtxt stored in tls")))
1795-
}
1796-
1835+
/// Allows access to the TyCtxt in the current ImplicitCtxt.
1836+
/// Panics if there is no ImplicitCtxt available
17971837
pub fn with<F, R>(f: F) -> R
17981838
where F: for<'a, 'gcx, 'tcx> FnOnce(TyCtxt<'a, 'gcx, 'tcx>) -> R
17991839
{
18001840
with_context(|context| f(context.tcx))
18011841
}
18021842

1843+
/// Allows access to the TyCtxt in the current ImplicitCtxt.
1844+
/// The closure is passed None if there is no ImplicitCtxt available
18031845
pub fn with_opt<F, R>(f: F) -> R
18041846
where F: for<'a, 'gcx, 'tcx> FnOnce(Option<TyCtxt<'a, 'gcx, 'tcx>>) -> R
18051847
{

src/librustc/ty/maps/job.rs

+34-35
Original file line numberDiff line numberDiff line change
@@ -8,65 +8,69 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![allow(warnings)]
12-
13-
use std::mem;
14-
use std::sync::atomic::AtomicBool;
15-
use std::sync::atomic::Ordering;
16-
use rustc_data_structures::sync::{Lock, LockGuard, Lrc};
11+
use rustc_data_structures::sync::{Lock, Lrc};
1712
use syntax_pos::Span;
1813
use ty::tls;
1914
use ty::maps::Query;
2015
use ty::maps::plumbing::CycleError;
2116
use ty::context::TyCtxt;
2217
use errors::Diagnostic;
23-
use std::process;
24-
use std::fmt;
25-
use std::sync::{Arc, Mutex};
26-
use std::collections::HashSet;
2718

28-
pub struct PoisonedJob;
19+
/// Indicates the state of a query for a given key in a query map
20+
pub(super) enum QueryResult<'tcx, T> {
21+
/// An already executing query. The query job can be used to await for its completion
22+
Started(Lrc<QueryJob<'tcx>>),
23+
24+
/// The query is complete and produced `T`
25+
Complete(T),
2926

27+
/// The query panicked. Queries trying to wait on this will raise a fatal error / silently panic
28+
Poisoned,
29+
}
30+
31+
/// A span and a query key
3032
#[derive(Clone, Debug)]
31-
pub struct StackEntry<'tcx> {
33+
pub struct QueryInfo<'tcx> {
3234
pub span: Span,
3335
pub query: Query<'tcx>,
3436
}
3537

38+
/// A object representing an active query job.
3639
pub struct QueryJob<'tcx> {
37-
pub entry: StackEntry<'tcx>,
40+
pub info: QueryInfo<'tcx>,
41+
42+
/// The parent query job which created this job and is implicitly waiting on it.
3843
pub parent: Option<Lrc<QueryJob<'tcx>>>,
39-
pub track_diagnostics: bool,
44+
45+
/// Diagnostic messages which are emitted while the query executes
4046
pub diagnostics: Lock<Vec<Diagnostic>>,
4147
}
4248

4349
impl<'tcx> QueryJob<'tcx> {
44-
pub fn new(
45-
entry: StackEntry<'tcx>,
46-
track_diagnostics: bool,
47-
parent: Option<Lrc<QueryJob<'tcx>>>,
48-
) -> Self {
50+
/// Creates a new query job
51+
pub fn new(info: QueryInfo<'tcx>, parent: Option<Lrc<QueryJob<'tcx>>>) -> Self {
4952
QueryJob {
50-
track_diagnostics,
5153
diagnostics: Lock::new(Vec::new()),
52-
entry,
54+
info,
5355
parent,
5456
}
5557
}
5658

59+
/// Awaits for the query job to complete.
60+
///
61+
/// For single threaded rustc there's no concurrent jobs running, so if we are waiting for any
62+
/// query that means that there is a query cycle, thus this always running a cycle error.
5763
pub(super) fn await<'lcx>(
5864
&self,
5965
tcx: TyCtxt<'_, 'tcx, 'lcx>,
6066
span: Span,
6167
) -> Result<(), CycleError<'tcx>> {
62-
// The query is already executing, so this must be a cycle for single threaded rustc,
63-
// so we find the cycle and return it
64-
68+
// Get the current executing query (waiter) and find the waitee amongst its parents
6569
let mut current_job = tls::with_related_context(tcx, |icx| icx.query.clone());
6670
let mut cycle = Vec::new();
6771

6872
while let Some(job) = current_job {
69-
cycle.insert(0, job.entry.clone());
73+
cycle.insert(0, job.info.clone());
7074

7175
if &*job as *const _ == self as *const _ {
7276
break;
@@ -78,14 +82,9 @@ impl<'tcx> QueryJob<'tcx> {
7882
Err(CycleError { span, cycle })
7983
}
8084

81-
pub fn signal_complete(&self) {
82-
// Signals to waiters that the query is complete.
83-
// This is a no-op for single threaded rustc
84-
}
85-
}
86-
87-
pub(super) enum QueryResult<'tcx, T> {
88-
Started(Lrc<QueryJob<'tcx>>),
89-
Complete(T),
90-
Poisoned,
85+
/// Signals to waiters that the query is complete.
86+
///
87+
/// This does nothing for single threaded rustc,
88+
/// as there are no concurrent jobs which could be waiting on us
89+
pub fn signal_complete(&self) {}
9190
}

src/librustc/ty/maps/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use self::plumbing::*;
6767
pub use self::plumbing::force_from_dep_node;
6868

6969
mod job;
70-
pub use self::job::{QueryJob, StackEntry, PoisonedJob};
70+
pub use self::job::{QueryJob, QueryInfo};
7171
use self::job::QueryResult;
7272

7373
mod keys;

0 commit comments

Comments
 (0)