Skip to content

Rollup of 9 pull requests #28886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8e420e0
trpl: Clarify closure terminology
chills42 Oct 6, 2015
a78a874
possessive its
chills42 Oct 6, 2015
7895ec2
address review concerns
chills42 Oct 6, 2015
836be40
doc: Mention split_whitespace in split doc
JIghtuse Oct 6, 2015
9a38747
book: Add documentation on custom allocators
alexcrichton Oct 6, 2015
4d40dd3
Restore line endings in a test
steveklabnik Oct 7, 2015
d21b4f5
Use the correct mod name from the example
id4ho Oct 4, 2015
cbf97c3
style guide: suggest manual links to constructors
sourcefrog Oct 7, 2015
03dfe89
Fix a typo
ykomatsu Oct 7, 2015
8fee548
Add new error code
GuillaumeGomez Oct 6, 2015
a94f684
Add error explanation for E0515
GuillaumeGomez Oct 6, 2015
e84461a
Alter formatting for words in Option::cloned doc comment
frewsxcv Oct 7, 2015
a5f3f89
Rollup merge of #28836 - jackwilsonv:patch-6, r=steveklabnik
steveklabnik Oct 7, 2015
1516893
Rollup merge of #28856 - chills42:master, r=steveklabnik
steveklabnik Oct 7, 2015
809ee09
Rollup merge of #28868 - JIghtuse:str_doc, r=steveklabnik
steveklabnik Oct 7, 2015
e5f272e
Rollup merge of #28869 - alexcrichton:allocator-dox, r=steveklabnik
steveklabnik Oct 7, 2015
3ec38c8
Rollup merge of #28874 - GuillaumeGomez:error_code, r=Manishearth
steveklabnik Oct 7, 2015
66a4fc8
Rollup merge of #28876 - steveklabnik:oops, r=Gankro
steveklabnik Oct 7, 2015
d21f448
Rollup merge of #28878 - sourcefrog:doc-links, r=steveklabnik
steveklabnik Oct 7, 2015
a4774c2
Rollup merge of #28882 - ykomatsu:trpl, r=steveklabnik
steveklabnik Oct 7, 2015
917489c
Rollup merge of #28885 - frewsxcv:patch-25, r=steveklabnik
steveklabnik Oct 7, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/doc/style/style/comments.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,20 @@ Use inner doc comments _only_ to document crates and file-level modules:
//!
//! The core library is a something something...
```

### Explain context.

Rust doesn't have special constructors, only functions that return new
instances. These aren't visible in the automatically generated documentation
for a type, so you should specifically link to them:

``` rust
/// An iterator that yields `None` forever after the underlying iterator
/// yields `None` once.
///
/// These can be created through
/// [`iter.fuse()`](trait.Iterator.html#method.fuse).
pub struct Fuse<I> {
// ...
}
```
1 change: 1 addition & 0 deletions src/doc/trpl/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,6 @@
* [Box Syntax and Patterns](box-syntax-and-patterns.md)
* [Slice Patterns](slice-patterns.md)
* [Associated Constants](associated-constants.md)
* [Custom Allocators](custom-allocators.md)
* [Glossary](glossary.md)
* [Bibliography](bibliography.md)
4 changes: 2 additions & 2 deletions src/doc/trpl/advanced-linking.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ shells out to the system linker (`gcc` on most systems, `link.exe` on MSVC),
so it makes sense to provide extra command line
arguments, but this will not always be the case. In the future `rustc` may use
LLVM directly to link native libraries, in which case `link_args` will have no
meaning. You can achieve the same effect as the `link-args` attribute with the
meaning. You can achieve the same effect as the `link_args` attribute with the
`-C link-args` argument to `rustc`.

It is highly recommended to *not* use this attribute, and rather use the more
Expand Down Expand Up @@ -71,7 +71,7 @@ Dynamic linking on Linux can be undesirable if you wish to use new library
features on old systems or target systems which do not have the required
dependencies for your program to run.

Static linking is supported via an alternative `libc`, `musl`. You can compile
Static linking is supported via an alternative `libc`, [`musl`](http://www.musl-libc.org). You can compile
your own version of Rust with `musl` enabled and install it into a custom
directory with the instructions below:

Expand Down
45 changes: 24 additions & 21 deletions src/doc/trpl/closures.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
% Closures

Rust not only has named functions, but anonymous functions as well. Anonymous
functions that have an associated environment are called ‘closures’, because they
close over an environment. Rust has a really great implementation of them, as
we’ll see.
Sometimes it is useful to wrap up a function and _free variables_ for better
clarity and reuse. The free variables that can be used come from the
enclosing scope and are ‘closed over’ when used in the function. From this, we
get the name ‘closures’ and Rust provides a really great implementation of
them, as we’ll see.

# Syntax

Expand Down Expand Up @@ -34,7 +35,7 @@ assert_eq!(4, plus_two(2));
```

You’ll notice a few things about closures that are a bit different from regular
functions defined with `fn`. The first is that we did not need to
named functions defined with `fn`. The first is that we did not need to
annotate the types of arguments the closure takes or the values it returns. We
can:

Expand All @@ -44,14 +45,15 @@ let plus_one = |x: i32| -> i32 { x + 1 };
assert_eq!(2, plus_one(1));
```

But we don’t have to. Why is this? Basically, it was chosen for ergonomic reasons.
While specifying the full type for named functions is helpful with things like
documentation and type inference, the types of closures are rarely documented
since they’re anonymous, and they don’t cause the kinds of error-at-a-distance
problems that inferring named function types can.
But we don’t have to. Why is this? Basically, it was chosen for ergonomic
reasons. While specifying the full type for named functions is helpful with
things like documentation and type inference, the full type signatures of
closures are rarely documented since they’re anonymous, and they don’t cause
the kinds of error-at-a-distance problems that inferring named function types
can.

The second is that the syntax is similar, but a bit different. I’ve added spaces
here for easier comparison:
The second is that the syntax is similar, but a bit different. I’ve added
spaces here for easier comparison:

```rust
fn plus_one_v1 (x: i32) -> i32 { x + 1 }
Expand All @@ -63,8 +65,8 @@ Small differences, but they’re similar.

# Closures and their environment

Closures are called such because they ‘close over their environment’. It
looks like this:
The environment for a closure can include bindings from its enclosing scope in
addition to parameters and local bindings. It looks like this:

```rust
let num = 5;
Expand Down Expand Up @@ -197,9 +199,10 @@ frame. Without `move`, a closure may be tied to the stack frame that created
it, while a `move` closure is self-contained. This means that you cannot
generally return a non-`move` closure from a function, for example.

But before we talk about taking and returning closures, we should talk some more
about the way that closures are implemented. As a systems language, Rust gives
you tons of control over what your code does, and closures are no different.
But before we talk about taking and returning closures, we should talk some
more about the way that closures are implemented. As a systems language, Rust
gives you tons of control over what your code does, and closures are no
different.

# Closure implementation

Expand Down Expand Up @@ -288,9 +291,9 @@ isn’t interesting. The next part is:
# some_closure(1) }
```

Because `Fn` is a trait, we can bound our generic with it. In this case, our closure
takes a `i32` as an argument and returns an `i32`, and so the generic bound we use
is `Fn(i32) -> i32`.
Because `Fn` is a trait, we can bound our generic with it. In this case, our
closure takes a `i32` as an argument and returns an `i32`, and so the generic
bound we use is `Fn(i32) -> i32`.

There’s one other key point here: because we’re bounding a generic with a
trait, this will get monomorphized, and therefore, we’ll be doing static
Expand Down Expand Up @@ -452,7 +455,7 @@ autogenerated name.
The error also points out that the return type is expected to be a reference,
but what we are trying to return is not. Further, we cannot directly assign a
`'static` lifetime to an object. So we'll take a different approach and return
a "trait object" by `Box`ing up the `Fn`. This _almost_ works:
a trait object by `Box`ing up the `Fn`. This _almost_ works:

```rust,ignore
fn factory() -> Box<Fn(i32) -> i32> {
Expand Down
4 changes: 2 additions & 2 deletions src/doc/trpl/crates-and-modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,8 @@ What's going on here?
First, both `extern crate` and `use` allow renaming the thing that is being
imported. So the crate is still called "phrases", but here we will refer
to it as "sayings". Similarly, the first `use` statement pulls in the
`japanese::farewells` module from the crate, but makes it available as
`jp_farewells` as opposed to simply `farewells`. This can help to avoid
`japanese::greetings` module from the crate, but makes it available as
`ja_greetings` as opposed to simply `greetings`. This can help to avoid
ambiguity when importing similarly-named items from different places.

The second `use` statement uses a star glob to bring in _all_ symbols from the
Expand Down
169 changes: 169 additions & 0 deletions src/doc/trpl/custom-allocators.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
% Custom Allocators

Allocating memory isn't always the easiest thing to do, and while Rust generally
takes care of this by default it often becomes necessary to customize how
allocation occurs. The compiler and standard library currently allow switching
out the default global allocator in use at compile time. The design is currently
spelled out in [RFC 1183][rfc] but this will walk you through how to get your
own allocator up and running.

[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1183-swap-out-jemalloc.md

# Default Allocator

The compiler currently ships two default allocators: `alloc_system` and
`alloc_jemalloc` (some targets don't have jemalloc, however). These allocators
are just normal Rust crates and contain an implementation of the routines to
allocate and deallocate memory. The standard library is not compiled assuming
either one, and the compiler will decide which allocator is in use at
compile-time depending on the type of output artifact being produced.

Binaries generated by the compiler will use `alloc_jemalloc` by default (where
available). In this situation the compiler "controls the world" in the sense of
it has power over the final link. Primarily this means that the allocator
decision can be left up the compiler.

Dynamic and static libraries, however, will use `alloc_system` by default. Here
Rust is typically a 'guest' in another application or another world where it
cannot authoritatively decide what allocator is in use. As a result it resorts
back to the standard APIs (e.g. `malloc` and `free`) for acquiring and releasing
memory.

# Switching Allocators

Although the compiler's default choices may work most of the time, it's often
necessary to tweak certain aspects. Overriding the compiler's decision about
which allocator is in use is done simply by linking to the desired allocator:

```rust,no_run
#![feature(alloc_system)]

extern crate alloc_system;

fn main() {
let a = Box::new(4); // allocates from the system allocator
println!("{}", a);
}
```

In this example the binary generated will not link to jemalloc by default but
instead use the system allocator. Conversely to generate a dynamic library which
uses jemalloc by default one would write:

```rust,no_run
#![feature(alloc_jemalloc)]
#![crate_type = "dylib"]

extern crate alloc_jemalloc;

pub fn foo() {
let a = Box::new(4); // allocates from jemalloc
println!("{}", a);
}
# fn main() {}
```

# Writing a custom allocator

Sometimes even the choices of jemalloc vs the system allocator aren't enough and
an entirely new custom allocator is required. In this you'll write your own
crate which implements the allocator API (e.g. the same as `alloc_system` or
`alloc_jemalloc`). As an example, let's take a look at a simplified and
annotated version of `alloc_system`

```rust,no_run
# // only needed for rustdoc --test down below
# #![feature(lang_items)]
// The compiler needs to be instructed that this crate is an allocator in order
// to realize that when this is linked in another allocator like jemalloc should
// not be linked in
#![feature(allocator)]
#![allocator]

// Allocators are not allowed to depend on the standard library which in turn
// requires an allocator in order to avoid circular dependencies. This crate,
// however, can use all of libcore.
#![feature(no_std)]
#![no_std]

// Let's give a unique name to our custom allocator
#![crate_name = "my_allocator"]
#![crate_type = "rlib"]

// Our system allocator will use the in-tree libc crate for FFI bindings. Note
// that currently the external (crates.io) libc cannot be used because it links
// to the standard library (e.g. `#![no_std]` isn't stable yet), so that's why
// this specifically requires the in-tree version.
#![feature(libc)]
extern crate libc;

// Listed below are the five allocation functions currently required by custom
// allocators. Their signatures and symbol names are not currently typechecked
// by the compiler, but this is a future extension and are required to match
// what is found below.
//
// Note that the standard `malloc` and `realloc` functions do not provide a way
// to communicate alignment so this implementation would need to be improved
// with respect to alignment in that aspect.

#[no_mangle]
pub extern fn __rust_allocate(size: usize, _align: usize) -> *mut u8 {
unsafe { libc::malloc(size as libc::size_t) as *mut u8 }
}

#[no_mangle]
pub extern fn __rust_deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
unsafe { libc::free(ptr as *mut libc::c_void) }
}

#[no_mangle]
pub extern fn __rust_reallocate(ptr: *mut u8, _old_size: usize, size: usize,
_align: usize) -> *mut u8 {
unsafe {
libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8
}
}

#[no_mangle]
pub extern fn __rust_reallocate_inplace(_ptr: *mut u8, old_size: usize,
_size: usize, _align: usize) -> usize {
old_size // this api is not supported by libc
}

#[no_mangle]
pub extern fn __rust_usable_size(size: usize, _align: usize) -> usize {
size
}

# // just needed to get rustdoc to test this
# fn main() {}
# #[lang = "panic_fmt"] fn panic_fmt() {}
# #[lang = "eh_personality"] fn eh_personality() {}
```

After we compile this crate, it can be used as follows:

```rust,ignore
extern crate my_allocator;

fn main() {
let a = Box::new(8); // allocates memory via our custom allocator crate
println!("{}", a);
}
```

# Custom allocator limitations

There are a few restrictions when working with custom allocators which may cause
compiler errors:

* Any one artifact may only be linked to at most one allocator. Binaries,
dylibs, and staticlibs must link to exactly one allocator, and if none have
been explicitly chosen the compiler will choose one. On the other than rlibs
do not need to link to an allocator (but still can).

* A consumer of an allocator is tagged with `#![needs_allocator]` (e.g. the
`liballoc` crate currently) and an `#[allocator]` crate cannot transitively
depend on a crate which needs an allocator (e.g. circular dependencies are not
allowed). This basically means that allocators must restrict themselves to
libcore currently.
4 changes: 4 additions & 0 deletions src/libcollections/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,10 @@ impl str {
/// ```rust,ignore
/// assert_eq!(d, &["a", "b", "c"]);
/// ```
///
/// Use [`.split_whitespace()`][split_whitespace] for this behavior.
///
/// [split_whitespace]: #method.split_whitespace
#[stable(feature = "rust1", since = "1.0.0")]
pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
core_str::StrExt::split(self, pat)
Expand Down
3 changes: 2 additions & 1 deletion src/libcore/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,8 @@ impl<T> Option<T> {
}

impl<'a, T: Clone> Option<&'a T> {
/// Maps an Option<&T> to an Option<T> by cloning the contents of the Option.
/// Maps an `Option<&T>` to an `Option<T>` by cloning the contents of the
/// option.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn cloned(self) -> Option<T> {
self.map(|t| t.clone())
Expand Down
15 changes: 15 additions & 0 deletions src/librustc_trans/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,21 @@

register_long_diagnostics! {

E0515: r##"
A constant index expression was out of bounds. Erroneous code example:

```
let x = &[0, 1, 2][7]; // error: const index-expr is out of bounds
```

Please specify a valid index (not inferior to 0 or superior to array length).
Example:

```
let x = &[0, 1, 2][2]; // ok!
```
"##,

}

register_diagnostics! {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -628,8 +628,8 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
if iv >= len {
// FIXME #3170: report this earlier on in the const-eval
// pass. Reporting here is a bit late.
cx.sess().span_err(e.span,
"const index-expr is out of bounds");
span_err!(cx.sess(), e.span, E0515,
"const index-expr is out of bounds");
C_undef(val_ty(arr).element_type())
} else {
const_get_elt(cx, arr, &[iv as c_uint])
Expand Down
Loading