@@ -11,6 +11,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
1111use parking_lot:: Mutex ;
1212use smallvec:: { smallvec, SmallVec } ;
1313use std:: collections:: hash_map:: Entry ;
14+ use std:: fmt:: Debug ;
1415use std:: hash:: Hash ;
1516use std:: marker:: PhantomData ;
1617use std:: sync:: atomic:: Ordering :: Relaxed ;
@@ -208,89 +209,99 @@ impl<K: DepKind> DepGraph<K> {
208209 /// `arg` parameter.
209210 ///
210211 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html
211- pub fn with_task < Ctxt : HasDepContext < DepKind = K > , A , R > (
212+ pub fn with_task < Ctxt : HasDepContext < DepKind = K > , A : Debug , R > (
212213 & self ,
213214 key : DepNode < K > ,
214215 cx : Ctxt ,
215216 arg : A ,
216217 task : fn ( Ctxt , A ) -> R ,
217- hash_result : impl FnOnce ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
218+ hash_result : fn ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
218219 ) -> ( R , DepNodeIndex ) {
219- self . with_task_impl (
220- key,
221- cx,
222- arg,
223- task,
224- |_key| {
225- Some ( TaskDeps {
226- #[ cfg( debug_assertions) ]
227- node : Some ( _key) ,
228- reads : SmallVec :: new ( ) ,
229- read_set : Default :: default ( ) ,
230- phantom_data : PhantomData ,
231- } )
232- } ,
233- hash_result,
234- )
220+ if self . is_fully_enabled ( ) {
221+ self . with_task_impl ( key, cx, arg, task, hash_result)
222+ } else {
223+ // Incremental compilation is turned off. We just execute the task
224+ // without tracking. We still provide a dep-node index that uniquely
225+ // identifies the task so that we have a cheap way of referring to
226+ // the query for self-profiling.
227+ ( task ( cx, arg) , self . next_virtual_depnode_index ( ) )
228+ }
235229 }
236230
237- fn with_task_impl < Ctxt : HasDepContext < DepKind = K > , A , R > (
231+ fn with_task_impl < Ctxt : HasDepContext < DepKind = K > , A : Debug , R > (
238232 & self ,
239233 key : DepNode < K > ,
240234 cx : Ctxt ,
241235 arg : A ,
242236 task : fn ( Ctxt , A ) -> R ,
243- create_task : fn ( DepNode < K > ) -> Option < TaskDeps < K > > ,
244- hash_result : impl FnOnce ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
237+ hash_result : fn ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
245238 ) -> ( R , DepNodeIndex ) {
246- if let Some ( ref data) = self . data {
247- let dcx = cx. dep_context ( ) ;
248- let task_deps = create_task ( key) . map ( Lock :: new) ;
249- let result = K :: with_deps ( task_deps. as_ref ( ) , || task ( cx, arg) ) ;
250- let edges = task_deps. map_or_else ( || smallvec ! [ ] , |lock| lock. into_inner ( ) . reads ) ;
251-
252- let mut hcx = dcx. create_stable_hashing_context ( ) ;
253- let hashing_timer = dcx. profiler ( ) . incr_result_hashing ( ) ;
254- let current_fingerprint = hash_result ( & mut hcx, & result) ;
255-
256- let print_status = cfg ! ( debug_assertions) && dcx. sess ( ) . opts . debugging_opts . dep_tasks ;
257-
258- // Get timer for profiling `DepNode` interning
259- let node_intern_timer = self
260- . node_intern_event_id
261- . map ( |eid| dcx. profiler ( ) . generic_activity_with_event_id ( eid) ) ;
262- // Intern the new `DepNode`.
263- let ( dep_node_index, prev_and_color) = data. current . intern_node (
264- dcx. profiler ( ) ,
265- & data. previous ,
266- key,
267- edges,
268- current_fingerprint,
269- print_status,
270- ) ;
271- drop ( node_intern_timer) ;
239+ // This function is only called when the graph is enabled.
240+ let data = self . data . as_ref ( ) . unwrap ( ) ;
272241
273- hashing_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
242+ // If the following assertion triggers, it can have two reasons:
243+ // 1. Something is wrong with DepNode creation, either here or
244+ // in `DepGraph::try_mark_green()`.
245+ // 2. Two distinct query keys get mapped to the same `DepNode`
246+ // (see for example #48923).
247+ assert ! (
248+ !self . dep_node_exists( & key) ,
249+ "forcing query with already existing `DepNode`\n \
250+ - query-key: {:?}\n \
251+ - dep-node: {:?}",
252+ arg,
253+ key
254+ ) ;
274255
275- if let Some ( ( prev_index, color) ) = prev_and_color {
276- debug_assert ! (
277- data. colors. get( prev_index) . is_none( ) ,
278- "DepGraph::with_task() - Duplicate DepNodeColor \
279- insertion for {:?}",
280- key
281- ) ;
256+ let task_deps = if key. kind . is_eval_always ( ) {
257+ None
258+ } else {
259+ Some ( Lock :: new ( TaskDeps {
260+ #[ cfg( debug_assertions) ]
261+ node : Some ( key) ,
262+ reads : SmallVec :: new ( ) ,
263+ read_set : Default :: default ( ) ,
264+ phantom_data : PhantomData ,
265+ } ) )
266+ } ;
267+ let result = K :: with_deps ( task_deps. as_ref ( ) , || task ( cx, arg) ) ;
268+ let edges = task_deps. map_or_else ( || smallvec ! [ ] , |lock| lock. into_inner ( ) . reads ) ;
269+
270+ let dcx = cx. dep_context ( ) ;
271+ let mut hcx = dcx. create_stable_hashing_context ( ) ;
272+ let hashing_timer = dcx. profiler ( ) . incr_result_hashing ( ) ;
273+ let current_fingerprint = hash_result ( & mut hcx, & result) ;
274+
275+ let print_status = cfg ! ( debug_assertions) && dcx. sess ( ) . opts . debugging_opts . dep_tasks ;
276+
277+ // Get timer for profiling `DepNode` interning
278+ let node_intern_timer =
279+ self . node_intern_event_id . map ( |eid| dcx. profiler ( ) . generic_activity_with_event_id ( eid) ) ;
280+ // Intern the new `DepNode`.
281+ let ( dep_node_index, prev_and_color) = data. current . intern_node (
282+ dcx. profiler ( ) ,
283+ & data. previous ,
284+ key,
285+ edges,
286+ current_fingerprint,
287+ print_status,
288+ ) ;
289+ drop ( node_intern_timer) ;
282290
283- data. colors . insert ( prev_index, color) ;
284- }
291+ hashing_timer. finish_with_query_invocation_id ( dep_node_index. into ( ) ) ;
285292
286- ( result, dep_node_index)
287- } else {
288- // Incremental compilation is turned off. We just execute the task
289- // without tracking. We still provide a dep-node index that uniquely
290- // identifies the task so that we have a cheap way of referring to
291- // the query for self-profiling.
292- ( task ( cx, arg) , self . next_virtual_depnode_index ( ) )
293+ if let Some ( ( prev_index, color) ) = prev_and_color {
294+ debug_assert ! (
295+ data. colors. get( prev_index) . is_none( ) ,
296+ "DepGraph::with_task() - Duplicate DepNodeColor \
297+ insertion for {:?}",
298+ key
299+ ) ;
300+
301+ data. colors . insert ( prev_index, color) ;
293302 }
303+
304+ ( result, dep_node_index)
294305 }
295306
296307 /// Executes something within an "anonymous" task, that is, a task the
@@ -357,19 +368,6 @@ impl<K: DepKind> DepGraph<K> {
357368 }
358369 }
359370
360- /// Executes something within an "eval-always" task which is a task
361- /// that runs whenever anything changes.
362- pub fn with_eval_always_task < Ctxt : HasDepContext < DepKind = K > , A , R > (
363- & self ,
364- key : DepNode < K > ,
365- cx : Ctxt ,
366- arg : A ,
367- task : fn ( Ctxt , A ) -> R ,
368- hash_result : impl FnOnce ( & mut Ctxt :: StableHashingContext , & R ) -> Option < Fingerprint > ,
369- ) -> ( R , DepNodeIndex ) {
370- self . with_task_impl ( key, cx, arg, task, |_| None , hash_result)
371- }
372-
373371 #[ inline]
374372 pub fn read_index ( & self , dep_node_index : DepNodeIndex ) {
375373 if let Some ( ref data) = self . data {
@@ -484,22 +482,11 @@ impl<K: DepKind> DepGraph<K> {
484482 None
485483 }
486484
487- /// Try to read a node index for the node dep_node.
485+ /// Try to mark a node index for the node dep_node.
486+ ///
488487 /// A node will have an index, when it's already been marked green, or when we can mark it
489488 /// green. This function will mark the current task as a reader of the specified node, when
490489 /// a node index can be found for that node.
491- pub fn try_mark_green_and_read < Ctxt : QueryContext < DepKind = K > > (
492- & self ,
493- tcx : Ctxt ,
494- dep_node : & DepNode < K > ,
495- ) -> Option < ( SerializedDepNodeIndex , DepNodeIndex ) > {
496- self . try_mark_green ( tcx, dep_node) . map ( |( prev_index, dep_node_index) | {
497- debug_assert ! ( self . is_green( & dep_node) ) ;
498- self . read_index ( dep_node_index) ;
499- ( prev_index, dep_node_index)
500- } )
501- }
502-
503490 pub fn try_mark_green < Ctxt : QueryContext < DepKind = K > > (
504491 & self ,
505492 tcx : Ctxt ,
0 commit comments