Skip to content
Closed
50 changes: 50 additions & 0 deletions src/librustc_data_structures/access_tracker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright 2015 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.

use std::ops::{Deref, DerefMut};

/// Takes ownership of `T` and tracks whether it was accessed mutably
/// (via `DerefMut`). You can access this via the `maybe_mutated` fn.
#[derive(Clone, Debug)]
pub struct AccessTracker<T> {
value: T,
mutated: bool,
}

impl<T> AccessTracker<T> {
pub fn new(value: T) -> Self {
AccessTracker { value, mutated: false }
}

/// True if the owned value was accessed mutably (so far).
pub fn maybe_mutated(this: &Self) -> bool {
this.mutated
}

pub fn into_inner(this: Self) -> (T, bool) {
(this.value, this.mutated)
}
}

impl<T> Deref for AccessTracker<T> {
type Target = T;

fn deref(&self) -> &T {
&self.value
}
}

impl<T> DerefMut for AccessTracker<T> {
fn deref_mut(&mut self) -> &mut T {
self.mutated = true;
&mut self.value
}
}

5 changes: 5 additions & 0 deletions src/librustc_data_structures/indexed_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ impl<T: Idx> IdxSet<T> {
}
}

/// True if there are no elements
pub fn is_empty(&self) -> bool {
self.bits.iter().all(|&b| b == 0)
}

/// Removes all elements
pub fn clear(&mut self) {
for b in &mut self.bits {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_data_structures/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ extern crate stable_deref_trait;
pub use rustc_serialize::hex::ToHex;

pub mod array_vec;
pub mod access_tracker;
pub mod accumulate_vec;
pub mod small_vec;
pub mod base_n;
Expand Down
31 changes: 18 additions & 13 deletions src/librustc_mir/dataflow/impls/borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ use rustc::ty::RegionKind;
use rustc::ty::RegionKind::ReScope;
use rustc::util::nodemap::{FxHashMap, FxHashSet};

use rustc_data_structures::access_tracker::AccessTracker;
use rustc_data_structures::bitslice::{BitwiseOperator};
use rustc_data_structures::indexed_set::{IdxSet};
use rustc_data_structures::indexed_vec::{Idx, IndexVec};

use dataflow::{BitDenotation, BlockSets, InitialFlow};
use dataflow::{BitDenotation, BlockSets, EdgeKind, InitialFlow};
pub use dataflow::indexes::{BorrowIndex, ReserveOrActivateIndex};
use borrow_check::nll::region_infer::RegionInferenceContext;
use borrow_check::nll::ToRegionVid;
Expand Down Expand Up @@ -677,12 +678,14 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Reservations<'a, 'gcx, 'tcx> {
self.0.terminator_effect_on_borrows(sets, location, false);
}

fn propagate_call_return(&self,
_in_out: &mut IdxSet<ReserveOrActivateIndex>,
_call_bb: mir::BasicBlock,
_dest_bb: mir::BasicBlock,
_dest_place: &mir::Place) {
// there are no effects on borrows from method call return...
fn edge_effect(
&self,
_sets: &mut AccessTracker<&mut BlockSets<Self::Idx>>,
_source_block: mir::BasicBlock,
_edge_kind: EdgeKind<'_>,
_target_terminator: mir::BasicBlock,
) {
// there are no effects on borrows from edges...
//
// ... but if overwriting a place can affect flow state, then
// latter is not true; see NOTE on Assign case in
Expand Down Expand Up @@ -738,12 +741,14 @@ impl<'a, 'gcx, 'tcx> BitDenotation for ActiveBorrows<'a, 'gcx, 'tcx> {
self.0.terminator_effect_on_borrows(sets, location, true);
}

fn propagate_call_return(&self,
_in_out: &mut IdxSet<ReserveOrActivateIndex>,
_call_bb: mir::BasicBlock,
_dest_bb: mir::BasicBlock,
_dest_place: &mir::Place) {
// there are no effects on borrows from method call return...
fn edge_effect(
&self,
_sets: &mut AccessTracker<&mut BlockSets<Self::Idx>>,
_source_block: mir::BasicBlock,
_edge_kind: EdgeKind<'_>,
_target_terminator: mir::BasicBlock,
) {
// there are no effects on borrows from edges...
//
// ... but If overwriting a place can affect flow state, then
// latter is not true; see NOTE on Assign case in
Expand Down
Loading