Implement a least upper bound for marks.
This is useful when trying to compute when something is lexically before something else, but they aren't necessarily in the same SyntaxContext
This commit is contained in:
parent
263b36b071
commit
498dbe4453
1 changed files with 27 additions and 0 deletions
|
|
@ -21,6 +21,7 @@ use symbol::{Ident, Symbol};
|
|||
|
||||
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||
use std::collections::HashMap;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use std::fmt;
|
||||
|
||||
/// A SyntaxContext represents a chain of macro expansions (represented by marks).
|
||||
|
|
@ -117,6 +118,32 @@ impl Mark {
|
|||
true
|
||||
})
|
||||
}
|
||||
|
||||
/// Computes a mark such that both input marks are descendants of (or equal to) the returned
|
||||
/// mark. That is, the following holds:
|
||||
///
|
||||
/// ```rust
|
||||
/// let lub = lub(a, b);
|
||||
/// assert!(a.is_descendant_of(lub))
|
||||
/// assert!(b.is_descendant_of(lub))
|
||||
/// ```
|
||||
pub fn lub(mut a: Mark, mut b: Mark) -> Mark {
|
||||
HygieneData::with(|data| {
|
||||
// Compute the path from a to the root
|
||||
let mut a_path = FxHashSet::<Mark>();
|
||||
while a != Mark::root() {
|
||||
a_path.insert(a);
|
||||
a = data.marks[a.0 as usize].parent;
|
||||
}
|
||||
|
||||
// While the path from b to the root hasn't intersected, move up the tree
|
||||
while !a_path.contains(&b) {
|
||||
b = data.marks[b.0 as usize].parent;
|
||||
}
|
||||
|
||||
b
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct HygieneData {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue