about summary refs log tree commit diff
path: root/src/libsyntax/ext
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-02-08 00:24:03 +0000
committerbors <bors@rust-lang.org>2015-02-08 00:24:03 +0000
commit74b8740719c1b427f79b67d6bc51e9d448dd9c49 (patch)
tree51327a08df4c0f510c0a851c41a6e400645afc97 /src/libsyntax/ext
parentbfaa1a8434de3991d9ceae3eea88674a74c5eef2 (diff)
parent312f8bd850ca4d575b1414badabab4f5aee99c67 (diff)
downloadrust-74b8740719c1b427f79b67d6bc51e9d448dd9c49.tar.gz
rust-74b8740719c1b427f79b67d6bc51e9d448dd9c49.zip
Auto merge of #21988 - kmcallister:no-std, r=sfackler
Fixes #21833.

[breaking-change]

r? @alexcrichton 

The tests in #21912 will also need `#[feature(no_std)]`. If you're okay with both PRs, I can merge and test them.
Diffstat (limited to 'src/libsyntax/ext')
-rw-r--r--src/libsyntax/ext/base.rs5
-rw-r--r--src/libsyntax/ext/build.rs45
-rw-r--r--src/libsyntax/ext/deriving/bounds.rs8
-rw-r--r--src/libsyntax/ext/deriving/clone.rs4
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs4
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs12
-rw-r--r--src/libsyntax/ext/deriving/cmp/totaleq.rs2
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs8
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs8
-rw-r--r--src/libsyntax/ext/deriving/default.rs4
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs8
-rw-r--r--src/libsyntax/ext/deriving/hash.rs8
-rw-r--r--src/libsyntax/ext/deriving/mod.rs28
-rw-r--r--src/libsyntax/ext/deriving/primitive.rs12
-rw-r--r--src/libsyntax/ext/deriving/rand.rs10
-rw-r--r--src/libsyntax/ext/deriving/show.rs6
-rw-r--r--src/libsyntax/ext/env.rs4
-rw-r--r--src/libsyntax/ext/expand.rs7
-rw-r--r--src/libsyntax/ext/format.rs10
19 files changed, 131 insertions, 62 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index b5f6893a8c2..778b2cabea6 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -544,6 +544,7 @@ pub struct ExtCtxt<'a> {
     pub cfg: ast::CrateConfig,
     pub backtrace: ExpnId,
     pub ecfg: expand::ExpansionConfig,
+    pub use_std: bool,
 
     pub mod_path: Vec<ast::Ident> ,
     pub trace_mac: bool,
@@ -563,6 +564,7 @@ impl<'a> ExtCtxt<'a> {
             backtrace: NO_EXPANSION,
             mod_path: Vec::new(),
             ecfg: ecfg,
+            use_std: true,
             trace_mac: false,
             exported_macros: Vec::new(),
             syntax_env: env,
@@ -737,6 +739,9 @@ impl<'a> ExtCtxt<'a> {
     pub fn ident_of(&self, st: &str) -> ast::Ident {
         str_to_ident(st)
     }
+    pub fn ident_of_std(&self, st: &str) -> ast::Ident {
+        self.ident_of(if self.use_std { "std" } else { st })
+    }
     pub fn name_of(&self, st: &str) -> ast::Name {
         token::intern(st)
     }
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 55faf692e98..a7d1baf08be 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -386,7 +386,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             self.path_all(DUMMY_SP,
                           true,
                           vec!(
-                              self.ident_of("std"),
+                              self.ident_of_std("core"),
                               self.ident_of("option"),
                               self.ident_of("Option")
                           ),
@@ -656,7 +656,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
     fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> {
         self.expr_call_global(sp,
-                              vec!(self.ident_of("std"),
+                              vec!(self.ident_of_std("collections"),
                                    self.ident_of("vec"),
                                    self.ident_of("Vec"),
                                    self.ident_of("new")),
@@ -676,7 +676,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
         let some = vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("option"),
             self.ident_of("Option"),
             self.ident_of("Some"));
@@ -685,7 +685,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn expr_none(&self, sp: Span) -> P<ast::Expr> {
         let none = self.path_global(sp, vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("option"),
             self.ident_of("Option"),
             self.ident_of("None")));
@@ -712,7 +712,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.expr_call_global(
             span,
             vec!(
-                self.ident_of("std"),
+                self.ident_of_std("core"),
                 self.ident_of("rt"),
                 self.ident_of("begin_unwind")),
             vec!(
@@ -728,7 +728,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
         let ok = vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("result"),
             self.ident_of("Result"),
             self.ident_of("Ok"));
@@ -737,7 +737,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
         let err = vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("result"),
             self.ident_of("Result"),
             self.ident_of("Err"));
@@ -745,10 +745,20 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
-        let ok = self.ident_of("Ok");
-        let ok_path = self.path_ident(sp, ok);
-        let err = self.ident_of("Err");
-        let err_path = self.path_ident(sp, err);
+        let ok = vec![
+            self.ident_of_std("core"),
+            self.ident_of("result"),
+            self.ident_of("Result"),
+            self.ident_of("Ok")
+        ];
+        let ok_path = self.path_global(sp, ok);
+        let err = vec![
+            self.ident_of_std("core"),
+            self.ident_of("result"),
+            self.ident_of("Result"),
+            self.ident_of("Err")
+        ];
+        let err_path = self.path_global(sp, err);
 
         let binding_variable = self.ident_of("__try_var");
         let binding_pat = self.pat_ident(sp, binding_variable);
@@ -758,8 +768,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let ok_pat = self.pat_enum(sp, ok_path, vec!(binding_pat.clone()));
 
         // Err(__try_var)  (pattern and expression resp.)
-        let err_pat = self.pat_enum(sp, err_path, vec!(binding_pat));
-        let err_inner_expr = self.expr_call_ident(sp, err, vec!(binding_expr.clone()));
+        let err_pat = self.pat_enum(sp, err_path.clone(), vec!(binding_pat));
+        let err_inner_expr = self.expr_call(sp, self.expr_path(err_path),
+                                            vec!(binding_expr.clone()));
         // return Err(__try_var)
         let err_expr = self.expr(sp, ast::ExprRet(Some(err_inner_expr)));
 
@@ -808,7 +819,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
         let some = vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("option"),
             self.ident_of("Option"),
             self.ident_of("Some"));
@@ -818,7 +829,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn pat_none(&self, span: Span) -> P<ast::Pat> {
         let some = vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("option"),
             self.ident_of("Option"),
             self.ident_of("None"));
@@ -828,7 +839,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
         let some = vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("result"),
             self.ident_of("Result"),
             self.ident_of("Ok"));
@@ -838,7 +849,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
         let some = vec!(
-            self.ident_of("std"),
+            self.ident_of_std("core"),
             self.ident_of("result"),
             self.ident_of("Result"),
             self.ident_of("Err"));
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
index 1c82ca5d2ad..879718a6399 100644
--- a/src/libsyntax/ext/deriving/bounds.rs
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -45,10 +45,16 @@ pub fn expand_deriving_bound<F>(cx: &mut ExtCtxt,
         }
     };
 
+    let path = Path::new(vec![
+        if cx.use_std { "std" } else { "core" },
+        "marker",
+        name
+    ]);
+
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "marker", name)),
+        path: path,
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: Vec::new(),
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index 6eb18e29023..9f009ad4d78 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -29,7 +29,7 @@ pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "clone", "Clone")),
+        path: path_std!(cx, core::clone::Clone),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
@@ -58,7 +58,7 @@ fn cs_clone(
     let ctor_path;
     let all_fields;
     let fn_path = vec![
-        cx.ident_of("std"),
+        cx.ident_of_std("core"),
         cx.ident_of("clone"),
         cx.ident_of("Clone"),
         cx.ident_of("clone"),
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index 00971b96e92..91212a86958 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -70,7 +70,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
-                ret_ty: Literal(Path::new(vec!("bool"))),
+                ret_ty: Literal(path!(bool)),
                 attributes: attrs,
                 combine_substructure: combine_substructure(box |a, b, c| {
                     $f(a, b, c)
@@ -82,7 +82,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "cmp", "PartialEq")),
+        path: path_std!(cx, core::cmp::PartialEq),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 1f92f8d7b37..b109850a6bd 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -36,7 +36,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
-                ret_ty: Literal(Path::new(vec!("bool"))),
+                ret_ty: Literal(path!(bool)),
                 attributes: attrs,
                 combine_substructure: combine_substructure(box |cx, span, substr| {
                     cs_op($op, $equal, cx, span, substr)
@@ -45,8 +45,8 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
         } }
     }
 
-    let ordering_ty = Literal(Path::new(vec!["std", "cmp", "Ordering"]));
-    let ret_ty = Literal(Path::new_(vec!["std", "option", "Option"],
+    let ordering_ty = Literal(path_std!(cx, core::cmp::Ordering));
+    let ret_ty = Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                     None,
                                     vec![box ordering_ty],
                                     true));
@@ -69,7 +69,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: vec![],
-        path: Path::new(vec!["std", "cmp", "PartialOrd"]),
+        path: path_std!(cx, core::cmp::PartialOrd),
         additional_bounds: vec![],
         generics: LifetimeBounds::empty(),
         methods: vec![
@@ -107,7 +107,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
               substr: &Substructure) -> P<Expr> {
     let test_id = cx.ident_of("__test");
     let ordering = cx.path_global(span,
-                                  vec!(cx.ident_of("std"),
+                                  vec!(cx.ident_of_std("core"),
                                        cx.ident_of("cmp"),
                                        cx.ident_of("Ordering"),
                                        cx.ident_of("Equal")));
@@ -115,7 +115,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
     let equals_expr = cx.expr_some(span, ordering);
 
     let partial_cmp_path = vec![
-        cx.ident_of("std"),
+        cx.ident_of_std("core"),
         cx.ident_of("cmp"),
         cx.ident_of("PartialOrd"),
         cx.ident_of("partial_cmp"),
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index 0429db3643b..31a754a1254 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -46,7 +46,7 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "cmp", "Eq")),
+        path: path_std!(cx, core::cmp::Eq),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index e90c1aa6fce..2f6f99bc1ee 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -30,7 +30,7 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "cmp", "Ord")),
+        path: path_std!(cx, core::cmp::Ord),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
@@ -39,7 +39,7 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(borrowed_self()),
-                ret_ty: Literal(Path::new(vec!("std", "cmp", "Ordering"))),
+                ret_ty: Literal(path_std!(cx, core::cmp::Ordering)),
                 attributes: attrs,
                 combine_substructure: combine_substructure(box |a, b, c| {
                     cs_cmp(a, b, c)
@@ -65,13 +65,13 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
               substr: &Substructure) -> P<Expr> {
     let test_id = cx.ident_of("__test");
     let equals_path = cx.path_global(span,
-                                     vec!(cx.ident_of("std"),
+                                     vec!(cx.ident_of_std("core"),
                                           cx.ident_of("cmp"),
                                           cx.ident_of("Ordering"),
                                           cx.ident_of("Equal")));
 
     let cmp_path = vec![
-        cx.ident_of("std"),
+        cx.ident_of_std("core"),
         cx.ident_of("cmp"),
         cx.ident_of("Ord"),
         cx.ident_of("cmp"),
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 9552dff941d..f003a3453e1 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -49,6 +49,12 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
                                     krate: &'static str) where
     F: FnOnce(P<Item>),
 {
+    if !cx.use_std {
+        // FIXME(#21880): lift this requirement.
+        cx.span_err(span, "this trait cannot be derived with #![no_std]");
+        return;
+    }
+
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -68,7 +74,7 @@ fn expand_deriving_decodable_imp<F>(cx: &mut ExtCtxt,
                 args: vec!(Ptr(box Literal(Path::new_local("__D")),
                             Borrowed(None, MutMutable))),
                 ret_ty: Literal(Path::new_(
-                    vec!("std", "result", "Result"),
+                    pathvec_std!(cx, core::result::Result),
                     None,
                     vec!(box Self, box Literal(Path::new_(
                         vec!["__D", "Error"], None, vec![], false
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index df5e1863d55..9b76f4b1658 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -29,7 +29,7 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "default", "Default")),
+        path: path_std!(cx, core::default::Default),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
@@ -52,7 +52,7 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
 
 fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
     let default_ident = vec!(
-        cx.ident_of("std"),
+        cx.ident_of_std("core"),
         cx.ident_of("default"),
         cx.ident_of("Default"),
         cx.ident_of("default")
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index d0b2c2faf37..dd609470599 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -125,6 +125,12 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
                                     krate: &'static str) where
     F: FnOnce(P<Item>),
 {
+    if !cx.use_std {
+        // FIXME(#21880): lift this requirement.
+        cx.span_err(span, "this trait cannot be derived with #![no_std]");
+        return;
+    }
+
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -144,7 +150,7 @@ fn expand_deriving_encodable_imp<F>(cx: &mut ExtCtxt,
                 args: vec!(Ptr(box Literal(Path::new_local("__S")),
                             Borrowed(None, MutMutable))),
                 ret_ty: Literal(Path::new_(
-                    vec!("std", "result", "Result"),
+                    pathvec_std!(cx, core::result::Result),
                     None,
                     vec!(box Tuple(Vec::new()), box Literal(Path::new_(
                         vec!["__S", "Error"], None, vec![], false
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index f8a7af3aa91..5aa9f9a0c3e 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -25,13 +25,13 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
     F: FnOnce(P<Item>),
 {
 
-    let path = Path::new_(vec!("std", "hash", "Hash"), None,
+    let path = Path::new_(pathvec_std!(cx, core::hash::Hash), None,
                           vec!(box Literal(Path::new_local("__S"))), true);
     let generics = LifetimeBounds {
         lifetimes: Vec::new(),
         bounds: vec!(("__S",
-                      vec!(Path::new(vec!("std", "hash", "Writer")),
-                           Path::new(vec!("std", "hash", "Hasher"))))),
+                      vec!(path_std!(cx, core::hash::Writer),
+                           path_std!(cx, core::hash::Hasher)))),
     };
     let args = Path::new_local("__S");
     let inline = cx.meta_word(span, InternedString::new("inline"));
@@ -69,7 +69,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
     let call_hash = |span, thing_expr| {
         let hash_path = {
             let strs = vec![
-                cx.ident_of("std"),
+                cx.ident_of_std("core"),
                 cx.ident_of("hash"),
                 cx.ident_of("Hash"),
                 cx.ident_of("hash"),
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 318b748ad7f..9c3fa58ad09 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -18,6 +18,34 @@ use ext::base::ExtCtxt;
 use codemap::Span;
 use ptr::P;
 
+macro_rules! pathvec {
+    ($($x:ident)::+) => (
+        vec![ $( stringify!($x) ),+ ]
+    )
+}
+
+macro_rules! path {
+    ($($x:tt)*) => (
+        ::ext::deriving::generic::ty::Path::new( pathvec!( $($x)* ) )
+    )
+}
+
+macro_rules! pathvec_std {
+    ($cx:expr, $first:ident :: $($rest:ident)::+) => (
+        if $cx.use_std {
+            pathvec!(std :: $($rest)::+)
+        } else {
+            pathvec!($first :: $($rest)::+)
+        }
+    )
+}
+
+macro_rules! path_std {
+    ($($x:tt)*) => (
+        ::ext::deriving::generic::ty::Path::new( pathvec_std!( $($x)* ) )
+    )
+}
+
 pub mod bounds;
 pub mod clone;
 pub mod encodable;
diff --git a/src/libsyntax/ext/deriving/primitive.rs b/src/libsyntax/ext/deriving/primitive.rs
index ae7b20f7853..bf742263c6d 100644
--- a/src/libsyntax/ext/deriving/primitive.rs
+++ b/src/libsyntax/ext/deriving/primitive.rs
@@ -30,7 +30,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "num", "FromPrimitive")),
+        path: path_std!(cx, core::num::FromPrimitive),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
@@ -38,9 +38,8 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
                 name: "from_i64",
                 generics: LifetimeBounds::empty(),
                 explicit_self: None,
-                args: vec!(
-                    Literal(Path::new(vec!("i64")))),
-                ret_ty: Literal(Path::new_(vec!("std", "option", "Option"),
+                args: vec!(Literal(path!(i64))),
+                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                            None,
                                            vec!(box Self),
                                            true)),
@@ -54,9 +53,8 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
                 name: "from_u64",
                 generics: LifetimeBounds::empty(),
                 explicit_self: None,
-                args: vec!(
-                    Literal(Path::new(vec!("u64")))),
-                ret_ty: Literal(Path::new_(vec!("std", "option", "Option"),
+                args: vec!(Literal(path!(u64))),
+                ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
                                            None,
                                            vec!(box Self),
                                            true)),
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
index c708a09b53c..4c3678d9572 100644
--- a/src/libsyntax/ext/deriving/rand.rs
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -28,10 +28,16 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
                  "`#[derive(Rand)]` is deprecated in favour of `#[derive_Rand]` from \
                   `rand_macros` on crates.io");
 
+    if !cx.use_std {
+        // FIXME(#21880): lift this requirement.
+        cx.span_err(span, "this trait cannot be derived with #![no_std]");
+        return;
+    }
+
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!("std", "rand", "Rand")),
+        path: path!(std::rand::Rand),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec!(
@@ -40,7 +46,7 @@ pub fn expand_deriving_rand<F>(cx: &mut ExtCtxt,
                 generics: LifetimeBounds {
                     lifetimes: Vec::new(),
                     bounds: vec!(("R",
-                                  vec!( Path::new(vec!("std", "rand", "Rng")) )))
+                                  vec!( path!(std::rand::Rng) ))),
                 },
                 explicit_self: None,
                 args: vec!(
diff --git a/src/libsyntax/ext/deriving/show.rs b/src/libsyntax/ext/deriving/show.rs
index 821fdeaa86a..3f5947672e0 100644
--- a/src/libsyntax/ext/deriving/show.rs
+++ b/src/libsyntax/ext/deriving/show.rs
@@ -29,13 +29,13 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
     F: FnOnce(P<Item>),
 {
     // &mut ::std::fmt::Formatter
-    let fmtr = Ptr(box Literal(Path::new(vec!("std", "fmt", "Formatter"))),
+    let fmtr = Ptr(box Literal(path_std!(cx, core::fmt::Formatter)),
                    Borrowed(None, ast::MutMutable));
 
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
-        path: Path::new(vec!["std", "fmt", "Debug"]),
+        path: path_std!(cx, core::fmt::Debug),
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         methods: vec![
@@ -44,7 +44,7 @@ pub fn expand_deriving_show<F>(cx: &mut ExtCtxt,
                 generics: LifetimeBounds::empty(),
                 explicit_self: borrowed_explicit_self(),
                 args: vec!(fmtr),
-                ret_ty: Literal(Path::new(vec!("std", "fmt", "Result"))),
+                ret_ty: Literal(path_std!(cx, core::fmt::Result)),
                 attributes: Vec::new(),
                 combine_substructure: combine_substructure(box |a, b, c| {
                     show_substructure(a, b, c)
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 417506cf3aa..ef9d3799879 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -34,7 +34,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
       Err(..) => {
           cx.expr_path(cx.path_all(sp,
                                    true,
-                                   vec!(cx.ident_of("std"),
+                                   vec!(cx.ident_of_std("core"),
                                         cx.ident_of("option"),
                                         cx.ident_of("Option"),
                                         cx.ident_of("None")),
@@ -50,7 +50,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
       }
       Ok(s) => {
           cx.expr_call_global(sp,
-                              vec!(cx.ident_of("std"),
+                              vec!(cx.ident_of_std("core"),
                                    cx.ident_of("option"),
                                    cx.ident_of("Option"),
                                    cx.ident_of("Some")),
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index f9d8406b845..fd7593f2a3b 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -31,6 +31,7 @@ use ptr::P;
 use util::small_vector::SmallVector;
 use visit;
 use visit::Visitor;
+use std_inject;
 
 pub fn expand_type(t: P<ast::Ty>,
                    fld: &mut MacroExpander,
@@ -278,7 +279,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             let match_expr = {
                 let next_path = {
                     let strs = vec![
-                        fld.cx.ident_of("std"),
+                        fld.cx.ident_of_std("core"),
                         fld.cx.ident_of("iter"),
                         fld.cx.ident_of("Iterator"),
                         fld.cx.ident_of("next"),
@@ -311,7 +312,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             let into_iter_expr = {
                 let into_iter_path = {
                     let strs = vec![
-                        fld.cx.ident_of("std"),
+                        fld.cx.ident_of_std("core"),
                         fld.cx.ident_of("iter"),
                         fld.cx.ident_of("IntoIterator"),
                         fld.cx.ident_of("into_iter"),
@@ -1429,6 +1430,8 @@ pub fn expand_crate(parse_sess: &parse::ParseSess,
                     user_exts: Vec<NamedSyntaxExtension>,
                     c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
+    cx.use_std = std_inject::use_std(&c);
+
     let mut expander = MacroExpander::new(&mut cx);
 
     for def in imported_macros {
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 96055e3635a..170a455a913 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -302,7 +302,7 @@ impl<'a, 'b> Context<'a, 'b> {
     }
 
     fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec<ast::Ident> {
-        vec![ecx.ident_of("std"), ecx.ident_of("fmt"), ecx.ident_of("rt"),
+        vec![ecx.ident_of_std("core"), ecx.ident_of("fmt"), ecx.ident_of("rt"),
              ecx.ident_of("v1"), ecx.ident_of(s)]
     }
 
@@ -576,7 +576,7 @@ impl<'a, 'b> Context<'a, 'b> {
         };
 
         self.ecx.expr_call_global(self.fmtsp, vec!(
-                self.ecx.ident_of("std"),
+                self.ecx.ident_of_std("core"),
                 self.ecx.ident_of("fmt"),
                 self.ecx.ident_of("Arguments"),
                 self.ecx.ident_of(fn_name)), fn_args)
@@ -607,7 +607,7 @@ impl<'a, 'b> Context<'a, 'b> {
             }
             Unsigned => {
                 return ecx.expr_call_global(sp, vec![
-                        ecx.ident_of("std"),
+                        ecx.ident_of_std("core"),
                         ecx.ident_of("fmt"),
                         ecx.ident_of("ArgumentV1"),
                         ecx.ident_of("from_uint")], vec![arg])
@@ -615,12 +615,12 @@ impl<'a, 'b> Context<'a, 'b> {
         };
 
         let format_fn = ecx.path_global(sp, vec![
-                ecx.ident_of("std"),
+                ecx.ident_of_std("core"),
                 ecx.ident_of("fmt"),
                 ecx.ident_of(trait_),
                 ecx.ident_of("fmt")]);
         ecx.expr_call_global(sp, vec![
-                ecx.ident_of("std"),
+                ecx.ident_of_std("core"),
                 ecx.ident_of("fmt"),
                 ecx.ident_of("ArgumentV1"),
                 ecx.ident_of("new")], vec![arg, ecx.expr_path(format_fn)])