about summary refs log tree commit diff
path: root/src/libsyntax_pos
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-09-07 08:06:04 +0200
committerGitHub <noreply@github.com>2019-09-07 08:06:04 +0200
commitdb493ef613305c7bff31d3e1959b07c3ddbbe245 (patch)
treea7fc1a3835731254574aa13bb7907e09facf5730 /src/libsyntax_pos
parentda13f06ea0dc368f1350bfc356b7f81a838defde (diff)
parent3f3fc52bfa255e68d84ca40a497137f5c6bae4a8 (diff)
downloadrust-db493ef613305c7bff31d3e1959b07c3ddbbe245.tar.gz
rust-db493ef613305c7bff31d3e1959b07c3ddbbe245.zip
Rollup merge of #63919 - matthewjasper:remove-gensymmed, r=petrochenkov
Use hygiene for AST passes

AST passes are now able to have resolve consider their expansions as if they were opaque macros defined either in some module in the current crate, or a fake empty module with `#[no_implicit_prelude]`.

* Add an ExpnKind for AST passes.
* Remove gensyms in AST passes.
* Remove gensyms in`#[test]`, `#[bench]` and `#[test_case]`.
* Allow opaque macros to define tests.
* Move tests for unit tests to their own directory.
* Remove `Ident::{gensym, is_gensymed}` - `Ident::gensym_if_underscore` still exists.

cc #60869, #61019

r? @petrochenkov
Diffstat (limited to 'src/libsyntax_pos')
-rw-r--r--src/libsyntax_pos/hygiene.rs28
-rw-r--r--src/libsyntax_pos/lib.rs20
-rw-r--r--src/libsyntax_pos/symbol.rs27
3 files changed, 57 insertions, 18 deletions
diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs
index 733f6f04490..f0e7344c1b9 100644
--- a/src/libsyntax_pos/hygiene.rs
+++ b/src/libsyntax_pos/hygiene.rs
@@ -360,7 +360,7 @@ impl SyntaxContext {
     }
 
     /// Extend a syntax context with a given expansion and transparency.
-    pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
+    crate fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext {
         HygieneData::with(|data| data.apply_mark(self, expn_id, transparency))
     }
 
@@ -550,7 +550,7 @@ impl Span {
     /// The returned span belongs to the created expansion and has the new properties,
     /// but its location is inherited from the current span.
     pub fn fresh_expansion(self, expn_data: ExpnData) -> Span {
-        self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent)
+        self.fresh_expansion_with_transparency(expn_data, Transparency::Transparent)
     }
 
     pub fn fresh_expansion_with_transparency(
@@ -639,8 +639,9 @@ pub enum ExpnKind {
     /// No expansion, aka root expansion. Only `ExpnId::root()` has this kind.
     Root,
     /// Expansion produced by a macro.
-    /// FIXME: Some code injected by the compiler before HIR lowering also gets this kind.
     Macro(MacroKind, Symbol),
+    /// Transform done by the compiler on the AST.
+    AstPass(AstPass),
     /// Desugaring done by the compiler during HIR lowering.
     Desugaring(DesugaringKind)
 }
@@ -650,6 +651,7 @@ impl ExpnKind {
         match *self {
             ExpnKind::Root => kw::PathRoot,
             ExpnKind::Macro(_, descr) => descr,
+            ExpnKind::AstPass(kind) => Symbol::intern(kind.descr()),
             ExpnKind::Desugaring(kind) => Symbol::intern(kind.descr()),
         }
     }
@@ -683,6 +685,26 @@ impl MacroKind {
     }
 }
 
+/// The kind of AST transform.
+#[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)]
+pub enum AstPass {
+    StdImports,
+    TestHarness,
+    ProcMacroHarness,
+    PluginMacroDefs,
+}
+
+impl AstPass {
+    fn descr(self) -> &'static str {
+        match self {
+            AstPass::StdImports => "standard library imports",
+            AstPass::TestHarness => "test harness",
+            AstPass::ProcMacroHarness => "proc macro harness",
+            AstPass::PluginMacroDefs => "plugin macro definitions",
+        }
+    }
+}
+
 /// The kind of compiler desugaring.
 #[derive(Clone, Copy, PartialEq, Debug, RustcEncodable, RustcDecodable)]
 pub enum DesugaringKind {
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 3d8bfc77a89..9a296f17aaf 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -442,6 +442,7 @@ impl Span {
                 let (pre, post) = match expn_data.kind {
                     ExpnKind::Root => break,
                     ExpnKind::Desugaring(..) => ("desugaring of ", ""),
+                    ExpnKind::AstPass(..) => ("", ""),
                     ExpnKind::Macro(macro_kind, _) => match macro_kind {
                         MacroKind::Bang => ("", "!"),
                         MacroKind::Attr => ("#[", "]"),
@@ -513,6 +514,25 @@ impl Span {
                   span.ctxt)
     }
 
+    /// Equivalent of `Span::def_site` from the proc macro API,
+    /// except that the location is taken from the `self` span.
+    pub fn with_def_site_ctxt(self, expn_id: ExpnId) -> Span {
+        self.with_ctxt_from_mark(expn_id, Transparency::Opaque)
+    }
+
+    /// Equivalent of `Span::call_site` from the proc macro API,
+    /// except that the location is taken from the `self` span.
+    pub fn with_call_site_ctxt(&self, expn_id: ExpnId) -> Span {
+        self.with_ctxt_from_mark(expn_id, Transparency::Transparent)
+    }
+
+    /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items).
+    /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably),
+    /// or with `with_call_site_ctxt` (where necessary).
+    pub fn with_legacy_ctxt(&self, expn_id: ExpnId) -> Span {
+        self.with_ctxt_from_mark(expn_id, Transparency::SemiTransparent)
+    }
+
     /// Produces a span with the same location as `self` and context produced by a macro with the
     /// given ID and transparency, assuming that macro was defined directly and not produced by
     /// some other macro (which is the case for built-in and procedural macros).
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 3a4dc1f5a09..ecc31cfeb3d 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -801,21 +801,15 @@ impl Ident {
         Ident::new(self.name, self.span.modern_and_legacy())
     }
 
-    /// Transforms an identifier into one with the same name, but gensymed.
-    pub fn gensym(self) -> Ident {
-        let name = with_interner(|interner| interner.gensymed(self.name));
-        Ident::new(name, self.span)
-    }
-
     /// Transforms an underscore identifier into one with the same name, but
     /// gensymed. Leaves non-underscore identifiers unchanged.
     pub fn gensym_if_underscore(self) -> Ident {
-        if self.name == kw::Underscore { self.gensym() } else { self }
-    }
-
-    // WARNING: this function is deprecated and will be removed in the future.
-    pub fn is_gensymed(self) -> bool {
-        with_interner(|interner| interner.is_gensymed(self.name))
+        if self.name == kw::Underscore {
+            let name = with_interner(|interner| interner.gensymed(self.name));
+            Ident::new(name, self.span)
+        } else {
+            self
+        }
     }
 
     /// Convert the name to a `LocalInternedString`. This is a slowish
@@ -892,9 +886,12 @@ impl UseSpecializedDecodable for Ident {
 ///
 /// Examples:
 /// ```
-/// assert_eq!(Ident::from_str("x"), Ident::from_str("x"))
-/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x"))
-/// assert_ne!(Ident::from_str("x").gensym(), Ident::from_str("x").gensym())
+/// assert_eq!(Ident::from_str("_"), Ident::from_str("_"))
+/// assert_ne!(Ident::from_str("_").gensym_if_underscore(), Ident::from_str("_"))
+/// assert_ne!(
+///     Ident::from_str("_").gensym_if_underscore(),
+///     Ident::from_str("_").gensym_if_underscore(),
+/// )
 /// ```
 /// Internally, a symbol is implemented as an index, and all operations
 /// (including hashing, equality, and ordering) operate on that index. The use