@@ -5,6 +5,7 @@ use rustc::mir;
5
5
use rustc:: ty:: { self , TyCtxt , Ty , Instance } ;
6
6
use rustc:: ty:: layout:: { self , LayoutOf } ;
7
7
use rustc:: ty:: subst:: Subst ;
8
+ use rustc:: util:: nodemap:: FxHashSet ;
8
9
9
10
use syntax:: ast:: Mutability ;
10
11
use syntax:: codemap:: Span ;
@@ -504,7 +505,13 @@ pub fn const_eval_provider<'a, 'tcx>(
504
505
} ;
505
506
506
507
let ( res, ecx) = eval_body_and_ecx ( tcx, cid, None , key. param_env ) ;
507
- res. map ( |( miri_value, _, miri_ty) | {
508
+ res. map ( |( miri_value, ptr, miri_ty) | {
509
+ if tcx. is_static ( def_id) . is_some ( ) {
510
+ if let Ok ( ptr) = ptr. primval . to_ptr ( ) {
511
+ let mut seen = FxHashSet :: default ( ) ;
512
+ create_depgraph_edges ( tcx, ptr. alloc_id , & mut seen) ;
513
+ }
514
+ }
508
515
tcx. mk_const ( ty:: Const {
509
516
val : ConstVal :: Value ( miri_value) ,
510
517
ty : miri_ty,
@@ -521,3 +528,35 @@ pub fn const_eval_provider<'a, 'tcx>(
521
528
}
522
529
} )
523
530
}
531
+
532
+ // This function creates dep graph edges from statics to all referred to statics.
533
+ // This is necessary, because the `const_eval` query cannot directly call itself
534
+ // for other statics, because we cannot prevent recursion in queries.
535
+ //
536
+ // see test/incremental/static_refering_to_other_static2/issue.rs for an example
537
+ // where not creating those edges would cause static A, which refers to static B
538
+ // to point to the old allocation of static B, even though B has changed.
539
+ //
540
+ // In the future we will want to remove this funcion in favour of a system that
541
+ // makes sure that statics don't need to have edges to other statics as long as
542
+ // they are only referring by reference and not inspecting the other static's body.
543
+ fn create_depgraph_edges < ' a , ' tcx > (
544
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
545
+ alloc_id : AllocId ,
546
+ seen : & mut FxHashSet < AllocId > ,
547
+ ) {
548
+ trace ! ( "create_depgraph_edges: {:?}, {:?}" , alloc_id, seen) ;
549
+ if seen. insert ( alloc_id) {
550
+ trace ! ( "seen: {:?}, {:?}" , alloc_id, seen) ;
551
+ if let Some ( alloc) = tcx. interpret_interner . get_alloc ( alloc_id) {
552
+ trace ! ( "get_alloc: {:?}, {:?}, {:?}" , alloc_id, seen, alloc) ;
553
+ for ( _, & reloc) in & alloc. relocations {
554
+ if let Some ( did) = tcx. interpret_interner . get_corresponding_static_def_id ( reloc) {
555
+ trace ! ( "get_corresponding: {:?}, {:?}, {:?}, {:?}, {:?}" , alloc_id, seen, alloc, did, reloc) ;
556
+ let _ = tcx. maybe_optimized_mir ( did) ;
557
+ }
558
+ create_depgraph_edges ( tcx, reloc, seen) ;
559
+ }
560
+ }
561
+ }
562
+ }
0 commit comments