mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 04:08:40 +00:00
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:
commit
bf5da36f1d
@ -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
|
||||||
|
@ -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, let’s break it up into multiple files.
|
crate from another crate, let’s 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. It’s often
|
If each crate were just one file, these files would get very large. It’s 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 don’t have their own sub-modules, we’ve 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 don’t have
|
||||||
|
their own sub-modules, we’ve 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. Let’s add some functions.
|
`src/english/farewells.rs`, `src/japanese/greetings.rs` and
|
||||||
|
`src/japanese/farewells.rs` are all empty at the moment. Let’s add
|
||||||
|
some functions.
|
||||||
|
|
||||||
Put this in `src/english/greetings.rs`:
|
Put this in `src/english/greetings.rs`:
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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]
|
||||||
|
@ -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)]`"
|
||||||
}
|
}
|
||||||
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
@ -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:
|
||||||
///
|
///
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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]
|
||||||
|
@ -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() {
|
||||||
|
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user