Skip to content

Commit 869fa27

Browse files
committed
hygiene: Rename MarkKind to Transparency
Move `is_builtin` for `Mark` to a separate flag
1 parent b15785b commit 869fa27

File tree

4 files changed

+58
-26
lines changed

4 files changed

+58
-26
lines changed

src/librustc_resolve/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
4545
use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap};
4646

4747
use syntax::codemap::CodeMap;
48-
use syntax::ext::hygiene::{Mark, MarkKind, SyntaxContext};
48+
use syntax::ext::hygiene::{Mark, Transparency, SyntaxContext};
4949
use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
5050
use syntax::ext::base::SyntaxExtension;
5151
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
@@ -1988,7 +1988,7 @@ impl<'a> Resolver<'a> {
19881988
// When resolving `$crate` from a `macro_rules!` invoked in a `macro`,
19891989
// we don't want to pretend that the `macro_rules!` definition is in the `macro`
19901990
// as described in `SyntaxContext::apply_mark`, so we ignore prepended modern marks.
1991-
ctxt.marks().into_iter().find(|&mark| mark.kind() != MarkKind::Modern)
1991+
ctxt.marks().into_iter().find(|&mark| mark.transparency() != Transparency::Opaque)
19921992
} else {
19931993
ctxt = ctxt.modern();
19941994
ctxt.adjust(Mark::root())

src/librustc_resolve/macros.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use syntax::errors::DiagnosticBuilder;
2424
use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
2525
use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
2626
use syntax::ext::expand::{Expansion, ExpansionKind, Invocation, InvocationKind, find_attr_invoc};
27-
use syntax::ext::hygiene::{self, Mark, MarkKind};
27+
use syntax::ext::hygiene::{self, Mark, Transparency};
2828
use syntax::ext::placeholders::placeholder;
2929
use syntax::ext::tt::macro_rules;
3030
use syntax::feature_gate::{self, emit_feature_err, GateIssue};
@@ -331,9 +331,9 @@ impl<'a> base::Resolver for Resolver<'a> {
331331
self.unused_macros.remove(&def_id);
332332
let ext = self.get_macro(def);
333333
if ext.is_modern() {
334-
invoc.expansion_data.mark.set_kind(MarkKind::Modern);
334+
invoc.expansion_data.mark.set_transparency(Transparency::Opaque);
335335
} else if def_id.krate == BUILTIN_MACROS_CRATE {
336-
invoc.expansion_data.mark.set_kind(MarkKind::Builtin);
336+
invoc.expansion_data.mark.set_is_builtin(true);
337337
}
338338
Ok(Some(ext))
339339
}

src/libsyntax/print/pprust.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use util::parser::{self, AssocOp, Fixity};
1818
use attr;
1919
use codemap::{self, CodeMap};
2020
use syntax_pos::{self, BytePos};
21-
use syntax_pos::hygiene::{Mark, MarkKind, SyntaxContext};
21+
use syntax_pos::hygiene::{Mark, SyntaxContext};
2222
use parse::token::{self, BinOpToken, Token};
2323
use parse::lexer::comments;
2424
use parse::{self, ParseSess};
@@ -842,7 +842,7 @@ pub trait PrintState<'a> {
842842
fn print_dollar_crate(&mut self, mut ctxt: SyntaxContext) -> io::Result<()> {
843843
if let Some(mark) = ctxt.adjust(Mark::root()) {
844844
// Make a best effort to print something that complies
845-
if mark.kind() == MarkKind::Builtin {
845+
if mark.is_builtin() {
846846
if let Some(name) = std_inject::injected_crate_name() {
847847
self.writer().word("::")?;
848848
self.writer().word(name)?;

src/libsyntax_pos/hygiene.rs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,41 @@ pub struct Mark(u32);
4343
#[derive(Debug)]
4444
struct MarkData {
4545
parent: Mark,
46-
kind: MarkKind,
46+
transparency: Transparency,
47+
is_builtin: bool,
4748
expn_info: Option<ExpnInfo>,
4849
}
4950

51+
/// A property of a macro expansion that determines how identifiers
52+
/// produced by that expansion are resolved.
5053
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
51-
pub enum MarkKind {
52-
Modern,
53-
Builtin,
54-
Legacy,
54+
pub enum Transparency {
55+
/// Identifier produced by a transparent expansion is always resolved at call-site.
56+
/// Call-site spans in procedural macros, hygiene opt-out in `macro` should use this.
57+
/// (Not used yet.)
58+
Transparent,
59+
/// Identifier produced by a semi-transparent expansion may be resolved
60+
/// either at call-site or at definition-site.
61+
/// If it's a local variable, label or `$crate` then it's resolved at def-site.
62+
/// Otherwise it's resolved at call-site.
63+
/// `macro_rules` macros behave like this, built-in macros currently behave like this too,
64+
/// but that's an implementation detail.
65+
SemiTransparent,
66+
/// Identifier produced by an opaque expansion is always resolved at definition-site.
67+
/// Def-site spans in procedural macros, identifiers from `macro` by default use this.
68+
Opaque,
5569
}
5670

5771
impl Mark {
5872
pub fn fresh(parent: Mark) -> Self {
5973
HygieneData::with(|data| {
60-
data.marks.push(MarkData { parent: parent, kind: MarkKind::Legacy, expn_info: None });
74+
data.marks.push(MarkData {
75+
parent,
76+
// By default expansions behave like `macro_rules`.
77+
transparency: Transparency::SemiTransparent,
78+
is_builtin: false,
79+
expn_info: None,
80+
});
6181
Mark(data.marks.len() as u32 - 1)
6282
})
6383
}
@@ -97,23 +117,31 @@ impl Mark {
97117

98118
pub fn modern(mut self) -> Mark {
99119
HygieneData::with(|data| {
100-
loop {
101-
if self == Mark::root() || data.marks[self.0 as usize].kind == MarkKind::Modern {
102-
return self;
103-
}
120+
while data.marks[self.0 as usize].transparency != Transparency::Opaque {
104121
self = data.marks[self.0 as usize].parent;
105122
}
123+
self
106124
})
107125
}
108126

109127
#[inline]
110-
pub fn kind(self) -> MarkKind {
111-
HygieneData::with(|data| data.marks[self.0 as usize].kind)
128+
pub fn transparency(self) -> Transparency {
129+
HygieneData::with(|data| data.marks[self.0 as usize].transparency)
130+
}
131+
132+
#[inline]
133+
pub fn set_transparency(self, transparency: Transparency) {
134+
HygieneData::with(|data| data.marks[self.0 as usize].transparency = transparency)
135+
}
136+
137+
#[inline]
138+
pub fn is_builtin(self) -> bool {
139+
HygieneData::with(|data| data.marks[self.0 as usize].is_builtin)
112140
}
113141

114142
#[inline]
115-
pub fn set_kind(self, kind: MarkKind) {
116-
HygieneData::with(|data| data.marks[self.0 as usize].kind = kind)
143+
pub fn set_is_builtin(self, is_builtin: bool) {
144+
HygieneData::with(|data| data.marks[self.0 as usize].is_builtin = is_builtin)
117145
}
118146

119147
pub fn is_descendant_of(mut self, ancestor: Mark) -> bool {
@@ -169,7 +197,10 @@ impl HygieneData {
169197
HygieneData {
170198
marks: vec![MarkData {
171199
parent: Mark::root(),
172-
kind: MarkKind::Builtin,
200+
// If the root is opaque, then loops searching for an opaque mark
201+
// will automatically stop after reaching it.
202+
transparency: Transparency::Opaque,
203+
is_builtin: true,
173204
expn_info: None,
174205
}],
175206
syntax_contexts: vec![SyntaxContextData {
@@ -215,8 +246,9 @@ impl SyntaxContext {
215246
HygieneData::with(|data| {
216247
data.marks.push(MarkData {
217248
parent: Mark::root(),
218-
kind: MarkKind::Legacy,
219-
expn_info: Some(expansion_info)
249+
transparency: Transparency::SemiTransparent,
250+
is_builtin: false,
251+
expn_info: Some(expansion_info),
220252
});
221253

222254
let mark = Mark(data.marks.len() as u32 - 1);
@@ -232,7 +264,7 @@ impl SyntaxContext {
232264

233265
/// Extend a syntax context with a given mark
234266
pub fn apply_mark(self, mark: Mark) -> SyntaxContext {
235-
if mark.kind() == MarkKind::Modern {
267+
if mark.transparency() == Transparency::Opaque {
236268
return self.apply_mark_internal(mark);
237269
}
238270

@@ -262,7 +294,7 @@ impl SyntaxContext {
262294
HygieneData::with(|data| {
263295
let syntax_contexts = &mut data.syntax_contexts;
264296
let mut modern = syntax_contexts[self.0 as usize].modern;
265-
if data.marks[mark.0 as usize].kind == MarkKind::Modern {
297+
if data.marks[mark.0 as usize].transparency == Transparency::Opaque {
266298
modern = *data.markings.entry((modern, mark)).or_insert_with(|| {
267299
let len = syntax_contexts.len() as u32;
268300
syntax_contexts.push(SyntaxContextData {

0 commit comments

Comments
 (0)