diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c3851dcc8f1..e864172e813 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -174,7 +174,7 @@ labels to triage issues: * Yellow, **A**-prefixed labels state which **area** of the project an issue relates to. -* Magenta, **B**-prefixed labels identify bugs which **belong** elsewhere. +* Magenta, **B**-prefixed labels identify bugs which are **blockers**. * Green, **E**-prefixed labels explain the level of **experience** necessary to fix the issue. diff --git a/src/doc/book/SUMMARY.md b/src/doc/book/SUMMARY.md index 3df791fd51b..fe5e1c3990c 100644 --- a/src/doc/book/SUMMARY.md +++ b/src/doc/book/SUMMARY.md @@ -51,6 +51,7 @@ * [FFI](ffi.md) * [Borrow and AsRef](borrow-and-asref.md) * [Release Channels](release-channels.md) + * [Using Rust without the standard library](using-rust-without-the-standard-library.md) * [Nightly Rust](nightly-rust.md) * [Compiler Plugins](compiler-plugins.md) * [Inline Assembly](inline-assembly.md) diff --git a/src/doc/book/error-handling.md b/src/doc/book/error-handling.md index 1556caaf993..9b1d16170b9 100644 --- a/src/doc/book/error-handling.md +++ b/src/doc/book/error-handling.md @@ -1795,6 +1795,10 @@ To convert this to proper error handling, we need to do the following: Let's try it: ```rust,ignore +use std::error::Error; + +// The rest of the code before this is unchanged + fn search> (file_path: P, city: &str) -> Result, Box> { @@ -1903,8 +1907,13 @@ let city = if !matches.free.is_empty() { return; }; -for pop in search(&data_file, &city) { - println!("{}, {}: {:?}", pop.city, pop.country, pop.count); +match search(&data_file, &city) { + Ok(pops) => { + for pop in pops { + println!("{}, {}: {:?}", pop.city, pop.country, pop.count); + } + } + Err(err) => println!("{}", err) } ... ``` @@ -1927,6 +1936,10 @@ that it is generic on some type parameter `R` that satisfies `io::Read`. Another way is to use trait objects: ```rust,ignore +use std::io; + +// The rest of the code before this is unchanged + fn search> (file_path: &Option

, city: &str) -> Result, Box> { diff --git a/src/doc/book/no-stdlib.md b/src/doc/book/no-stdlib.md index 0b7eec72c91..65beaed2fc7 100644 --- a/src/doc/book/no-stdlib.md +++ b/src/doc/book/no-stdlib.md @@ -1,8 +1,15 @@ % No stdlib -By default, `std` is linked to every Rust crate. In some contexts, -this is undesirable, and can be avoided with the `#![no_std]` -attribute attached to the crate. +Rust’s standard library provides a lot of useful functionality, but assumes +support for various features of its host system: threads, networking, heap +allocation, and others. There are systems that do not have these features, +however, and Rust can work with those too! To do so, we tell Rust that we +don’t want to use the standard library via an attribute: `#![no_std]`. + +> Note: This feature is technically stable, but there are some caveats. For +> one, you can build a `#![no_std]` _library_ on stable, but not a _binary_. +> For details on libraries without the standard library, see [the chapter on +> `#![no_std]`](using-rust-without-the-standard-library.html) Obviously there's more to life than just libraries: one can use `#[no_std]` with an executable, controlling the entry point is @@ -77,89 +84,3 @@ personality function (see the information), but crates which do not trigger a panic can be assured that this function is never called. The second function, `panic_fmt`, is also used by the failure mechanisms of the compiler. - -## Using libcore - -> **Note**: the core library's structure is unstable, and it is recommended to -> use the standard library instead wherever possible. - -With the above techniques, we've got a bare-metal executable running some Rust -code. There is a good deal of functionality provided by the standard library, -however, that is necessary to be productive in Rust. If the standard library is -not sufficient, then [libcore](../core/index.html) is designed to be used -instead. - -The core library has very few dependencies and is much more portable than the -standard library itself. Additionally, the core library has most of the -necessary functionality for writing idiomatic and effective Rust code. When -using `#![no_std]`, Rust will automatically inject the `core` crate, like -we do for `std` when we’re using it. - -As an example, here is a program that will calculate the dot product of two -vectors provided from C, using idiomatic Rust practices. - -```rust -# #![feature(libc)] -#![feature(lang_items)] -#![feature(start)] -#![feature(raw)] -#![no_std] - -extern crate libc; - -use core::mem; - -#[no_mangle] -pub extern fn dot_product(a: *const u32, a_len: u32, - b: *const u32, b_len: u32) -> u32 { - use core::raw::Slice; - - // Convert the provided arrays into Rust slices. - // The core::raw module guarantees that the Slice - // structure has the same memory layout as a &[T] - // slice. - // - // This is an unsafe operation because the compiler - // cannot tell the pointers are valid. - let (a_slice, b_slice): (&[u32], &[u32]) = unsafe { - mem::transmute(( - Slice { data: a, len: a_len as usize }, - Slice { data: b, len: b_len as usize }, - )) - }; - - // Iterate over the slices, collecting the result - let mut ret = 0; - for (i, j) in a_slice.iter().zip(b_slice.iter()) { - ret += (*i) * (*j); - } - return ret; -} - -#[lang = "panic_fmt"] -extern fn panic_fmt(args: &core::fmt::Arguments, - file: &str, - line: u32) -> ! { - loop {} -} - -#[lang = "eh_personality"] extern fn eh_personality() {} -# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 } -# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {} -# #[no_mangle] pub extern fn rust_eh_register_frames () {} -# #[no_mangle] pub extern fn rust_eh_unregister_frames () {} -# fn main() {} -``` - -Note that there is one lang item here whose signature differs from the examples -above, `panic_fmt`. This must be defined by consumers of libcore because the -core library declares panics, but it does not define it. The `panic_fmt` -lang item is this crate's definition of panic, and it must be guaranteed to -never return. - -As can be seen in this example, the core library is intended to provide the -power of Rust in all circumstances, regardless of platform requirements. Further -libraries, such as liballoc, add functionality to libcore which make other -platform-specific assumptions, but continue to be more portable than the -standard library itself. - diff --git a/src/doc/book/the-stack-and-the-heap.md b/src/doc/book/the-stack-and-the-heap.md index 3be4096e971..a7b6faccd8d 100644 --- a/src/doc/book/the-stack-and-the-heap.md +++ b/src/doc/book/the-stack-and-the-heap.md @@ -185,7 +185,7 @@ After `italic()` is over, its frame is deallocated, leaving only `bold()` and | **3** | **c**|**1** | | **2** | **b**|**100**| | **1** | **a**| **5** | -| 0 | x | 42 | +| 0 | x | 42 | And then `bold()` ends, leaving only `main()`: @@ -554,8 +554,8 @@ Managing the memory for the stack is trivial: The machine increments or decrements a single value, the so-called “stack pointer”. Managing memory for the heap is non-trivial: heap-allocated memory is freed at arbitrary points, and each block of heap-allocated memory can be of arbitrary -size, the memory manager must generally work much harder to identify memory for -reuse. +size, so the memory manager must generally work much harder to +identify memory for reuse. If you’d like to dive into this topic in greater detail, [this paper][wilson] is a great introduction. @@ -579,4 +579,3 @@ comes at the cost of either significant runtime support (e.g. in the form of a garbage collector) or significant programmer effort (in the form of explicit memory management calls that require verification not provided by the Rust compiler). - diff --git a/src/doc/book/using-rust-without-the-standard-library.md b/src/doc/book/using-rust-without-the-standard-library.md new file mode 100644 index 00000000000..59182e1a4ef --- /dev/null +++ b/src/doc/book/using-rust-without-the-standard-library.md @@ -0,0 +1,41 @@ +% Using Rust Without the Standard Library + +Rust’s standard library provides a lot of useful functionality, but assumes +support for various features of its host system: threads, networking, heap +allocation, and others. There are systems that do not have these features, +however, and Rust can work with those too! To do so, we tell Rust that we +don’t want to use the standard library via an attribute: `#![no_std]`. + +> Note: This feature is technically stable, but there are some caveats. For +> one, you can build a `#![no_std]` _library_ on stable, but not a _binary_. +> For details on binaries without the standard library, see [the nightly +> chapter on `#![no_std]`](no-stdlib.html) + +To use `#![no_std]`, add a it to your crate root: + +```rust +#![no_std] + +fn plus_one(x: i32) -> i32 { + x + 1 +} +``` + +Much of the functionality that’s exposed in the standard library is also +available via the [`core` crate](../core/). When we’re using the standard +library, Rust automatically brings `std` into scope, allowing you to use +its features without an explicit import. By the same token, when using +`!#[no_std]`, Rust will bring `core` into scope for you, as well as [its +prelude](../core/prelude/v1/). This means that a lot of code will Just Work: + +```rust +#![no_std] + +fn may_fail(failure: bool) -> Result<(), &'static str> { + if failure { + Err("this didn’t work!") + } else { + Ok(()) + } +} +``` diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index efc28be92a4..be140469eb6 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -222,12 +222,12 @@ impl Drop for IntermediateBox { } impl Box { - /// Allocates memory on the heap and then moves `x` into it. + /// Allocates memory on the heap and then places `x` into it. /// /// # Examples /// /// ``` - /// let x = Box::new(5); + /// let five = Box::new(5); /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline(always)] @@ -266,7 +266,7 @@ impl Box { /// # Examples /// /// ``` - /// let seventeen = Box::new(17u32); + /// let seventeen = Box::new(17); /// let raw = Box::into_raw(seventeen); /// let boxed_again = unsafe { Box::from_raw(raw) }; /// ``` diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index ee6e708ea32..fb6dac40798 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -130,7 +130,7 @@ pub fn size_of() -> usize { unsafe { intrinsics::size_of::() } } -/// Returns the size of the type that `val` points to in bytes. +/// Returns the size of the given value in bytes. /// /// # Examples /// diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs index 259f0d390b4..7f57d6dc650 100644 --- a/src/libstd/num/f32.rs +++ b/src/libstd/num/f32.rs @@ -62,7 +62,7 @@ mod cmath { pub fn hypotf(x: c_float, y: c_float) -> c_float; } - // See the comments in `core::float::Float::floor` for why MSVC is special + // See the comments in the `floor` function for why MSVC is special // here. #[cfg(not(target_env = "msvc"))] extern {