mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-07 20:58:39 +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`
|
||||
closures are explained in depth [here](closures.html#move-closures); basically
|
||||
they move variables from their environment into themselves. This means that `x`
|
||||
is now owned by the closure, and cannot be used in `main()` after the call to
|
||||
`spawn()`.
|
||||
they move variables from their environment into themselves.
|
||||
|
||||
```rust
|
||||
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
|
||||
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:
|
||||
|
||||
```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
|
||||
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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
`src/english/greetings.rs` and `src/japanese/greetings.rs` or
|
||||
`src/english/farewells/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` and `src/japanese/farewells.rs`. Whew!
|
||||
`src/english/greetings.rs`, `src/english/farewells.rs`,
|
||||
`src/japanese/greetings.rs` and `src/japanese/farewells.rs` or
|
||||
`src/english/greetings/mod.rs`, `src/english/farewells/mod.rs`,
|
||||
`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
|
||||
both empty at the moment. Let’s add some functions.
|
||||
The contents of `src/english/greetings.rs`,
|
||||
`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`:
|
||||
|
||||
|
@ -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
|
||||
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
|
||||
or explicit about the lifetime of the reference:
|
||||
When we have a function that takes an argument by reference, we can be
|
||||
implicit or explicit about the lifetime of the reference:
|
||||
|
||||
```rust
|
||||
// implicit
|
||||
|
@ -49,6 +49,18 @@ pub trait ToOwned {
|
||||
type Owned: Borrow<Self>;
|
||||
|
||||
/// 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")]
|
||||
fn to_owned(&self) -> Self::Owned;
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ impl<T: ?Sized> *const T {
|
||||
/// ```
|
||||
/// let s: &str = "Follow the rabbit";
|
||||
/// let ptr: *const u8 = s.as_ptr();
|
||||
/// assert!(ptr.is_null() == false);
|
||||
/// assert!(!ptr.is_null());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
@ -306,7 +306,7 @@ impl<T: ?Sized> *mut T {
|
||||
/// ```
|
||||
/// let mut s = [1, 2, 3];
|
||||
/// let ptr: *mut u32 = s.as_mut_ptr();
|
||||
/// assert!(ptr.is_null() == false);
|
||||
/// assert!(!ptr.is_null());
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
|
@ -144,7 +144,7 @@ declare_lint! {
|
||||
|
||||
declare_lint! {
|
||||
pub ILLEGAL_STRUCT_OR_ENUM_CONSTANT_PATTERN,
|
||||
Deny,
|
||||
Warn,
|
||||
"constants of struct or enum type can only be used in a pattern if \
|
||||
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> {
|
||||
// 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
|
||||
// import is only used for a single namespace, we remove the other namespace
|
||||
// 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));
|
||||
|
||||
// used now. If an import is not used at all, we signal a lint error.
|
||||
fn check_import(&mut self, id: ast::NodeId, span: Span) {
|
||||
if !self.used_imports.contains(&(id, TypeNS)) &&
|
||||
!self.used_imports.contains(&(id, ValueNS)) {
|
||||
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) => {
|
||||
match p.node {
|
||||
ViewPathSimple(_, _) => {
|
||||
self.finalize_import(item.id, p.span)
|
||||
self.check_import(item.id, p.span)
|
||||
}
|
||||
|
||||
ViewPathList(_, ref list) => {
|
||||
for i in list {
|
||||
self.finalize_import(i.node.id(), i.span);
|
||||
self.check_import(i.node.id(), i.span);
|
||||
}
|
||||
}
|
||||
ViewPathGlob(_) => {
|
||||
if !self.used_imports.contains(&(item.id, TypeNS)) &&
|
||||
!self.used_imports.contains(&(item.id, ValueNS)) {
|
||||
self.session
|
||||
.add_lint(lint::builtin::UNUSED_IMPORTS,
|
||||
item.id,
|
||||
p.span,
|
||||
"unused import".to_string());
|
||||
}
|
||||
self.check_import(item.id, p.span)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,10 +428,7 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>,
|
||||
mut val: V)
|
||||
-> &'a mut V {
|
||||
let starting_index = bucket.index();
|
||||
let size = {
|
||||
let table = bucket.table(); // FIXME "lifetime too short".
|
||||
table.size()
|
||||
};
|
||||
let size = bucket.table().size();
|
||||
// Save the *starting point*.
|
||||
let mut bucket = bucket.stash();
|
||||
// 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 (b, k, v) = bucket.take();
|
||||
self.insert_hashed_ordered(h, k, v);
|
||||
{
|
||||
let t = b.table(); // FIXME "lifetime too short".
|
||||
if t.size() == 0 { break }
|
||||
};
|
||||
if b.table().size() == 0 {
|
||||
break;
|
||||
}
|
||||
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
|
||||
/// None if the variable isn't set.
|
||||
/// `None` if the variable isn't set.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -617,7 +617,7 @@ pub mod consts {
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
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:
|
||||
///
|
||||
@ -626,8 +626,8 @@ pub mod consts {
|
||||
#[stable(feature = "env", since = "1.0.0")]
|
||||
pub const FAMILY: &'static str = super::os::FAMILY;
|
||||
|
||||
/// A string describing the specific operating system in use: in this
|
||||
/// case, `linux`.
|
||||
/// A string describing the specific operating system in use.
|
||||
/// Example value is `linux`.
|
||||
///
|
||||
/// Some possible values:
|
||||
///
|
||||
@ -646,7 +646,7 @@ pub mod consts {
|
||||
pub const OS: &'static str = super::os::OS;
|
||||
|
||||
/// Specifies the filename prefix used for shared libraries on this
|
||||
/// platform: in this case, `lib`.
|
||||
/// platform. Example value is `lib`.
|
||||
///
|
||||
/// Some possible values:
|
||||
///
|
||||
@ -656,7 +656,7 @@ pub mod consts {
|
||||
pub const DLL_PREFIX: &'static str = super::os::DLL_PREFIX;
|
||||
|
||||
/// Specifies the filename suffix used for shared libraries on this
|
||||
/// platform: in this case, `.so`.
|
||||
/// platform. Example value is `.so`.
|
||||
///
|
||||
/// Some possible values:
|
||||
///
|
||||
@ -667,7 +667,7 @@ pub mod consts {
|
||||
pub const DLL_SUFFIX: &'static str = super::os::DLL_SUFFIX;
|
||||
|
||||
/// 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:
|
||||
///
|
||||
@ -678,7 +678,7 @@ pub mod consts {
|
||||
pub const DLL_EXTENSION: &'static str = super::os::DLL_EXTENSION;
|
||||
|
||||
/// 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:
|
||||
///
|
||||
@ -690,7 +690,7 @@ pub mod consts {
|
||||
pub const EXE_SUFFIX: &'static str = super::os::EXE_SUFFIX;
|
||||
|
||||
/// 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:
|
||||
///
|
||||
|
@ -1708,7 +1708,7 @@ mod tests {
|
||||
let tmpdir = tmpdir();
|
||||
let dir = &tmpdir.join("fileinfo_false_on_dir");
|
||||
check!(fs::create_dir(dir));
|
||||
assert!(dir.is_file() == false);
|
||||
assert!(!dir.is_file());
|
||||
check!(fs::remove_dir(dir));
|
||||
}
|
||||
|
||||
|
@ -425,10 +425,11 @@ mod prim_str { }
|
||||
///
|
||||
/// # Trait implementations
|
||||
///
|
||||
/// If every type inside a tuple implements one of the following
|
||||
/// traits, then a tuple itself also implements it.
|
||||
/// If every type inside a tuple implements one of the following traits, then a
|
||||
/// tuple itself also implements it.
|
||||
///
|
||||
/// * [`Clone`]
|
||||
/// * [`Copy`]
|
||||
/// * [`PartialEq`]
|
||||
/// * [`Eq`]
|
||||
/// * [`PartialOrd`]
|
||||
@ -438,6 +439,7 @@ mod prim_str { }
|
||||
/// * [`Hash`]
|
||||
///
|
||||
/// [`Clone`]: clone/trait.Clone.html
|
||||
/// [`Copy`]: marker/trait.Copy.html
|
||||
/// [`PartialEq`]: cmp/trait.PartialEq.html
|
||||
/// [`Eq`]: cmp/trait.Eq.html
|
||||
/// [`PartialOrd`]: cmp/trait.PartialOrd.html
|
||||
|
@ -1188,12 +1188,12 @@ impl<'a> Parser<'a> {
|
||||
-> PResult<'a, TyKind> {
|
||||
/*
|
||||
|
||||
[unsafe] [extern "ABI"] fn <'lt> (S) -> T
|
||||
^~~~^ ^~~~^ ^~~~^ ^~^ ^
|
||||
| | | | |
|
||||
| | | | Return type
|
||||
| | | Argument types
|
||||
| | Lifetimes
|
||||
[unsafe] [extern "ABI"] fn (S) -> T
|
||||
^~~~^ ^~~~^ ^~^ ^
|
||||
| | | |
|
||||
| | | Return type
|
||||
| | Argument types
|
||||
| |
|
||||
| ABI
|
||||
Function Style
|
||||
*/
|
||||
|
@ -1509,7 +1509,7 @@ mod tests {
|
||||
|
||||
assert_eq!(filtered.len(), 1);
|
||||
assert_eq!(filtered[0].desc.name.to_string(), "1");
|
||||
assert!(filtered[0].desc.ignore == false);
|
||||
assert!(!filtered[0].desc.ignore);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -26,12 +26,12 @@ impl Foo for LocalOverride {
|
||||
}
|
||||
|
||||
fn test_foo() {
|
||||
assert!(0i8.foo() == false);
|
||||
assert!(0i32.foo() == false);
|
||||
assert!(0i64.foo() == true);
|
||||
assert!(!0i8.foo());
|
||||
assert!(!0i32.foo());
|
||||
assert!(0i64.foo());
|
||||
|
||||
assert!(LocalDefault.foo() == false);
|
||||
assert!(LocalOverride.foo() == true);
|
||||
assert!(!LocalDefault.foo());
|
||||
assert!(LocalOverride.foo());
|
||||
}
|
||||
|
||||
fn test_bar() {
|
||||
|
@ -35,9 +35,9 @@ impl Foo for i64 {
|
||||
}
|
||||
|
||||
fn test_foo() {
|
||||
assert!(0i8.foo() == false);
|
||||
assert!(0i32.foo() == false);
|
||||
assert!(0i64.foo() == true);
|
||||
assert!(!0i8.foo());
|
||||
assert!(!0i32.foo());
|
||||
assert!(0i64.foo());
|
||||
}
|
||||
|
||||
// Next, test mixture of explicit `default` and provided methods:
|
||||
|
Loading…
Reference in New Issue
Block a user