Auto merge of #34720 - Manishearth:rollup, r=Manishearth
Rollup of 9 pull requests - Successful merges: #34097, #34456, #34610, #34612, #34659, #34688, #34691, #34699, #34700 - Failed merges:
This commit is contained in:
commit
e7751e436b
|
@ -41,8 +41,9 @@ they get set in the [`[features]` section][features] of your `Cargo.toml`:
|
||||||
# no features by default
|
# no features by default
|
||||||
default = []
|
default = []
|
||||||
|
|
||||||
# The “secure-password” feature depends on the bcrypt package.
|
# Add feature "foo" here, then you can use it.
|
||||||
secure-password = ["bcrypt"]
|
# Our "foo" feature depends on nothing else.
|
||||||
|
foo = []
|
||||||
```
|
```
|
||||||
|
|
||||||
When you do this, Cargo passes along a flag to `rustc`:
|
When you do this, Cargo passes along a flag to `rustc`:
|
||||||
|
|
|
@ -11,7 +11,7 @@ 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
|
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
|
start with `$`. You don't need to type in the `$`s, they are there to indicate
|
||||||
the start of each command. We’ll see many tutorials and examples around the web
|
the start of each command. We’ll see many tutorials and examples around the web
|
||||||
that follow this convention: `$` for commands run as our regular user, and `#`
|
that follow this convention: `$` for commands run as our regular user, and `#`
|
||||||
for commands we should be running as an administrator.
|
for commands we should be running as an administrator.
|
||||||
|
@ -159,9 +159,11 @@ You should see the version number, commit hash, and commit date.
|
||||||
If you do, Rust has been installed successfully! Congrats!
|
If you do, Rust has been installed successfully! Congrats!
|
||||||
|
|
||||||
If you don't and you're on Windows, check that Rust is in your %PATH% system
|
If you don't and you're on Windows, check that Rust is in your %PATH% system
|
||||||
variable. If it isn't, run the installer again, select "Change" on the "Change,
|
variable: `$ echo %PATH%`. If it isn't, run the installer again, select "Change"
|
||||||
repair, or remove installation" page and ensure "Add to PATH" is installed on
|
on the "Change, repair, or remove installation" page and ensure "Add to PATH" is
|
||||||
the local hard drive.
|
installed on the local hard drive. If you need to configure your path manually,
|
||||||
|
you can find the Rust executables in a directory like
|
||||||
|
`"C:\Program Files\Rust stable GNU 1.x\bin"`.
|
||||||
|
|
||||||
Rust does not do its own linking, and so you’ll need to have a linker
|
Rust does not do its own linking, and so you’ll need to have a linker
|
||||||
installed. Doing so will depend on your specific system, consult its
|
installed. Doing so will depend on your specific system, consult its
|
||||||
|
@ -339,7 +341,8 @@ On Windows, you'd enter:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ dir
|
$ dir
|
||||||
main.exe main.rs
|
main.exe
|
||||||
|
main.rs
|
||||||
```
|
```
|
||||||
|
|
||||||
This shows we have two files: the source code, with an `.rs` extension, and the
|
This shows we have two files: the source code, with an `.rs` extension, and the
|
||||||
|
@ -347,7 +350,7 @@ executable (`main.exe` on Windows, `main` everywhere else). All that's left to
|
||||||
do from here is run the `main` or `main.exe` file, like this:
|
do from here is run the `main` or `main.exe` file, like this:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ./main # or main.exe on Windows
|
$ ./main # or .\main.exe on Windows
|
||||||
```
|
```
|
||||||
|
|
||||||
If *main.rs* were your "Hello, world!" program, this would print `Hello,
|
If *main.rs* were your "Hello, world!" program, this would print `Hello,
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
|
|
||||||
//! Thread-local reference-counted boxes (the `Rc<T>` type).
|
//! Unsynchronized reference-counted boxes (the `Rc<T>` type) which are usable
|
||||||
|
//! only within a single thread.
|
||||||
//!
|
//!
|
||||||
//! The `Rc<T>` type provides shared ownership of an immutable value.
|
//! The `Rc<T>` type provides shared ownership of an immutable value.
|
||||||
//! Destruction is deterministic, and will occur as soon as the last owner is
|
//! Destruction is deterministic, and will occur as soon as the last owner is
|
||||||
|
|
|
@ -371,13 +371,16 @@ pub trait Extend<A> {
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let numbers = vec![1, 2, 3];
|
/// let numbers = vec![1, 2, 3, 4, 5, 6];
|
||||||
///
|
///
|
||||||
/// let mut iter = numbers.iter();
|
/// let mut iter = numbers.iter();
|
||||||
///
|
///
|
||||||
/// assert_eq!(Some(&1), iter.next());
|
/// assert_eq!(Some(&1), iter.next());
|
||||||
/// assert_eq!(Some(&3), iter.next_back());
|
/// assert_eq!(Some(&6), iter.next_back());
|
||||||
/// assert_eq!(Some(&2), iter.next_back());
|
/// assert_eq!(Some(&5), iter.next_back());
|
||||||
|
/// assert_eq!(Some(&2), iter.next());
|
||||||
|
/// assert_eq!(Some(&3), iter.next());
|
||||||
|
/// assert_eq!(Some(&4), iter.next());
|
||||||
/// assert_eq!(None, iter.next());
|
/// assert_eq!(None, iter.next());
|
||||||
/// assert_eq!(None, iter.next_back());
|
/// assert_eq!(None, iter.next_back());
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -395,13 +398,16 @@ pub trait DoubleEndedIterator: Iterator {
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let numbers = vec![1, 2, 3];
|
/// let numbers = vec![1, 2, 3, 4, 5, 6];
|
||||||
///
|
///
|
||||||
/// let mut iter = numbers.iter();
|
/// let mut iter = numbers.iter();
|
||||||
///
|
///
|
||||||
/// assert_eq!(Some(&1), iter.next());
|
/// assert_eq!(Some(&1), iter.next());
|
||||||
/// assert_eq!(Some(&3), iter.next_back());
|
/// assert_eq!(Some(&6), iter.next_back());
|
||||||
/// assert_eq!(Some(&2), iter.next_back());
|
/// assert_eq!(Some(&5), iter.next_back());
|
||||||
|
/// assert_eq!(Some(&2), iter.next());
|
||||||
|
/// assert_eq!(Some(&3), iter.next());
|
||||||
|
/// assert_eq!(Some(&4), iter.next());
|
||||||
/// assert_eq!(None, iter.next());
|
/// assert_eq!(None, iter.next());
|
||||||
/// assert_eq!(None, iter.next_back());
|
/// assert_eq!(None, iter.next_back());
|
||||||
/// ```
|
/// ```
|
||||||
|
|
|
@ -214,6 +214,30 @@ impl Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new instance of an `Error` from a particular OS error code.
|
/// Creates a new instance of an `Error` from a particular OS error code.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// On Linux:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # if cfg!(target_os = "linux") {
|
||||||
|
/// use std::io;
|
||||||
|
///
|
||||||
|
/// let error = io::Error::from_raw_os_error(98);
|
||||||
|
/// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// On Windows:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # if cfg!(windows) {
|
||||||
|
/// use std::io;
|
||||||
|
///
|
||||||
|
/// let error = io::Error::from_raw_os_error(10048);
|
||||||
|
/// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn from_raw_os_error(code: i32) -> Error {
|
pub fn from_raw_os_error(code: i32) -> Error {
|
||||||
Error { repr: Repr::Os(code) }
|
Error { repr: Repr::Os(code) }
|
||||||
|
|
|
@ -1529,8 +1529,7 @@ impl Path {
|
||||||
|
|
||||||
/// The final component of the path, if it is a normal file.
|
/// The final component of the path, if it is a normal file.
|
||||||
///
|
///
|
||||||
/// If the path terminates in `.`, `..`, or consists solely of a root of
|
/// If the path terminates in `..`, `file_name` will return `None`.
|
||||||
/// prefix, `file_name` will return `None`.
|
|
||||||
///
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
|
@ -1543,6 +1542,17 @@ impl Path {
|
||||||
///
|
///
|
||||||
/// assert_eq!(Some(os_str), path.file_name());
|
/// assert_eq!(Some(os_str), path.file_name());
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// # Other examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::path::Path;
|
||||||
|
/// use std::ffi::OsStr;
|
||||||
|
///
|
||||||
|
/// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.").file_name());
|
||||||
|
/// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.//").file_name());
|
||||||
|
/// assert_eq!(None, Path::new("foo.txt/..").file_name());
|
||||||
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn file_name(&self) -> Option<&OsStr> {
|
pub fn file_name(&self) -> Option<&OsStr> {
|
||||||
self.components().next_back().and_then(|p| {
|
self.components().next_back().and_then(|p| {
|
||||||
|
|
|
@ -152,9 +152,19 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
|
||||||
init();
|
init();
|
||||||
|
|
||||||
let c_host = CString::new(host)?;
|
let c_host = CString::new(host)?;
|
||||||
|
let hints = c::addrinfo {
|
||||||
|
ai_flags: 0,
|
||||||
|
ai_family: 0,
|
||||||
|
ai_socktype: c::SOCK_STREAM,
|
||||||
|
ai_protocol: 0,
|
||||||
|
ai_addrlen: 0,
|
||||||
|
ai_addr: ptr::null_mut(),
|
||||||
|
ai_canonname: ptr::null_mut(),
|
||||||
|
ai_next: ptr::null_mut()
|
||||||
|
};
|
||||||
let mut res = ptr::null_mut();
|
let mut res = ptr::null_mut();
|
||||||
unsafe {
|
unsafe {
|
||||||
cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
|
cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints,
|
||||||
&mut res))?;
|
&mut res))?;
|
||||||
Ok(LookupHost { original: res, cur: res })
|
Ok(LookupHost { original: res, cur: res })
|
||||||
}
|
}
|
||||||
|
|
|
@ -495,64 +495,6 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check for erroneous `ident { }`; if matches, signal error and
|
|
||||||
/// recover (without consuming any expected input token). Returns
|
|
||||||
/// true if and only if input was consumed for recovery.
|
|
||||||
pub fn check_for_erroneous_unit_struct_expecting(&mut self,
|
|
||||||
expected: &[token::Token])
|
|
||||||
-> bool {
|
|
||||||
if self.token == token::OpenDelim(token::Brace)
|
|
||||||
&& expected.iter().all(|t| *t != token::OpenDelim(token::Brace))
|
|
||||||
&& self.look_ahead(1, |t| *t == token::CloseDelim(token::Brace)) {
|
|
||||||
// matched; signal non-fatal error and recover.
|
|
||||||
let span = self.span;
|
|
||||||
self.span_err(span, "unit-like struct construction is written with no trailing `{ }`");
|
|
||||||
self.eat(&token::OpenDelim(token::Brace));
|
|
||||||
self.eat(&token::CloseDelim(token::Brace));
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Commit to parsing a complete expression `e` expected to be
|
|
||||||
/// followed by some token from the set edible + inedible. Recover
|
|
||||||
/// from anticipated input errors, discarding erroneous characters.
|
|
||||||
pub fn commit_expr(&mut self, e: &Expr, edible: &[token::Token],
|
|
||||||
inedible: &[token::Token]) -> PResult<'a, ()> {
|
|
||||||
debug!("commit_expr {:?}", e);
|
|
||||||
if let ExprKind::Path(..) = e.node {
|
|
||||||
// might be unit-struct construction; check for recoverableinput error.
|
|
||||||
let expected = edible.iter()
|
|
||||||
.cloned()
|
|
||||||
.chain(inedible.iter().cloned())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
self.check_for_erroneous_unit_struct_expecting(&expected[..]);
|
|
||||||
}
|
|
||||||
self.expect_one_of(edible, inedible)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn commit_expr_expecting(&mut self, e: &Expr, edible: token::Token) -> PResult<'a, ()> {
|
|
||||||
self.commit_expr(e, &[edible], &[])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Commit to parsing a complete statement `s`, which expects to be
|
|
||||||
/// followed by some token from the set edible + inedible. Check
|
|
||||||
/// for recoverable input errors, discarding erroneous characters.
|
|
||||||
pub fn commit_stmt(&mut self, edible: &[token::Token],
|
|
||||||
inedible: &[token::Token]) -> PResult<'a, ()> {
|
|
||||||
if self.last_token
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |t| t.is_ident() || t.is_path()) {
|
|
||||||
let expected = edible.iter()
|
|
||||||
.cloned()
|
|
||||||
.chain(inedible.iter().cloned())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
self.check_for_erroneous_unit_struct_expecting(&expected);
|
|
||||||
}
|
|
||||||
self.expect_one_of(edible, inedible)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// returns the span of expr, if it was not interpolated or the span of the interpolated token
|
/// returns the span of expr, if it was not interpolated or the span of the interpolated token
|
||||||
fn interpolated_or_expr_span(&self,
|
fn interpolated_or_expr_span(&self,
|
||||||
expr: PResult<'a, P<Expr>>)
|
expr: PResult<'a, P<Expr>>)
|
||||||
|
@ -1247,7 +1189,7 @@ impl<'a> Parser<'a> {
|
||||||
let default = if self.check(&token::Eq) {
|
let default = if self.check(&token::Eq) {
|
||||||
self.bump();
|
self.bump();
|
||||||
let expr = self.parse_expr()?;
|
let expr = self.parse_expr()?;
|
||||||
self.commit_expr_expecting(&expr, token::Semi)?;
|
self.expect(&token::Semi)?;
|
||||||
Some(expr)
|
Some(expr)
|
||||||
} else {
|
} else {
|
||||||
self.expect(&token::Semi)?;
|
self.expect(&token::Semi)?;
|
||||||
|
@ -2195,8 +2137,7 @@ impl<'a> Parser<'a> {
|
||||||
let mut trailing_comma = false;
|
let mut trailing_comma = false;
|
||||||
while self.token != token::CloseDelim(token::Paren) {
|
while self.token != token::CloseDelim(token::Paren) {
|
||||||
es.push(self.parse_expr()?);
|
es.push(self.parse_expr()?);
|
||||||
self.commit_expr(&es.last().unwrap(), &[],
|
self.expect_one_of(&[], &[token::Comma, token::CloseDelim(token::Paren)])?;
|
||||||
&[token::Comma, token::CloseDelim(token::Paren)])?;
|
|
||||||
if self.check(&token::Comma) {
|
if self.check(&token::Comma) {
|
||||||
trailing_comma = true;
|
trailing_comma = true;
|
||||||
|
|
||||||
|
@ -2407,9 +2348,8 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.commit_expr(&fields.last().unwrap().expr,
|
match self.expect_one_of(&[token::Comma],
|
||||||
&[token::Comma],
|
&[token::CloseDelim(token::Brace)]) {
|
||||||
&[token::CloseDelim(token::Brace)]) {
|
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(mut e) => {
|
Err(mut e) => {
|
||||||
e.emit();
|
e.emit();
|
||||||
|
@ -2662,7 +2602,7 @@ impl<'a> Parser<'a> {
|
||||||
self.bump();
|
self.bump();
|
||||||
let ix = self.parse_expr()?;
|
let ix = self.parse_expr()?;
|
||||||
hi = self.span.hi;
|
hi = self.span.hi;
|
||||||
self.commit_expr_expecting(&ix, token::CloseDelim(token::Bracket))?;
|
self.expect(&token::CloseDelim(token::Bracket))?;
|
||||||
let index = self.mk_index(e, ix);
|
let index = self.mk_index(e, ix);
|
||||||
e = self.mk_expr(lo, hi, index, ThinVec::new())
|
e = self.mk_expr(lo, hi, index, ThinVec::new())
|
||||||
}
|
}
|
||||||
|
@ -3329,8 +3269,7 @@ impl<'a> Parser<'a> {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let discriminant = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL,
|
let discriminant = self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL,
|
||||||
None)?;
|
None)?;
|
||||||
if let Err(mut e) = self.commit_expr_expecting(&discriminant,
|
if let Err(mut e) = self.expect(&token::OpenDelim(token::Brace)) {
|
||||||
token::OpenDelim(token::Brace)) {
|
|
||||||
if self.token == token::Token::Semi {
|
if self.token == token::Token::Semi {
|
||||||
e.span_note(match_span, "did you mean to remove this `match` keyword?");
|
e.span_note(match_span, "did you mean to remove this `match` keyword?");
|
||||||
}
|
}
|
||||||
|
@ -3376,7 +3315,7 @@ impl<'a> Parser<'a> {
|
||||||
&& self.token != token::CloseDelim(token::Brace);
|
&& self.token != token::CloseDelim(token::Brace);
|
||||||
|
|
||||||
if require_comma {
|
if require_comma {
|
||||||
self.commit_expr(&expr, &[token::Comma], &[token::CloseDelim(token::Brace)])?;
|
self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)])?;
|
||||||
} else {
|
} else {
|
||||||
self.eat(&token::Comma);
|
self.eat(&token::Comma);
|
||||||
}
|
}
|
||||||
|
@ -4118,7 +4057,7 @@ impl<'a> Parser<'a> {
|
||||||
_ => { // all other kinds of statements:
|
_ => { // all other kinds of statements:
|
||||||
let mut hi = span.hi;
|
let mut hi = span.hi;
|
||||||
if classify::stmt_ends_with_semi(&node) {
|
if classify::stmt_ends_with_semi(&node) {
|
||||||
self.commit_stmt(&[token::Semi], &[])?;
|
self.expect(&token::Semi)?;
|
||||||
hi = self.last_span.hi;
|
hi = self.last_span.hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4196,7 +4135,7 @@ impl<'a> Parser<'a> {
|
||||||
if classify::expr_requires_semi_to_be_stmt(&e) {
|
if classify::expr_requires_semi_to_be_stmt(&e) {
|
||||||
// Just check for errors and recover; do not eat semicolon yet.
|
// Just check for errors and recover; do not eat semicolon yet.
|
||||||
if let Err(mut e) =
|
if let Err(mut e) =
|
||||||
self.commit_stmt(&[], &[token::Semi, token::CloseDelim(token::Brace)])
|
self.expect_one_of(&[], &[token::Semi, token::CloseDelim(token::Brace)])
|
||||||
{
|
{
|
||||||
e.emit();
|
e.emit();
|
||||||
self.recover_stmt();
|
self.recover_stmt();
|
||||||
|
@ -4863,7 +4802,7 @@ impl<'a> Parser<'a> {
|
||||||
let typ = self.parse_ty_sum()?;
|
let typ = self.parse_ty_sum()?;
|
||||||
self.expect(&token::Eq)?;
|
self.expect(&token::Eq)?;
|
||||||
let expr = self.parse_expr()?;
|
let expr = self.parse_expr()?;
|
||||||
self.commit_expr_expecting(&expr, token::Semi)?;
|
self.expect(&token::Semi)?;
|
||||||
(name, ast::ImplItemKind::Const(typ, expr))
|
(name, ast::ImplItemKind::Const(typ, expr))
|
||||||
} else {
|
} else {
|
||||||
let (name, inner_attrs, node) = self.parse_impl_method(&vis)?;
|
let (name, inner_attrs, node) = self.parse_impl_method(&vis)?;
|
||||||
|
@ -5287,7 +5226,7 @@ impl<'a> Parser<'a> {
|
||||||
let ty = self.parse_ty_sum()?;
|
let ty = self.parse_ty_sum()?;
|
||||||
self.expect(&token::Eq)?;
|
self.expect(&token::Eq)?;
|
||||||
let e = self.parse_expr()?;
|
let e = self.parse_expr()?;
|
||||||
self.commit_expr_expecting(&e, token::Semi)?;
|
self.expect(&token::Semi)?;
|
||||||
let item = match m {
|
let item = match m {
|
||||||
Some(m) => ItemKind::Static(ty, m, e),
|
Some(m) => ItemKind::Static(ty, m, e),
|
||||||
None => ItemKind::Const(ty, e),
|
None => ItemKind::Const(ty, e),
|
||||||
|
|
Loading…
Reference in New Issue