diff --git a/RELEASES.md b/RELEASES.md index e969b91b2b643..1f7ffb53d3cad 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -144,7 +144,7 @@ Compatibility Notes [`alloc::handle_alloc_error`]: https://doc.rust-lang.org/std/alloc/fn.handle_alloc_error.html [`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default [`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html -[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default +[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_default [`iter::repeat_with`]: https://doc.rust-lang.org/std/iter/fn.repeat_with.html [`num::NonZeroUsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroUsize.html [`num::NonZeroU128`]: https://doc.rust-lang.org/std/num/struct.NonZeroU128.html diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 724d3b741903f..dc0b0aaf0bb3c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -777,7 +777,7 @@ impl<'a> Builder<'a> { // compiler, but for tools we just use the precompiled libraries that // we've downloaded let use_snapshot = mode == Mode::ToolBootstrap; - assert!(!use_snapshot || stage == 0); + assert!(!use_snapshot || stage == 0 || self.local_rebuild); let maybe_sysroot = self.sysroot(compiler); let sysroot = if use_snapshot { diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 16055078ad5eb..d876cb7f37a41 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -17,9 +17,11 @@ TOOLSTATE_FILE="$(realpath $2)" OS="$3" COMMIT="$(git rev-parse HEAD)" CHANGED_FILES="$(git diff --name-status HEAD HEAD^)" -SIX_WEEK_CYCLE="$(( ($(date +%s) / 604800 - 3) % 6 ))" -# ^ 1970 Jan 1st is a Thursday, and our release dates are also on Thursdays, -# thus we could divide by 604800 (7 days in seconds) directly. +SIX_WEEK_CYCLE="$(( ($(date +%s) / 86400 - 20) % 42 ))" +# ^ Number of days after the last promotion of beta. +# Its value is 41 on the Tuesday where "Promote master to beta (T-2)" happens. +# The Wednesday after this has value 0. +# We track this value to prevent regressing tools in the last week of the 6-week cycle. touch "$TOOLSTATE_FILE" @@ -98,7 +100,7 @@ change_toolstate() { if python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" changed; then echo 'Toolstate is not changed. Not updating.' else - if [ $SIX_WEEK_CYCLE -eq 5 ]; then + if [ $SIX_WEEK_CYCLE -ge 35 ]; then python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" regressed fi sed -i "1 a\\ diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 137e9fe2c1533..009aba5f59869 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1258,7 +1258,7 @@ impl<'b, T: ?Sized> RefMut<'b, T> { let RefMut { value, borrow } = orig; RefMut { value: f(value), - borrow: borrow, + borrow, } } @@ -1324,7 +1324,7 @@ impl<'b> BorrowRefMut<'b> { match borrow.get() { UNUSED => { borrow.set(UNUSED - 1); - Some(BorrowRefMut { borrow: borrow }) + Some(BorrowRefMut { borrow }) }, _ => None, } @@ -1467,7 +1467,7 @@ impl UnsafeCell { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub const fn new(value: T) -> UnsafeCell { - UnsafeCell { value: value } + UnsafeCell { value } } /// Unwraps the value. diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 48c6eb9414429..5681cfb04f208 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -507,7 +507,7 @@ pub trait Iterator { fn map(self, f: F) -> Map where Self: Sized, F: FnMut(Self::Item) -> B, { - Map{iter: self, f: f} + Map { iter: self, f } } /// Calls a closure on each element of an iterator. @@ -618,7 +618,7 @@ pub trait Iterator { fn filter

(self, predicate: P) -> Filter where Self: Sized, P: FnMut(&Self::Item) -> bool, { - Filter{iter: self, predicate: predicate} + Filter {iter: self, predicate } } /// Creates an iterator that both filters and maps. @@ -675,7 +675,7 @@ pub trait Iterator { fn filter_map(self, f: F) -> FilterMap where Self: Sized, F: FnMut(Self::Item) -> Option, { - FilterMap { iter: self, f: f } + FilterMap { iter: self, f } } /// Creates an iterator which gives the current iteration count as well as @@ -828,7 +828,7 @@ pub trait Iterator { fn skip_while

(self, predicate: P) -> SkipWhile where Self: Sized, P: FnMut(&Self::Item) -> bool, { - SkipWhile{iter: self, flag: false, predicate: predicate} + SkipWhile { iter: self, flag: false, predicate } } /// Creates an iterator that yields elements based on a predicate. @@ -908,7 +908,7 @@ pub trait Iterator { fn take_while

(self, predicate: P) -> TakeWhile where Self: Sized, P: FnMut(&Self::Item) -> bool, { - TakeWhile{iter: self, flag: false, predicate: predicate} + TakeWhile { iter: self, flag: false, predicate } } /// Creates an iterator that skips the first `n` elements. @@ -930,7 +930,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn skip(self, n: usize) -> Skip where Self: Sized { - Skip{iter: self, n: n} + Skip { iter: self, n } } /// Creates an iterator that yields its first `n` elements. @@ -962,7 +962,7 @@ pub trait Iterator { #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn take(self, n: usize) -> Take where Self: Sized, { - Take{iter: self, n: n} + Take { iter: self, n } } /// An iterator adaptor similar to [`fold`] that holds internal state and @@ -1007,7 +1007,7 @@ pub trait Iterator { fn scan(self, initial_state: St, f: F) -> Scan where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option, { - Scan{iter: self, f: f, state: initial_state} + Scan { iter: self, f, state: initial_state } } /// Creates an iterator that works like map, but flattens nested structure. @@ -1256,7 +1256,7 @@ pub trait Iterator { fn inspect(self, f: F) -> Inspect where Self: Sized, F: FnMut(&Self::Item), { - Inspect{iter: self, f: f} + Inspect { iter: self, f } } /// Borrows an iterator, rather than consuming it. diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index 69418434ebead..e7ed94d4d91c2 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -40,7 +40,7 @@ pub struct Decimal<'a> { impl<'a> Decimal<'a> { pub fn new(integral: &'a [u8], fractional: &'a [u8], exp: i64) -> Decimal<'a> { - Decimal { integral: integral, fractional: fractional, exp: exp } + Decimal { integral, fractional, exp } } } diff --git a/src/libcore/num/dec2flt/rawfp.rs b/src/libcore/num/dec2flt/rawfp.rs index 456d0e956d42a..38f4e4687a99b 100644 --- a/src/libcore/num/dec2flt/rawfp.rs +++ b/src/libcore/num/dec2flt/rawfp.rs @@ -45,7 +45,7 @@ pub struct Unpacked { impl Unpacked { pub fn new(sig: u64, k: i16) -> Self { - Unpacked { sig: sig, k: k } + Unpacked { sig, k } } } @@ -317,13 +317,13 @@ pub fn big_to_fp(f: &Big) -> Fp { // We cut off all bits prior to the index `start`, i.e., we effectively right-shift by // an amount of `start`, so this is also the exponent we need. let e = start as i16; - let rounded_down = Fp { f: leading, e: e }.normalize(); + let rounded_down = Fp { f: leading, e }.normalize(); // Round (half-to-even) depending on the truncated bits. match num::compare_with_half_ulp(f, start) { Less => rounded_down, Equal if leading % 2 == 0 => rounded_down, Equal | Greater => match leading.checked_add(1) { - Some(f) => Fp { f: f, e: e }.normalize(), + Some(f) => Fp { f, e }.normalize(), None => Fp { f: 1 << 63, e: e + 1 }, } } diff --git a/src/libcore/num/diy_float.rs b/src/libcore/num/diy_float.rs index 97bcba2f2ffbc..b0561da5934c0 100644 --- a/src/libcore/num/diy_float.rs +++ b/src/libcore/num/diy_float.rs @@ -42,7 +42,7 @@ impl Fp { let tmp = (bd >> 32) + (ad & MASK) + (bc & MASK) + (1 << 31) /* round */; let f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32); let e = self.e + other.e + 64; - Fp { f: f, e: e } + Fp { f, e } } /// Normalizes itself so that the resulting mantissa is at least `2^63`. @@ -74,7 +74,7 @@ impl Fp { e -= 1; } debug_assert!(f >= (1 >> 63)); - Fp { f: f, e: e } + Fp { f, e } } /// Normalizes itself to have the shared exponent. diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index b779eefce5752..c34a56f288fd4 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -77,8 +77,8 @@ pub fn decode(v: T) -> (/*negative?*/ bool, FullDecoded) { // neighbors: (mant - 2, exp) -- (mant, exp) -- (mant + 2, exp) // Float::integer_decode always preserves the exponent, // so the mantissa is scaled for subnormals. - FullDecoded::Finite(Decoded { mant: mant, minus: 1, plus: 1, - exp: exp, inclusive: even }) + FullDecoded::Finite(Decoded { mant, minus: 1, plus: 1, + exp, inclusive: even }) } FpCategory::Normal => { let minnorm = ::min_pos_norm_value().integer_decode(); diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index beaa6e140a699..21a2e72dac8c3 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -424,20 +424,20 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, match full_decoded { FullDecoded::Nan => { parts[0] = Part::Copy(b"NaN"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Infinite => { parts[0] = Part::Copy(b"inf"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Zero => { if frac_digits > 0 { // [0.][0000] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(frac_digits); - Formatted { sign: sign, parts: &parts[..2] } + Formatted { sign, parts: &parts[..2] } } else { parts[0] = Part::Copy(b"0"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } } FullDecoded::Finite(ref decoded) => { @@ -480,11 +480,11 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, match full_decoded { FullDecoded::Nan => { parts[0] = Part::Copy(b"NaN"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Infinite => { parts[0] = Part::Copy(b"inf"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Zero => { parts[0] = if dec_bounds.0 <= 0 && 0 < dec_bounds.1 { @@ -492,7 +492,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, } else { Part::Copy(if upper { b"0E0" } else { b"0e0" }) }; - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Finite(ref decoded) => { let (len, exp) = format_shortest(decoded, buf); @@ -502,7 +502,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, } else { digits_to_exp_str(&buf[..len], exp, 0, upper, parts) }; - Formatted { sign: sign, parts: parts } + Formatted { sign, parts } } } } @@ -558,21 +558,21 @@ pub fn to_exact_exp_str<'a, T, F>(mut format_exact: F, v: T, match full_decoded { FullDecoded::Nan => { parts[0] = Part::Copy(b"NaN"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Infinite => { parts[0] = Part::Copy(b"inf"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Zero => { if ndigits > 1 { // [0.][0000][e0] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(ndigits - 1); parts[2] = Part::Copy(if upper { b"E0" } else { b"e0" }); - Formatted { sign: sign, parts: &parts[..3] } + Formatted { sign, parts: &parts[..3] } } else { parts[0] = Part::Copy(if upper { b"0E0" } else { b"0e0" }); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } } FullDecoded::Finite(ref decoded) => { @@ -613,20 +613,20 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, match full_decoded { FullDecoded::Nan => { parts[0] = Part::Copy(b"NaN"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Infinite => { parts[0] = Part::Copy(b"inf"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } FullDecoded::Zero => { if frac_digits > 0 { // [0.][0000] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(frac_digits); - Formatted { sign: sign, parts: &parts[..2] } + Formatted { sign, parts: &parts[..2] } } else { parts[0] = Part::Copy(b"0"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } } FullDecoded::Finite(ref decoded) => { @@ -646,10 +646,10 @@ pub fn to_exact_fixed_str<'a, T, F>(mut format_exact: F, v: T, if frac_digits > 0 { // [0.][0000] parts[0] = Part::Copy(b"0."); parts[1] = Part::Zero(frac_digits); - Formatted { sign: sign, parts: &parts[..2] } + Formatted { sign, parts: &parts[..2] } } else { parts[0] = Part::Copy(b"0"); - Formatted { sign: sign, parts: &parts[..1] } + Formatted { sign, parts: &parts[..1] } } } else { Formatted { sign, diff --git a/src/libcore/num/flt2dec/strategy/grisu.rs b/src/libcore/num/flt2dec/strategy/grisu.rs index f33186e59c2e6..effe073c3816c 100644 --- a/src/libcore/num/flt2dec/strategy/grisu.rs +++ b/src/libcore/num/flt2dec/strategy/grisu.rs @@ -129,7 +129,7 @@ pub fn cached_power(alpha: i16, gamma: i16) -> (i16, Fp) { let idx = ((gamma as i32) - offset) * range / domain; let (f, e, k) = CACHED_POW10[idx as usize]; debug_assert!(alpha <= e && e <= gamma); - (k, Fp { f: f, e: e }) + (k, Fp { f, e }) } /// Given `x > 0`, returns `(k, 10^k)` such that `10^k <= x < 10^(k+1)`. diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 3bc2861460e14..6e2fbf6f84f0f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1892,47 +1892,119 @@ $EndFeature, " pub fn is_negative(self) -> bool { self < 0 } } - /// Return the memory representation of this integer as a byte array. + /// Return the memory representation of this integer as a byte array in + /// big-endian (network) byte order. /// - /// The target platform’s native endianness is used. - /// Portable code likely wants to use this after [`to_be`] or [`to_le`]. + /// # Examples /// - /// [`to_be`]: #method.to_be - /// [`to_le`]: #method.to_le + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let bytes = 0x12345678i32.to_be_bytes(); + /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn to_be_bytes(self) -> [u8; mem::size_of::()] { + self.to_be().to_ne_bytes() + } + + /// Return the memory representation of this integer as a byte array in + /// little-endian byte order. + /// + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let bytes = 0x12345678i32.to_le_bytes(); + /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn to_le_bytes(self) -> [u8; mem::size_of::()] { + self.to_le().to_ne_bytes() + } + + /// Return the memory representation of this integer as a byte array in + /// native byte order. + /// + /// As the target platform's native endianness is used, portable code + /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, + /// instead. + /// + /// [`to_be_bytes`]: #method.to_be_bytes + /// [`to_le_bytes`]: #method.to_le_bytes /// /// # Examples /// /// ``` /// #![feature(int_to_from_bytes)] /// - /// let bytes = i32::min_value().to_be().to_bytes(); + /// let bytes = i32::min_value().to_be().to_ne_bytes(); /// assert_eq!(bytes, [0x80, 0, 0, 0]); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] - pub fn to_bytes(self) -> [u8; mem::size_of::()] { + pub fn to_ne_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } } - /// Create an integer value from its memory representation as a byte array. + /// Create an integer value from its representation as a byte array in + /// big endian. /// - /// The target platform’s native endianness is used. - /// Portable code likely wants to use [`from_be`] or [`from_le`] after this. + /// # Examples /// - /// [`from_be`]: #method.from_be - /// [`from_le`]: #method.from_le + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let int = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]); + /// assert_eq!(int, 0x12_34_56_78); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn from_be_bytes(bytes: [u8; mem::size_of::()]) -> Self { + Self::from_be(Self::from_ne_bytes(bytes)) + } + + /// Create an integer value from its representation as a byte array in + /// little endian. /// /// # Examples /// /// ``` /// #![feature(int_to_from_bytes)] /// - /// let int = i32::from_be(i32::from_bytes([0x80, 0, 0, 0])); + /// let int = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]); + /// assert_eq!(int, 0x78_56_34_12); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn from_le_bytes(bytes: [u8; mem::size_of::()]) -> Self { + Self::from_le(Self::from_ne_bytes(bytes)) + } + + /// Create an integer value from its memory representation as a byte + /// array in native endianness. + /// + /// As the target platform's native endianness is used, portable code + /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as + /// appropriate instead. + /// + /// [`from_be_bytes`]: #method.from_be_bytes + /// [`from_le_bytes`]: #method.from_le_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let int = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0])); /// assert_eq!(int, i32::min_value()); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] - pub fn from_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) } } } @@ -3517,7 +3589,7 @@ $EndFeature, " /// let bytes = 0x1234_5678_u32.to_be().to_bytes(); /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn to_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } @@ -3539,7 +3611,7 @@ $EndFeature, " /// let int = u32::from_be(u32::from_bytes([0x12, 0x34, 0x56, 0x78])); /// assert_eq!(int, 0x1234_5678_u32); /// ``` - #[unstable(feature = "int_to_from_bytes", issue = "49792")] + #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] pub fn from_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 479c10c4ffbae..c8670e5ec34d3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -448,6 +448,12 @@ pub unsafe fn write_unaligned(dst: *mut T, src: T) { /// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use /// because it will attempt to drop the value previously at `*src`. /// +/// Just like in C, whether an operation is volatile has no bearing whatsoever +/// on questions involving concurrent access from multiple threads. Volatile +/// accesses behave exactly like non-atomic accesses in that regard. In particular, +/// a race between a `read_volatile` and any write operation to the same location +/// is undefined behavior. +/// /// # Examples /// /// Basic usage: @@ -498,6 +504,12 @@ pub unsafe fn read_volatile(src: *const T) -> T { /// This is appropriate for initializing uninitialized memory, or overwriting /// memory that has previously been `read` from. /// +/// Just like in C, whether an operation is volatile has no bearing whatsoever +/// on questions involving concurrent access from multiple threads. Volatile +/// accesses behave exactly like non-atomic accesses in that regard. In particular, +/// a race between a `write_volatile` and any other operation (reading or writing) +/// on the same location is undefined behavior. +/// /// # Examples /// /// Basic usage: @@ -1057,6 +1069,12 @@ impl *const T { /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use /// because it will attempt to drop the value previously at `*self`. /// + /// Just like in C, whether an operation is volatile has no bearing whatsoever + /// on questions involving concurrent access from multiple threads. Volatile + /// accesses behave exactly like non-atomic accesses in that regard. In particular, + /// a race between a `read_volatile` and any write operation to the same location + /// is undefined behavior. + /// /// # Examples /// /// Basic usage: @@ -1790,6 +1808,12 @@ impl *mut T { /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use /// because it will attempt to drop the value previously at `*self`. /// + /// Just like in C, whether an operation is volatile has no bearing whatsoever + /// on questions involving concurrent access from multiple threads. Volatile + /// accesses behave exactly like non-atomic accesses in that regard. In particular, + /// a race between a `read_volatile` and any write operation to the same location + /// is undefined behavior. + /// /// # Examples /// /// Basic usage: @@ -2105,6 +2129,12 @@ impl *mut T { /// This is appropriate for initializing uninitialized memory, or overwriting /// memory that has previously been `read` from. /// + /// Just like in C, whether an operation is volatile has no bearing whatsoever + /// on questions involving concurrent access from multiple threads. Volatile + /// accesses behave exactly like non-atomic accesses in that regard. In particular, + /// a race between a `write_volatile` and any other operation (reading or writing) + /// on the same location is undefined behavior. + /// /// # Examples /// /// Basic usage: diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index a4dde38cb7bb6..dfebe460ff801 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -621,7 +621,7 @@ impl [T] { #[inline] pub fn windows(&self, size: usize) -> Windows { assert!(size != 0); - Windows { v: self, size: size } + Windows { v: self, size } } /// Returns an iterator over `chunk_size` elements of the slice at a @@ -652,7 +652,7 @@ impl [T] { #[inline] pub fn chunks(&self, chunk_size: usize) -> Chunks { assert!(chunk_size != 0); - Chunks { v: self, chunk_size: chunk_size } + Chunks { v: self, chunk_size } } /// Returns an iterator over `chunk_size` elements of the slice at a time. @@ -687,7 +687,7 @@ impl [T] { #[inline] pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut { assert!(chunk_size != 0); - ChunksMut { v: self, chunk_size: chunk_size } + ChunksMut { v: self, chunk_size } } /// Returns an iterator over `chunk_size` elements of the slice at a @@ -724,7 +724,7 @@ impl [T] { let rem = self.len() % chunk_size; let len = self.len() - rem; let (fst, snd) = self.split_at(len); - ExactChunks { v: fst, rem: snd, chunk_size: chunk_size} + ExactChunks { v: fst, rem: snd, chunk_size } } /// Returns an iterator over `chunk_size` elements of the slice at a time. @@ -766,7 +766,7 @@ impl [T] { let rem = self.len() % chunk_size; let len = self.len() - rem; let (fst, snd) = self.split_at_mut(len); - ExactChunksMut { v: fst, rem: snd, chunk_size: chunk_size} + ExactChunksMut { v: fst, rem: snd, chunk_size } } /// Divides one slice into two at an index. @@ -916,7 +916,7 @@ impl [T] { pub fn split_mut(&mut self, pred: F) -> SplitMut where F: FnMut(&T) -> bool { - SplitMut { v: self, pred: pred, finished: false } + SplitMut { v: self, pred, finished: false } } /// Returns an iterator over subslices separated by elements that match diff --git a/src/libcore/task/context.rs b/src/libcore/task/context.rs index 1fc975cb17881..121f93b666bce 100644 --- a/src/libcore/task/context.rs +++ b/src/libcore/task/context.rs @@ -86,7 +86,7 @@ impl<'a> Context<'a> { { Context { local_waker: self.local_waker, - executor: executor, + executor, } } } diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 54973b7b7783a..b58920224eb70 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -91,7 +91,7 @@ impl Duration { let secs = secs.checked_add((nanos / NANOS_PER_SEC) as u64) .expect("overflow in Duration::new"); let nanos = nanos % NANOS_PER_SEC; - Duration { secs: secs, nanos: nanos } + Duration { secs, nanos } } /// Creates a new `Duration` from the specified number of whole seconds. @@ -109,7 +109,7 @@ impl Duration { #[stable(feature = "duration", since = "1.3.0")] #[inline] pub const fn from_secs(secs: u64) -> Duration { - Duration { secs: secs, nanos: 0 } + Duration { secs, nanos: 0 } } /// Creates a new `Duration` from the specified number of milliseconds. @@ -387,7 +387,7 @@ impl Duration { } }; debug_assert!(nanos < NANOS_PER_SEC); - Some(Duration { secs: secs, nanos: nanos }) + Some(Duration { secs, nanos }) } else { None } @@ -453,7 +453,7 @@ impl Duration { let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64); let nanos = self.nanos / rhs + (extra_nanos as u32); debug_assert!(nanos < NANOS_PER_SEC); - Some(Duration { secs: secs, nanos: nanos }) + Some(Duration { secs, nanos }) } else { None } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 8481f738adc7b..4ef4397d974c4 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -84,7 +84,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue { let msg = "denote infinite loops with `loop { ... }`"; let condition_span = cx.tcx.sess.codemap().def_span(e.span); let mut err = cx.struct_span_lint(WHILE_TRUE, condition_span, msg); - err.span_suggestion_short(condition_span, "use `loop`", "loop".to_owned()); + err.span_suggestion_short_with_applicability( + condition_span, + "use `loop`", + "loop".to_owned(), + Applicability::MachineApplicable + ); err.emit(); } } @@ -191,7 +196,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonShorthandFieldPatterns { fieldpat.span, &format!("the `{}:` in this pattern is redundant", ident)); let subspan = cx.tcx.sess.codemap().span_through_char(fieldpat.span, ':'); - err.span_suggestion_short(subspan, "remove this", ident.to_string()); + err.span_suggestion_short_with_applicability( + subspan, + "remove this", + ident.to_string(), + Applicability::MachineApplicable + ); err.emit(); } } @@ -708,10 +718,11 @@ impl EarlyLintPass for BadRepr { | "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => { // if the literal could have been a valid `repr` arg, // suggest the correct syntax - warn.span_suggestion( + warn.span_suggestion_with_applicability( attr.span, "give `repr` a hint", repr_str(&lit.as_str()), + Applicability::MachineApplicable ); suggested = true; } @@ -779,7 +790,12 @@ impl EarlyLintPass for DeprecatedAttr { let msg = format!("use of deprecated attribute `{}`: {}. See {}", name, reason, link); let mut err = cx.struct_span_lint(DEPRECATED, attr.span, &msg); - err.span_suggestion_short(attr.span, "remove this attribute", "".to_owned()); + err.span_suggestion_short_with_applicability( + attr.span, + "remove this attribute", + "".to_owned(), + Applicability::MachineApplicable + ); err.emit(); } return; @@ -1201,7 +1217,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { } }; if let Some(replacement) = suggestion { - err.span_suggestion(vis.span, "try making it public", replacement); + err.span_suggestion_with_applicability( + vis.span, + "try making it public", + replacement, + Applicability::MachineApplicable + ); } }; @@ -1225,9 +1246,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { it.span, "functions generic over \ types must be mangled"); - err.span_suggestion_short(no_mangle_attr.span, - "remove this attribute", - "".to_owned()); + err.span_suggestion_short_with_applicability( + no_mangle_attr.span, + "remove this attribute", + "".to_owned(), + // Use of `#[no_mangle]` suggests FFI intent; correct + // fix may be to monomorphize source by hand + Applicability::MaybeIncorrect + ); err.emit(); break; } @@ -1257,9 +1283,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems { .unwrap_or(0) as u32; // `const` is 5 chars let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5)); - err.span_suggestion(const_span, - "try a static value", - "pub static".to_owned()); + err.span_suggestion_with_applicability( + const_span, + "try a static value", + "pub static".to_owned(), + Applicability::MachineApplicable + ); err.emit(); } } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index ad4a4fbff649c..4dc66fb812144 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -22,6 +22,7 @@ use std::cmp; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::{ast, attr}; +use syntax::errors::Applicability; use rustc_target::spec::abi::Abi; use syntax_pos::Span; use syntax::codemap; @@ -143,9 +144,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { OVERFLOWING_LITERALS, parent_expr.span, "only u8 can be cast into char"); - err.span_suggestion(parent_expr.span, - &"use a char literal instead", - format!("'\\u{{{:X}}}'", lit_val)); + err.span_suggestion_with_applicability( + parent_expr.span, + &"use a char literal instead", + format!("'\\u{{{:X}}}'", lit_val), + Applicability::MachineApplicable + ); err.emit(); return } @@ -398,10 +402,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits { { if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { let (sans_suffix, _) = repr_str.split_at(pos); - err.span_suggestion( + err.span_suggestion_with_applicability( expr.span, &format!("consider using `{}` instead", sugg_ty), format!("{}{}", sans_suffix, sugg_ty), + Applicability::MachineApplicable ); } else { err.help(&format!("consider using `{}` instead", sugg_ty)); diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index da291f56ee4e5..2b8540ea3861a 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -17,6 +17,7 @@ use lint::{LintPass, EarlyLintPass, LateLintPass}; use syntax::ast; use syntax::attr; +use syntax::errors::Applicability; use syntax::feature_gate::{BUILTIN_ATTRIBUTES, AttributeType}; use syntax::print::pprust; use syntax::symbol::keywords; @@ -303,9 +304,12 @@ impl UnusedParens { _ => false, } }).to_owned(); - err.span_suggestion_short(value.span, - "remove these parentheses", - parens_removed); + err.span_suggestion_short_with_applicability( + value.span, + "remove these parentheses", + parens_removed, + Applicability::MachineApplicable + ); err.emit(); } } diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 405952065dacb..5c3a016a82b4c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1015,7 +1015,7 @@ struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b: 'a, 'tcx: 'b> { impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { fn path_is_private_type(&self, path: &hir::Path) -> bool { let did = match path.def { - Def::PrimTy(..) | Def::SelfTy(..) => return false, + Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => return false, def => def.def_id(), }; diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index b689e2fa3854e..496029e33fc65 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -610,11 +610,16 @@ a { .content .search-results td:first-child { padding-right: 0; - width: 75%; + width: 50%; } .content .search-results td:first-child a { padding-right: 10px; } +.content .search-results td:first-child a:after { + clear: both; + content: ""; + display: block; +} .content .search-results td:first-child a span { float: left; } diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index b4342f4749185..faca264ea1006 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -33,7 +33,7 @@ h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.t background: rgba(0, 0, 0, 0); } -.docblock p > code, .docblock-short p > code { +.docblock code, .docblock-short code { background-color: #2A2A2A; } pre { diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index e84e3cb56636e..5725a41d939d5 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -35,7 +35,7 @@ h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.t background: rgba(0, 0, 0, 0); } -.docblock p > code, .docblock-short p > code { +.docblock code, .docblock-short code { background-color: #F5F5F5; } pre { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 0a4955f4fbd10..dda97cfdb2c4b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -290,7 +290,7 @@ fn opts() -> Vec { "edition to use when compiling rust code (default: 2015)", "EDITION") }), - unstable("color", |o| { + stable("color", |o| { o.optopt("", "color", "Configure coloring of output: @@ -299,7 +299,7 @@ fn opts() -> Vec { never = never colorize output", "auto|always|never") }), - unstable("error-format", |o| { + stable("error-format", |o| { o.optopt("", "error-format", "How errors and other messages are produced", diff --git a/src/libstd/future.rs b/src/libstd/future.rs index c1cc36f3b419a..12ea1ea9f9d49 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -108,9 +108,9 @@ where #[unstable(feature = "gen_future", issue = "50547")] /// Polls a future in the current thread-local task context. -pub fn poll_in_task_cx(f: &mut PinMut) -> Poll +pub fn poll_in_task_cx(f: PinMut) -> Poll where F: Future { - get_task_cx(|cx| f.reborrow().poll(cx)) + get_task_cx(|cx| f.poll(cx)) } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a96e2ba21345b..f15494c5fd7f5 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -227,14 +227,17 @@ macro_rules! eprintln { macro_rules! await { ($e:expr) => { { let mut pinned = $e; - let mut pinned = unsafe { $crate::mem::PinMut::new_unchecked(&mut pinned) }; loop { - match $crate::future::poll_in_task_cx(&mut pinned) { - // FIXME(cramertj) prior to stabilizing await, we have to ensure that this - // can't be used to create a generator on stable via `|| await!()`. - $crate::task::Poll::Pending => yield, - $crate::task::Poll::Ready(x) => break x, + if let $crate::task::Poll::Ready(x) = + $crate::future::poll_in_task_cx(unsafe { + $crate::mem::PinMut::new_unchecked(&mut pinned) + }) + { + break x; } + // FIXME(cramertj) prior to stabilizing await, we have to ensure that this + // can't be used to create a generator on stable via `|| await!()`. + yield } } } } diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 10282ecb65883..3abc260b45868 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -178,6 +178,10 @@ impl Once { /// happens-before relation between the closure and code executing after the /// return). /// + /// If the given closure recusively invokes `call_once` on the same `Once` + /// instance the exact behavior is not specified, allowed outcomes are + /// a panic or a deadlock. + /// /// # Examples /// /// ``` diff --git a/src/test/ui/lint/unused_parens_json_suggestion.stderr b/src/test/ui/lint/unused_parens_json_suggestion.stderr index 2ec0111ff4b66..2a9bd2948ffeb 100644 --- a/src/test/ui/lint/unused_parens_json_suggestion.stderr +++ b/src/test/ui/lint/unused_parens_json_suggestion.stderr @@ -82,7 +82,7 @@ ], "label": null, "suggested_replacement": "1 / (2 + 3)", - "suggestion_applicability": "Unspecified", + "suggestion_applicability": "MachineApplicable", "expansion": null } ],