Don't use std:: paths in syntax extensions when compiling a #![no_std] crate

Fixes #16803.
Fixes #14342.
Fixes half of #21827 -- slice syntax is still broken.
This commit is contained in:
Keegan McAllister 2014-09-07 14:57:26 -07:00
parent 74eef05e7d
commit 67350bc868
41 changed files with 413 additions and 145 deletions

View File

@ -576,10 +576,6 @@ extern fn panic_fmt(args: &core::fmt::Arguments,
#[lang = "eh_personality"] extern fn eh_personality() {}
# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
# fn main() {}
# mod std { // for-loops
# pub use core::iter;
# pub use core::option;
# }
```
Note that there is one extra lang item here which differs from the examples

View File

@ -126,7 +126,8 @@ pub fn oom() -> ! {
#[doc(hidden)]
pub fn fixme_14344_be_sure_to_link_to_collections() {}
#[cfg(not(test))]
// NOTE: remove after next snapshot
#[cfg(all(stage0, not(test)))]
#[doc(hidden)]
mod std {
pub use core::fmt;

56
src/libcollections/fmt.rs Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Formatting support for `String`.
//!
//! See `core::fmt` and `std::fmt` for full documentation on string
//! formatting.
#![stable(feature = "rust1", since = "1.0.0")]
use core::fmt;
use string;
/// The format function takes a precompiled format string and a list of
/// arguments, to return the resulting formatted string.
///
/// # Arguments
///
/// * args - a structure of arguments generated via the `format_args!` macro.
///
/// # Example
///
/// ```rust
/// use std::fmt;
///
/// let s = fmt::format(format_args!("Hello, {}!", "world"));
/// assert_eq!(s, "Hello, world!".to_string());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn format(args: fmt::Arguments) -> string::String {
// FIXME #21826
use core::fmt::Writer;
let mut output = string::String::new();
let _ = write!(&mut output, "{}", args);
output
}
#[cfg(test)]
mod tests {
use prelude::*;
use fmt;
#[test]
fn test_format() {
let s = fmt::format(format_args!("Hello, {}!", "world"));
assert_eq!(s.as_slice(), "Hello, world!");
}
}

View File

@ -68,6 +68,7 @@ mod bit;
mod btree;
pub mod dlist;
pub mod enum_set;
pub mod fmt;
pub mod ring_buf;
pub mod slice;
pub mod str;
@ -107,15 +108,16 @@ pub fn fixme_14344_be_sure_to_link_to_collections() {}
#[cfg(not(test))]
mod std {
pub use core::fmt; // necessary for panic!()
pub use core::option; // necessary for panic!()
pub use core::clone; // derive(Clone)
pub use core::cmp; // derive(Eq, Ord, etc.)
pub use core::marker; // derive(Copy)
pub use core::hash; // derive(Hash)
// NOTE: remove after next snapshot
#[cfg(stage0)] pub use core::clone; // derive(Clone)
#[cfg(stage0)] pub use core::cmp; // derive(Eq, Ord, etc.)
#[cfg(stage0)] pub use core::marker; // derive(Copy)
#[cfg(stage0)] pub use core::hash; // derive(Hash)
#[cfg(stage0)] pub use core::iter;
#[cfg(stage0)] pub use core::fmt; // necessary for panic!()
#[cfg(stage0)] pub use core::option; // necessary for panic!()
pub use core::ops; // RangeFull
// for-loops
pub use core::iter;
}
#[cfg(test)]

View File

@ -22,3 +22,19 @@ macro_rules! vec {
);
($($x:expr,)*) => (vec![$($x),*])
}
/// Use the syntax described in `std::fmt` to create a value of type `String`.
/// See `std::fmt` for more information.
///
/// # Example
///
/// ```
/// format!("test");
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
/// ```
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! format {
($($arg:tt)*) => ($crate::fmt::format(format_args!($($arg)*)))
}

View File

@ -27,8 +27,8 @@ use core::ops::{Index, IndexMut};
use core::ptr;
use core::raw::Slice as RawSlice;
use std::hash::{Writer, Hash, Hasher};
use std::cmp;
use core::hash::{Writer, Hash, Hasher};
use core::cmp;
use alloc::heap;

View File

@ -67,7 +67,7 @@ use num::{ToPrimitive, Int};
use ops::{Add, Deref, FnMut};
use option::Option;
use option::Option::{Some, None};
use std::marker::Sized;
use marker::Sized;
use usize;
/// An interface for dealing with "external iterators". These types of iterators

View File

@ -148,17 +148,25 @@ mod array;
mod core {
pub use panicking;
pub use fmt;
#[cfg(not(stage0))] pub use clone;
#[cfg(not(stage0))] pub use cmp;
#[cfg(not(stage0))] pub use hash;
#[cfg(not(stage0))] pub use marker;
#[cfg(not(stage0))] pub use option;
#[cfg(not(stage0))] pub use iter;
}
#[doc(hidden)]
mod std {
pub use clone;
pub use cmp;
pub use fmt;
pub use hash;
pub use marker;
// NOTE: remove after next snapshot
#[cfg(stage0)] pub use clone;
#[cfg(stage0)] pub use cmp;
#[cfg(stage0)] pub use hash;
#[cfg(stage0)] pub use marker;
#[cfg(stage0)] pub use option;
#[cfg(stage0)] pub use fmt;
#[cfg(stage0)] pub use iter;
// range syntax
pub use ops;
pub use option;
// for-loops
pub use iter;
}

View File

@ -5729,8 +5729,9 @@ pub fn issue_14344_workaround() {} // FIXME #14344 force linkage to happen corre
#[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows
// NOTE: remove after next snapshot
#[doc(hidden)]
#[cfg(not(test))]
#[cfg(all(stage0, not(test)))]
mod std {
pub use core::marker;
}

View File

@ -496,7 +496,8 @@ pub struct Open01<F>(pub F);
/// ```
pub struct Closed01<F>(pub F);
#[cfg(not(test))]
// NOTE: remove after next snapshot
#[cfg(all(stage0, not(test)))]
mod std {
pub use core::{option, fmt}; // panic!()
pub use core::clone; // derive Clone

View File

@ -281,6 +281,13 @@ macro_rules! bitflags {
};
}
// This is a no_std crate. So the test code's invocation of #[derive] etc, via
// bitflags!, will use names from the underlying crates.
#[cfg(test)]
mod core {
pub use std::{fmt, hash, clone, cmp, marker, option};
}
#[cfg(test)]
#[allow(non_upper_case_globals)]
mod tests {

View File

@ -403,8 +403,6 @@
#![unstable(feature = "std_misc")]
use string;
pub use core::fmt::{Formatter, Result, Writer, rt};
pub use core::fmt::{Show, String, Octal, Binary};
pub use core::fmt::{Display, Debug};
@ -413,24 +411,4 @@ pub use core::fmt::{LowerExp, UpperExp};
pub use core::fmt::Error;
pub use core::fmt::{ArgumentV1, Arguments, write, radix, Radix, RadixFmt};
/// The format function takes a precompiled format string and a list of
/// arguments, to return the resulting formatted string.
///
/// # Arguments
///
/// * args - a structure of arguments generated via the `format_args!` macro.
///
/// # Example
///
/// ```rust
/// use std::fmt;
///
/// let s = fmt::format(format_args!("Hello, {}!", "world"));
/// assert_eq!(s, "Hello, world!".to_string());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn format(args: Arguments) -> string::String {
let mut output = string::String::new();
let _ = write!(&mut output, "{}", args);
output
}
pub use core_collections::fmt::format;

View File

@ -137,7 +137,7 @@
extern crate core;
#[macro_use]
#[macro_reexport(vec)]
#[macro_reexport(vec, format)]
extern crate "collections" as core_collections;
#[allow(deprecated)] extern crate "rand" as core_rand;
@ -285,11 +285,12 @@ mod tuple;
// can be resolved within libstd.
#[doc(hidden)]
mod std {
// NOTE: remove after next snapshot
// mods used for deriving
pub use clone;
pub use cmp;
pub use hash;
pub use default;
#[cfg(stage0)] pub use clone;
#[cfg(stage0)] pub use cmp;
#[cfg(stage0)] pub use hash;
#[cfg(stage0)] pub use default;
pub use sync; // used for select!()
pub use error; // used for try!()
@ -312,5 +313,6 @@ mod std {
pub use boxed; // used for vec![]
// for-loops
pub use iter;
// NOTE: remove after next snapshot
#[cfg(stage0)] pub use iter;
}

View File

@ -70,6 +70,7 @@ macro_rules! panic {
/// format!("hello {}", "world!");
/// format!("x = {}, y = {y}", 10, y = 30);
/// ```
#[cfg(stage0)] // NOTE: remove after snapshot
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
macro_rules! format {

View File

@ -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)
}

View File

@ -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"));

View File

@ -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(),

View File

@ -29,7 +29,7 @@ pub fn expand_deriving_clone<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path!(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"),

View File

@ -82,7 +82,7 @@ pub fn expand_deriving_eq<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path!(std::cmp::PartialEq),
path: path_std!(cx, core::cmp::PartialEq),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(

View File

@ -45,8 +45,8 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
} }
}
let ordering_ty = Literal(path!(std::cmp::Ordering));
let ret_ty = Literal(Path::new_(pathvec!(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!(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"),

View File

@ -46,7 +46,7 @@ pub fn expand_deriving_totaleq<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path!(std::cmp::Eq),
path: path_std!(cx, core::cmp::Eq),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(

View File

@ -30,7 +30,7 @@ pub fn expand_deriving_totalord<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path!(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!(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"),

View File

@ -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_(
pathvec!(std::result::Result),
pathvec_std!(cx, core::result::Result),
None,
vec!(box Self, box Literal(Path::new_(
vec!["__D", "Error"], None, vec![], false

View File

@ -29,7 +29,7 @@ pub fn expand_deriving_default<F>(cx: &mut ExtCtxt,
let trait_def = TraitDef {
span: span,
attributes: Vec::new(),
path: path!(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")

View File

@ -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_(
pathvec!(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

View File

@ -25,13 +25,13 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
F: FnOnce(P<Item>),
{
let path = Path::new_(pathvec!(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!(std::hash::Writer),
path!(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"),

View File

@ -30,6 +30,22 @@ macro_rules! path {
)
}
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;

View File

@ -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!(std::num::FromPrimitive),
path: path_std!(cx, core::num::FromPrimitive),
additional_bounds: Vec::new(),
generics: LifetimeBounds::empty(),
methods: vec!(
@ -39,7 +39,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
explicit_self: None,
args: vec!(Literal(path!(i64))),
ret_ty: Literal(Path::new_(pathvec!(std::option::Option),
ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
None,
vec!(box Self),
true)),
@ -54,7 +54,7 @@ pub fn expand_deriving_from_primitive<F>(cx: &mut ExtCtxt,
generics: LifetimeBounds::empty(),
explicit_self: None,
args: vec!(Literal(path!(u64))),
ret_ty: Literal(Path::new_(pathvec!(std::option::Option),
ret_ty: Literal(Path::new_(pathvec_std!(cx, core::option::Option),
None,
vec!(box Self),
true)),

View File

@ -28,6 +28,12 @@ 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(),

View File

@ -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!(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!(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!(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)

View File

@ -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")),

View File

@ -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,
@ -275,7 +276,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"),
@ -308,7 +309,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"),
@ -1417,6 +1418,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 {

View File

@ -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)])

View File

@ -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")
}

View File

@ -78,7 +78,9 @@ pub mod str {
pub use u_str::{utf16_items, Utf16Encoder};
}
// NOTE: remove after next snapshot
// this lets us use #[derive(..)]
#[cfg(stage0)]
mod std {
pub use core::clone;
pub use core::cmp;

View File

@ -0,0 +1,37 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![no_std]
extern crate core;
extern crate rand;
extern crate "serialize" as rustc_serialize;
#[derive(Rand)] //~ ERROR this trait cannot be derived
//~^ WARNING `#[derive(Rand)]` is deprecated
struct Foo {
x: u32,
}
#[derive(RustcEncodable)] //~ ERROR this trait cannot be derived
struct Bar {
x: u32,
}
#[derive(RustcDecodable)] //~ ERROR this trait cannot be derived
struct Baz {
x: u32,
}
fn main() {
Foo { x: 0 };
Bar { x: 0 };
Baz { x: 0 };
}

View File

@ -41,41 +41,41 @@ pub fn bar() {
((::std::fmt::format as
fn(core::fmt::Arguments<'_>) -> collections::string::String {std::fmt::format})(((::std::fmt::Arguments::new_v1
as
fn(&[&str], &[core::fmt::ArgumentV1<'_>]) -> core::fmt::Arguments<'_> {core::fmt::Arguments<'a>::new_v1})(({
static __STATIC_FMTSTR:
&'static [&'static str]
=
(&([("test"
fn(core::fmt::Arguments<'_>) -> collections::string::String {collections::fmt::format})(((::std::fmt::Arguments::new_v1
as
fn(&[&str], &[core::fmt::ArgumentV1<'_>]) -> core::fmt::Arguments<'_> {core::fmt::Arguments<'a>::new_v1})(({
static __STATIC_FMTSTR:
&'static [&'static str]
=
(&([("test"
as
&'static str)]
as
[&'static str; 1])
as
&'static [&'static str; 1]);
(__STATIC_FMTSTR
as
&'static str)]
as
[&'static str; 1])
as
&'static [&'static str; 1]);
(__STATIC_FMTSTR
as
&'static [&'static str])
}
as
&[&str]),
(&(match (()
as
())
{
()
=>
([]
as
[core::fmt::ArgumentV1<'_>; 0]),
}
as
[core::fmt::ArgumentV1<'_>; 0])
as
&[core::fmt::ArgumentV1<'_>; 0]))
as
core::fmt::Arguments<'_>))
&'static [&'static str])
}
as
&[&str]),
(&(match (()
as
())
{
()
=>
([]
as
[core::fmt::ArgumentV1<'_>; 0]),
}
as
[core::fmt::ArgumentV1<'_>; 0])
as
&[core::fmt::ArgumentV1<'_>; 0]))
as
core::fmt::Arguments<'_>))
as collections::string::String);
}
pub type Foo = [i32; (3us as usize)];

View File

@ -74,7 +74,7 @@ trait Sized {}
#[lang = "copy"]
trait Copy {}
mod std {
mod core {
pub mod marker {
pub use Copy;
}

View File

@ -0,0 +1,40 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![no_std]
extern crate core;
extern crate rand;
extern crate "serialize" as rustc_serialize;
extern crate collections;
// Issue #16803
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
Debug, Default, Copy)]
struct Foo {
x: u32,
}
#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord,
Debug, Copy)]
enum Bar {
Qux,
Quux(u32),
}
#[derive(FromPrimitive)]
enum Baz { A=0, B=5, }
fn main() {
Foo { x: 0 };
Bar::Quux(3);
Baz::A;
}

View File

@ -0,0 +1,25 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![no_std]
#![feature(lang_items, start)]
extern crate "std" as other;
#[macro_use] extern crate core;
#[macro_use] extern crate collections;
use core::slice::SliceExt;
#[start]
fn start(_argc: int, _argv: *const *const u8) -> int {
for _ in [1,2,3].iter() { }
0
}

View File

@ -0,0 +1,36 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![no_std]
#![feature(lang_items, start)]
extern crate "std" as other;
#[macro_use] extern crate core;
#[macro_use] extern crate collections;
use collections::string::ToString;
#[start]
fn start(_argc: int, _argv: *const *const u8) -> int {
let s = format!("{}", 1i);
assert_eq!(s, "1".to_string());
let s = format!("test");
assert_eq!(s, "test".to_string());
let s = format!("{test}", test=3i);
assert_eq!(s, "3".to_string());
let s = format!("hello {}", "world");
assert_eq!(s, "hello world".to_string());
0
}