1
- use super :: { ptr_eq , GlobalCtxt , TyCtxt } ;
1
+ use super :: { GlobalCtxt , TyCtxt } ;
2
2
3
3
use crate :: dep_graph:: TaskDepsRef ;
4
4
use crate :: ty:: query;
5
5
use rustc_data_structures:: sync:: { self , Lock } ;
6
6
use rustc_errors:: Diagnostic ;
7
7
use std:: mem;
8
+ use std:: ptr;
8
9
use thin_vec:: ThinVec ;
9
10
10
- #[ cfg( not( parallel_compiler) ) ]
11
- use std:: cell:: Cell ;
12
-
13
- #[ cfg( parallel_compiler) ]
14
- use rustc_rayon_core as rayon_core;
15
-
16
11
/// This is the implicit state of rustc. It contains the current
17
12
/// `TyCtxt` and query. It is updated when creating a local interner or
18
13
/// executing a new query. Whenever there's a `TyCtxt` value available
@@ -52,46 +47,53 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> {
52
47
}
53
48
}
54
49
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`.
58
50
#[ 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
+ }
63
61
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
+ }
70
69
}
71
70
72
71
#[ 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;
77
75
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
+ }
89
80
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
+ }
95
97
}
96
98
97
99
/// 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) ->
100
102
where
101
103
F : FnOnce ( & ImplicitCtxt < ' a , ' tcx > ) -> R ,
102
104
{
103
- set_tlv ( context as * const _ as usize , || f ( & context) )
105
+ tlv :: with_tlv ( context as * const _ as usize , || f ( & context) )
104
106
}
105
107
106
108
/// 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
109
111
where
110
112
F : for <' a , ' tcx > FnOnce ( Option < & ImplicitCtxt < ' a , ' tcx > > ) -> R ,
111
113
{
112
- let context = get_tlv ( ) ;
114
+ let context = tlv :: get_tlv ( ) ;
113
115
if context == 0 {
114
116
f ( None )
115
117
} else {
@@ -141,9 +143,15 @@ pub fn with_related_context<'tcx, F, R>(tcx: TyCtxt<'tcx>, f: F) -> R
141
143
where
142
144
F : FnOnce ( & ImplicitCtxt < ' _ , ' tcx > ) -> R ,
143
145
{
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
+
147
155
f ( context)
148
156
} )
149
157
}
0 commit comments