use ich::{self, CachingCodemapView, Fingerprint};
use middle::cstore::CrateStore;
use ty::{TyCtxt, fast_reject};
+use mir::interpret::AllocId;
use session::Session;
use std::cmp::Ord;
// CachingCodemapView, so we initialize it lazily.
raw_codemap: &'a CodeMap,
caching_codemap: Option<CachingCodemapView<'a>>,
+
+ pub(super) alloc_id_recursion_tracker: FxHashSet<AllocId>,
}
#[derive(PartialEq, Eq, Clone, Copy)]
hash_spans: hash_spans_initial,
hash_bodies: true,
node_id_hashing_mode: NodeIdHashingMode::HashDefPath,
+ alloc_id_recursion_tracker: Default::default(),
}
}
});
enum AllocDiscriminant {
- Static,
- Constant,
+ Alloc,
+ ExternStatic,
Function,
}
impl_stable_hash_for!(enum self::AllocDiscriminant {
- Static,
- Constant,
+ Alloc,
+ ExternStatic,
Function
});
) {
ty::tls::with_opt(|tcx| {
let tcx = tcx.expect("can't hash AllocIds during hir lowering");
- if let Some(def_id) = tcx.interpret_interner.get_corresponding_static_def_id(*self) {
- AllocDiscriminant::Static.hash_stable(hcx, hasher);
- // statics are unique via their DefId
- def_id.hash_stable(hcx, hasher);
- } else if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) {
- // not a static, can't be recursive, hash the allocation
- AllocDiscriminant::Constant.hash_stable(hcx, hasher);
- alloc.hash_stable(hcx, hasher);
+ if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) {
+ AllocDiscriminant::Alloc.hash_stable(hcx, hasher);
+ if !hcx.alloc_id_recursion_tracker.insert(*self) {
+ tcx
+ .interpret_interner
+ .get_corresponding_static_def_id(*self)
+ .hash_stable(hcx, hasher);
+ alloc.hash_stable(hcx, hasher);
+ assert!(hcx.alloc_id_recursion_tracker.remove(self));
+ }
} else if let Some(inst) = tcx.interpret_interner.get_fn(*self) {
AllocDiscriminant::Function.hash_stable(hcx, hasher);
inst.hash_stable(hcx, hasher);
+ } else if let Some(def_id) = tcx.interpret_interner
+ .get_corresponding_static_def_id(*self) {
+ AllocDiscriminant::ExternStatic.hash_stable(hcx, hasher);
+ def_id.hash_stable(hcx, hasher);
} else {
bug!("no allocation for {}", self);
}
--- /dev/null
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// https://github.com/rust-lang/rust/issues/49081
+
+// revisions:rpass1 rpass2
+
+#[cfg(rpass1)]
+pub static A: &str = "hello";
+#[cfg(rpass2)]
+pub static A: &str = "xxxxx";
+
+#[cfg(rpass1)]
+fn main() {
+ assert_eq!(A, "hello");
+}
+
+#[cfg(rpass2)]
+fn main() {
+ assert_eq!(A, "xxxxx");
+}