about summary refs log tree commit diff
path: root/src/libsyntax/std_inject.rs
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/std_inject.rs
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/std_inject.rs')
-rw-r--r--src/libsyntax/std_inject.rs26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index ae22230198f..00546400bb5 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -10,6 +10,7 @@
 
 use ast;
 use attr;
+use std::cell::Cell;
 use ext::hygiene::{Mark, SyntaxContext};
 use symbol::{Symbol, keywords};
 use syntax_pos::{DUMMY_SP, Span};
@@ -34,22 +35,25 @@ fn ignored_span(sp: Span) -> Span {
     sp.with_ctxt(SyntaxContext::empty().apply_mark(mark))
 }
 
-pub fn injected_crate_name(krate: &ast::Crate) -> Option<&'static str> {
-    if attr::contains_name(&krate.attrs, "no_core") {
-        None
-    } else if attr::contains_name(&krate.attrs, "no_std") {
-        Some("core")
-    } else {
-        Some("std")
-    }
+pub fn injected_crate_name() -> Option<&'static str> {
+    INJECTED_CRATE_NAME.with(|name| name.get())
+}
+
+thread_local! {
+    static INJECTED_CRATE_NAME: Cell<Option<&'static str>> = Cell::new(None);
 }
 
 pub fn maybe_inject_crates_ref(mut krate: ast::Crate, alt_std_name: Option<String>) -> ast::Crate {
-    let name = match injected_crate_name(&krate) {
-        Some(name) => name,
-        None => return krate,
+    let name = if attr::contains_name(&krate.attrs, "no_core") {
+        return krate;
+    } else if attr::contains_name(&krate.attrs, "no_std") {
+        "core"
+    } else {
+        "std"
     };
 
+    INJECTED_CRATE_NAME.with(|opt_name| opt_name.set(Some(name)));
+
     let crate_name = Symbol::intern(&alt_std_name.unwrap_or_else(|| name.to_string()));
 
     krate.module.items.insert(0, P(ast::Item {