diff options
| author | bors <bors@rust-lang.org> | 2015-02-08 00:24:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-02-08 00:24:03 +0000 |
| commit | 74b8740719c1b427f79b67d6bc51e9d448dd9c49 (patch) | |
| tree | 51327a08df4c0f510c0a851c41a6e400645afc97 /src/libsyntax | |
| parent | bfaa1a8434de3991d9ceae3eea88674a74c5eef2 (diff) | |
| parent | 312f8bd850ca4d575b1414badabab4f5aee99c67 (diff) | |
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')
22 files changed, 163 insertions, 78 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)]) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 12efd959918..c8ab46ff8fd 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -122,7 +122,10 @@ static KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[ ("staged_api", "1.0.0", Active), // Allows using items which are missing stability attributes - ("unmarked_api", "1.0.0", Active) + ("unmarked_api", "1.0.0", Active), + + // Allows using #![no_std] + ("no_std", "1.0.0", Active), ]; enum Status { @@ -466,6 +469,11 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { attr.span, "language items are subject to change"); } + + if attr.check_name("no_std") { + self.gate_feature("no_std", attr.span, + "no_std is experimental"); + } } fn visit_pat(&mut self, pattern: &ast::Pat) { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c177cd1fafa..0da15859ea2 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -15,17 +15,19 @@ use ast; use ast::{MethodImplItem, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; use ast::{RequiredMethod, ProvidedMethod, TypeImplItem, TypeTraitItem}; use ast_util; +use attr; use owned_slice::OwnedSlice; use attr::{AttrMetaMethods, AttributeMethods}; use codemap::{self, CodeMap, BytePos}; use diagnostic; -use parse::token::{self, BinOpToken, Token}; +use parse::token::{self, BinOpToken, Token, InternedString}; use parse::lexer::comments; use parse; use print::pp::{self, break_offset, word, space, zerobreak, hardbreak}; use print::pp::{Breaks, eof}; use print::pp::Breaks::{Consistent, Inconsistent}; use ptr::P; +use std_inject; use std::{ascii, mem}; use std::old_io::{self, IoResult}; @@ -113,6 +115,25 @@ pub fn print_crate<'a>(cm: &'a CodeMap, out, ann, is_expanded); + if is_expanded && std_inject::use_std(krate) { + // We need to print `#![no_std]` (and its feature gate) so that + // compiling pretty-printed source won't inject libstd again. + // However we don't want these attributes in the AST because + // of the feature gate, so we fake them up here. + + let no_std_meta = attr::mk_word_item(InternedString::new("no_std")); + + // #![feature(no_std)] + let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), + attr::mk_list_item(InternedString::new("feature"), + vec![no_std_meta.clone()])); + try!(s.print_attribute(&fake_attr)); + + // #![no_std] + let fake_attr = attr::mk_attr_inner(attr::mk_attr_id(), no_std_meta); + try!(s.print_attribute(&fake_attr)); + } + try!(s.print_mod(&krate.module, &krate.attrs[])); try!(s.print_remaining_comments()); eof(&mut s.s) diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index d75fbcf199d..98c193c7e6b 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -37,7 +37,7 @@ pub fn maybe_inject_prelude(krate: ast::Crate) -> ast::Crate { } } -fn use_std(krate: &ast::Crate) -> bool { +pub fn use_std(krate: &ast::Crate) -> bool { !attr::contains_name(&krate.attrs[], "no_std") } @@ -69,9 +69,6 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> { span: DUMMY_SP })); - // don't add #![no_std] here, that will block the prelude injection later. - // Add it during the prelude injection instead. - krate } } @@ -87,16 +84,6 @@ struct PreludeInjector<'a>; impl<'a> fold::Folder for PreludeInjector<'a> { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { - // Add #![no_std] here, so we don't re-inject when compiling pretty-printed source. - // This must happen here and not in StandardLibraryInjector because this - // fold happens second. - - let no_std_attr = attr::mk_attr_inner(attr::mk_attr_id(), - attr::mk_word_item(InternedString::new("no_std"))); - // std_inject runs after feature checking so manually mark this attr - attr::mark_used(&no_std_attr); - krate.attrs.push(no_std_attr); - // only add `use std::prelude::*;` if there wasn't a // `#![no_implicit_prelude]` at the crate level. // fold_mod() will insert glob path. |
