hygiene: Rename MarkKind
to Transparency
Move `is_builtin` for `Mark` to a separate flag
This commit is contained in:
parent
b15785b671
commit
869fa27d13
@ -45,7 +45,7 @@ use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
|
||||
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
|
||||
|
||||
use syntax::codemap::CodeMap;
|
||||
use syntax::ext::hygiene::{Mark, MarkKind, SyntaxContext};
|
||||
use syntax::ext::hygiene::{Mark, Transparency, SyntaxContext};
|
||||
use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
|
||||
use syntax::ext::base::SyntaxExtension;
|
||||
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
|
||||
@ -1988,7 +1988,7 @@ impl<'a> Resolver<'a> {
|
||||
// When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
|
||||
// we don't want to pretend that the `macro_rules!` definition is in the `macro`
|
||||
// as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
|
||||
ctxt.marks().into_iter().find(|&mark| mark.kind() != MarkKind::Modern)
|
||||
ctxt.marks().into_iter().find(|&mark| mark.transparency() != Transparency::Opaque)
|
||||
} else {
|
||||
ctxt = ctxt.modern();
|
||||
ctxt.adjust(Mark::root())
|
||||
|
@ -24,7 +24,7 @@ use syntax::errors::DiagnosticBuilder;
|
||||
use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
|
||||
use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
|
||||
use syntax::ext::expand::{Expansion, ExpansionKind, Invocation, InvocationKind, find_attr_invoc};
|
||||
use syntax::ext::hygiene::{self, Mark, MarkKind};
|
||||
use syntax::ext::hygiene::{self, Mark, Transparency};
|
||||
use syntax::ext::placeholders::placeholder;
|
||||
use syntax::ext::tt::macro_rules;
|
||||
use syntax::feature_gate::{self, emit_feature_err, GateIssue};
|
||||
@ -331,9 +331,9 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
self.unused_macros.remove(&def_id);
|
||||
let ext = self.get_macro(def);
|
||||
if ext.is_modern() {
|
||||
invoc.expansion_data.mark.set_kind(MarkKind::Modern);
|
||||
invoc.expansion_data.mark.set_transparency(Transparency::Opaque);
|
||||
} else if def_id.krate == BUILTIN_MACROS_CRATE {
|
||||
invoc.expansion_data.mark.set_kind(MarkKind::Builtin);
|
||||
invoc.expansion_data.mark.set_is_builtin(true);
|
||||
}
|
||||
Ok(Some(ext))
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use util::parser::{self, AssocOp, Fixity};
|
||||
use attr;
|
||||
use codemap::{self, CodeMap};
|
||||
use syntax_pos::{self, BytePos};
|
||||
use syntax_pos::hygiene::{Mark, MarkKind, SyntaxContext};
|
||||
use syntax_pos::hygiene::{Mark, SyntaxContext};
|
||||
use parse::token::{self, BinOpToken, Token};
|
||||
use parse::lexer::comments;
|
||||
use parse::{self, ParseSess};
|
||||
@ -842,7 +842,7 @@ pub trait PrintState<'a> {
|
||||
fn print_dollar_crate(&mut self, mut ctxt: SyntaxContext) -> io::Result<()> {
|
||||
if let Some(mark) = ctxt.adjust(Mark::root()) {
|
||||
// Make a best effort to print something that complies
|
||||
if mark.kind() == MarkKind::Builtin {
|
||||
if mark.is_builtin() {
|
||||
if let Some(name) = std_inject::injected_crate_name() {
|
||||
self.writer().word("::")?;
|
||||
self.writer().word(name)?;
|
||||
|
@ -43,21 +43,41 @@ pub struct Mark(u32);
|
||||
#[derive(Debug)]
|
||||
struct MarkData {
|
||||
parent: Mark,
|
||||
kind: MarkKind,
|
||||
transparency: Transparency,
|
||||
is_builtin: bool,
|
||||
expn_info: Option<ExpnInfo>,
|
||||
}
|
||||
|
||||
/// A property of a macro expansion that determines how identifiers
|
||||
/// produced by that expansion are resolved.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum MarkKind {
|
||||
Modern,
|
||||
Builtin,
|
||||
Legacy,
|
||||
pub enum Transparency {
|
||||
/// Identifier produced by a transparent expansion is always resolved at call-site.
|
||||
/// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this.
|
||||
/// (Not used yet.)
|
||||
Transparent,
|
||||
/// Identifier produced by a semi-transparent expansion may be resolved
|
||||
/// either at call-site or at definition-site.
|
||||
/// If it's a local variable, label or `$crate` then it's resolved at def-site.
|
||||
/// Otherwise it's resolved at call-site.
|
||||
/// `macro_rules` macros behave like this, built-in macros currently behave like this too,
|
||||
/// but that's an implementation detail.
|
||||
SemiTransparent,
|
||||
/// Identifier produced by an opaque expansion is always resolved at definition-site.
|
||||
/// Def-site spans in procedural macros, identifiers from `macro` by default use this.
|
||||
Opaque,
|
||||
}
|
||||
|
||||
impl Mark {
|
||||
pub fn fresh(parent: Mark) -> Self {
|
||||
HygieneData::with(|data| {
|
||||
data.marks.push(MarkData { parent: parent, kind: MarkKind::Legacy, expn_info: None });
|
||||
data.marks.push(MarkData {
|
||||
parent,
|
||||
// By default expansions behave like `macro_rules`.
|
||||
transparency: Transparency::SemiTransparent,
|
||||
is_builtin: false,
|
||||
expn_info: None,
|
||||
});
|
||||
Mark(data.marks.len() as u32 - 1)
|
||||
})
|
||||
}
|
||||
@ -97,23 +117,31 @@ impl Mark {
|
||||
|
||||
pub fn modern(mut self) -> Mark {
|
||||
HygieneData::with(|data| {
|
||||
loop {
|
||||
if self == Mark::root() || data.marks[self.0 as usize].kind == MarkKind::Modern {
|
||||
return self;
|
||||
}
|
||||
while data.marks[self.0 as usize].transparency != Transparency::Opaque {
|
||||
self = data.marks[self.0 as usize].parent;
|
||||
}
|
||||
self
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn kind(self) -> MarkKind {
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].kind)
|
||||
pub fn transparency(self) -> Transparency {
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].transparency)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_kind(self, kind: MarkKind) {
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].kind = kind)
|
||||
pub fn set_transparency(self, transparency: Transparency) {
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].transparency = transparency)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_builtin(self) -> bool {
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].is_builtin)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn set_is_builtin(self, is_builtin: bool) {
|
||||
HygieneData::with(|data| data.marks[self.0 as usize].is_builtin = is_builtin)
|
||||
}
|
||||
|
||||
pub fn is_descendant_of(mut self, ancestor: Mark) -> bool {
|
||||
@ -169,7 +197,10 @@ impl HygieneData {
|
||||
HygieneData {
|
||||
marks: vec![MarkData {
|
||||
parent: Mark::root(),
|
||||
kind: MarkKind::Builtin,
|
||||
// If the root is opaque, then loops searching for an opaque mark
|
||||
// will automatically stop after reaching it.
|
||||
transparency: Transparency::Opaque,
|
||||
is_builtin: true,
|
||||
expn_info: None,
|
||||
}],
|
||||
syntax_contexts: vec![SyntaxContextData {
|
||||
@ -215,8 +246,9 @@ impl SyntaxContext {
|
||||
HygieneData::with(|data| {
|
||||
data.marks.push(MarkData {
|
||||
parent: Mark::root(),
|
||||
kind: MarkKind::Legacy,
|
||||
expn_info: Some(expansion_info)
|
||||
transparency: Transparency::SemiTransparent,
|
||||
is_builtin: false,
|
||||
expn_info: Some(expansion_info),
|
||||
});
|
||||
|
||||
let mark = Mark(data.marks.len() as u32 - 1);
|
||||
@ -232,7 +264,7 @@ impl SyntaxContext {
|
||||
|
||||
/// Extend a syntax context with a given mark
|
||||
pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
|
||||
if mark.kind() == MarkKind::Modern {
|
||||
if mark.transparency() == Transparency::Opaque {
|
||||
return self.apply_mark_internal(mark);
|
||||
}
|
||||
|
||||
@ -262,7 +294,7 @@ impl SyntaxContext {
|
||||
HygieneData::with(|data| {
|
||||
let syntax_contexts = &mut data.syntax_contexts;
|
||||
let mut modern = syntax_contexts[self.0 as usize].modern;
|
||||
if data.marks[mark.0 as usize].kind == MarkKind::Modern {
|
||||
if data.marks[mark.0 as usize].transparency == Transparency::Opaque {
|
||||
modern = *data.markings.entry((modern, mark)).or_insert_with(|| {
|
||||
let len = syntax_contexts.len() as u32;
|
||||
syntax_contexts.push(SyntaxContextData {
|
||||
|
Loading…
x
Reference in New Issue
Block a user