mirror of
https://github.com/rust-lang/rust
synced 2024-09-05 08:37:14 +00:00
Auto merge of #37170 - jonathandturner:rollup, r=jonathandturner
Rollup of 10 pull requests - Successful merges: #36307, #36755, #36961, #37102, #37115, #37119, #37122, #37123, #37141, #37159 - Failed merges:
This commit is contained in:
commit
a8d189af90
|
@ -89,6 +89,7 @@ build.
|
|||
$ pacman -S git \
|
||||
make \
|
||||
diffutils \
|
||||
tar \
|
||||
mingw-w64-x86_64-python2 \
|
||||
mingw-w64-x86_64-cmake \
|
||||
mingw-w64-x86_64-gcc
|
||||
|
|
|
@ -50,11 +50,78 @@ complicated. For example, imagine this set of operations:
|
|||
4. You decide to use the resource.
|
||||
|
||||
Uh oh! Your reference is pointing to an invalid resource. This is called a
|
||||
dangling pointer or ‘use after free’, when the resource is memory.
|
||||
dangling pointer or ‘use after free’, when the resource is memory. A small
|
||||
example of such a situation would be:
|
||||
|
||||
```rust,compile_fail
|
||||
let r; // Introduce reference: r
|
||||
{
|
||||
let i = 1; // Introduce scoped value: i
|
||||
r = &i; // Store reference of i in r
|
||||
} // i goes out of scope and is dropped.
|
||||
|
||||
println!("{}", r); // r still refers to i
|
||||
```
|
||||
|
||||
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.
|
||||
three. In the small example above the Rust compiler is able to report the issue
|
||||
as it can see the lifetimes of the various values in the function.
|
||||
|
||||
When we have a function that takes arguments by reference the situation becomes
|
||||
more complex. Consider the following example:
|
||||
|
||||
```rust,compile_fail,E0106
|
||||
fn skip_prefix(line: &str, prefix: &str) -> &str {
|
||||
// ...
|
||||
# line
|
||||
}
|
||||
|
||||
let line = "lang:en=Hello World!";
|
||||
let lang = "en";
|
||||
|
||||
let v;
|
||||
{
|
||||
let p = format!("lang:{}=", lang); // -+ p goes into scope
|
||||
v = skip_prefix(line, p.as_str()); // |
|
||||
} // -+ p goes out of scope
|
||||
println!("{}", v);
|
||||
```
|
||||
|
||||
Here we have a function `skip_prefix` which takes two `&str` references
|
||||
as parameters and returns a single `&str` reference. We call it
|
||||
by passing in references to `line` and `p`: Two variables with different
|
||||
lifetimes. Now the safety of the `println!`-line depends on whether the
|
||||
reference returned by `skip_prefix` function references the still living
|
||||
`line` or the already dropped `p` string.
|
||||
|
||||
Because of the above ambiguity, Rust will refuse to compile the example
|
||||
code. To get it to compile we need to tell the compiler more about the
|
||||
lifetimes of the references. This can be done by making the lifetimes
|
||||
explicit in the function declaration:
|
||||
|
||||
```rust
|
||||
fn skip_prefix<'a, 'b>(line: &'a str, prefix: &'b str) -> &'a str {
|
||||
// ...
|
||||
# line
|
||||
}
|
||||
```
|
||||
|
||||
Let's examine the changes without going too deep into the syntax for now -
|
||||
we'll get to that later. The first change was adding the `<'a, 'b>` after the
|
||||
method name. This introduces two lifetime parameters: `'a` and `'b`. Next each
|
||||
reference in the function signature was associated with one of the lifetime
|
||||
parameters by adding the lifetime name after the `&`. This tells the compiler
|
||||
how the lifetimes between different references are related.
|
||||
|
||||
As a result the compiler is now able to deduce that the return value of
|
||||
`skip_prefix` has the same lifetime as the `line` parameter, which makes the `v`
|
||||
reference safe to use even after the `p` goes out of scope in the original
|
||||
example.
|
||||
|
||||
In addition to the compiler being able to validate the usage of `skip_prefix`
|
||||
return value, it can also ensure that the implementation follows the contract
|
||||
established by the function declaration. This is useful especially when you are
|
||||
implementing traits that are introduced [later in the book][traits].
|
||||
|
||||
**Note** It's important to understand that lifetime annotations are
|
||||
_descriptive_, not _prescriptive_. This means that how long a reference is valid
|
||||
|
@ -63,20 +130,14 @@ give information about lifetimes to the compiler that uses them to check the
|
|||
validity of references. The compiler can do so without annotations in simple
|
||||
cases, but needs the programmers support in complex scenarios.
|
||||
|
||||
```rust
|
||||
// implicit
|
||||
fn foo(x: &i32) {
|
||||
}
|
||||
[traits]: traits.html
|
||||
|
||||
// explicit
|
||||
fn bar<'a>(x: &'a i32) {
|
||||
}
|
||||
```
|
||||
# Syntax
|
||||
|
||||
The `'a` reads ‘the lifetime a’. Technically, every reference has some lifetime
|
||||
associated with it, but the compiler lets you elide (i.e. omit, see
|
||||
["Lifetime Elision"][lifetime-elision] below) them in common cases.
|
||||
Before we get to that, though, let’s break the explicit example down:
|
||||
["Lifetime Elision"][lifetime-elision] below) them in common cases. Before we
|
||||
get to that, though, let’s look at a short example with explicit lifetimes:
|
||||
|
||||
[lifetime-elision]: #lifetime-elision
|
||||
|
||||
|
@ -94,7 +155,8 @@ focus on the lifetimes aspect.
|
|||
[generics]: generics.html
|
||||
|
||||
We use `<>` to declare our lifetimes. This says that `bar` has one lifetime,
|
||||
`'a`. If we had two reference parameters, it would look like this:
|
||||
`'a`. If we had two reference parameters with different lifetimes, it would
|
||||
look like this:
|
||||
|
||||
|
||||
```rust,ignore
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
% `type` Aliases
|
||||
% Type Aliases
|
||||
|
||||
The `type` keyword lets you declare an alias of another type:
|
||||
|
||||
|
|
|
@ -38,7 +38,9 @@
|
|||
//! ```
|
||||
//!
|
||||
//! If you need more control over how a value is hashed, you need to implement
|
||||
//! the `Hash` trait:
|
||||
//! the [`Hash`] trait:
|
||||
//!
|
||||
//! [`Hash`]: trait.Hash.html
|
||||
//!
|
||||
//! ```rust
|
||||
//! use std::hash::{Hash, Hasher, SipHasher};
|
||||
|
@ -90,7 +92,7 @@
|
|||
/// The `H` type parameter is an abstract hash state that is used by the `Hash`
|
||||
/// to compute the hash.
|
||||
///
|
||||
/// If you are also implementing `Eq`, there is an additional property that
|
||||
/// If you are also implementing [`Eq`], there is an additional property that
|
||||
/// is important:
|
||||
///
|
||||
/// ```text
|
||||
|
@ -98,13 +100,13 @@
|
|||
/// ```
|
||||
///
|
||||
/// In other words, if two keys are equal, their hashes should also be equal.
|
||||
/// `HashMap` and `HashSet` both rely on this behavior.
|
||||
/// [`HashMap`] and [`HashSet`] both rely on this behavior.
|
||||
///
|
||||
/// ## Derivable
|
||||
///
|
||||
/// This trait can be used with `#[derive]` if all fields implement `Hash`.
|
||||
/// When `derive`d, the resulting hash will be the combination of the values
|
||||
/// from calling `.hash()` on each field.
|
||||
/// from calling [`.hash()`] on each field.
|
||||
///
|
||||
/// ## How can I implement `Hash`?
|
||||
///
|
||||
|
@ -127,6 +129,11 @@
|
|||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`Eq`]: ../../std/cmp/trait.Eq.html
|
||||
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
|
||||
/// [`HashSet`]: ../../std/collections/struct.HashSet.html
|
||||
/// [`.hash()`]: #tymethod.hash
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Hash {
|
||||
/// Feeds this value into the state given, updating the hasher as necessary.
|
||||
|
@ -151,35 +158,35 @@ pub trait Hasher {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn finish(&self) -> u64;
|
||||
|
||||
/// Writes some data into this `Hasher`
|
||||
/// Writes some data into this `Hasher`.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn write(&mut self, bytes: &[u8]);
|
||||
|
||||
/// Write a single `u8` into this hasher
|
||||
/// Write a single `u8` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_u8(&mut self, i: u8) {
|
||||
self.write(&[i])
|
||||
}
|
||||
/// Write a single `u16` into this hasher.
|
||||
/// Writes a single `u16` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_u16(&mut self, i: u16) {
|
||||
self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i) })
|
||||
}
|
||||
/// Write a single `u32` into this hasher.
|
||||
/// Writes a single `u32` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_u32(&mut self, i: u32) {
|
||||
self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i) })
|
||||
}
|
||||
/// Write a single `u64` into this hasher.
|
||||
/// Writes a single `u64` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_u64(&mut self, i: u64) {
|
||||
self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i) })
|
||||
}
|
||||
/// Write a single `usize` into this hasher.
|
||||
/// Writes a single `usize` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_usize(&mut self, i: usize) {
|
||||
|
@ -189,31 +196,31 @@ fn write_usize(&mut self, i: usize) {
|
|||
self.write(bytes);
|
||||
}
|
||||
|
||||
/// Write a single `i8` into this hasher.
|
||||
/// Writes a single `i8` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_i8(&mut self, i: i8) {
|
||||
self.write_u8(i as u8)
|
||||
}
|
||||
/// Write a single `i16` into this hasher.
|
||||
/// Writes a single `i16` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_i16(&mut self, i: i16) {
|
||||
self.write_u16(i as u16)
|
||||
}
|
||||
/// Write a single `i32` into this hasher.
|
||||
/// Writes a single `i32` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_i32(&mut self, i: i32) {
|
||||
self.write_u32(i as u32)
|
||||
}
|
||||
/// Write a single `i64` into this hasher.
|
||||
/// Writes a single `i64` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_i64(&mut self, i: i64) {
|
||||
self.write_u64(i as u64)
|
||||
}
|
||||
/// Write a single `isize` into this hasher.
|
||||
/// Writes a single `isize` into this hasher.
|
||||
#[inline]
|
||||
#[stable(feature = "hasher_write", since = "1.3.0")]
|
||||
fn write_isize(&mut self, i: isize) {
|
||||
|
|
|
@ -34,19 +34,22 @@
|
|||
pub trait FullOps: Sized {
|
||||
/// Returns `(carry', v')` such that `carry' * 2^W + v' = self + other + carry`,
|
||||
/// where `W` is the number of bits in `Self`.
|
||||
fn full_add(self, other: Self, carry: bool) -> (bool /*carry*/, Self);
|
||||
fn full_add(self, other: Self, carry: bool) -> (bool /* carry */, Self);
|
||||
|
||||
/// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + carry`,
|
||||
/// where `W` is the number of bits in `Self`.
|
||||
fn full_mul(self, other: Self, carry: Self) -> (Self /*carry*/, Self);
|
||||
fn full_mul(self, other: Self, carry: Self) -> (Self /* carry */, Self);
|
||||
|
||||
/// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + other2 + carry`,
|
||||
/// where `W` is the number of bits in `Self`.
|
||||
fn full_mul_add(self, other: Self, other2: Self, carry: Self) -> (Self /*carry*/, Self);
|
||||
fn full_mul_add(self, other: Self, other2: Self, carry: Self) -> (Self /* carry */, Self);
|
||||
|
||||
/// Returns `(quo, rem)` such that `borrow * 2^W + self = quo * other + rem`
|
||||
/// and `0 <= rem < other`, where `W` is the number of bits in `Self`.
|
||||
fn full_div_rem(self, other: Self, borrow: Self) -> (Self /*quotient*/, Self /*remainder*/);
|
||||
fn full_div_rem(self,
|
||||
other: Self,
|
||||
borrow: Self)
|
||||
-> (Self /* quotient */, Self /* remainder */);
|
||||
}
|
||||
|
||||
macro_rules! impl_full_ops {
|
||||
|
@ -100,11 +103,7 @@ fn full_div_rem(self, other: $ty, borrow: $ty) -> ($ty, $ty) {
|
|||
|
||||
/// Table of powers of 5 representable in digits. Specifically, the largest {u8, u16, u32} value
|
||||
/// that's a power of five, plus the corresponding exponent. Used in `mul_pow5`.
|
||||
const SMALL_POW5: [(u64, usize); 3] = [
|
||||
(125, 3),
|
||||
(15625, 6),
|
||||
(1_220_703_125, 13),
|
||||
];
|
||||
const SMALL_POW5: [(u64, usize); 3] = [(125, 3), (15625, 6), (1_220_703_125, 13)];
|
||||
|
||||
macro_rules! define_bignum {
|
||||
($name:ident: type=$ty:ty, n=$n:expr) => (
|
||||
|
|
|
@ -49,12 +49,30 @@ pub fn mul(&self, other: &Fp) -> Fp {
|
|||
pub fn normalize(&self) -> Fp {
|
||||
let mut f = self.f;
|
||||
let mut e = self.e;
|
||||
if f >> (64 - 32) == 0 { f <<= 32; e -= 32; }
|
||||
if f >> (64 - 16) == 0 { f <<= 16; e -= 16; }
|
||||
if f >> (64 - 8) == 0 { f <<= 8; e -= 8; }
|
||||
if f >> (64 - 4) == 0 { f <<= 4; e -= 4; }
|
||||
if f >> (64 - 2) == 0 { f <<= 2; e -= 2; }
|
||||
if f >> (64 - 1) == 0 { f <<= 1; e -= 1; }
|
||||
if f >> (64 - 32) == 0 {
|
||||
f <<= 32;
|
||||
e -= 32;
|
||||
}
|
||||
if f >> (64 - 16) == 0 {
|
||||
f <<= 16;
|
||||
e -= 16;
|
||||
}
|
||||
if f >> (64 - 8) == 0 {
|
||||
f <<= 8;
|
||||
e -= 8;
|
||||
}
|
||||
if f >> (64 - 4) == 0 {
|
||||
f <<= 4;
|
||||
e -= 4;
|
||||
}
|
||||
if f >> (64 - 2) == 0 {
|
||||
f <<= 2;
|
||||
e -= 2;
|
||||
}
|
||||
if f >> (64 - 1) == 0 {
|
||||
f <<= 1;
|
||||
e -= 1;
|
||||
}
|
||||
debug_assert!(f >= (1 >> 63));
|
||||
Fp { f: f, e: e }
|
||||
}
|
||||
|
@ -66,6 +84,9 @@ pub fn normalize_to(&self, e: i16) -> Fp {
|
|||
assert!(edelta >= 0);
|
||||
let edelta = edelta as usize;
|
||||
assert_eq!(self.f << edelta >> edelta, self.f);
|
||||
Fp { f: self.f << edelta, e: e }
|
||||
Fp {
|
||||
f: self.f << edelta,
|
||||
e: e,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,13 +61,13 @@
|
|||
|
||||
/// Not a Number (NaN).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const NAN: f32 = 0.0_f32/0.0_f32;
|
||||
pub const NAN: f32 = 0.0_f32 / 0.0_f32;
|
||||
/// Infinity (∞).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const INFINITY: f32 = 1.0_f32/0.0_f32;
|
||||
pub const INFINITY: f32 = 1.0_f32 / 0.0_f32;
|
||||
/// Negative infinity (-∞).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const NEG_INFINITY: f32 = -1.0_f32/0.0_f32;
|
||||
pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32;
|
||||
|
||||
/// Basic mathematical constants.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -144,26 +144,40 @@ pub mod consts {
|
|||
issue = "32110")]
|
||||
impl Float for f32 {
|
||||
#[inline]
|
||||
fn nan() -> f32 { NAN }
|
||||
fn nan() -> f32 {
|
||||
NAN
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn infinity() -> f32 { INFINITY }
|
||||
fn infinity() -> f32 {
|
||||
INFINITY
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn neg_infinity() -> f32 { NEG_INFINITY }
|
||||
fn neg_infinity() -> f32 {
|
||||
NEG_INFINITY
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn zero() -> f32 { 0.0 }
|
||||
fn zero() -> f32 {
|
||||
0.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn neg_zero() -> f32 { -0.0 }
|
||||
fn neg_zero() -> f32 {
|
||||
-0.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn one() -> f32 { 1.0 }
|
||||
fn one() -> f32 {
|
||||
1.0
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is NaN.
|
||||
#[inline]
|
||||
fn is_nan(self) -> bool { self != self }
|
||||
fn is_nan(self) -> bool {
|
||||
self != self
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is infinite.
|
||||
#[inline]
|
||||
|
@ -192,11 +206,11 @@ fn classify(self) -> Fp {
|
|||
|
||||
let bits: u32 = unsafe { mem::transmute(self) };
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
(0, 0) => Fp::Zero,
|
||||
(_, 0) => Fp::Subnormal,
|
||||
(0, 0) => Fp::Zero,
|
||||
(_, 0) => Fp::Subnormal,
|
||||
(0, EXP_MASK) => Fp::Infinite,
|
||||
(_, EXP_MASK) => Fp::Nan,
|
||||
_ => Fp::Normal,
|
||||
_ => Fp::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +266,9 @@ fn is_sign_negative(self) -> bool {
|
|||
|
||||
/// Returns the reciprocal (multiplicative inverse) of the number.
|
||||
#[inline]
|
||||
fn recip(self) -> f32 { 1.0 / self }
|
||||
fn recip(self) -> f32 {
|
||||
1.0 / self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn powi(self, n: i32) -> f32 {
|
||||
|
@ -261,7 +277,9 @@ fn powi(self, n: i32) -> f32 {
|
|||
|
||||
/// Converts to degrees, assuming the number is in radians.
|
||||
#[inline]
|
||||
fn to_degrees(self) -> f32 { self * (180.0f32 / consts::PI) }
|
||||
fn to_degrees(self) -> f32 {
|
||||
self * (180.0f32 / consts::PI)
|
||||
}
|
||||
|
||||
/// Converts to radians, assuming the number is in degrees.
|
||||
#[inline]
|
||||
|
|
|
@ -61,13 +61,13 @@
|
|||
|
||||
/// Not a Number (NaN).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const NAN: f64 = 0.0_f64/0.0_f64;
|
||||
pub const NAN: f64 = 0.0_f64 / 0.0_f64;
|
||||
/// Infinity (∞).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const INFINITY: f64 = 1.0_f64/0.0_f64;
|
||||
pub const INFINITY: f64 = 1.0_f64 / 0.0_f64;
|
||||
/// Negative infinity (-∞).
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub const NEG_INFINITY: f64 = -1.0_f64/0.0_f64;
|
||||
pub const NEG_INFINITY: f64 = -1.0_f64 / 0.0_f64;
|
||||
|
||||
/// Basic mathematical constants.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -144,26 +144,40 @@ pub mod consts {
|
|||
issue = "32110")]
|
||||
impl Float for f64 {
|
||||
#[inline]
|
||||
fn nan() -> f64 { NAN }
|
||||
fn nan() -> f64 {
|
||||
NAN
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn infinity() -> f64 { INFINITY }
|
||||
fn infinity() -> f64 {
|
||||
INFINITY
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn neg_infinity() -> f64 { NEG_INFINITY }
|
||||
fn neg_infinity() -> f64 {
|
||||
NEG_INFINITY
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn zero() -> f64 { 0.0 }
|
||||
fn zero() -> f64 {
|
||||
0.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn neg_zero() -> f64 { -0.0 }
|
||||
fn neg_zero() -> f64 {
|
||||
-0.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn one() -> f64 { 1.0 }
|
||||
fn one() -> f64 {
|
||||
1.0
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is NaN.
|
||||
#[inline]
|
||||
fn is_nan(self) -> bool { self != self }
|
||||
fn is_nan(self) -> bool {
|
||||
self != self
|
||||
}
|
||||
|
||||
/// Returns `true` if the number is infinite.
|
||||
#[inline]
|
||||
|
@ -192,11 +206,11 @@ fn classify(self) -> Fp {
|
|||
|
||||
let bits: u64 = unsafe { mem::transmute(self) };
|
||||
match (bits & MAN_MASK, bits & EXP_MASK) {
|
||||
(0, 0) => Fp::Zero,
|
||||
(_, 0) => Fp::Subnormal,
|
||||
(0, 0) => Fp::Zero,
|
||||
(_, 0) => Fp::Subnormal,
|
||||
(0, EXP_MASK) => Fp::Infinite,
|
||||
(_, EXP_MASK) => Fp::Nan,
|
||||
_ => Fp::Normal,
|
||||
_ => Fp::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -252,7 +266,9 @@ fn is_sign_negative(self) -> bool {
|
|||
|
||||
/// Returns the reciprocal (multiplicative inverse) of the number.
|
||||
#[inline]
|
||||
fn recip(self) -> f64 { 1.0 / self }
|
||||
fn recip(self) -> f64 {
|
||||
1.0 / self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn powi(self, n: i32) -> f64 {
|
||||
|
@ -261,7 +277,9 @@ fn powi(self, n: i32) -> f64 {
|
|||
|
||||
/// Converts to degrees, assuming the number is in radians.
|
||||
#[inline]
|
||||
fn to_degrees(self) -> f64 { self * (180.0f64 / consts::PI) }
|
||||
fn to_degrees(self) -> f64 {
|
||||
self * (180.0f64 / consts::PI)
|
||||
}
|
||||
|
||||
/// Converts to radians, assuming the number is in degrees.
|
||||
#[inline]
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Default, Hash)]
|
||||
pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
|
||||
pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub T);
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: fmt::Debug> fmt::Debug for Wrapping<T> {
|
||||
|
@ -2402,7 +2403,7 @@ pub enum FpCategory {
|
|||
|
||||
/// Positive or negative infinity.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
Infinite ,
|
||||
Infinite,
|
||||
|
||||
/// Positive or negative zero.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -2662,8 +2663,7 @@ fn checked_add(&self, other: u32) -> Option<Self> {
|
|||
}
|
||||
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
|
||||
|
||||
fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
|
||||
-> Result<T, ParseIntError> {
|
||||
fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32) -> Result<T, ParseIntError> {
|
||||
use self::IntErrorKind::*;
|
||||
use self::ParseIntError as PIE;
|
||||
|
||||
|
@ -2686,7 +2686,7 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
|
|||
let (is_positive, digits) = match src[0] {
|
||||
b'+' => (true, &src[1..]),
|
||||
b'-' if is_signed_ty => (false, &src[1..]),
|
||||
_ => (true, src)
|
||||
_ => (true, src),
|
||||
};
|
||||
|
||||
if digits.is_empty() {
|
||||
|
@ -2738,7 +2738,9 @@ fn from_str_radix<T: FromStrRadixHelper>(src: &str, radix: u32)
|
|||
/// [`i8::from_str_radix()`]: ../../std/primitive.i8.html#method.from_str_radix
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct ParseIntError { kind: IntErrorKind }
|
||||
pub struct ParseIntError {
|
||||
kind: IntErrorKind,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum IntErrorKind {
|
||||
|
|
|
@ -310,13 +310,13 @@ mod platform {
|
|||
pub const isize: u32 = super::i64;
|
||||
}
|
||||
|
||||
pub const i8: u32 = (1 << 3) - 1;
|
||||
pub const i8: u32 = (1 << 3) - 1;
|
||||
pub const i16: u32 = (1 << 4) - 1;
|
||||
pub const i32: u32 = (1 << 5) - 1;
|
||||
pub const i64: u32 = (1 << 6) - 1;
|
||||
pub use self::platform::isize;
|
||||
|
||||
pub const u8: u32 = i8;
|
||||
pub const u8: u32 = i8;
|
||||
pub const u16: u32 = i16;
|
||||
pub const u32: u32 = i32;
|
||||
pub const u64: u32 = i64;
|
||||
|
|
|
@ -22,12 +22,12 @@ pub struct LogDirective {
|
|||
/// Parse an individual log level that is either a number or a symbolic log level
|
||||
fn parse_log_level(level: &str) -> Option<u32> {
|
||||
level.parse::<u32>()
|
||||
.ok()
|
||||
.or_else(|| {
|
||||
let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level));
|
||||
pos.map(|p| p as u32 + 1)
|
||||
})
|
||||
.map(|p| cmp::min(p, ::MAX_LOG_LEVEL))
|
||||
.ok()
|
||||
.or_else(|| {
|
||||
let pos = LOG_LEVEL_NAMES.iter().position(|&name| name.eq_ignore_ascii_case(level));
|
||||
pos.map(|p| p as u32 + 1)
|
||||
})
|
||||
.map(|p| cmp::min(p, ::MAX_LOG_LEVEL))
|
||||
}
|
||||
|
||||
/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1/foo")
|
||||
|
@ -52,32 +52,31 @@ pub fn parse_logging_spec(spec: &str) -> (Vec<LogDirective>, Option<String>) {
|
|||
continue;
|
||||
}
|
||||
let mut parts = s.split('=');
|
||||
let (log_level, name) = match (parts.next(),
|
||||
parts.next().map(|s| s.trim()),
|
||||
parts.next()) {
|
||||
(Some(part0), None, None) => {
|
||||
// if the single argument is a log-level string or number,
|
||||
// treat that as a global fallback
|
||||
match parse_log_level(part0) {
|
||||
Some(num) => (num, None),
|
||||
None => (::MAX_LOG_LEVEL, Some(part0)),
|
||||
}
|
||||
}
|
||||
(Some(part0), Some(""), None) => (::MAX_LOG_LEVEL, Some(part0)),
|
||||
(Some(part0), Some(part1), None) => {
|
||||
match parse_log_level(part1) {
|
||||
Some(num) => (num, Some(part0)),
|
||||
_ => {
|
||||
println!("warning: invalid logging spec '{}', ignoring it", part1);
|
||||
continue;
|
||||
let (log_level, name) =
|
||||
match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) {
|
||||
(Some(part0), None, None) => {
|
||||
// if the single argument is a log-level string or number,
|
||||
// treat that as a global fallback
|
||||
match parse_log_level(part0) {
|
||||
Some(num) => (num, None),
|
||||
None => (::MAX_LOG_LEVEL, Some(part0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
println!("warning: invalid logging spec '{}', ignoring it", s);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
(Some(part0), Some(""), None) => (::MAX_LOG_LEVEL, Some(part0)),
|
||||
(Some(part0), Some(part1), None) => {
|
||||
match parse_log_level(part1) {
|
||||
Some(num) => (num, Some(part0)),
|
||||
_ => {
|
||||
println!("warning: invalid logging spec '{}', ignoring it", part1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
println!("warning: invalid logging spec '{}', ignoring it", s);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
dirs.push(LogDirective {
|
||||
name: name.map(str::to_owned),
|
||||
level: log_level,
|
||||
|
|
|
@ -276,13 +276,15 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
|
|||
err
|
||||
}
|
||||
ResolutionError::VariableNotBoundInPattern(variable_name, from, to) => {
|
||||
struct_span_err!(resolver.session,
|
||||
let mut err = struct_span_err!(resolver.session,
|
||||
span,
|
||||
E0408,
|
||||
"variable `{}` from pattern #{} is not bound in pattern #{}",
|
||||
variable_name,
|
||||
from,
|
||||
to)
|
||||
to);
|
||||
err.span_label(span, &format!("pattern doesn't bind `{}`", variable_name));
|
||||
err
|
||||
}
|
||||
ResolutionError::VariableBoundWithDifferentMode(variable_name,
|
||||
pattern_number,
|
||||
|
|
|
@ -104,6 +104,7 @@ pub enum Class {
|
|||
Lifetime,
|
||||
PreludeTy,
|
||||
PreludeVal,
|
||||
QuestionMark,
|
||||
}
|
||||
|
||||
/// Trait that controls writing the output of syntax highlighting. Users should
|
||||
|
@ -237,8 +238,10 @@ fn write_token<W: Writer>(&mut self,
|
|||
token::Dot | token::DotDot | token::DotDotDot | token::Comma | token::Semi |
|
||||
token::Colon | token::ModSep | token::LArrow | token::OpenDelim(_) |
|
||||
token::CloseDelim(token::Brace) | token::CloseDelim(token::Paren) |
|
||||
token::CloseDelim(token::NoDelim) |
|
||||
token::Question => Class::None,
|
||||
token::CloseDelim(token::NoDelim) => Class::None,
|
||||
|
||||
token::Question => Class::QuestionMark,
|
||||
|
||||
token::Dollar => {
|
||||
if self.lexer.peek().tok.is_ident() {
|
||||
self.in_macro_nonterminal = true;
|
||||
|
@ -348,6 +351,7 @@ pub fn rustdoc_class(self) -> &'static str {
|
|||
Class::Lifetime => "lifetime",
|
||||
Class::PreludeTy => "prelude-ty",
|
||||
Class::PreludeVal => "prelude-val",
|
||||
Class::QuestionMark => "question-mark"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -570,6 +570,10 @@ pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val,
|
|||
pre.rust .attribute, pre.rust .attribute .ident { color: #C82829; }
|
||||
pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
|
||||
pre.rust .lifetime { color: #B76514; }
|
||||
pre.rust .question-mark {
|
||||
color: #ff9011;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rusttest { display: none; }
|
||||
pre.rust { position: relative; }
|
||||
|
|
|
@ -20,11 +20,15 @@
|
|||
|
||||
/// The `BufReader` struct adds buffering to any reader.
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with a `Read` instance.
|
||||
/// For example, every call to `read` on `TcpStream` results in a system call.
|
||||
/// A `BufReader` performs large, infrequent reads on the underlying `Read`
|
||||
/// It can be excessively inefficient to work directly with a [`Read`] instance.
|
||||
/// For example, every call to [`read`] on [`TcpStream`] results in a system call.
|
||||
/// A `BufReader` performs large, infrequent reads on the underlying [`Read`]
|
||||
/// and maintains an in-memory buffer of the results.
|
||||
///
|
||||
/// [`Read`]: ../../std/io/trait.Read.html
|
||||
/// [`read`]: ../../std/net/struct.TcpStream.html#method.read
|
||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
@ -254,7 +258,7 @@ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
|||
/// Wraps a writer and buffers its output.
|
||||
///
|
||||
/// It can be excessively inefficient to work directly with something that
|
||||
/// implements `Write`. For example, every call to `write` on `TcpStream`
|
||||
/// implements [`Write`]. For example, every call to [`write`] on [`TcpStream`]
|
||||
/// results in a system call. A `BufWriter` keeps an in-memory buffer of data
|
||||
/// and writes it to an underlying writer in large, infrequent batches.
|
||||
///
|
||||
|
@ -262,7 +266,7 @@ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Let's write the numbers one through ten to a `TcpStream`:
|
||||
/// Let's write the numbers one through ten to a [`TcpStream`]:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::io::prelude::*;
|
||||
|
@ -294,6 +298,10 @@ fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
|
|||
/// By wrapping the stream with a `BufWriter`, these ten writes are all grouped
|
||||
/// together by the buffer, and will all be written out in one system call when
|
||||
/// the `stream` is dropped.
|
||||
///
|
||||
/// [`Write`]: ../../std/io/trait.Write.html
|
||||
/// [`write`]: ../../std/net/struct.TcpStream.html#method.write
|
||||
/// [`TcpStream`]: ../../std/net/struct.TcpStream.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct BufWriter<W: Write> {
|
||||
inner: Option<W>,
|
||||
|
|
|
@ -136,6 +136,10 @@ impl<T: ?Sized> RwLock<T> {
|
|||
/// This function will return an error if the RwLock is poisoned. An RwLock
|
||||
/// is poisoned whenever a writer panics while holding an exclusive lock.
|
||||
/// The failure will occur immediately after the lock has been acquired.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function might panic when called if the lock is already held by the current thread.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
|
||||
|
@ -188,6 +192,10 @@ pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
|
|||
/// This function will return an error if the RwLock is poisoned. An RwLock
|
||||
/// is poisoned whenever a writer panics while holding an exclusive lock.
|
||||
/// An error will be returned when the lock is acquired.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function might panic when called if the lock is already held by the current thread.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
|
||||
|
|
|
@ -12,7 +12,7 @@ fn main() {
|
|||
let x = Some(0);
|
||||
|
||||
match x {
|
||||
Some(y) | None => {} //~ ERROR E0408
|
||||
_ => ()
|
||||
Some(y) | None => {} //~ ERROR variable `y` from pattern #1 is not bound in pattern #2
|
||||
_ => () //~| NOTE pattern doesn't bind `y`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub enum foo {
|
|||
fn main() {
|
||||
use bar::foo::{alpha, charlie};
|
||||
match alpha {
|
||||
alpha | beta => {} //~ ERROR variable `beta` from pattern #2 is not bound in pattern #1
|
||||
charlie => {}
|
||||
alpha | beta => {} //~ ERROR variable `beta` from pattern #2 is not bound in pattern #1
|
||||
charlie => {} //~| NOTE pattern doesn't bind `beta`
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@
|
|||
fn main() {
|
||||
let y = 1;
|
||||
match y {
|
||||
a | b => {} //~ ERROR variable `a` from pattern #1 is not bound in pattern #2
|
||||
//~^ ERROR variable `b` from pattern #2 is not bound in pattern #1
|
||||
a | b => {} //~ ERROR variable `a` from pattern #1 is not bound in pattern #2
|
||||
//~^ ERROR variable `b` from pattern #2 is not bound in pattern #1
|
||||
//~| NOTE pattern doesn't bind `a`
|
||||
//~| NOTE pattern doesn't bind `b`
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue