@@ -86,6 +86,93 @@ pub use self::on_disk_cache::OnDiskCache;
86
86
mod profiling_support;
87
87
pub use self :: profiling_support:: alloc_self_profile_query_strings;
88
88
89
+ #[ derive( Copy , Clone ) ]
90
+ pub struct TyCtxtAt < ' tcx > {
91
+ pub tcx : TyCtxt < ' tcx > ,
92
+ pub span : Span ,
93
+ }
94
+
95
+ impl Deref for TyCtxtAt < ' tcx > {
96
+ type Target = TyCtxt < ' tcx > ;
97
+ #[ inline( always) ]
98
+ fn deref ( & self ) -> & Self :: Target {
99
+ & self . tcx
100
+ }
101
+ }
102
+
103
+ #[ derive( Copy , Clone ) ]
104
+ pub struct TyCtxtEnsure < ' tcx > {
105
+ pub tcx : TyCtxt < ' tcx > ,
106
+ }
107
+
108
+ impl TyCtxt < ' tcx > {
109
+ /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
110
+ /// are executed instead of just returning their results.
111
+ #[ inline( always) ]
112
+ pub fn ensure ( self ) -> TyCtxtEnsure < ' tcx > {
113
+ TyCtxtEnsure { tcx : self }
114
+ }
115
+
116
+ /// Returns a transparent wrapper for `TyCtxt` which uses
117
+ /// `span` as the location of queries performed through it.
118
+ #[ inline( always) ]
119
+ pub fn at ( self , span : Span ) -> TyCtxtAt < ' tcx > {
120
+ TyCtxtAt { tcx : self , span }
121
+ }
122
+ }
123
+
124
+ macro_rules! define_callbacks {
125
+ ( <$tcx: tt>
126
+ $( $( #[ $attr: meta] ) *
127
+ [ $( $modifiers: tt) * ] fn $name: ident( $( $K: tt) * ) -> $V: ty, ) * ) => {
128
+
129
+ impl TyCtxtEnsure <$tcx> {
130
+ $( $( #[ $attr] ) *
131
+ #[ inline( always) ]
132
+ pub fn $name( self , key: query_helper_param_ty!( $( $K) * ) ) {
133
+ let key = key. into_query_param( ) ;
134
+ let cached = try_get_cached( self . tcx, & self . tcx. query_caches. $name, & key, |_| { } ) ;
135
+
136
+ let lookup = match cached {
137
+ Ok ( ( ) ) => return ,
138
+ Err ( lookup) => lookup,
139
+ } ;
140
+
141
+ self . tcx. queries. $name( self . tcx, DUMMY_SP , key, lookup, QueryMode :: Ensure ) ;
142
+ } ) *
143
+ }
144
+
145
+ impl TyCtxt <$tcx> {
146
+ $( $( #[ $attr] ) *
147
+ #[ inline( always) ]
148
+ #[ must_use]
149
+ pub fn $name( self , key: query_helper_param_ty!( $( $K) * ) ) -> query_stored:: $name<$tcx>
150
+ {
151
+ self . at( DUMMY_SP ) . $name( key)
152
+ } ) *
153
+ }
154
+
155
+ impl TyCtxtAt <$tcx> {
156
+ $( $( #[ $attr] ) *
157
+ #[ inline( always) ]
158
+ pub fn $name( self , key: query_helper_param_ty!( $( $K) * ) ) -> query_stored:: $name<$tcx>
159
+ {
160
+ let key = key. into_query_param( ) ;
161
+ let cached = try_get_cached( self . tcx, & self . tcx. query_caches. $name, & key, |value| {
162
+ value. clone( )
163
+ } ) ;
164
+
165
+ let lookup = match cached {
166
+ Ok ( value) => return value,
167
+ Err ( lookup) => lookup,
168
+ } ;
169
+
170
+ self . tcx. queries. $name( self . tcx, self . span, key, lookup, QueryMode :: Get ) . unwrap( )
171
+ } ) *
172
+ }
173
+ }
174
+ }
175
+
89
176
// Each of these queries corresponds to a function pointer field in the
90
177
// `Providers` struct for requesting a value of that type, and a method
91
178
// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
@@ -99,6 +186,7 @@ pub use self::profiling_support::alloc_self_profile_query_strings;
99
186
// as they will raise an fatal error on query cycles instead.
100
187
101
188
rustc_query_append ! { [ define_queries!] [ <' tcx>] }
189
+ rustc_query_append ! { [ define_callbacks!] [ <' tcx>] }
102
190
103
191
mod sealed {
104
192
use super :: { DefId , LocalDefId } ;
0 commit comments