]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax_pos/hygiene.rs
Add `HygieneData::default_transparency`.
[rust.git] / src / libsyntax_pos / hygiene.rs
index 1d9dc26bf609260fa9106903f0f0eb7e8dced8e3..1f09bb1df710a6711869610a4407e7772c90e7e0 100644 (file)
@@ -7,8 +7,8 @@
 
 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};
@@ -98,7 +98,7 @@ pub fn parent(self) -> Mark {
 
     #[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]
@@ -112,16 +112,14 @@ pub fn set_default_transparency(self, transparency: Transparency) {
         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
@@ -174,7 +172,6 @@ pub fn looks_like_proc_macro_derive(self) -> bool {
     marks: Vec<MarkData>,
     syntax_contexts: Vec<SyntaxContextData>,
     markings: FxHashMap<(SyntaxContext, Mark, Transparency), SyntaxContext>,
-    default_edition: Edition,
 }
 
 impl HygieneData {
@@ -193,24 +190,53 @@ 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() {
@@ -255,7 +281,7 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
                 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)
         })
@@ -265,7 +291,7 @@ pub fn allocate_directly(expansion_info: ExpnInfo) -> Self {
     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))
         )
     }
 
@@ -322,7 +348,7 @@ fn apply_mark_internal(self, mark: Mark, transparency: Transparency) -> SyntaxCo
                         prev_ctxt,
                         opaque: new_opaque,
                         opaque_and_semitransparent: new_opaque,
-                        dollar_crate_name: keywords::DollarCrate.name(),
+                        dollar_crate_name: kw::DollarCrate,
                     });
                     new_opaque
                 });
@@ -340,7 +366,7 @@ fn apply_mark_internal(self, mark: Mark, transparency: Transparency) -> SyntaxCo
                         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
                 });
@@ -356,7 +382,7 @@ fn apply_mark_internal(self, mark: Mark, transparency: Transparency) -> SyntaxCo
                     prev_ctxt,
                     opaque,
                     opaque_and_semitransparent,
-                    dollar_crate_name: keywords::DollarCrate.name(),
+                    dollar_crate_name: kw::DollarCrate,
                 });
                 new_opaque_and_semitransparent_and_transparent
             })
@@ -382,7 +408,7 @@ fn apply_mark_internal(self, mark: Mark, transparency: Transparency) -> SyntaxCo
     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
         })
     }
@@ -391,9 +417,11 @@ pub fn marks(mut self) -> Vec<(Mark, Transparency)> {
         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
@@ -426,7 +454,7 @@ pub fn marks(mut self) -> Vec<(Mark, Transparency)> {
     /// 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
@@ -457,10 +485,10 @@ pub fn adjust(&mut self, expansion: Mark) -> Option<Mark> {
     /// ```
     /// 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;
@@ -479,14 +507,15 @@ pub fn glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxContext)
     ///     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());
         }
 
@@ -499,17 +528,24 @@ pub fn reverse_glob_adjust(&mut self, expansion: Mark, mut glob_ctxt: SyntaxCont
 
     #[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 {
@@ -522,7 +558,7 @@ pub fn set_dollar_crate_name(self, dollar_crate_name: 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");
         })
     }