]> git.lizzy.rs Git - rust.git/commitdiff
hygiene: Rename `MarkKind` to `Transparency`
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Tue, 19 Jun 2018 21:54:17 +0000 (00:54 +0300)
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>
Sat, 23 Jun 2018 17:09:21 +0000 (20:09 +0300)
Move `is_builtin` for `Mark` to a separate flag

src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/libsyntax/print/pprust.rs
src/libsyntax_pos/hygiene.rs

index 792edf4d12b1d25a3cc28ea7463ee30a0bd6852b..2052918747b39301f1f14364c7d244b77a7eb00c 100644 (file)
@@ -45,7 +45,7 @@
 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 @@ fn resolve_crate_root(&mut self, mut ctxt: SyntaxContext, legacy: bool) -> Modul
             // 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())
index 649e8858b0971b4b45a25690ed4fa74be2216ce3..65dec8ad16c7d60e62b993a47d7b1f7e4effd831 100644 (file)
@@ -24,7 +24,7 @@
 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 @@ fn resolve_invoc(&mut self, invoc: &mut Invocation, scope: Mark, force: bool)
         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))
     }
index ac8088507dde7b6941d0fc211d4aa06ec726a112..70c4324a056a0ff62028a7bddf1dcc234b81a1d6 100644 (file)
@@ -18,7 +18,7 @@
 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 @@ fn nbsp(&mut self) -> io::Result<()> { self.writer().word(" ") }
     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)?;
index 64cd31a485cdfb17a8f12e8d3ff00eef2f2804e2..cd2b8b2bff8b8f54ec495249796c012162391ea6 100644 (file)
@@ -43,21 +43,41 @@ pub struct SyntaxContextData {
 #[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 @@ pub fn set_expn_info(self, info: ExpnInfo) {
 
     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_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_kind(self, kind: MarkKind) {
-        HygieneData::with(|data| data.marks[self.0 as usize].kind = kind)
+    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 @@ pub fn new() -> Self {
         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 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
         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 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
 
     /// 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 @@ fn apply_mark_internal(self, mark: Mark) -> 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 {