diff --git a/src/doc/reference.md b/src/doc/reference.md index cfb34dae690..9c8191a386d 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -2467,6 +2467,12 @@ The currently implemented features of the reference compiler are: * `associated_types` - Allows type aliases in traits. Experimental. +* `no_std` - Allows the `#![no_std]` crate attribute, which disables the implicit + `extern crate std`. This typically requires use of the unstable APIs + behind the libstd "facade", such as libcore and libcollections. It + may also cause problems when using syntax extensions, including + `#[derive]`. + If a feature is promoted to a language feature, then all existing programs will start to receive compilation warnings about #[feature] directives which enabled the new feature (because the directive is no longer necessary). However, if a diff --git a/src/doc/trpl/unsafe.md b/src/doc/trpl/unsafe.md index 2bd86fa987f..b364d00f95c 100644 --- a/src/doc/trpl/unsafe.md +++ b/src/doc/trpl/unsafe.md @@ -433,6 +433,7 @@ attribute attached to the crate. ```ignore // a minimal library #![crate_type="lib"] +#![feature(no_std)] #![no_std] # // fn main() {} tricked you, rustdoc! ``` @@ -446,8 +447,8 @@ The function marked `#[start]` is passed the command line parameters in the same format as C: ``` +#![feature(lang_items, start, no_std)] #![no_std] -#![feature(lang_items, start)] // Pull in the system libc library for what crt0.o likely requires extern crate libc; @@ -473,6 +474,7 @@ correct ABI and the correct name, which requires overriding the compiler's name mangling too: ```ignore +#![feature(no_std)] #![no_std] #![no_main] #![feature(lang_items, start)] @@ -528,8 +530,8 @@ As an example, here is a program that will calculate the dot product of two vectors provided from C, using idiomatic Rust practices. ``` +#![feature(lang_items, start, no_std)] #![no_std] -#![feature(lang_items, start)] # extern crate libc; extern crate core; @@ -576,10 +578,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 @@ -656,8 +654,8 @@ and one for deallocation. A freestanding program that uses the `Box` sugar for dynamic allocations via `malloc` and `free`: ``` +#![feature(lang_items, box_syntax, start, no_std)] #![no_std] -#![feature(lang_items, box_syntax, start)] extern crate libc; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index d99a5e2cc6d..81391fd63eb 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -65,6 +65,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/")] +#![feature(no_std)] #![no_std] #![feature(lang_items, unsafe_destructor)] #![feature(box_syntax)] @@ -126,7 +127,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; diff --git a/src/libstd/fmt.rs b/src/libcollections/fmt.rs similarity index 97% rename from src/libstd/fmt.rs rename to src/libcollections/fmt.rs index 47f5d64e260..5f337528d78 100644 --- a/src/libstd/fmt.rs +++ b/src/libcollections/fmt.rs @@ -1,4 +1,4 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -134,7 +134,7 @@ //! * `E` ⇒ `UpperExp` //! //! What this means is that any type of argument which implements the -//! `std::fmt::Binary` trait can then be formatted with `{:b}`. Implementations +//! `fmt::Binary` trait can then be formatted with `{:b}`. Implementations //! are provided for these traits for a number of primitive types by the //! standard library as well. If no format is specified (as in `{}` or `{:6}`), //! then the format trait used is the `Display` trait. @@ -146,7 +146,7 @@ //! # use std::fmt; //! # struct Foo; // our custom type //! # impl fmt::Display for Foo { -//! fn fmt(&self, f: &mut std::fmt::Formatter) -> fmt::Result { +//! fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { //! # write!(f, "testing, testing") //! # } } //! ``` @@ -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,6 +411,8 @@ pub use core::fmt::Error; pub use core::fmt::{ArgumentV1, Arguments, write, radix, Radix, RadixFmt}; +use string; + /// The format function takes a precompiled format string and a list of /// arguments, to return the resulting formatted string. /// @@ -434,3 +434,15 @@ pub fn format(args: Arguments) -> string::String { 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!"); + } +} diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 57c799785e8..f220724c42e 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -33,6 +33,7 @@ #![cfg_attr(test, feature(test))] #![cfg_attr(test, allow(deprecated))] // rand +#![feature(no_std)] #![no_std] #[macro_use] @@ -68,6 +69,7 @@ mod btree; pub mod dlist; pub mod enum_set; +pub mod fmt; pub mod ring_buf; pub mod slice; pub mod str; @@ -107,15 +109,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)] diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs index 15048998592..79c86a846f1 100644 --- a/src/libcollections/macros.rs +++ b/src/libcollections/macros.rs @@ -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)*))) +} diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 41749303840..76849e6ade8 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -27,8 +27,8 @@ 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; diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index f3b42e4f0a5..5df64cfaada 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -67,7 +67,7 @@ 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 diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 5e9793f270d..df4942b509b 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -56,6 +56,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] +#![feature(no_std)] #![no_std] #![allow(raw_pointer_derive)] #![deny(missing_docs)] @@ -148,17 +149,25 @@ 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; } diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index b643b04035f..38d5c5eb27a 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -16,6 +16,7 @@ #![cfg_attr(not(feature = "cargo-build"), staged_api)] #![cfg_attr(not(feature = "cargo-build"), feature(core))] #![feature(int_uint)] +#![feature(no_std)] #![no_std] #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "http://www.rust-lang.org/favicon.ico", @@ -5729,8 +5730,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; } diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 0a64da6f137..4113718cfd1 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -23,6 +23,7 @@ html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] #![feature(int_uint)] +#![feature(no_std)] #![no_std] #![unstable(feature = "rand")] #![feature(staged_api)] @@ -496,7 +497,8 @@ fn rand(rng: &mut R) -> XorShiftRng { /// ``` pub struct Closed01(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 diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs index 03160772879..370a5d48dec 100644 --- a/src/librustc_bitflags/lib.rs +++ b/src/librustc_bitflags/lib.rs @@ -12,6 +12,7 @@ #![feature(staged_api)] #![staged_api] #![crate_type = "rlib"] +#![feature(no_std)] #![no_std] #![unstable(feature = "rustc_private")] @@ -281,6 +282,13 @@ fn not(self) -> $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 { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 8761b5f72ec..9df90258462 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -43,7 +43,7 @@ struct RH<'a> { sub: &'a [RH<'a>] } -static EMPTY_SOURCE_STR: &'static str = "#![no_std]"; +static EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]"; struct ExpectErrorEmitter { messages: Vec diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 14e779f9c4a..9a9a554ec98 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -124,6 +124,7 @@ #![cfg_attr(test, feature(test))] // Don't link to std. We are std. +#![feature(no_std)] #![no_std] #![deny(missing_docs)] @@ -137,7 +138,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; @@ -180,6 +181,7 @@ #[cfg(not(test))] pub use alloc::boxed; pub use alloc::rc; +pub use core_collections::fmt; pub use core_collections::slice; pub use core_collections::str; pub use core_collections::string; @@ -245,7 +247,6 @@ pub mod dynamic_lib; pub mod ffi; -pub mod fmt; pub mod old_io; pub mod io; pub mod os; @@ -285,11 +286,12 @@ // 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 +314,6 @@ mod std { pub use boxed; // used for vec![] // for-loops - pub use iter; + // NOTE: remove after next snapshot + #[cfg(stage0)] pub use iter; } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index e91e8241a55..6a2aafcf8f3 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -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 { 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 , pub trace_mac: bool, @@ -563,6 +564,7 @@ pub fn new(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig, 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 @@ pub fn set_trace_macros(&mut self, x: bool) { 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 @@ fn ty_option(&self, ty: P) -> P { 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 @@ fn expr_vec(&self, sp: Span, exprs: Vec>) -> P { } fn expr_vec_ng(&self, sp: Span) -> P { 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 @@ fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P) -> P { 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 @@ fn expr_some(&self, sp: Span, expr: P) -> P { fn expr_none(&self, sp: Span) -> P { 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 @@ fn expr_fail(&self, span: Span, msg: InternedString) -> P { 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 @@ fn expr_unreachable(&self, span: Span) -> P { fn expr_ok(&self, sp: Span, expr: P) -> P { 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 @@ fn expr_ok(&self, sp: Span, expr: P) -> P { fn expr_err(&self, sp: Span, expr: P) -> P { 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 @@ fn expr_err(&self, sp: Span, expr: P) -> P { } fn expr_try(&self, sp: Span, head: P) -> P { - 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 @@ fn expr_try(&self, sp: Span, head: P) -> P { 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 @@ fn pat_tuple(&self, span: Span, pats: Vec>) -> P { fn pat_some(&self, span: Span, pat: P) -> P { 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 @@ fn pat_some(&self, span: Span, pat: P) -> P { fn pat_none(&self, span: Span) -> P { 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 @@ fn pat_none(&self, span: Span) -> P { fn pat_ok(&self, span: Span, pat: P) -> P { 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 @@ fn pat_ok(&self, span: Span, pat: P) -> P { fn pat_err(&self, span: Span, pat: P) -> P { 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(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(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 @@ macro_rules! md { 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 @@ macro_rules! md { 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 @@ macro_rules! md { 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 @@ macro_rules! md { } } } - 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 @@ macro_rules! md { 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 { 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 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P< 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(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(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 { 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(cx: &mut ExtCtxt, krate: &'static str) where F: FnOnce(P), { + 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(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(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(cx: &mut ExtCtxt, fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P { 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(cx: &mut ExtCtxt, krate: &'static str) where F: FnOnce(P), { + 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(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(cx: &mut ExtCtxt, F: FnOnce(P), { - 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 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(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(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(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(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(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(cx: &mut ExtCtxt, F: FnOnce(P), { // &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(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 util::small_vector::SmallVector; use visit; use visit::Visitor; +use std_inject; pub fn expand_type(t: P, fld: &mut MacroExpander, @@ -278,7 +279,7 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { 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, fld: &mut MacroExpander) -> P { 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, 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 @@ fn verify_same(&self, } fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec { - 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 @@ fn into_expr(mut self) -> P { }; 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 @@ fn format_arg(ecx: &ExtCtxt, sp: Span, } 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 @@ fn format_arg(ecx: &ExtCtxt, sp: Span, }; 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 @@ ("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 @@ fn visit_attribute(&mut self, attr: &ast::Attribute) { 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::{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 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { 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 @@ fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option) -> ast::Cr 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. diff --git a/src/libunicode/lib.rs b/src/libunicode/lib.rs index 822dde7eb2c..54c8fcd205b 100644 --- a/src/libunicode/lib.rs +++ b/src/libunicode/lib.rs @@ -29,6 +29,7 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/nightly/", html_playground_url = "http://play.rust-lang.org/")] +#![feature(no_std)] #![no_std] #![feature(slicing_syntax)] #![feature(int_uint)] @@ -78,7 +79,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; diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs index e99a8f0b877..834667968c8 100644 --- a/src/test/auxiliary/lang-item-public.rs +++ b/src/test/auxiliary/lang-item-public.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(no_std)] #![no_std] #![feature(lang_items)] diff --git a/src/test/auxiliary/no_std_crate.rs b/src/test/auxiliary/no_std_crate.rs index 7cfae6d121d..d830aef54f5 100644 --- a/src/test/auxiliary/no_std_crate.rs +++ b/src/test/auxiliary/no_std_crate.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(no_std)] #![no_std] pub fn foo() {} diff --git a/src/test/auxiliary/weak-lang-items.rs b/src/test/auxiliary/weak-lang-items.rs index 39462fdc1e5..fa254cb91ad 100644 --- a/src/test/auxiliary/weak-lang-items.rs +++ b/src/test/auxiliary/weak-lang-items.rs @@ -13,6 +13,7 @@ // This aux-file will require the eh_personality function to be codegen'd, but // it hasn't been defined just yet. Make sure we don't explode. +#![feature(no_std)] #![no_std] #![crate_type = "rlib"] diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs index b35d5131c78..621f5ec9660 100644 --- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs @@ -13,6 +13,7 @@ #![crate_type = "lib"] #![feature(lang_items)] +#![feature(no_std)] #![no_std] #[lang="sized"] diff --git a/src/test/compile-fail/bad-mid-path-type-params.rs b/src/test/compile-fail/bad-mid-path-type-params.rs index 79fe4e7165e..c91849ca53e 100644 --- a/src/test/compile-fail/bad-mid-path-type-params.rs +++ b/src/test/compile-fail/bad-mid-path-type-params.rs @@ -10,6 +10,7 @@ // ignore-tidy-linelength +#![feature(no_std)] #![no_std] #![feature(lang_items)] diff --git a/src/test/compile-fail/derive-no-std-not-supported.rs b/src/test/compile-fail/derive-no-std-not-supported.rs new file mode 100644 index 00000000000..f82e7f3e36a --- /dev/null +++ b/src/test/compile-fail/derive-no-std-not-supported.rs @@ -0,0 +1,38 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(no_std)] +#![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 }; +} diff --git a/src/test/compile-fail/gated-no-std.rs b/src/test/compile-fail/gated-no-std.rs new file mode 100644 index 00000000000..893ba8a8a86 --- /dev/null +++ b/src/test/compile-fail/gated-no-std.rs @@ -0,0 +1,13 @@ +// Copyright 2105 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![no_std] //~ ERROR no_std is experimental + +fn main() {} diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs index f83037d47bb..14601e67a77 100644 --- a/src/test/compile-fail/issue-19660.rs +++ b/src/test/compile-fail/issue-19660.rs @@ -10,7 +10,7 @@ // error-pattern: requires `copy` lang_item -#![feature(lang_items, start)] +#![feature(lang_items, start, no_std)] #![no_std] #[lang = "sized"] diff --git a/src/test/compile-fail/lang-item-missing.rs b/src/test/compile-fail/lang-item-missing.rs index 61d55fd0964..c7426fc6fc1 100644 --- a/src/test/compile-fail/lang-item-missing.rs +++ b/src/test/compile-fail/lang-item-missing.rs @@ -13,8 +13,8 @@ // error-pattern: requires `sized` lang_item +#![feature(start, no_std)] #![no_std] -#![feature(start)] #[start] fn start(argc: isize, argv: *const *const u8) -> isize { diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs index b1bb28f7ce7..e91e6efd1cb 100644 --- a/src/test/compile-fail/lint-dead-code-1.rs +++ b/src/test/compile-fail/lint-dead-code-1.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(no_std)] #![no_std] #![allow(unused_variables)] #![allow(non_camel_case_types)] diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs index b2ee62ddabe..7ebbcc2809a 100644 --- a/src/test/compile-fail/privacy1.rs +++ b/src/test/compile-fail/privacy1.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, start)] +#![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) #[lang="sized"] diff --git a/src/test/compile-fail/privacy2.rs b/src/test/compile-fail/privacy2.rs index b3d7321edab..7b4a2a3595b 100644 --- a/src/test/compile-fail/privacy2.rs +++ b/src/test/compile-fail/privacy2.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(start)] +#![feature(start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) // Test to make sure that globs don't leak in regular `use` statements. diff --git a/src/test/compile-fail/privacy3.rs b/src/test/compile-fail/privacy3.rs index 245a9c21a6b..8c9de1fa25c 100644 --- a/src/test/compile-fail/privacy3.rs +++ b/src/test/compile-fail/privacy3.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(start)] +#![feature(start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) // Test to make sure that private items imported through globs remain private diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs index e35089b8606..bcb46663aa8 100644 --- a/src/test/compile-fail/privacy4.rs +++ b/src/test/compile-fail/privacy4.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, start)] +#![feature(lang_items, start, no_std)] #![no_std] // makes debugging this test *a lot* easier (during resolve) #[lang = "sized"] pub trait Sized {} diff --git a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs index acc721f26b3..74c2c6e584b 100644 --- a/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs +++ b/src/test/compile-fail/regions-bounded-method-type-parameters-trait-bound.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(lang_items, no_std)] #![no_std] -#![feature(lang_items)] // Check that explicit region bounds are allowed on the various // nominal types (but not on other types) and that they are type diff --git a/src/test/compile-fail/regions-struct-not-wf.rs b/src/test/compile-fail/regions-struct-not-wf.rs index 3de137a9efb..3b8312a3019 100644 --- a/src/test/compile-fail/regions-struct-not-wf.rs +++ b/src/test/compile-fail/regions-struct-not-wf.rs @@ -10,6 +10,7 @@ // Various examples of structs whose fields are not well-formed. +#![feature(no_std)] #![no_std] #![allow(dead_code)] diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs index ae561878e9b..7d252604883 100644 --- a/src/test/compile-fail/required-lang-item.rs +++ b/src/test/compile-fail/required-lang-item.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items)] +#![feature(lang_items, no_std)] #![no_std] #[lang="sized"] pub trait Sized {} diff --git a/src/test/compile-fail/weak-lang-item.rs b/src/test/compile-fail/weak-lang-item.rs index baac192cbf0..42df43934a8 100644 --- a/src/test/compile-fail/weak-lang-item.rs +++ b/src/test/compile-fail/weak-lang-item.rs @@ -13,6 +13,7 @@ // error-pattern: language item required, but not found: `stack_exhausted` // error-pattern: language item required, but not found: `eh_personality` +#![feature(no_std)] #![no_std] extern crate core; diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index cc8337027b0..60660d48274 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -1,3 +1,4 @@ +#![feature(no_std)] #![no_std] #[prelude_import] use std::prelude::v1::*; @@ -41,41 +42,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)]; diff --git a/src/test/run-make/alloc-extern-crates/fakealloc.rs b/src/test/run-make/alloc-extern-crates/fakealloc.rs index 563a527b941..6d30956ab2b 100644 --- a/src/test/run-make/alloc-extern-crates/fakealloc.rs +++ b/src/test/run-make/alloc-extern-crates/fakealloc.rs @@ -9,8 +9,8 @@ // except according to those terms. #![crate_type = "rlib"] +#![feature(no_std, core)] #![no_std] -#![feature(core)] extern crate core; diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make/mismatching-target-triples/bar.rs index ed15e5d880a..8695ab58e5f 100755 --- a/src/test/run-make/mismatching-target-triples/bar.rs +++ b/src/test/run-make/mismatching-target-triples/bar.rs @@ -7,5 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(no_std)] #![no_std] extern crate foo; diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make/mismatching-target-triples/foo.rs index 8afa43710dd..afd4f298a97 100755 --- a/src/test/run-make/mismatching-target-triples/foo.rs +++ b/src/test/run-make/mismatching-target-triples/foo.rs @@ -7,5 +7,6 @@ // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(no_std)] #![no_std] #![crate_type = "lib"] diff --git a/src/test/run-make/no-duplicate-libs/bar.rs b/src/test/run-make/no-duplicate-libs/bar.rs index 11834756105..0bec6148189 100644 --- a/src/test/run-make/no-duplicate-libs/bar.rs +++ b/src/test/run-make/no-duplicate-libs/bar.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(lang_items, no_std)] #![no_std] -#![feature(lang_items)] #![crate_type = "dylib"] extern crate libc; diff --git a/src/test/run-make/no-duplicate-libs/foo.rs b/src/test/run-make/no-duplicate-libs/foo.rs index 61a2a51da08..9e8afdc5696 100644 --- a/src/test/run-make/no-duplicate-libs/foo.rs +++ b/src/test/run-make/no-duplicate-libs/foo.rs @@ -8,8 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![feature(lang_items, no_std)] #![no_std] -#![feature(lang_items)] #![crate_type = "dylib"] extern crate libc; diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs index 6febe2ff7c1..6aff4c9b3d5 100755 --- a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs +++ b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs @@ -9,6 +9,7 @@ // except according to those terms. // minimal junk +#![feature(no_std)] #![no_std] diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make/pretty-expanded-hygiene/input.rs index c31b67b8043..a46fa12ac05 100755 --- a/src/test/run-make/pretty-expanded-hygiene/input.rs +++ b/src/test/run-make/pretty-expanded-hygiene/input.rs @@ -9,6 +9,7 @@ // except according to those terms. // minimal junk +#![feature(no_std)] #![no_std] macro_rules! foo { diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs index 76079ddb8bd..834a2adf01f 100755 --- a/src/test/run-make/simd-ffi/simd.rs +++ b/src/test/run-make/simd-ffi/simd.rs @@ -12,6 +12,7 @@ #![crate_type = "lib"] // we can compile to a variety of platforms, because we don't need // cross-compiled standard libraries. +#![feature(no_std)] #![no_std] #![feature(simd, simd_ffi, link_llvm_intrinsics, lang_items)] @@ -74,7 +75,7 @@ trait Sized {} #[lang = "copy"] trait Copy {} -mod std { +mod core { pub mod marker { pub use Copy; } diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs index fd112034f40..365fc039a4e 100644 --- a/src/test/run-make/target-specs/foo.rs +++ b/src/test/run-make/target-specs/foo.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items)] +#![feature(lang_items, no_std)] #![no_std] #[lang="copy"] diff --git a/src/test/run-pass/derive-no-std.rs b/src/test/run-pass/derive-no-std.rs new file mode 100644 index 00000000000..d3034c2d485 --- /dev/null +++ b/src/test/run-pass/derive-no-std.rs @@ -0,0 +1,41 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(no_std)] +#![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; +} diff --git a/src/test/run-pass/for-loop-no-std.rs b/src/test/run-pass/for-loop-no-std.rs new file mode 100644 index 00000000000..30c2aec33ad --- /dev/null +++ b/src/test/run-pass/for-loop-no-std.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(lang_items, start, no_std)] +#![no_std] + +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 +} diff --git a/src/test/run-pass/format-no-std.rs b/src/test/run-pass/format-no-std.rs new file mode 100644 index 00000000000..44d80490e69 --- /dev/null +++ b/src/test/run-pass/format-no-std.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(lang_items, start, no_std)] +#![no_std] + +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 +} diff --git a/src/test/run-pass/lang-item-public.rs b/src/test/run-pass/lang-item-public.rs index 2d70fa0c819..350ec68a7d1 100644 --- a/src/test/run-pass/lang-item-public.rs +++ b/src/test/run-pass/lang-item-public.rs @@ -12,8 +12,8 @@ // ignore-android // ignore-windows #13361 +#![feature(lang_items, start, no_std)] #![no_std] -#![feature(lang_items, start)] extern crate "lang-item-public" as lang_lib; diff --git a/src/test/run-pass/no-std-xcrate2.rs b/src/test/run-pass/no-std-xcrate2.rs index dcafb5f451f..f5f34607aff 100644 --- a/src/test/run-pass/no-std-xcrate2.rs +++ b/src/test/run-pass/no-std-xcrate2.rs @@ -16,6 +16,7 @@ // This tests that libraries built with #[no_std] can be linked to crates with // #[no_std] and actually run. +#![feature(no_std)] #![no_std] extern crate no_std_crate; diff --git a/src/test/run-pass/smallest-hello-world.rs b/src/test/run-pass/smallest-hello-world.rs index 4913b34c4b3..197890c1277 100644 --- a/src/test/run-pass/smallest-hello-world.rs +++ b/src/test/run-pass/smallest-hello-world.rs @@ -12,8 +12,8 @@ // Smallest "hello world" with a libc runtime +#![feature(intrinsics, lang_items, start, no_std)] #![no_std] -#![feature(intrinsics, lang_items, start)] extern crate libc; diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs index a2e1d8a5671..65a392e63c5 100644 --- a/src/test/run-pass/use.rs +++ b/src/test/run-pass/use.rs @@ -10,7 +10,7 @@ // except according to those terms. #![allow(unused_imports)] -#![feature(start)] +#![feature(start, no_std)] #![no_std] extern crate std; diff --git a/src/test/run-pass/vec-macro-no-std.rs b/src/test/run-pass/vec-macro-no-std.rs index c6c37017349..47b87fce2ab 100644 --- a/src/test/run-pass/vec-macro-no-std.rs +++ b/src/test/run-pass/vec-macro-no-std.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(lang_items, start)] +#![feature(lang_items, start, no_std)] #![no_std] extern crate "std" as other;