@@ -109,40 +109,12 @@ pub(crate) fn query_feed<'tcx, C>(
109109 C : QueryCache ,
110110 C :: Key : DepNodeKey < ' tcx > ,
111111{
112- let format_value = query. format_value ;
113-
114112 // Check whether the in-memory cache already has a value for this key.
115113 match try_get_cached ( tcx, & query. cache , key) {
116114 Some ( old) => {
117- // The query already has a cached value for this key.
118- // That's OK if both values are the same, i.e. they have the same hash,
119- // so now we check their hashes.
120- if let Some ( hash_value_fn) = query. hash_value_fn {
121- let ( old_hash, value_hash) = tcx. with_stable_hashing_context ( |ref mut hcx| {
122- ( hash_value_fn ( hcx, & old) , hash_value_fn ( hcx, & value) )
123- } ) ;
124- if old_hash != value_hash {
125- // We have an inconsistency. This can happen if one of the two
126- // results is tainted by errors. In this case, delay a bug to
127- // ensure compilation is doomed, and keep the `old` value.
128- tcx. dcx ( ) . delayed_bug ( format ! (
129- "Trying to feed an already recorded value for query {query:?} key={key:?}:\n \
130- old value: {old}\n new value: {value}",
131- old = format_value( & old) ,
132- value = format_value( & value) ,
133- ) ) ;
134- }
135- } else {
136- // The query is `no_hash`, so we have no way to perform a sanity check.
137- // If feeding the same value multiple times needs to be supported,
138- // the query should not be marked `no_hash`.
139- bug ! (
140- "Trying to feed an already recorded value for query {query:?} key={key:?}:\n \
141- old value: {old}\n new value: {value}",
142- old = format_value( & old) ,
143- value = format_value( & value) ,
144- )
145- }
115+ // There was already a cached value for this key.
116+ // Check whether the collision is fine or a compiler bug.
117+ on_query_feed_collision ( tcx, query, key, old, value) ;
146118 }
147119 None => {
148120 // There is no cached value for this key, so feed the query by
@@ -159,3 +131,47 @@ pub(crate) fn query_feed<'tcx, C>(
159131 }
160132 }
161133}
134+
135+ /// Called when a query is fed with a key/value pair, but there is already a value
136+ /// for that key in the query's in-memory cache.
137+ ///
138+ /// Depending on the circumstances, this might be fine, or it might be a compiler bug.
139+ fn on_query_feed_collision < ' tcx , C : QueryCache > (
140+ tcx : TyCtxt < ' tcx > ,
141+ query : & ' tcx QueryVTable < ' tcx , C > ,
142+ key : C :: Key ,
143+ old : C :: Value ,
144+ value : C :: Value ,
145+ ) {
146+ let format_value = query. format_value ;
147+
148+ // The query already has a cached value for this key.
149+ // That's OK if both values are the same, i.e. they have the same hash,
150+ // so now we check their hashes.
151+ if let Some ( hash_value_fn) = query. hash_value_fn {
152+ let ( old_hash, value_hash) = tcx. with_stable_hashing_context ( |ref mut hcx| {
153+ ( hash_value_fn ( hcx, & old) , hash_value_fn ( hcx, & value) )
154+ } ) ;
155+ if old_hash != value_hash {
156+ // We have an inconsistency. This can happen if one of the two
157+ // results is tainted by errors. In this case, delay a bug to
158+ // ensure compilation is doomed, and keep the `old` value.
159+ tcx. dcx ( ) . delayed_bug ( format ! (
160+ "Trying to feed an already recorded value for query {query:?} key={key:?}:\n \
161+ old value: {old}\n new value: {value}",
162+ old = format_value( & old) ,
163+ value = format_value( & value) ,
164+ ) ) ;
165+ }
166+ } else {
167+ // The query is `no_hash`, so we have no way to perform a sanity check.
168+ // If feeding the same value multiple times needs to be supported,
169+ // the query should not be marked `no_hash`.
170+ bug ! (
171+ "Trying to feed an already recorded value for query {query:?} key={key:?}:\n \
172+ old value: {old}\n new value: {value}",
173+ old = format_value( & old) ,
174+ value = format_value( & value) ,
175+ )
176+ }
177+ }
0 commit comments