use crate::GLOBALS;
use crate::Span;
-use crate::edition::{Edition, DEFAULT_EDITION};
-use crate::symbol::{keywords, Symbol};
+use crate::edition::Edition;
+use crate::symbol::{kw, Symbol};
use serialize::{Encodable, Decodable, Encoder, Decoder};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
#[inline]
pub fn expn_info(self) -> Option<ExpnInfo> {
- HygieneData::with(|data| data.marks[self.0 as usize].expn_info.clone())
+ HygieneData::with(|data| data.expn_info(self))
}
#[inline]
HygieneData::with(|data| data.marks[self.0 as usize].default_transparency = transparency)
}
- pub fn is_descendant_of(mut self, ancestor: Mark) -> bool {
- HygieneData::with(|data| {
- while self != ancestor {
- if self == Mark::root() {
- return false;
- }
- self = data.marks[self.0 as usize].parent;
- }
- true
- })
+ pub fn is_descendant_of(self, ancestor: Mark) -> bool {
+ HygieneData::with(|data| data.is_descendant_of(self, ancestor))
+ }
+
+ /// `mark.outer_is_descendant_of(ctxt)` is equivalent to but faster than
+ /// `mark.is_descendant_of(ctxt.outer())`.
+ pub fn outer_is_descendant_of(self, ctxt: SyntaxContext) -> bool {
+ HygieneData::with(|data| data.is_descendant_of(self, data.outer(ctxt)))
}
/// Computes a mark such that both input marks are descendants of (or equal to) the returned
marks: Vec<MarkData>,
syntax_contexts: Vec<SyntaxContextData>,
markings: FxHashMap<(SyntaxContext, Mark, Transparency), SyntaxContext>,
- default_edition: Edition,
}
impl HygieneData {
prev_ctxt: SyntaxContext(0),
opaque: SyntaxContext(0),
opaque_and_semitransparent: SyntaxContext(0),
- dollar_crate_name: keywords::DollarCrate.name(),
+ dollar_crate_name: kw::DollarCrate,
}],
markings: FxHashMap::default(),
- default_edition: DEFAULT_EDITION,
}
}
fn with<T, F: FnOnce(&mut HygieneData) -> T>(f: F) -> T {
GLOBALS.with(|globals| f(&mut *globals.hygiene_data.borrow_mut()))
}
-}
-pub fn default_edition() -> Edition {
- HygieneData::with(|data| data.default_edition)
-}
+ fn expn_info(&self, mark: Mark) -> Option<ExpnInfo> {
+ self.marks[mark.0 as usize].expn_info.clone()
+ }
-pub fn set_default_edition(edition: Edition) {
- HygieneData::with(|data| data.default_edition = edition);
+ fn is_descendant_of(&self, mut mark: Mark, ancestor: Mark) -> bool {
+ while mark != ancestor {
+ if mark == Mark::root() {
+ return false;
+ }
+ mark = self.marks[mark.0 as usize].parent;
+ }
+ true
+ }
+
+ fn default_transparency(&self, mark: Mark) -> Transparency {
+ self.marks[mark.0 as usize].default_transparency
+ }
+
+ fn modern(&self, ctxt: SyntaxContext) -> SyntaxContext {
+ self.syntax_contexts[ctxt.0 as usize].opaque
+ }
+
+ fn modern_and_legacy(&self, ctxt: SyntaxContext) -> SyntaxContext {
+ self.syntax_contexts[ctxt.0 as usize].opaque_and_semitransparent
+ }
+
+ fn outer(&self, ctxt: SyntaxContext) -> Mark {
+ self.syntax_contexts[ctxt.0 as usize].outer_mark
+ }
+
+ fn transparency(&self, ctxt: SyntaxContext) -> Transparency {
+ self.syntax_contexts[ctxt.0 as usize].transparency
+ }
+
+ fn prev_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext {
+ self.syntax_contexts[ctxt.0 as usize].prev_ctxt
+ }
}
pub fn clear_markings() {
prev_ctxt: SyntaxContext::empty(),
opaque: SyntaxContext::empty(),
opaque_and_semitransparent: SyntaxContext::empty(),
- dollar_crate_name: keywords::DollarCrate.name(),
+ dollar_crate_name: kw::DollarCrate,
});
SyntaxContext(data.syntax_contexts.len() as u32 - 1)
})
pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
assert_ne!(mark, Mark::root());
self.apply_mark_with_transparency(
- mark, HygieneData::with(|data| data.marks[mark.0 as usize].default_transparency)
+ mark, HygieneData::with(|data| data.default_transparency(mark))
)
}
prev_ctxt,
opaque: new_opaque,
opaque_and_semitransparent: new_opaque,
- dollar_crate_name: keywords::DollarCrate.name(),
+ dollar_crate_name: kw::DollarCrate,
});
new_opaque
});
prev_ctxt,
opaque,
opaque_and_semitransparent: new_opaque_and_semitransparent,
- dollar_crate_name: keywords::DollarCrate.name(),
+ dollar_crate_name: kw::DollarCrate,
});
new_opaque_and_semitransparent
});
prev_ctxt,
opaque,
opaque_and_semitransparent,
- dollar_crate_name: keywords::DollarCrate.name(),
+ dollar_crate_name: kw::DollarCrate,
});
new_opaque_and_semitransparent_and_transparent
})
pub fn remove_mark(&mut self) -> Mark {
HygieneData::with(|data| {
let outer_mark = data.syntax_contexts[self.0 as usize].outer_mark;
- *self = data.syntax_contexts[self.0 as usize].prev_ctxt;
+ *self = data.prev_ctxt(*self);
outer_mark
})
}
HygieneData::with(|data| {
let mut marks = Vec::new();
while self != SyntaxContext::empty() {
- let ctxt_data = &data.syntax_contexts[self.0 as usize];
- marks.push((ctxt_data.outer_mark, ctxt_data.transparency));
- self = ctxt_data.prev_ctxt;
+ let outer_mark = data.outer(self);
+ let transparency = data.transparency(self);
+ let prev_ctxt = data.prev_ctxt(self);
+ marks.push((outer_mark, transparency));
+ self = prev_ctxt;
}
marks.reverse();
marks
/// or `None` if we privacy check as usual (i.e., not w.r.t. a macro definition scope).
pub fn adjust(&mut self, expansion: Mark) -> Option<Mark> {
let mut scope = None;
- while !expansion.is_descendant_of(self.outer()) {
+ while !expansion.outer_is_descendant_of(*self) {
scope = Some(self.remove_mark());
}
scope
/// ```
/// This returns `None` if the context cannot be glob-adjusted.
/// Otherwise, it returns the scope to use when privacy checking (see `adjust` for details).
- pub fn glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext)
- -> Option<Option<Mark>> {
+ pub fn glob_adjust(&mut self, expansion: Mark, glob_span: Span) -> Option<Option<Mark>> {
let mut scope = None;
- while !expansion.is_descendant_of(glob_ctxt.outer()) {
+ let mut glob_ctxt = glob_span.ctxt().modern();
+ while !expansion.outer_is_descendant_of(glob_ctxt) {
scope = Some(glob_ctxt.remove_mark());
if self.remove_mark() != scope.unwrap() {
return None;
/// assert!(self.glob_adjust(expansion, glob_ctxt) == Some(privacy_checking_scope));
/// }
/// ```
- pub fn reverse_glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext)
+ pub fn reverse_glob_adjust(&mut self, expansion: Mark, glob_span: Span)
-> Option<Option<Mark>> {
if self.adjust(expansion).is_some() {
return None;
}
+ let mut glob_ctxt = glob_span.ctxt().modern();
let mut marks = Vec::new();
- while !expansion.is_descendant_of(glob_ctxt.outer()) {
+ while !expansion.outer_is_descendant_of(glob_ctxt) {
marks.push(glob_ctxt.remove_mark());
}
#[inline]
pub fn modern(self) -> SyntaxContext {
- HygieneData::with(|data| data.syntax_contexts[self.0 as usize].opaque)
+ HygieneData::with(|data| data.modern(self))
}
#[inline]
pub fn modern_and_legacy(self) -> SyntaxContext {
- HygieneData::with(|data| data.syntax_contexts[self.0 as usize].opaque_and_semitransparent)
+ HygieneData::with(|data| data.modern_and_legacy(self))
}
#[inline]
pub fn outer(self) -> Mark {
- HygieneData::with(|data| data.syntax_contexts[self.0 as usize].outer_mark)
+ HygieneData::with(|data| data.outer(self))
+ }
+
+ /// `ctxt.outer_expn_info()` is equivalent to but faster than
+ /// `ctxt.outer().expn_info()`.
+ #[inline]
+ pub fn outer_expn_info(self) -> Option<ExpnInfo> {
+ HygieneData::with(|data| data.expn_info(data.outer(self)))
}
pub fn dollar_crate_name(self) -> Symbol {
&mut data.syntax_contexts[self.0 as usize].dollar_crate_name, dollar_crate_name
);
assert!(dollar_crate_name == prev_dollar_crate_name ||
- prev_dollar_crate_name == keywords::DollarCrate.name(),
+ prev_dollar_crate_name == kw::DollarCrate,
"$crate name is reset for a syntax context");
})
}