@@ -5,6 +5,7 @@ use rustc::mir;
55use rustc:: ty:: { self , TyCtxt , Ty , Instance } ;
66use rustc:: ty:: layout:: { self , LayoutOf } ;
77use rustc:: ty:: subst:: Subst ;
8+ use rustc:: util:: nodemap:: FxHashSet ;
89
910use syntax:: ast:: Mutability ;
1011use syntax:: codemap:: Span ;
@@ -504,7 +505,13 @@ pub fn const_eval_provider<'a, 'tcx>(
504505 } ;
505506
506507 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+ }
508515 tcx. mk_const ( ty:: Const {
509516 val : ConstVal :: Value ( miri_value) ,
510517 ty : miri_ty,
@@ -521,3 +528,35 @@ pub fn const_eval_provider<'a, 'tcx>(
521528 }
522529 } )
523530}
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