@@ -1682,155 +1682,61 @@ CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } }
16821682
16831683pub mod tls {
16841684 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;
16931686 use std:: cell:: Cell ;
16941687
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) ) ]
17551688 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( ) ) } ;
17771693 }
17781694
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`.
17801696 #[ 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
17821698 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 ,
17931700 {
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 < ' _ > > ( ) ;
18051704
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 } )
18141713 }
18151714
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.
18181717 #[ inline]
18191718 pub fn with < F , R > ( f : F ) -> R
18201719 where
18211720 F : for < ' tcx > FnOnce ( TyCtxt < ' tcx > ) -> R ,
18221721 {
1823- with_context ( |context | f ( context . tcx ) )
1722+ with_opt ( |opt_tcx | f ( opt_tcx . expect ( "no TyCtxt stored in tls" ) ) )
18241723 }
18251724
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.
18281727 #[ inline]
18291728 pub fn with_opt < F , R > ( f : F ) -> R
18301729 where
18311730 F : for < ' tcx > FnOnce ( Option < TyCtxt < ' tcx > > ) -> R ,
18321731 {
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)
18341740 }
18351741}
18361742
0 commit comments