@@ -1699,16 +1699,21 @@ impl<'a, 'tcx> Lift<'tcx> for &'a Slice<CanonicalVarInfo> {
16991699pub mod tls {
17001700 use super :: { GlobalCtxt , TyCtxt } ;
17011701
1702- use std:: cell:: Cell ;
17031702 use std:: fmt;
17041703 use std:: mem;
17051704 use syntax_pos;
17061705 use ty:: maps;
17071706 use errors:: { Diagnostic , TRACK_DIAGNOSTICS } ;
17081707 use rustc_data_structures:: OnDrop ;
1709- use rustc_data_structures:: sync:: { self , Lrc } ;
1708+ use rustc_data_structures:: sync:: { self , Lrc , Lock } ;
17101709 use dep_graph:: OpenTask ;
17111710
1711+ #[ cfg( not( parallel_queries) ) ]
1712+ use std:: cell:: Cell ;
1713+
1714+ #[ cfg( parallel_queries) ]
1715+ use rayon_core;
1716+
17121717 /// This is the implicit state of rustc. It contains the current
17131718 /// TyCtxt and query. It is updated when creating a local interner or
17141719 /// executing a new query. Whenever there's a TyCtxt value available
@@ -1732,16 +1737,29 @@ pub mod tls {
17321737 pub task : & ' a OpenTask ,
17331738 }
17341739
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+
17351750 // A thread local value which stores a pointer to the current ImplicitCtxt
1751+ #[ cfg( not( parallel_queries) ) ]
17361752 thread_local ! ( static TLV : Cell <usize > = Cell :: new( 0 ) ) ;
17371753
1754+ #[ cfg( not( parallel_queries) ) ]
17381755 fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
17391756 let old = get_tlv ( ) ;
17401757 let _reset = OnDrop ( move || TLV . with ( |tlv| tlv. set ( old) ) ) ;
17411758 TLV . with ( |tlv| tlv. set ( value) ) ;
17421759 f ( )
17431760 }
17441761
1762+ #[ cfg( not( parallel_queries) ) ]
17451763 fn get_tlv ( ) -> usize {
17461764 TLV . with ( |tlv| tlv. get ( ) )
17471765 }
@@ -1810,6 +1828,13 @@ pub mod tls {
18101828 where F : for < ' a > FnOnce ( TyCtxt < ' a , ' gcx , ' gcx > ) -> R
18111829 {
18121830 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+
18131838 let tcx = TyCtxt {
18141839 gcx,
18151840 interners : & gcx. global_interners ,
@@ -1826,6 +1851,27 @@ pub mod tls {
18261851 } )
18271852 }
18281853
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+
18291875 /// Allows access to the current ImplicitCtxt in a closure if one is available
18301876 pub fn with_context_opt < F , R > ( f : F ) -> R
18311877 where F : for <' a , ' gcx , ' tcx > FnOnce ( Option < & ImplicitCtxt < ' a , ' gcx , ' tcx > > ) -> R
0 commit comments