Auto merge of #30916 - steveklabnik:rollup, r=steveklabnik
- Successful merges: #30712, #30895, #30902, #30903, #30909, #30910, #30911, #30912, #30914 - Failed merges:
This commit is contained in:
commit
2fb0c5ebcf
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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<P: AsRef<Path>>
|
||||
(file_path: P, city: &str)
|
||||
-> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
|
||||
@ -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<P: AsRef<Path>>
|
||||
(file_path: &Option<P>, city: &str)
|
||||
-> Result<Vec<PopulationCount>, Box<Error+Send+Sync>> {
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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).
|
||||
|
||||
|
41
src/doc/book/using-rust-without-the-standard-library.md
Normal file
41
src/doc/book/using-rust-without-the-standard-library.md
Normal file
@ -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(())
|
||||
}
|
||||
}
|
||||
```
|
@ -222,12 +222,12 @@ fn drop(&mut self) {
|
||||
}
|
||||
|
||||
impl<T> Box<T> {
|
||||
/// 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 @@ pub unsafe fn from_raw(raw: *mut T) -> Self {
|
||||
/// # 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) };
|
||||
/// ```
|
||||
|
@ -130,7 +130,7 @@ pub fn size_of<T>() -> usize {
|
||||
unsafe { intrinsics::size_of::<T>() }
|
||||
}
|
||||
|
||||
/// Returns the size of the type that `val` points to in bytes.
|
||||
/// Returns the size of the given value in bytes.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user