about summary refs log tree commit diff
path: root/src/libsyntax_ext/deriving/generic
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-13 11:09:55 +0000
committerbors <bors@rust-lang.org>2017-12-13 11:09:55 +0000
commit3dfbc88a626625be01e112da11ec367e2fc71bb3 (patch)
tree3123349d2f450ac5317944d5f5803b20c3eca65b /src/libsyntax_ext/deriving/generic
parent61100840e5c978a99b0489e8eaa922da06c05f65 (diff)
parent85d19b33357897c51d80727a4208f46b19c5c5a6 (diff)
downloadrust-3dfbc88a626625be01e112da11ec367e2fc71bb3.tar.gz
rust-3dfbc88a626625be01e112da11ec367e2fc71bb3.zip
Auto merge of #46550 - jseyfried:cleanup_builtin_hygiene, r=nrc
macros: hygienize use of `core`/`std` in builtin macros

Today, if a builtin macro wants to access an item from `core` or `std` (depending `#![no_std]`), it generates `::core::path::to::item` or `::std::path::to::item` respectively (c.f. `fn std_path()` in `libsyntax/ext/base.rs`).

This PR refactors the builtin macros to instead always emit `$crate::path::to::item` here. That is, the def site of builtin macros is taken to be in `extern crate core;` or `extern crate std;`. Since builtin macros are macros 1.0 (i.e. mostly unhygienic), changing the def site can only effect the resolution of `$crate`.

r? @nrc
Diffstat (limited to 'src/libsyntax_ext/deriving/generic')
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 47b5f40832a..e4faf652389 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -21,6 +21,8 @@ use syntax::ext::build::AstBuilder;
 use syntax::codemap::respan;
 use syntax::ptr::P;
 use syntax_pos::Span;
+use syntax_pos::hygiene::SyntaxContext;
+use syntax_pos::symbol::keywords;
 
 /// The types of pointers
 #[derive(Clone, Eq, PartialEq)]
@@ -36,29 +38,36 @@ pub enum PtrTy<'a> {
 /// for type parameters and a lifetime.
 #[derive(Clone, Eq, PartialEq)]
 pub struct Path<'a> {
-    pub path: Vec<&'a str>,
-    pub lifetime: Option<&'a str>,
-    pub params: Vec<Box<Ty<'a>>>,
-    pub global: bool,
+    path: Vec<&'a str>,
+    lifetime: Option<&'a str>,
+    params: Vec<Box<Ty<'a>>>,
+    kind: PathKind,
+}
+
+#[derive(Clone, Eq, PartialEq)]
+pub enum PathKind {
+    Local,
+    Global,
+    Std,
 }
 
 impl<'a> Path<'a> {
     pub fn new<'r>(path: Vec<&'r str>) -> Path<'r> {
-        Path::new_(path, None, Vec::new(), true)
+        Path::new_(path, None, Vec::new(), PathKind::Std)
     }
     pub fn new_local<'r>(path: &'r str) -> Path<'r> {
-        Path::new_(vec![path], None, Vec::new(), false)
+        Path::new_(vec![path], None, Vec::new(), PathKind::Local)
     }
     pub fn new_<'r>(path: Vec<&'r str>,
                     lifetime: Option<&'r str>,
                     params: Vec<Box<Ty<'r>>>,
-                    global: bool)
+                    kind: PathKind)
                     -> Path<'r> {
         Path {
             path,
             lifetime,
             params,
-            global,
+            kind,
         }
     }
 
@@ -76,11 +85,20 @@ impl<'a> Path<'a> {
                    self_ty: Ident,
                    self_generics: &Generics)
                    -> ast::Path {
-        let idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
+        let mut idents = self.path.iter().map(|s| cx.ident_of(*s)).collect();
         let lt = mk_lifetimes(cx, span, &self.lifetime);
         let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect();
 
-        cx.path_all(span, self.global, idents, lt, tys, Vec::new())
+        match self.kind {
+            PathKind::Global => cx.path_all(span, true, idents, lt, tys, Vec::new()),
+            PathKind::Local => cx.path_all(span, false, idents, lt, tys, Vec::new()),
+            PathKind::Std => {
+                let def_site = SyntaxContext::empty().apply_mark(cx.current_expansion.mark);
+                idents.insert(0, Ident { ctxt: def_site, ..keywords::DollarCrate.ident() });
+                cx.path_all(span, false, idents, lt, tys, Vec::new())
+            }
+        }
+
     }
 }