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

Rollup of 12 pull requests

- Successful merges: #31762, #32538, #32634, #32668, #32679, #32691, #32724, #32727, #32744, #32761, #32766, #32774
- Failed merges:
This commit is contained in:
bors 2016-04-06 13:44:51 -07:00
commit bf5da36f1d
15 changed files with 75 additions and 71 deletions

View File

@ -127,9 +127,7 @@ thread may outlive the scope of `x`, leading to a dangling pointer.
To fix this, we use a `move` closure as mentioned in the error message. `move` To fix this, we use a `move` closure as mentioned in the error message. `move`
closures are explained in depth [here](closures.html#move-closures); basically closures are explained in depth [here](closures.html#move-closures); basically
they move variables from their environment into themselves. This means that `x` they move variables from their environment into themselves.
is now owned by the closure, and cannot be used in `main()` after the call to
`spawn()`.
```rust ```rust
use std::thread; use std::thread;
@ -164,7 +162,7 @@ The same [ownership system](ownership.html) that helps prevent using pointers
incorrectly also helps rule out data races, one of the worst kinds of incorrectly also helps rule out data races, one of the worst kinds of
concurrency bugs. concurrency bugs.
As an example, here is a Rust program that would have a data race in many As an example, here is a Rust program that could have a data race in many
languages. It will not compile: languages. It will not compile:
```ignore ```ignore
@ -197,6 +195,11 @@ thread, and the thread takes ownership of the reference, we'd have three owners!
`data` gets moved out of `main` in the first call to `spawn()`, so subsequent `data` gets moved out of `main` in the first call to `spawn()`, so subsequent
calls in the loop cannot use this variable. calls in the loop cannot use this variable.
Note that this specific example will not cause a data race since different array
indices are being accessed. But this can't be determined at compile time, and in
a similar situation where `i` is a constant or is random, you would have a data
race.
So, we need some type that lets us have more than one owning reference to a So, we need some type that lets us have more than one owning reference to a
value. Usually, we'd use `Rc<T>` for this, which is a reference counted type value. Usually, we'd use `Rc<T>` for this, which is a reference counted type
that provides shared ownership. It has some runtime bookkeeping that keeps track that provides shared ownership. It has some runtime bookkeeping that keeps track

View File

@ -118,7 +118,7 @@ build deps examples libphrases-a7448e02a0468eaa.rlib native
`libphrases-hash.rlib` is the compiled crate. Before we see how to use this `libphrases-hash.rlib` is the compiled crate. Before we see how to use this
crate from another crate, lets break it up into multiple files. crate from another crate, lets break it up into multiple files.
# Multiple file crates # Multiple File Crates
If each crate were just one file, these files would get very large. Its often If each crate were just one file, these files would get very large. Its often
easier to split up crates into multiple files, and Rust supports this in two easier to split up crates into multiple files, and Rust supports this in two
@ -190,13 +190,19 @@ mod farewells;
``` ```
Again, these declarations tell Rust to look for either Again, these declarations tell Rust to look for either
`src/english/greetings.rs` and `src/japanese/greetings.rs` or `src/english/greetings.rs`, `src/english/farewells.rs`,
`src/english/farewells/mod.rs` and `src/japanese/farewells/mod.rs`. Because `src/japanese/greetings.rs` and `src/japanese/farewells.rs` or
these sub-modules dont have their own sub-modules, weve chosen to make them `src/english/greetings/mod.rs`, `src/english/farewells/mod.rs`,
`src/english/greetings.rs` and `src/japanese/farewells.rs`. Whew! `src/japanese/greetings/mod.rs` and
`src/japanese/farewells/mod.rs`. Because these sub-modules dont have
their own sub-modules, weve chosen to make them
`src/english/greetings.rs`, `src/english/farewells.rs`,
`src/japanese/greetings.rs` and `src/japanese/farewells.rs`. Whew!
The contents of `src/english/greetings.rs` and `src/japanese/farewells.rs` are The contents of `src/english/greetings.rs`,
both empty at the moment. Lets add some functions. `src/english/farewells.rs`, `src/japanese/greetings.rs` and
`src/japanese/farewells.rs` are all empty at the moment. Lets add
some functions.
Put this in `src/english/greetings.rs`: Put this in `src/english/greetings.rs`:

View File

@ -56,8 +56,8 @@ To fix this, we have to make sure that step four never happens after step
three. The ownership system in Rust does this through a concept called three. The ownership system in Rust does this through a concept called
lifetimes, which describe the scope that a reference is valid for. lifetimes, which describe the scope that a reference is valid for.
When we have a function that takes a reference by argument, we can be implicit When we have a function that takes an argument by reference, we can be
or explicit about the lifetime of the reference: implicit or explicit about the lifetime of the reference:
```rust ```rust
// implicit // implicit

View File

@ -49,6 +49,18 @@ pub trait ToOwned {
type Owned: Borrow<Self>; type Owned: Borrow<Self>;
/// Creates owned data from borrowed data, usually by cloning. /// Creates owned data from borrowed data, usually by cloning.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// let s = "a"; // &str
/// let ss = s.to_owned(); // String
///
/// let v = &[1, 2]; // slice
/// let vv = v.to_owned(); // Vec
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn to_owned(&self) -> Self::Owned; fn to_owned(&self) -> Self::Owned;
} }

View File

@ -220,7 +220,7 @@ impl<T: ?Sized> *const T {
/// ``` /// ```
/// let s: &str = "Follow the rabbit"; /// let s: &str = "Follow the rabbit";
/// let ptr: *const u8 = s.as_ptr(); /// let ptr: *const u8 = s.as_ptr();
/// assert!(ptr.is_null() == false); /// assert!(!ptr.is_null());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline] #[inline]
@ -306,7 +306,7 @@ impl<T: ?Sized> *mut T {
/// ``` /// ```
/// let mut s = [1, 2, 3]; /// let mut s = [1, 2, 3];
/// let ptr: *mut u32 = s.as_mut_ptr(); /// let ptr: *mut u32 = s.as_mut_ptr();
/// assert!(ptr.is_null() == false); /// assert!(!ptr.is_null());
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline] #[inline]

View File

@ -144,7 +144,7 @@ declare_lint! {
declare_lint! { declare_lint! {
pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN, pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
Deny, Warn,
"constants of struct or enum type can only be used in a pattern if \ "constants of struct or enum type can only be used in a pattern if \
the struct or enum has `#[derive(PartialEq, Eq)]`" the struct or enum has `#[derive(PartialEq, Eq)]`"
} }

View File

@ -51,16 +51,8 @@ impl<'a, 'b, 'tcx:'b> DerefMut for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
// We have information about whether `use` (import) directives are actually // We have information about whether `use` (import) directives are actually
// used now. If an import is not used at all, we signal a lint error. If an // used now. If an import is not used at all, we signal a lint error.
// import is only used for a single namespace, we remove the other namespace fn check_import(&mut self, id: ast::NodeId, span: Span) {
// from the recorded privacy information. That means in privacy.rs, we will
// only check imports and namespaces which are used. In particular, this
// means that if an import could name either a public or private item, we
// will check the correct thing, dependent on how the import is used.
fn finalize_import(&mut self, id: ast::NodeId, span: Span) {
debug!("finalizing import uses for {:?}",
self.session.codemap().span_to_snippet(span));
if !self.used_imports.contains(&(id, TypeNS)) && if !self.used_imports.contains(&(id, TypeNS)) &&
!self.used_imports.contains(&(id, ValueNS)) { !self.used_imports.contains(&(id, ValueNS)) {
self.session.add_lint(lint::builtin::UNUSED_IMPORTS, self.session.add_lint(lint::builtin::UNUSED_IMPORTS,
@ -95,23 +87,16 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
hir::ItemUse(ref p) => { hir::ItemUse(ref p) => {
match p.node { match p.node {
ViewPathSimple(_, _) => { ViewPathSimple(_, _) => {
self.finalize_import(item.id, p.span) self.check_import(item.id, p.span)
} }
ViewPathList(_, ref list) => { ViewPathList(_, ref list) => {
for i in list { for i in list {
self.finalize_import(i.node.id(), i.span); self.check_import(i.node.id(), i.span);
} }
} }
ViewPathGlob(_) => { ViewPathGlob(_) => {
if !self.used_imports.contains(&(item.id, TypeNS)) && self.check_import(item.id, p.span)
!self.used_imports.contains(&(item.id, ValueNS)) {
self.session
.add_lint(lint::builtin::UNUSED_IMPORTS,
item.id,
p.span,
"unused import".to_string());
}
} }
} }
} }

View File

@ -428,10 +428,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
mut val: V) mut val: V)
-> &'a mut V { -> &'a mut V {
let starting_index = bucket.index(); let starting_index = bucket.index();
let size = { let size = bucket.table().size();
let table = bucket.table(); // FIXME "lifetime too short".
table.size()
};
// Save the *starting point*. // Save the *starting point*.
let mut bucket = bucket.stash(); let mut bucket = bucket.stash();
// There can be at most `size - dib` buckets to displace, because // There can be at most `size - dib` buckets to displace, because
@ -744,10 +741,9 @@ impl<K, V, S> HashMap<K, V, S>
let h = bucket.hash(); let h = bucket.hash();
let (b, k, v) = bucket.take(); let (b, k, v) = bucket.take();
self.insert_hashed_ordered(h, k, v); self.insert_hashed_ordered(h, k, v);
{ if b.table().size() == 0 {
let t = b.table(); // FIXME "lifetime too short". break;
if t.size() == 0 { break } }
};
b.into_bucket() b.into_bucket()
} }
Empty(b) => b.into_bucket() Empty(b) => b.into_bucket()

View File

@ -181,7 +181,7 @@ fn _var(key: &OsStr) -> Result<String, VarError> {
} }
/// Fetches the environment variable `key` from the current process, returning /// Fetches the environment variable `key` from the current process, returning
/// None if the variable isn't set. /// `None` if the variable isn't set.
/// ///
/// # Examples /// # Examples
/// ///
@ -617,7 +617,7 @@ pub mod consts {
#[stable(feature = "env", since = "1.0.0")] #[stable(feature = "env", since = "1.0.0")]
pub const ARCH: &'static str = super::arch::ARCH; pub const ARCH: &'static str = super::arch::ARCH;
/// The family of the operating system. In this case, `unix`. /// The family of the operating system. Example value is `unix`.
/// ///
/// Some possible values: /// Some possible values:
/// ///
@ -626,8 +626,8 @@ pub mod consts {
#[stable(feature = "env", since = "1.0.0")] #[stable(feature = "env", since = "1.0.0")]
pub const FAMILY: &'static str = super::os::FAMILY; pub const FAMILY: &'static str = super::os::FAMILY;
/// A string describing the specific operating system in use: in this /// A string describing the specific operating system in use.
/// case, `linux`. /// Example value is `linux`.
/// ///
/// Some possible values: /// Some possible values:
/// ///
@ -646,7 +646,7 @@ pub mod consts {
pub const OS: &'static str = super::os::OS; pub const OS: &'static str = super::os::OS;
/// Specifies the filename prefix used for shared libraries on this /// Specifies the filename prefix used for shared libraries on this
/// platform: in this case, `lib`. /// platform. Example value is `lib`.
/// ///
/// Some possible values: /// Some possible values:
/// ///
@ -656,7 +656,7 @@ pub mod consts {
pub const DLL_PREFIX: &'static str = super::os::DLL_PREFIX; pub const DLL_PREFIX: &'static str = super::os::DLL_PREFIX;
/// Specifies the filename suffix used for shared libraries on this /// Specifies the filename suffix used for shared libraries on this
/// platform: in this case, `.so`. /// platform. Example value is `.so`.
/// ///
/// Some possible values: /// Some possible values:
/// ///
@ -667,7 +667,7 @@ pub mod consts {
pub const DLL_SUFFIX: &'static str = super::os::DLL_SUFFIX; pub const DLL_SUFFIX: &'static str = super::os::DLL_SUFFIX;
/// Specifies the file extension used for shared libraries on this /// Specifies the file extension used for shared libraries on this
/// platform that goes after the dot: in this case, `so`. /// platform that goes after the dot. Example value is `so`.
/// ///
/// Some possible values: /// Some possible values:
/// ///
@ -678,7 +678,7 @@ pub mod consts {
pub const DLL_EXTENSION: &'static str = super::os::DLL_EXTENSION; pub const DLL_EXTENSION: &'static str = super::os::DLL_EXTENSION;
/// Specifies the filename suffix used for executable binaries on this /// Specifies the filename suffix used for executable binaries on this
/// platform: in this case, the empty string. /// platform. Example value is `.exe`.
/// ///
/// Some possible values: /// Some possible values:
/// ///
@ -690,7 +690,7 @@ pub mod consts {
pub const EXE_SUFFIX: &'static str = super::os::EXE_SUFFIX; pub const EXE_SUFFIX: &'static str = super::os::EXE_SUFFIX;
/// Specifies the file extension, if any, used for executable binaries /// Specifies the file extension, if any, used for executable binaries
/// on this platform: in this case, the empty string. /// on this platform. Example value is `exe`.
/// ///
/// Some possible values: /// Some possible values:
/// ///

View File

@ -1708,7 +1708,7 @@ mod tests {
let tmpdir = tmpdir(); let tmpdir = tmpdir();
let dir = &tmpdir.join("fileinfo_false_on_dir"); let dir = &tmpdir.join("fileinfo_false_on_dir");
check!(fs::create_dir(dir)); check!(fs::create_dir(dir));
assert!(dir.is_file() == false); assert!(!dir.is_file());
check!(fs::remove_dir(dir)); check!(fs::remove_dir(dir));
} }

View File

@ -425,10 +425,11 @@ mod prim_str { }
/// ///
/// # Trait implementations /// # Trait implementations
/// ///
/// If every type inside a tuple implements one of the following /// If every type inside a tuple implements one of the following traits, then a
/// traits, then a tuple itself also implements it. /// tuple itself also implements it.
/// ///
/// * [`Clone`] /// * [`Clone`]
/// * [`Copy`]
/// * [`PartialEq`] /// * [`PartialEq`]
/// * [`Eq`] /// * [`Eq`]
/// * [`PartialOrd`] /// * [`PartialOrd`]
@ -438,6 +439,7 @@ mod prim_str { }
/// * [`Hash`] /// * [`Hash`]
/// ///
/// [`Clone`]: clone/trait.Clone.html /// [`Clone`]: clone/trait.Clone.html
/// [`Copy`]: marker/trait.Copy.html
/// [`PartialEq`]: cmp/trait.PartialEq.html /// [`PartialEq`]: cmp/trait.PartialEq.html
/// [`Eq`]: cmp/trait.Eq.html /// [`Eq`]: cmp/trait.Eq.html
/// [`PartialOrd`]: cmp/trait.PartialOrd.html /// [`PartialOrd`]: cmp/trait.PartialOrd.html

View File

@ -1188,12 +1188,12 @@ impl<'a> Parser<'a> {
-> PResult<'a, TyKind> { -> PResult<'a, TyKind> {
/* /*
[unsafe] [extern "ABI"] fn <'lt> (S) -> T [unsafe] [extern "ABI"] fn (S) -> T
^~~~^ ^~~~^ ^~~~^ ^~^ ^ ^~~~^ ^~~~^ ^~^ ^
| | | | | | | | |
| | | | Return type | | | Return type
| | | Argument types | | Argument types
| | Lifetimes | |
| ABI | ABI
Function Style Function Style
*/ */

View File

@ -1509,7 +1509,7 @@ mod tests {
assert_eq!(filtered.len(), 1); assert_eq!(filtered.len(), 1);
assert_eq!(filtered[0].desc.name.to_string(), "1"); assert_eq!(filtered[0].desc.name.to_string(), "1");
assert!(filtered[0].desc.ignore == false); assert!(!filtered[0].desc.ignore);
} }
#[test] #[test]

View File

@ -26,12 +26,12 @@ impl Foo for LocalOverride {
} }
fn test_foo() { fn test_foo() {
assert!(0i8.foo() == false); assert!(!0i8.foo());
assert!(0i32.foo() == false); assert!(!0i32.foo());
assert!(0i64.foo() == true); assert!(0i64.foo());
assert!(LocalDefault.foo() == false); assert!(!LocalDefault.foo());
assert!(LocalOverride.foo() == true); assert!(LocalOverride.foo());
} }
fn test_bar() { fn test_bar() {

View File

@ -35,9 +35,9 @@ impl Foo for i64 {
} }
fn test_foo() { fn test_foo() {
assert!(0i8.foo() == false); assert!(!0i8.foo());
assert!(0i32.foo() == false); assert!(!0i32.foo());
assert!(0i64.foo() == true); assert!(0i64.foo());
} }
// Next, test mixture of explicit `default` and provided methods: // Next, test mixture of explicit `default` and provided methods: