Auto merge of #45668 - nikomatsakis:nll-free-region, r=arielb1
extend NLL with preliminary support for free regions on functions This PR extends https://github.com/rust-lang/rust/pull/45538 with support for free regions. This is pretty preliminary and will no doubt want to change in various ways, particularly as we add support for closures, but it's enough to get the basic idea in place: - We now create specific regions to represent each named lifetime declared on the function. - Region values can contain references to these regions (represented for now as a `BTreeSet<RegionIndex>`). - If we wind up trying to infer that `'a: 'b` must hold, but no such relationship was declared, we report an error. It also does a number of drive-by refactorings. r? @arielb1 cc @spastorino
This commit is contained in:
@@ -145,7 +145,7 @@ pub struct BitMatrix {
|
||||
}
|
||||
|
||||
impl BitMatrix {
|
||||
// Create a new `rows x columns` matrix, initially empty.
|
||||
/// Create a new `rows x columns` matrix, initially empty.
|
||||
pub fn new(rows: usize, columns: usize) -> BitMatrix {
|
||||
// For every element, we need one bit for every other
|
||||
// element. Round up to an even number of u64s.
|
||||
@@ -163,9 +163,13 @@ impl BitMatrix {
|
||||
(start, start + u64s_per_row)
|
||||
}
|
||||
|
||||
pub fn add(&mut self, source: usize, target: usize) -> bool {
|
||||
let (start, _) = self.range(source);
|
||||
let (word, mask) = word_mask(target);
|
||||
/// Sets the cell at `(row, column)` to true. Put another way, add
|
||||
/// `column` to the bitset for `row`.
|
||||
///
|
||||
/// Returns true if this changed the matrix, and false otherwies.
|
||||
pub fn add(&mut self, row: usize, column: usize) -> bool {
|
||||
let (start, _) = self.range(row);
|
||||
let (word, mask) = word_mask(column);
|
||||
let vector = &mut self.vector[..];
|
||||
let v1 = vector[start + word];
|
||||
let v2 = v1 | mask;
|
||||
@@ -173,19 +177,19 @@ impl BitMatrix {
|
||||
v1 != v2
|
||||
}
|
||||
|
||||
/// Do the bits from `source` contain `target`?
|
||||
///
|
||||
/// Put another way, if the matrix represents (transitive)
|
||||
/// reachability, can `source` reach `target`?
|
||||
pub fn contains(&self, source: usize, target: usize) -> bool {
|
||||
let (start, _) = self.range(source);
|
||||
let (word, mask) = word_mask(target);
|
||||
/// Do the bits from `row` contain `column`? Put another way, is
|
||||
/// the matrix cell at `(row, column)` true? Put yet another way,
|
||||
/// if the matrix represents (transitive) reachability, can
|
||||
/// `row` reach `column`?
|
||||
pub fn contains(&self, row: usize, column: usize) -> bool {
|
||||
let (start, _) = self.range(row);
|
||||
let (word, mask) = word_mask(column);
|
||||
(self.vector[start + word] & mask) != 0
|
||||
}
|
||||
|
||||
/// Returns those indices that are reachable from both `a` and
|
||||
/// `b`. This is an O(n) operation where `n` is the number of
|
||||
/// elements (somewhat independent from the actual size of the
|
||||
/// Returns those indices that are true in rows `a` and `b`. This
|
||||
/// is an O(n) operation where `n` is the number of elements
|
||||
/// (somewhat independent from the actual size of the
|
||||
/// intersection, in particular).
|
||||
pub fn intersection(&self, a: usize, b: usize) -> Vec<usize> {
|
||||
let (a_start, a_end) = self.range(a);
|
||||
@@ -206,7 +210,7 @@ impl BitMatrix {
|
||||
result
|
||||
}
|
||||
|
||||
/// Add the bits from `read` to the bits from `write`,
|
||||
/// Add the bits from row `read` to the bits from row `write`,
|
||||
/// return true if anything changed.
|
||||
///
|
||||
/// This is used when computing transitive reachability because if
|
||||
@@ -227,6 +231,8 @@ impl BitMatrix {
|
||||
changed
|
||||
}
|
||||
|
||||
/// Iterates through all the columns set to true in a given row of
|
||||
/// the matrix.
|
||||
pub fn iter<'a>(&'a self, row: usize) -> BitVectorIter<'a> {
|
||||
let (start, end) = self.range(row);
|
||||
BitVectorIter {
|
||||
|
||||
@@ -134,12 +134,12 @@ impl<T: Clone + Debug + Eq + Hash + Clone> TransitiveRelation<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a vector of all things less than `a`.
|
||||
/// Returns a vector of all things greater than `a`.
|
||||
///
|
||||
/// Really this probably ought to be `impl Iterator<Item=&T>`, but
|
||||
/// I'm too lazy to make that work, and -- given the caching
|
||||
/// strategy -- it'd be a touch tricky anyhow.
|
||||
pub fn less_than(&self, a: &T) -> Vec<&T> {
|
||||
pub fn greater_than(&self, a: &T) -> Vec<&T> {
|
||||
match self.index(a) {
|
||||
Some(a) => self.with_closure(|closure| {
|
||||
closure.iter(a.0).map(|i| &self.elements[i]).collect()
|
||||
|
||||
Reference in New Issue
Block a user