@@ -12,17 +12,16 @@ use rustc_middle::arena::Arena;
1212use rustc_middle:: dep_graph:: { self , DepKind , DepKindVTable , DepNodeIndex } ;
1313use rustc_middle:: query:: erase:: { Erase , erase, restore} ;
1414use rustc_middle:: query:: on_disk_cache:: { CacheEncoder , EncodedDepNodeIndex , OnDiskCache } ;
15- use rustc_middle:: query:: plumbing:: { DynamicQuery , QuerySystem , QuerySystemFns } ;
15+ use rustc_middle:: query:: plumbing:: { QuerySystem , QuerySystemFns , QueryVTable } ;
1616use rustc_middle:: query:: {
17- AsLocalKey , DynamicQueries , ExternProviders , Providers , QueryCaches , QueryEngine , QueryStates ,
18- queries,
17+ AsLocalKey , ExternProviders , Providers , QueryCaches , QueryEngine , QueryStates , queries,
1918} ;
2019use rustc_middle:: ty:: TyCtxt ;
2120use rustc_query_system:: Value ;
2221use rustc_query_system:: dep_graph:: SerializedDepNodeIndex ;
2322use rustc_query_system:: ich:: StableHashingContext ;
2423use rustc_query_system:: query:: {
25- CycleError , CycleErrorHandling , HashResult , QueryCache , QueryConfig , QueryMap , QueryMode ,
24+ CycleError , CycleErrorHandling , HashResult , QueryCache , QueryDispatcher , QueryMap , QueryMode ,
2625 QueryStackDeferred , QueryState , get_query_incr, get_query_non_incr,
2726} ;
2827use rustc_span:: { ErrorGuaranteed , Span } ;
@@ -37,30 +36,39 @@ pub use crate::plumbing::{QueryCtxt, query_key_hash_verify_all};
3736mod profiling_support;
3837pub use self :: profiling_support:: alloc_self_profile_query_strings;
3938
40- struct DynamicConfig <
39+ /// Combines a [`QueryVTable`] with some additional compile-time booleans
40+ /// to implement [`QueryDispatcher`], for use by code in [`rustc_query_system`].
41+ ///
42+ /// Baking these boolean flags into the type gives a modest but measurable
43+ /// improvement to compiler perf and compiler code size; see
44+ /// <https://github.com/rust-lang/rust/pull/151633>.
45+ struct SemiDynamicQueryDispatcher <
4146 ' tcx ,
4247 C : QueryCache ,
4348 const ANON : bool ,
4449 const DEPTH_LIMIT : bool ,
4550 const FEEDABLE : bool ,
4651> {
47- dynamic : & ' tcx DynamicQuery < ' tcx , C > ,
52+ vtable : & ' tcx QueryVTable < ' tcx , C > ,
4853}
4954
55+ // Manually implement Copy/Clone, because deriving would put trait bounds on the cache type.
5056impl < ' tcx , C : QueryCache , const ANON : bool , const DEPTH_LIMIT : bool , const FEEDABLE : bool > Copy
51- for DynamicConfig < ' tcx , C , ANON , DEPTH_LIMIT , FEEDABLE >
57+ for SemiDynamicQueryDispatcher < ' tcx , C , ANON , DEPTH_LIMIT , FEEDABLE >
5258{
5359}
5460impl < ' tcx , C : QueryCache , const ANON : bool , const DEPTH_LIMIT : bool , const FEEDABLE : bool > Clone
55- for DynamicConfig < ' tcx , C , ANON , DEPTH_LIMIT , FEEDABLE >
61+ for SemiDynamicQueryDispatcher < ' tcx , C , ANON , DEPTH_LIMIT , FEEDABLE >
5662{
5763 fn clone ( & self ) -> Self {
5864 * self
5965 }
6066}
6167
68+ // This is `impl QueryDispatcher for SemiDynamicQueryDispatcher`.
6269impl < ' tcx , C : QueryCache , const ANON : bool , const DEPTH_LIMIT : bool , const FEEDABLE : bool >
63- QueryConfig < QueryCtxt < ' tcx > > for DynamicConfig < ' tcx , C , ANON , DEPTH_LIMIT , FEEDABLE >
70+ QueryDispatcher < QueryCtxt < ' tcx > >
71+ for SemiDynamicQueryDispatcher < ' tcx , C , ANON , DEPTH_LIMIT , FEEDABLE >
6472where
6573 for < ' a > C :: Key : HashStable < StableHashingContext < ' a > > ,
6674{
@@ -70,12 +78,12 @@ where
7078
7179 #[ inline( always) ]
7280 fn name ( self ) -> & ' static str {
73- self . dynamic . name
81+ self . vtable . name
7482 }
7583
7684 #[ inline( always) ]
7785 fn cache_on_disk ( self , tcx : TyCtxt < ' tcx > , key : & Self :: Key ) -> bool {
78- ( self . dynamic . cache_on_disk ) ( tcx, key)
86+ ( self . vtable . cache_on_disk ) ( tcx, key)
7987 }
8088
8189 #[ inline( always) ]
9098 // This is just manually doing the subfield referencing through pointer math.
9199 unsafe {
92100 & * ( & qcx. tcx . query_system . states as * const QueryStates < ' tcx > )
93- . byte_add ( self . dynamic . query_state )
101+ . byte_add ( self . vtable . query_state )
94102 . cast :: < QueryState < Self :: Key , QueryStackDeferred < ' tcx > > > ( )
95103 }
96104 }
@@ -104,19 +112,19 @@ where
104112 // This is just manually doing the subfield referencing through pointer math.
105113 unsafe {
106114 & * ( & qcx. tcx . query_system . caches as * const QueryCaches < ' tcx > )
107- . byte_add ( self . dynamic . query_cache )
115+ . byte_add ( self . vtable . query_cache )
108116 . cast :: < Self :: Cache > ( )
109117 }
110118 }
111119
112120 #[ inline( always) ]
113121 fn execute_query ( self , tcx : TyCtxt < ' tcx > , key : Self :: Key ) -> Self :: Value {
114- ( self . dynamic . execute_query ) ( tcx, key)
122+ ( self . vtable . execute_query ) ( tcx, key)
115123 }
116124
117125 #[ inline( always) ]
118126 fn compute ( self , qcx : QueryCtxt < ' tcx > , key : Self :: Key ) -> Self :: Value {
119- ( self . dynamic . compute ) ( qcx. tcx , key)
127+ ( self . vtable . compute ) ( qcx. tcx , key)
120128 }
121129
122130 #[ inline( always) ]
@@ -127,8 +135,8 @@ where
127135 prev_index : SerializedDepNodeIndex ,
128136 index : DepNodeIndex ,
129137 ) -> Option < Self :: Value > {
130- if self . dynamic . can_load_from_disk {
131- ( self . dynamic . try_load_from_disk ) ( qcx. tcx , key, prev_index, index)
138+ if self . vtable . can_load_from_disk {
139+ ( self . vtable . try_load_from_disk ) ( qcx. tcx , key, prev_index, index)
132140 } else {
133141 None
134142 }
@@ -141,7 +149,7 @@ where
141149 key : & Self :: Key ,
142150 index : SerializedDepNodeIndex ,
143151 ) -> bool {
144- ( self . dynamic . loadable_from_disk ) ( qcx. tcx , key, index)
152+ ( self . vtable . loadable_from_disk ) ( qcx. tcx , key, index)
145153 }
146154
147155 fn value_from_cycle_error (
@@ -150,12 +158,12 @@ where
150158 cycle_error : & CycleError ,
151159 guar : ErrorGuaranteed ,
152160 ) -> Self :: Value {
153- ( self . dynamic . value_from_cycle_error ) ( tcx, cycle_error, guar)
161+ ( self . vtable . value_from_cycle_error ) ( tcx, cycle_error, guar)
154162 }
155163
156164 #[ inline( always) ]
157165 fn format_value ( self ) -> fn ( & Self :: Value ) -> String {
158- self . dynamic . format_value
166+ self . vtable . format_value
159167 }
160168
161169 #[ inline( always) ]
@@ -165,7 +173,7 @@ where
165173
166174 #[ inline( always) ]
167175 fn eval_always ( self ) -> bool {
168- self . dynamic . eval_always
176+ self . vtable . eval_always
169177 }
170178
171179 #[ inline( always) ]
@@ -180,31 +188,42 @@ where
180188
181189 #[ inline( always) ]
182190 fn dep_kind ( self ) -> DepKind {
183- self . dynamic . dep_kind
191+ self . vtable . dep_kind
184192 }
185193
186194 #[ inline( always) ]
187195 fn cycle_error_handling ( self ) -> CycleErrorHandling {
188- self . dynamic . cycle_error_handling
196+ self . vtable . cycle_error_handling
189197 }
190198
191199 #[ inline( always) ]
192200 fn hash_result ( self ) -> HashResult < Self :: Value > {
193- self . dynamic . hash_result
201+ self . vtable . hash_result
194202 }
195203}
196204
197- /// This is implemented per query. It allows restoring query values from their erased state
198- /// and constructing a QueryConfig.
199- trait QueryConfigRestored < ' tcx > {
200- type RestoredValue ;
201- type Config : QueryConfig < QueryCtxt < ' tcx > > ;
205+ /// Provides access to vtable-like operations for a query
206+ /// (by creating a [`QueryDispatcher`]),
207+ /// but also keeps track of the "unerased" value type of the query
208+ /// (i.e. the actual result type in the query declaration).
209+ ///
210+ /// This trait allows some per-query code to be defined in generic functions
211+ /// with a trait bound, instead of having to be defined inline within a macro
212+ /// expansion.
213+ ///
214+ /// There is one macro-generated implementation of this trait for each query,
215+ /// on the type `rustc_query_impl::query_impl::$name::QueryType`.
216+ trait QueryDispatcherUnerased < ' tcx > {
217+ type UnerasedValue ;
218+ type Dispatcher : QueryDispatcher < QueryCtxt < ' tcx > > ;
202219
203220 const NAME : & ' static & ' static str ;
204221
205- fn config ( tcx : TyCtxt < ' tcx > ) -> Self :: Config ;
206- fn restore ( value : <Self :: Config as QueryConfig < QueryCtxt < ' tcx > > >:: Value )
207- -> Self :: RestoredValue ;
222+ fn query_dispatcher ( tcx : TyCtxt < ' tcx > ) -> Self :: Dispatcher ;
223+
224+ fn restore_val (
225+ value : <Self :: Dispatcher as QueryDispatcher < QueryCtxt < ' tcx > > >:: Value ,
226+ ) -> Self :: UnerasedValue ;
208227}
209228
210229pub fn query_system < ' a > (
@@ -217,7 +236,7 @@ pub fn query_system<'a>(
217236 states : Default :: default ( ) ,
218237 arenas : Default :: default ( ) ,
219238 caches : Default :: default ( ) ,
220- dynamic_queries : dynamic_queries ( ) ,
239+ query_vtables : make_query_vtables ( ) ,
221240 on_disk_cache,
222241 fns : QuerySystemFns {
223242 engine : engine ( incremental) ,
0 commit comments