@@ -1699,16 +1699,21 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice<CanonicalVarInfo> {
1699
1699
pub mod tls {
1700
1700
use super :: { GlobalCtxt , TyCtxt } ;
1701
1701
1702
- use std:: cell:: Cell ;
1703
1702
use std:: fmt;
1704
1703
use std:: mem;
1705
1704
use syntax_pos;
1706
1705
use ty:: maps;
1707
1706
use errors:: { Diagnostic , TRACK_DIAGNOSTICS } ;
1708
1707
use rustc_data_structures:: OnDrop ;
1709
- use rustc_data_structures:: sync:: { self , Lrc } ;
1708
+ use rustc_data_structures:: sync:: { self , Lrc , Lock } ;
1710
1709
use dep_graph:: OpenTask ;
1711
1710
1711
+ #[ cfg( not( parallel_queries) ) ]
1712
+ use std:: cell:: Cell ;
1713
+
1714
+ #[ cfg( parallel_queries) ]
1715
+ use rayon_core;
1716
+
1712
1717
/// This is the implicit state of rustc. It contains the current
1713
1718
/// TyCtxt and query. It is updated when creating a local interner or
1714
1719
/// executing a new query. Whenever there's a TyCtxt value available
@@ -1732,16 +1737,29 @@ pub mod tls {
1732
1737
pub task : & ' a OpenTask ,
1733
1738
}
1734
1739
1740
+ #[ cfg( parallel_queries) ]
1741
+ fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
1742
+ rayon_core:: tlv:: with ( value, f)
1743
+ }
1744
+
1745
+ #[ cfg( parallel_queries) ]
1746
+ fn get_tlv ( ) -> usize {
1747
+ rayon_core:: tlv:: get ( )
1748
+ }
1749
+
1735
1750
// A thread local value which stores a pointer to the current ImplicitCtxt
1751
+ #[ cfg( not( parallel_queries) ) ]
1736
1752
thread_local ! ( static TLV : Cell <usize > = Cell :: new( 0 ) ) ;
1737
1753
1754
+ #[ cfg( not( parallel_queries) ) ]
1738
1755
fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
1739
1756
let old = get_tlv ( ) ;
1740
1757
let _reset = OnDrop ( move || TLV . with ( |tlv| tlv. set ( old) ) ) ;
1741
1758
TLV . with ( |tlv| tlv. set ( value) ) ;
1742
1759
f ( )
1743
1760
}
1744
1761
1762
+ #[ cfg( not( parallel_queries) ) ]
1745
1763
fn get_tlv ( ) -> usize {
1746
1764
TLV . with ( |tlv| tlv. get ( ) )
1747
1765
}
@@ -1810,6 +1828,13 @@ pub mod tls {
1810
1828
where F : for < ' a > FnOnce ( TyCtxt < ' a , ' gcx , ' gcx > ) -> R
1811
1829
{
1812
1830
with_thread_locals ( || {
1831
+ GCX_PTR . with ( |lock| {
1832
+ * lock. lock ( ) = gcx as * const _ as usize ;
1833
+ } ) ;
1834
+ let _on_drop = OnDrop ( move || {
1835
+ GCX_PTR . with ( |lock| * lock. lock ( ) = 0 ) ;
1836
+ } ) ;
1837
+
1813
1838
let tcx = TyCtxt {
1814
1839
gcx,
1815
1840
interners : & gcx. global_interners ,
@@ -1826,6 +1851,27 @@ pub mod tls {
1826
1851
} )
1827
1852
}
1828
1853
1854
+ scoped_thread_local ! ( pub static GCX_PTR : Lock <usize >) ;
1855
+
1856
+ pub unsafe fn with_global < F , R > ( f : F ) -> R
1857
+ where F : for <' a , ' gcx , ' tcx > FnOnce ( TyCtxt < ' a , ' gcx , ' tcx > ) -> R
1858
+ {
1859
+ let gcx = GCX_PTR . with ( |lock| * lock. lock ( ) ) ;
1860
+ assert ! ( gcx != 0 ) ;
1861
+ let gcx = & * ( gcx as * const GlobalCtxt < ' _ > ) ;
1862
+ let tcx = TyCtxt {
1863
+ gcx,
1864
+ interners : & gcx. global_interners ,
1865
+ } ;
1866
+ let icx = ImplicitCtxt {
1867
+ query : None ,
1868
+ tcx,
1869
+ layout_depth : 0 ,
1870
+ task : & OpenTask :: Ignore ,
1871
+ } ;
1872
+ enter_context ( & icx, |_| f ( tcx) )
1873
+ }
1874
+
1829
1875
/// Allows access to the current ImplicitCtxt in a closure if one is available
1830
1876
pub fn with_context_opt < F , R > ( f : F ) -> R
1831
1877
where F : for <' a , ' gcx , ' tcx > FnOnce ( Option < & ImplicitCtxt < ' a , ' gcx , ' tcx > > ) -> R
0 commit comments