Auto merge of #33081 - steveklabnik:rollup, r=steveklabnik

Rollup of 6 pull requests

- Successful merges: #32558, #32906, #33007, #33008, #33035, #33058
- Failed merges: #32912
This commit is contained in:
bors 2016-04-18 12:03:14 -07:00
commit b324fa7204
9 changed files with 74 additions and 52 deletions

View File

@ -140,9 +140,9 @@ Cargo
Performance
-----------
* [During type unification, the complexity of comparing variables for
equivalance was reduced from `O(n!)` to `O(n)`][1.9tu]. This leads
to major compile-time improvements in some scenarios.
* [The time complexity of comparing variables for equivalence during type
unification is reduced from _O_(_n_!) to _O_(_n_)][1.9tu]. This leads
to major compilation time improvement in some scenarios.
* [`ToString` is specialized for `str`, giving it the same performance
as `to_owned`][1.9ts].
* [Spawning processes with `Command::output` no longer creates extra

View File

@ -24,18 +24,16 @@ changed from one `i32` to another.
[vb]: variable-bindings.html
If you want to change what the binding points to, youll need a [mutable reference][mr]:
You can also create a [reference][ref] to it, using `&x`, but if you want to use the reference to change it, you will need a mutable reference:
```rust
let mut x = 5;
let y = &mut x;
```
[mr]: references-and-borrowing.html
[ref]: references-and-borrowing.html
`y` is an immutable binding to a mutable reference, which means that you cant
bind `y` to something else (`y = &mut z`), but you can mutate the thing thats
bound to `y` (`*y = 5`). A subtle distinction.
`y` is an immutable binding to a mutable reference, which means that you cant bind 'y' to something else (`y = &mut z`), but `y` can be used to bind `x` to something else (`*y = 5`). A subtle distinction.
Of course, if you need both:

View File

@ -173,11 +173,11 @@ For example if we truncated the vector to just two elements through `v2`:
v2.truncate(2);
```
and `v1` were still accessible we'd end up with an invalid vector since `v1`
and `v` were still accessible we'd end up with an invalid vector since `v`
would not know that the heap data has been truncated. Now, the part of the
vector `v1` on the stack does not agree with the corresponding part on the
heap. `v1` still thinks there are three elements in the vector and will
happily let us access the non existent element `v1[2]` but as you might
vector `v` on the stack does not agree with the corresponding part on the
heap. `v` still thinks there are three elements in the vector and will
happily let us access the non existent element `v[2]` but as you might
already know this is a recipe for disaster. Especially because it might lead
to a segmentation fault or worse allow an unauthorized user to read from
memory to which they don't have access.

View File

@ -97,9 +97,10 @@ and `i64` is a signed, 64-bit integer.
## Variable-size types
Rust also provides types whose size depends on the size of a pointer of the
underlying machine. These types have size as the category, and come in signed
and unsigned varieties. This makes for two types: `isize` and `usize`.
Rust also provides types whose particular size depends on the underlying machine
architecture. Their range is sufficient to express the size of any collection, so
these types have size as the category. They come in signed and unsigned varieties
which account for two types: `isize` and `usize`.
## Floating-point types

View File

@ -1420,45 +1420,24 @@ fn main() {
"##,
E0102: r##"
You hit this error because the compiler lacks information to
determine a type for this variable. Erroneous code example:
You hit this error because the compiler lacks the information to
determine the type of this variable. Erroneous code example:
```compile_fail
fn demo(devil: fn () -> !) {
let x: &_ = devil();
// error: cannot determine a type for this local variable
}
fn oh_no() -> ! { panic!("the devil is in the details") }
fn main() {
demo(oh_no);
// could be an array of anything
let x = []; // error: cannot determine a type for this local variable
}
```
To solve this situation, constrain the type of the variable.
Examples:
```no_run
```
#![allow(unused_variables)]
fn some_func(x: &u32) {
// some code
}
fn demo(devil: fn () -> !) {
let x: &u32 = devil();
// Here we defined the type at the variable creation
let x: &_ = devil();
some_func(x);
// Here, the type is determined by the function argument type
}
fn oh_no() -> ! { panic!("the devil is in the details") }
fn main() {
demo(oh_no);
let x: [u8; 0] = [];
}
```
"##,

View File

@ -1518,6 +1518,13 @@ impl Type {
_ => None,
}
}
pub fn trait_name(&self) -> Option<String> {
match *self {
ResolvedPath { ref path, .. } => Some(path.last_name()),
_ => None,
}
}
}
impl GetDefId for Type {
@ -2009,6 +2016,10 @@ impl Path {
}]
}
}
pub fn last_name(&self) -> String {
self.segments.last().unwrap().name.clone()
}
}
impl Clean<Path> for hir::Path {

View File

@ -561,19 +561,33 @@ impl fmt::Display for clean::Type {
}
}
fn fmt_impl(i: &clean::Impl, f: &mut fmt::Formatter, link_trait: bool) -> fmt::Result {
write!(f, "impl{} ", i.generics)?;
if let Some(ref ty) = i.trait_ {
write!(f, "{}",
if i.polarity == Some(clean::ImplPolarity::Negative) { "!" } else { "" })?;
if link_trait {
write!(f, "{}", *ty)?;
} else {
write!(f, "{}", ty.trait_name().unwrap())?;
}
write!(f, " for ")?;
}
write!(f, "{}{}", i.for_, WhereClause(&i.generics))?;
Ok(())
}
impl fmt::Display for clean::Impl {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "impl{} ", self.generics)?;
if let Some(ref ty) = self.trait_ {
write!(f, "{}{} for ",
if self.polarity == Some(clean::ImplPolarity::Negative) { "!" } else { "" },
*ty)?;
}
write!(f, "{}{}", self.for_, WhereClause(&self.generics))?;
Ok(())
fmt_impl(self, f, true)
}
}
// The difference from above is that trait is not hyperlinked.
pub fn fmt_impl_for_trait_page(i: &clean::Impl, f: &mut fmt::Formatter) -> fmt::Result {
fmt_impl(i, f, false)
}
impl fmt::Display for clean::Arguments {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (i, input) in self.values.iter().enumerate() {
@ -667,7 +681,7 @@ impl fmt::Display for clean::Import {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
clean::SimpleImport(ref name, ref src) => {
if *name == src.path.segments.last().unwrap().name {
if *name == src.path.last_name() {
write!(f, "use {};", *src)
} else {
write!(f, "use {} as {};", *src, *name)

View File

@ -69,6 +69,7 @@ use html::escape::Escape;
use html::format::{ConstnessSpace};
use html::format::{TyParamBounds, WhereClause, href, AbiSpace};
use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
use html::format::fmt_impl_for_trait_page;
use html::item_type::ItemType;
use html::markdown::{self, Markdown};
use html::{highlight, layout};
@ -2010,7 +2011,9 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
match cache.implementors.get(&it.def_id) {
Some(implementors) => {
for i in implementors {
writeln!(w, "<li><code>{}</code></li>", i.impl_)?;
write!(w, "<li><code>")?;
fmt_impl_for_trait_page(&i.impl_, w)?;
writeln!(w, "</code></li>")?;
}
}
None => {}

View File

@ -0,0 +1,16 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// @!has trait_self_link/trait.Foo.html //a/@href ../trait_self_link/trait.Foo.html
pub trait Foo {}
pub struct Bar;
impl Foo for Bar {}