1- use super :: { ptr_eq , GlobalCtxt , TyCtxt } ;
1+ use super :: { GlobalCtxt , TyCtxt } ;
22
33use crate :: dep_graph:: TaskDepsRef ;
44use crate :: ty:: query;
55use rustc_data_structures:: sync:: { self , Lock } ;
66use rustc_errors:: Diagnostic ;
77use std:: mem;
8+ use std:: ptr;
89use thin_vec:: ThinVec ;
910
10- #[ cfg( not( parallel_compiler) ) ]
11- use std:: cell:: Cell ;
12-
13- #[ cfg( parallel_compiler) ]
14- use rustc_rayon_core as rayon_core;
15-
1611/// This is the implicit state of rustc. It contains the current
1712/// `TyCtxt` and query. It is updated when creating a local interner or
1813/// executing a new query. Whenever there's a `TyCtxt` value available
@@ -52,46 +47,53 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
5247 }
5348}
5449
55- /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
56- /// to `value` during the call to `f`. It is restored to its previous value after.
57- /// This is used to set the pointer to the new `ImplicitCtxt`.
5850#[ cfg( parallel_compiler) ]
59- #[ inline]
60- fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
61- rayon_core:: tlv:: with ( value, f)
62- }
51+ mod tlv {
52+ use rustc_rayon_core as rayon_core;
53+ use std:: ptr;
54+
55+ /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
56+ /// This is used to get the pointer to the current `ImplicitCtxt`.
57+ #[ inline]
58+ pub ( super ) fn get_tlv ( ) -> usize {
59+ rayon_core:: tlv:: get ( )
60+ }
6361
64- /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs.
65- /// This is used to get the pointer to the current `ImplicitCtxt`.
66- #[ cfg( parallel_compiler) ]
67- #[ inline]
68- pub fn get_tlv ( ) -> usize {
69- rayon_core:: tlv:: get ( )
62+ /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs
63+ /// to `value` during the call to `f`. It is restored to its previous value after.
64+ /// This is used to set the pointer to the new `ImplicitCtxt`.
65+ #[ inline]
66+ pub ( super ) fn with_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
67+ rayon_core:: tlv:: with ( value, f)
68+ }
7069}
7170
7271#[ cfg( not( parallel_compiler) ) ]
73- thread_local ! {
74- /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
75- static TLV : Cell <usize > = const { Cell :: new( 0 ) } ;
76- }
72+ mod tlv {
73+ use std:: cell:: Cell ;
74+ use std:: ptr;
7775
78- /// Sets TLV to `value` during the call to `f`.
79- /// It is restored to its previous value after.
80- /// This is used to set the pointer to the new `ImplicitCtxt`.
81- #[ cfg( not( parallel_compiler) ) ]
82- #[ inline]
83- fn set_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
84- let old = get_tlv ( ) ;
85- let _reset = rustc_data_structures:: OnDrop ( move || TLV . with ( |tlv| tlv. set ( old) ) ) ;
86- TLV . with ( |tlv| tlv. set ( value) ) ;
87- f ( )
88- }
76+ thread_local ! {
77+ /// A thread local variable that stores a pointer to the current `ImplicitCtxt`.
78+ static TLV : Cell <usize > = const { Cell :: new( 0 ) } ;
79+ }
8980
90- /// Gets the pointer to the current `ImplicitCtxt`.
91- #[ cfg( not( parallel_compiler) ) ]
92- #[ inline]
93- fn get_tlv ( ) -> usize {
94- TLV . with ( |tlv| tlv. get ( ) )
81+ /// Gets the pointer to the current `ImplicitCtxt`.
82+ #[ inline]
83+ pub ( super ) fn get_tlv ( ) -> usize {
84+ TLV . with ( |tlv| tlv. get ( ) )
85+ }
86+
87+ /// Sets TLV to `value` during the call to `f`.
88+ /// It is restored to its previous value after.
89+ /// This is used to set the pointer to the new `ImplicitCtxt`.
90+ #[ inline]
91+ pub ( super ) fn with_tlv < F : FnOnce ( ) -> R , R > ( value : usize , f : F ) -> R {
92+ let old = get_tlv ( ) ;
93+ let _reset = rustc_data_structures:: OnDrop ( move || TLV . with ( |tlv| tlv. set ( old) ) ) ;
94+ TLV . with ( |tlv| tlv. set ( value) ) ;
95+ f ( )
96+ }
9597}
9698
9799/// Sets `context` as the new current `ImplicitCtxt` for the duration of the function `f`.
@@ -100,7 +102,7 @@ pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) ->
100102where
101103 F : FnOnce ( & ImplicitCtxt < ' a , ' tcx > ) -> R ,
102104{
103- set_tlv ( context as * const _ as usize , || f ( & context) )
105+ tlv :: with_tlv ( context as * const _ as usize , || f ( & context) )
104106}
105107
106108/// Allows access to the current `ImplicitCtxt` in a closure if one is available.
@@ -109,7 +111,7 @@ pub fn with_context_opt<F, R>(f: F) -> R
109111where
110112 F : for <' a , ' tcx > FnOnce ( Option < & ImplicitCtxt < ' a , ' tcx > > ) -> R ,
111113{
112- let context = get_tlv ( ) ;
114+ let context = tlv :: get_tlv ( ) ;
113115 if context == 0 {
114116 f ( None )
115117 } else {
@@ -141,9 +143,15 @@ pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
141143where
142144 F : FnOnce ( & ImplicitCtxt < ' _ , ' tcx > ) -> R ,
143145{
144- with_context ( |context| unsafe {
145- assert ! ( ptr_eq( context. tcx. gcx, tcx. gcx) ) ;
146- let context: & ImplicitCtxt < ' _ , ' _ > = mem:: transmute ( context) ;
146+ with_context ( |context| {
147+ // The two gcx have different invariant lifetimes, so we need to erase them for the comparison.
148+ assert ! ( ptr:: eq(
149+ context. tcx. gcx as * const _ as * const ( ) ,
150+ tcx. gcx as * const _ as * const ( )
151+ ) ) ;
152+
153+ let context: & ImplicitCtxt < ' _ , ' _ > = unsafe { mem:: transmute ( context) } ;
154+
147155 f ( context)
148156 } )
149157}
0 commit comments