@@ -1682,155 +1682,61 @@ CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
1682
1682
1683
1683
pub mod tls {
1684
1684
use super :: { GlobalCtxt , TyCtxt } ;
1685
-
1686
- use crate :: dep_graph:: TaskDepsRef ;
1687
- use crate :: ty:: query;
1688
- use rustc_data_structures:: sync:: { self , Lock } ;
1689
- use rustc_data_structures:: thin_vec:: ThinVec ;
1690
- use rustc_errors:: Diagnostic ;
1691
-
1692
- #[ cfg( not( parallel_compiler) ) ]
1685
+ use rustc_data_structures:: sync;
1693
1686
use std:: cell:: Cell ;
1694
1687
1695
- #[ cfg( parallel_compiler) ]
1696
- use rustc_rayon_core as rayon_core;
1697
-
1698
- /// This is the implicit state of rustc. It contains the current
1699
- /// `TyCtxt` and query. It is updated when creating a local interner or
1700
- /// executing a new query. Whenever there's a `TyCtxt` value available
1701
- /// you should also have access to an `ImplicitCtxt` through the functions
1702
- /// in this module.
1703
- #[ derive( Clone ) ]
1704
- pub struct ImplicitCtxt < ' a , ' tcx > {
1705
- /// The current `TyCtxt`.
1706
- pub tcx : TyCtxt < ' tcx > ,
1707
-
1708
- /// The current query job, if any. This is updated by `JobOwner::start` in
1709
- /// `ty::query::plumbing` when executing a query.
1710
- pub query : Option < query:: QueryJobId > ,
1711
-
1712
- /// Where to store diagnostics for the current query job, if any.
1713
- /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query.
1714
- pub diagnostics : Option < & ' a Lock < ThinVec < Diagnostic > > > ,
1715
-
1716
- /// Used to prevent layout from recursing too deeply.
1717
- pub layout_depth : usize ,
1718
-
1719
- /// The current dep graph task. This is used to add dependencies to queries
1720
- /// when executing them.
1721
- pub task_deps : TaskDepsRef < ' a > ,
1722
- }
1723
-
1724
- impl < ' a , ' tcx > ImplicitCtxt < ' a , ' tcx > {
1725
- pub fn new ( gcx : & ' tcx GlobalCtxt < ' tcx > ) -> Self {
1726
- let tcx = TyCtxt { gcx } ;
1727
- ImplicitCtxt {
1728
- tcx,
1729
- query : None ,
1730
- diagnostics : None ,
1731
- layout_depth : 0 ,
1732
- task_deps : TaskDepsRef :: Ignore ,
1733
- }
1734
- }
1735
- }
1736
-
1737
- /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
1738
- /// to `value` during the call to `f`. It is restored to its previous value after.
1739
- /// This is used to set the pointer to the new `ImplicitCtxt`.
1740
- #[ cfg( parallel_compiler) ]
1741
- #[ inline]
1742
- fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
1743
- rayon_core:: tlv:: with ( value, f)
1744
- }
1745
-
1746
- /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
1747
- /// This is used to get the pointer to the current `ImplicitCtxt`.
1748
- #[ cfg( parallel_compiler) ]
1749
- #[ inline]
1750
- pub fn get_tlv ( ) -> usize {
1751
- rayon_core:: tlv:: get ( )
1752
- }
1753
-
1754
- #[ cfg( not( parallel_compiler) ) ]
1755
1688
thread_local ! {
1756
- /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
1757
- static TLV : Cell <usize > = const { Cell :: new( 0 ) } ;
1758
- }
1759
-
1760
- /// Sets TLV to `value` during the call to `f`.
1761
- /// It is restored to its previous value after.
1762
- /// This is used to set the pointer to the new `ImplicitCtxt`.
1763
- #[ cfg( not( parallel_compiler) ) ]
1764
- #[ inline]
1765
- fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
1766
- let old = get_tlv ( ) ;
1767
- let _reset = rustc_data_structures:: OnDrop ( move || TLV . with ( |tlv| tlv. set ( old) ) ) ;
1768
- TLV . with ( |tlv| tlv. set ( value) ) ;
1769
- f ( )
1770
- }
1771
-
1772
- /// Gets the pointer to the current `ImplicitCtxt`.
1773
- #[ cfg( not( parallel_compiler) ) ]
1774
- #[ inline]
1775
- fn get_tlv ( ) -> usize {
1776
- TLV . with ( |tlv| tlv. get ( ) )
1689
+ /// This is the implicit state of rustc. It contains the `TyCtxt`. Whenever there's a
1690
+ /// `TyCtxt` value available you should also have access to it through the functions in this
1691
+ /// module.
1692
+ static TLV : Cell <* const GlobalCtxt <' static >> = const { Cell :: new( std:: ptr:: null( ) ) } ;
1777
1693
}
1778
1694
1779
- /// Sets `context` as the new current `ImplicitCtxt ` for the duration of the function `f`.
1695
+ /// Sets `context` as the new current `TyCtxt ` for the duration of the function `f`.
1780
1696
#[ inline]
1781
- pub fn enter_context < ' a , ' tcx , F , R > ( context : & ImplicitCtxt < ' a , ' tcx > , f : F ) -> R
1697
+ pub fn enter_context < ' gcx , F , R > ( gcx : & ' gcx GlobalCtxt < ' gcx > , f : F ) -> R
1782
1698
where
1783
- F : FnOnce ( & ImplicitCtxt < ' a , ' tcx > ) -> R ,
1784
- {
1785
- set_tlv ( context as * const _ as usize , || f ( & context) )
1786
- }
1787
-
1788
- /// Allows access to the current `ImplicitCtxt` in a closure if one is available.
1789
- #[ inline]
1790
- pub fn with_context_opt < F , R > ( f : F ) -> R
1791
- where
1792
- F : for <' a , ' tcx > FnOnce ( Option < & ImplicitCtxt < ' a , ' tcx > > ) -> R ,
1699
+ F : for < ' tcx > FnOnce ( TyCtxt < ' tcx > ) -> R ,
1793
1700
{
1794
- let context = get_tlv ( ) ;
1795
- if context == 0 {
1796
- f ( None )
1797
- } else {
1798
- // We could get an `ImplicitCtxt` pointer from another thread.
1799
- // Ensure that `ImplicitCtxt` is `Sync`.
1800
- sync:: assert_sync :: < ImplicitCtxt < ' _ , ' _ > > ( ) ;
1801
-
1802
- unsafe { f ( Some ( & * ( context as * const ImplicitCtxt < ' _ , ' _ > ) ) ) }
1803
- }
1804
- }
1701
+ // We are storing `GlobalCtxt` as a global.
1702
+ // Ensure that it is `Sync`.
1703
+ sync:: assert_sync :: < GlobalCtxt < ' _ > > ( ) ;
1805
1704
1806
- /// Allows access to the current `ImplicitCtxt`.
1807
- /// Panics if there is no `ImplicitCtxt` available.
1808
- # [ inline ]
1809
- pub fn with_context < F , R > ( f : F ) -> R
1810
- where
1811
- F : for < ' a , ' tcx > FnOnce ( & ImplicitCtxt < ' a , ' tcx > ) -> R ,
1812
- {
1813
- with_context_opt ( |opt_context| f ( opt_context . expect ( "no ImplicitCtxt stored in tls" ) ) )
1705
+ let address = ( gcx as * const GlobalCtxt < ' _ > ) . cast ( ) ;
1706
+ let old = TLV . with ( |tlv| tlv . replace ( address ) ) ;
1707
+ let _reset = rustc_data_structures :: OnDrop ( move || TLV . with ( |tlv| tlv . set ( old ) ) ) ;
1708
+ debug_assert ! (
1709
+ old == address || old == std :: ptr :: null ( ) ,
1710
+ "There can only be one GlobalCtxt."
1711
+ ) ;
1712
+ f ( TyCtxt { gcx } )
1814
1713
}
1815
1714
1816
- /// Allows access to the `TyCtxt` in the current `ImplicitCtxt `.
1817
- /// Panics if there is no `ImplicitCtxt ` available.
1715
+ /// Allows access to the current `TyCtxt `.
1716
+ /// Panics if there is no `TyCtxt ` available.
1818
1717
#[ inline]
1819
1718
pub fn with < F , R > ( f : F ) -> R
1820
1719
where
1821
1720
F : for < ' tcx > FnOnce ( TyCtxt < ' tcx > ) -> R ,
1822
1721
{
1823
- with_context ( |context | f ( context . tcx ) )
1722
+ with_opt ( |opt_tcx | f ( opt_tcx . expect ( "no TyCtxt stored in tls" ) ) )
1824
1723
}
1825
1724
1826
- /// Allows access to the `TyCtxt` in the current `ImplicitCtxt `.
1827
- /// The closure is passed None if there is no `ImplicitCtxt ` available.
1725
+ /// Allows access to the current `TyCtxt `.
1726
+ /// The closure is passed None if there is no `TyCtxt ` available.
1828
1727
#[ inline]
1829
1728
pub fn with_opt < F , R > ( f : F ) -> R
1830
1729
where
1831
1730
F : for < ' tcx > FnOnce ( Option < TyCtxt < ' tcx > > ) -> R ,
1832
1731
{
1833
- with_context_opt ( |opt_context| f ( opt_context. map ( |context| context. tcx ) ) )
1732
+ let context = TLV . with ( |tlv| tlv. get ( ) ) ;
1733
+ let tcx = if context == std:: ptr:: null ( ) {
1734
+ None
1735
+ } else {
1736
+ let gcx = unsafe { & * context. cast :: < GlobalCtxt < ' _ > > ( ) } ;
1737
+ Some ( TyCtxt { gcx } )
1738
+ } ;
1739
+ f ( tcx)
1834
1740
}
1835
1741
}
1836
1742
0 commit comments