Skip to content
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

Rollup of 7 pull requests #33349

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 4 additions & 4 deletions src/doc/book/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ we’ll talk about Cargo, Rust’s build system and package manager.

The first step to using Rust is to install it. Generally speaking, you’ll need
an Internet connection to run the commands in this section, as we’ll be
downloading Rust from the internet.
downloading Rust from the Internet.

We’ll be showing off a number of commands using a terminal, and those lines all
start with `$`. We don't need to type in the `$`s, they are there to indicate
Expand Down Expand Up @@ -399,13 +399,13 @@ Let’s convert the Hello World program to Cargo. To Cargo-fy a project, you nee
to do three things:

1. Put your source file in the right directory.
2. Get rid of the old executable (`main.exe` on Windows, `main` everywhere else)
and make a new one.
2. Get rid of the old executable (`main.exe` on Windows, `main` everywhere
else).
3. Make a Cargo configuration file.

Let's get started!

### Creating a new Executable and Source Directory
### Creating a Source Directory and Removing the Old Executable

First, go back to your terminal, move to your *hello_world* directory, and
enter the following commands:
Expand Down
25 changes: 21 additions & 4 deletions src/libcollections/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@
//! precision := count | '*'
//! type := identifier | ''
//! count := parameter | integer
//! parameter := integer '$'
//! parameter := argument '$'
//! ```
//!
//! # Formatting Parameters
Expand Down Expand Up @@ -403,11 +403,12 @@
//! println!("Hello {:5}!", "x");
//! println!("Hello {:1$}!", "x", 5);
//! println!("Hello {1:0$}!", 5, "x");
//! println!("Hello {:width$}!", "x", width = 5);
//! ```
//!
//! Referring to an argument with the dollar syntax does not affect the "next
//! argument" counter, so it's usually a good idea to refer to all arguments by
//! their position explicitly.
//! argument" counter, so it's usually a good idea to refer to arguments by
//! position, or use named arguments.
//!
//! ## Precision
//!
Expand All @@ -426,7 +427,7 @@
//!
//! the integer `N` itself is the precision.
//!
//! 2. An integer followed by dollar sign `.N$`:
//! 2. An integer or name followed by dollar sign `.N$`:
//!
//! use format *argument* `N` (which must be a `usize`) as the precision.
//!
Expand Down Expand Up @@ -456,6 +457,10 @@
//! // Hello {next arg (x)} is {arg 2 (0.01) with precision
//! // specified in its predecessor (5)}
//! println!("Hello {} is {2:.*}", "x", 5, 0.01);
//!
//! // Hello {next arg (x)} is {arg "number" (0.01) with precision specified
//! // in arg "prec" (5)}
//! println!("Hello {} is {number:.prec$}", "x", prec = 5, number = 0.01);
//! ```
//!
//! All print the same thing:
Expand Down Expand Up @@ -516,12 +521,24 @@ use string;
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::fmt;
///
/// let s = fmt::format(format_args!("Hello, {}!", "world"));
/// assert_eq!(s, "Hello, world!".to_string());
/// ```
///
/// Please note that using `[format!]` might be preferrable.
/// Example:
///
/// ```
/// let s = format!("Hello, {}!", "world");
/// assert_eq!(s, "Hello, world!".to_string());
/// ```
///
/// [format!]: ../std/macro.format!.html
#[stable(feature = "rust1", since = "1.0.0")]
pub fn format(args: Arguments) -> string::String {
let mut output = string::String::new();
Expand Down
26 changes: 26 additions & 0 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,32 @@ pub trait UpperExp {
///
/// * output - the buffer to write output to
/// * args - the precompiled arguments generated by `format_args!`
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::fmt;
///
/// let mut output = String::new();
/// fmt::write(&mut output, format_args!("Hello {}!", "world"))
/// .expect("Error occurred while trying to write in String");
/// assert_eq!(output, "Hello world!");
/// ```
///
/// Please note that using [write!][write_macro] might be preferrable. Example:
///
/// ```
/// use std::fmt::Write;
///
/// let mut output = String::new();
/// write!(&mut output, "Hello {}!", "world")
/// .expect("Error occurred while trying to write in String");
/// assert_eq!(output, "Hello world!");
/// ```
///
/// [write_macro]: ../std/macro.write!.html
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write(output: &mut Write, args: Arguments) -> Result {
let mut formatter = Formatter {
Expand Down
2 changes: 1 addition & 1 deletion src/liblibc
Submodule liblibc updated 45 files
+3 −1 .travis.yml
+1 −1 Cargo.toml
+4 −0 appveyor.yml
+7 −3 ci/landing-page-footer.html
+4 −7 ci/landing-page-head.html
+25 −12 libc-test/Cargo.lock
+0 −10 libc-test/build.rs
+5 −5 libc-test/generate-files/Cargo.lock
+1 −3 src/lib.rs
+0 −3 src/unix/bsd/apple/b32.rs
+0 −3 src/unix/bsd/apple/b64.rs
+1 −101 src/unix/bsd/apple/mod.rs
+1 −18 src/unix/bsd/freebsdlike/dragonfly/mod.rs
+2 −19 src/unix/bsd/freebsdlike/freebsd/mod.rs
+4 −46 src/unix/bsd/freebsdlike/mod.rs
+1 −10 src/unix/bsd/mod.rs
+0 −27 src/unix/bsd/openbsdlike/bitrig.rs
+4 −27 src/unix/bsd/openbsdlike/mod.rs
+0 −27 src/unix/bsd/openbsdlike/netbsd.rs
+0 −27 src/unix/bsd/openbsdlike/openbsd.rs
+4 −17 src/unix/mod.rs
+1 −9 src/unix/notbsd/android/mod.rs
+0 −7 src/unix/notbsd/linux/mips.rs
+21 −10 src/unix/notbsd/linux/mod.rs
+0 −1 src/unix/notbsd/linux/musl/b32/arm.rs
+0 −1 src/unix/notbsd/linux/musl/b32/mips.rs
+1 −3 src/unix/notbsd/linux/musl/b32/mod.rs
+0 −1 src/unix/notbsd/linux/musl/b32/x86.rs
+0 −1 src/unix/notbsd/linux/musl/b64/aarch64.rs
+1 −14 src/unix/notbsd/linux/musl/b64/mod.rs
+0 −1 src/unix/notbsd/linux/musl/b64/powerpc64.rs
+0 −3 src/unix/notbsd/linux/musl/b64/x86_64.rs
+0 −5 src/unix/notbsd/linux/musl/mod.rs
+0 −1 src/unix/notbsd/linux/other/b32/arm.rs
+1 −1 src/unix/notbsd/linux/other/b32/mod.rs
+0 −1 src/unix/notbsd/linux/other/b32/powerpc.rs
+0 −1 src/unix/notbsd/linux/other/b32/x86.rs
+0 −1 src/unix/notbsd/linux/other/b64/aarch64.rs
+1 −3 src/unix/notbsd/linux/other/b64/mod.rs
+0 −1 src/unix/notbsd/linux/other/b64/powerpc64.rs
+0 −1 src/unix/notbsd/linux/other/b64/x86_64.rs
+1 −8 src/unix/notbsd/linux/other/mod.rs
+4 −84 src/unix/notbsd/mod.rs
+3 −15 src/unix/solaris/mod.rs
+1 −3 src/windows.rs
77 changes: 76 additions & 1 deletion src/librustc_borrowck/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,82 @@ let c = &i; // still ok!
```
"##,

E0501: r##"
This error indicates that a mutable variable is being used while it is still
captured by a closure. Because the closure has borrowed the variable, it is not
available for use until the closure goes out of scope.

Note that a capture will either move or borrow a variable, but in this
situation, the closure is borrowing the variable. Take a look at
http://rustbyexample.com/fn/closures/capture.html for more information about
capturing.

Example of erroneous code:

```compile_fail
fn inside_closure(x: &mut i32) {
// Actions which require unique access
}

fn outside_closure(x: &mut i32) {
// Actions which require unique access
}

fn foo(a: &mut i32) {
let bar = || {
inside_closure(a)
};
outside_closure(a); // error: cannot borrow `*a` as mutable because previous
// closure requires unique access.
}
```

To fix this error, you can place the closure in its own scope:

```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}

fn foo(a: &mut i32) {
{
let bar = || {
inside_closure(a)
};
} // borrow on `a` ends.
outside_closure(a); // ok!
}
```

Or you can pass the variable as a parameter to the closure:

```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}

fn foo(a: &mut i32) {
let bar = |s: &mut i32| {
inside_closure(s)
};
outside_closure(a);
bar(a);
}
```

It may be possible to define the closure later:

```
fn inside_closure(x: &mut i32) {}
fn outside_closure(x: &mut i32) {}

fn foo(a: &mut i32) {
outside_closure(a);
let bar = || {
inside_closure(a)
};
}
```
"##,

E0507: r##"
You tried to move out of a value which was borrowed. Erroneous code example:

Expand Down Expand Up @@ -436,7 +512,6 @@ register_diagnostics! {
E0388, // {} in a static location
E0389, // {} in a `&` reference
E0500, // closure requires unique access to `..` but .. is already borrowed
E0501, // cannot borrow `..`.. as .. because previous closure requires unique access
E0502, // cannot borrow `..`.. as .. because .. is also borrowed as ...
E0503, // cannot use `..` because it was mutably borrowed
E0504, // cannot move `..` into closure because it is borrowed
Expand Down
61 changes: 51 additions & 10 deletions src/librustc_const_eval/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,22 +215,63 @@ match Some("hi".to_string()) {
The variable `s` has type `String`, and its use in the guard is as a variable of
type `String`. The guard code effectively executes in a separate scope to the
body of the arm, so the value would be moved into this anonymous scope and
therefore become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.
therefore becomes unavailable in the body of the arm.

```compile_fail
The problem above can be solved by using the `ref` keyword.

```
match Some("hi".to_string()) {
Some(s) if { drop(s); false } => (),
Some(s) => {}, // use s.
Some(ref s) if s.len() == 0 => {},
_ => {},
}
```

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
Though this example seems innocuous and easy to solve, the problem becomes clear
when it encounters functions which consume the value:

```compile_fail
struct A{}

impl A {
fn consume(self) -> usize {
0
}
}

fn main() {
let a = Some(A{});
match a {
Some(y) if y.consume() > 0 => {}
_ => {}
}
}
```

In this situation, even the `ref` keyword cannot solve it, since borrowed
content cannot be moved. This problem cannot be solved generally. If the value
can be cloned, here is a not-so-specific solution:

```
#[derive(Clone)]
struct A{}

impl A {
fn consume(self) -> usize {
0
}
}

fn main() {
let a = Some(A{});
match a{
Some(y) if y.clone().consume() > 0 => {}
_ => {}
}
}
```

If the value will be consumed in the pattern guard, using its clone will not
move its ownership, so the code works.
"##,

E0009: r##"
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_typeck/check/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
span: Span,
method_name: ast::Name,
self_ty: ty::Ty<'tcx>,
call_expr_id: ast::NodeId)
call_expr_id: ast::NodeId,
allow_private: bool)
-> bool
{
let mode = probe::Mode::MethodCall;
Expand All @@ -93,7 +94,7 @@ pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
Err(NoMatch(..)) => false,
Err(Ambiguity(..)) => true,
Err(ClosureAmbiguity(..)) => true,
Err(PrivateMatch(..)) => true,
Err(PrivateMatch(..)) => allow_private,
}
}

Expand Down
13 changes: 10 additions & 3 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2943,12 +2943,19 @@ fn check_expr_with_expectation_and_lvalue_pref<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,

if let Some((did, field_ty)) = private_candidate {
let struct_path = fcx.tcx().item_path_str(did);
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
fcx.tcx().sess.span_err(expr.span, &msg);
fcx.write_ty(expr.id, field_ty);
let msg = format!("field `{}` of struct `{}` is private", field.node, struct_path);
let mut err = fcx.tcx().sess.struct_span_err(expr.span, &msg);
// Also check if an accessible method exists, which is often what is meant.
if method::exists(fcx, field.span, field.node, expr_t, expr.id, false) {
err.fileline_note(field.span, &format!("a method called `{}` also exists, \
maybe a `()` to call it is missing?",
field.node));
}
err.emit();
} else if field.node == keywords::Invalid.name() {
fcx.write_error(expr.id);
} else if method::exists(fcx, field.span, field.node, expr_t, expr.id) {
} else if method::exists(fcx, field.span, field.node, expr_t, expr.id, true) {
fcx.type_error_struct(field.span,
|actual| {
format!("attempted to take value of method `{}` on type \
Expand Down
29 changes: 14 additions & 15 deletions src/libstd/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
//! ## The threading model
//!
//! An executing Rust program consists of a collection of native OS threads,
//! each with their own stack and local state.
//! each with their own stack and local state. Threads can be named, and
//! provide some built-in support for low-level synchronization.
//!
//! Communication between threads can be done through
//! [channels](../../std/sync/mpsc/index.html), Rust's message-passing
Expand All @@ -37,20 +38,6 @@
//! convenient facilities for automatically waiting for the termination of a
//! child thread (i.e., join).
//!
//! ## The `Thread` type
//!
//! Threads are represented via the `Thread` type, which you can
//! get in one of two ways:
//!
//! * By spawning a new thread, e.g. using the `thread::spawn` function.
//! * By requesting the current thread, using the `thread::current` function.
//!
//! Threads can be named, and provide some built-in support for low-level
//! synchronization (described below).
//!
//! The `thread::current()` function is available even for threads not spawned
//! by the APIs of this module.
//!
//! ## Spawning a thread
//!
//! A new thread can be spawned using the `thread::spawn` function:
Expand Down Expand Up @@ -99,6 +86,18 @@
//! });
//! ```
//!
//! ## The `Thread` type
//!
//! Threads are represented via the `Thread` type, which you can get in one of
//! two ways:
//!
//! * By spawning a new thread, e.g. using the `thread::spawn` function, and
//! calling `thread()` on the `JoinHandle`.
//! * By requesting the current thread, using the `thread::current` function.
//!
//! The `thread::current()` function is available even for threads not spawned
//! by the APIs of this module.
//!
//! ## Blocking support: park and unpark
//!
//! Every thread is equipped with some basic low-level blocking support, via the
Expand Down
Loading