4 use rustc::middle::region;
5 use rustc::ty::layout::Size;
7 ////////////////////////////////////////////////////////////////////////////////
9 ////////////////////////////////////////////////////////////////////////////////
11 // Just some dummy to keep this compiling; I think some of this will be useful later
12 type AbsPlace<'tcx> = ::rustc::ty::Ty<'tcx>;
14 /// Information about a lock that is currently held.
15 #[derive(Clone, Debug, PartialEq, Eq)]
16 pub struct LockInfo<'tcx> {
17 /// Stores for which lifetimes (of the original write lock) we got
18 /// which suspensions.
19 suspended: HashMap<WriteLockId<'tcx>, Vec<region::Scope>>,
20 /// The current state of the lock that's actually effective.
24 /// Write locks are identified by a stack frame and an "abstract" (untyped) place.
25 /// It may be tempting to use the lifetime as identifier, but that does not work
27 /// * First of all, due to subtyping, the same lock may be referred to with different
29 /// * Secondly, different write locks may actually have the same lifetime. See `test2`
30 /// in `run-pass/many_shr_bor.rs`.
31 /// The Id is "captured" when the lock is first suspended; at that point, the borrow checker
32 /// considers the path frozen and hence the Id remains stable.
33 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
34 pub struct WriteLockId<'tcx> {
40 use rustc::mir::interpret::Lock::*;
41 use rustc::mir::interpret::Lock;
43 impl<'tcx> Default for LockInfo<'tcx> {
44 fn default() -> Self {
49 impl<'tcx> LockInfo<'tcx> {
50 fn new(lock: Lock) -> LockInfo<'tcx> {
52 suspended: HashMap::new(),
57 fn access_permitted(&self, frame: Option<usize>, access: AccessKind) -> bool {
58 use super::AccessKind::*;
59 match (&self.active, access) {
61 (&ReadLock(ref lfts), Read) => {
62 assert!(!lfts.is_empty(), "Someone left an empty read lock behind.");
63 // Read access to read-locked region is okay, no matter who's holding the read lock.
66 (&WriteLock(ref lft), _) => {
67 // All access is okay if we are the ones holding it
68 Some(lft.frame) == frame
70 _ => false, // Nothing else is okay.
75 impl<'tcx> RangeMap<LockInfo<'tcx>> {
82 ) -> Result<(), LockInfo<'tcx>> {
86 for lock in self.iter(offset, len) {
87 // Check if the lock is in conflict with the access.
88 if !lock.access_permitted(frame, access) {
89 return Err(lock.clone());