Skip to content

Commit 70248b1

Browse files
committed
Auto merge of #49500 - oli-obk:mir_dep_graph, r=michaelwoerister
Introduce an edge from a const eval to the MIR of all statics it depends on r? @michaelwoerister
2 parents 8dd24c8 + 8107b56 commit 70248b1

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/librustc_mir/interpret/const_eval.rs

+40-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc::mir;
55
use rustc::ty::{self, TyCtxt, Ty, Instance};
66
use rustc::ty::layout::{self, LayoutOf};
77
use rustc::ty::subst::Subst;
8+
use rustc::util::nodemap::FxHashSet;
89

910
use syntax::ast::Mutability;
1011
use 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+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// revisions:rpass1 rpass2
12+
13+
#[cfg(rpass1)]
14+
pub static A: i32 = 42;
15+
#[cfg(rpass2)]
16+
pub static A: i32 = 43;
17+
18+
pub static B: &i32 = &A;
19+
20+
fn main() {}

0 commit comments

Comments
 (0)