From fdfb964a821a2f61353146629977eecafc0aa947 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 18 Jan 2018 15:28:10 +0000 Subject: [PATCH 01/26] Document the behaviour of infinite iterators on potentially-computable methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s not entirely clear from the current documentation what behaviour calling a method such as `min` on an infinite iterator like `RangeFrom` is. One might expect this to terminate, but in fact, for infinite iterators, `min` is always nonterminating (at least in the standard library). This adds a quick note about this behaviour for clarification. --- src/libcore/iter/iterator.rs | 4 ++++ src/libcore/iter/mod.rs | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 35cd7441c66bc..209a22d534a2e 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -24,6 +24,10 @@ fn _assert_is_object_safe(_: &Iterator) {} /// This is the main iterator trait. For more about the concept of iterators /// generally, please see the [module-level documentation]. In particular, you /// may want to know how to [implement `Iterator`][impl]. +/// +/// Note: Methods on infinite iterators that generally require traversing every +/// element to produce a result may not terminate, even on traits for which a +/// result is determinable in finite time. /// /// [module-level documentation]: index.html /// [impl]: index.html#implementing-iterator diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 06c29b47bf921..3a5a72d1b87c1 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -297,8 +297,22 @@ //! ``` //! //! This will print the numbers `0` through `4`, each on their own line. +//! +//! Bear in mind that methods on infinite iterators, even those for which a +//! result can be computed in finite time, may not terminate. Specifically, +//! methods such as [`min`], which in the general case require traversing +//! every element in the iterator, are likely never to terminate for any +//! infinite iterators. +//! +//! ``` +//! let positives = 1..; +//! let least = positives.min().unwrap(); // Oh no! An infinite loop! +//! // `positives.min` causes an infinite loop, so we won't reach this point! +//! println!("The least positive number is {}.", least); +//! ``` //! //! [`take`]: trait.Iterator.html#method.take +//! [`min`]: trait.Iterator.html#method.min #![stable(feature = "rust1", since = "1.0.0")] From 91668fbf230b388330da9591ba310c7e35ef9611 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 18 Jan 2018 17:49:32 +0000 Subject: [PATCH 02/26] Make example no_run --- src/libcore/iter/iterator.rs | 2 +- src/libcore/iter/mod.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 209a22d534a2e..da9af214207b6 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -24,7 +24,7 @@ fn _assert_is_object_safe(_: &Iterator) {} /// This is the main iterator trait. For more about the concept of iterators /// generally, please see the [module-level documentation]. In particular, you /// may want to know how to [implement `Iterator`][impl]. -/// +/// /// Note: Methods on infinite iterators that generally require traversing every /// element to produce a result may not terminate, even on traits for which a /// result is determinable in finite time. diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 3a5a72d1b87c1..ae10ac385ab50 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -297,14 +297,14 @@ //! ``` //! //! This will print the numbers `0` through `4`, each on their own line. -//! +//! //! Bear in mind that methods on infinite iterators, even those for which a //! result can be computed in finite time, may not terminate. Specifically, //! methods such as [`min`], which in the general case require traversing //! every element in the iterator, are likely never to terminate for any //! infinite iterators. -//! -//! ``` +//! +//! ```no_run //! let positives = 1..; //! let least = positives.min().unwrap(); // Oh no! An infinite loop! //! // `positives.min` causes an infinite loop, so we won't reach this point! From 0be51730ee51c009cdd7cd5f77fcd1f2b898f5b7 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 19 Jan 2018 21:16:34 +0000 Subject: [PATCH 03/26] Adjust language as per suggestions --- src/libcore/iter/iterator.rs | 8 ++++---- src/libcore/iter/mod.rs | 12 +++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index da9af214207b6..23fded0669a6f 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -25,10 +25,6 @@ fn _assert_is_object_safe(_: &Iterator) {} /// generally, please see the [module-level documentation]. In particular, you /// may want to know how to [implement `Iterator`][impl]. /// -/// Note: Methods on infinite iterators that generally require traversing every -/// element to produce a result may not terminate, even on traits for which a -/// result is determinable in finite time. -/// /// [module-level documentation]: index.html /// [impl]: index.html#implementing-iterator #[stable(feature = "rust1", since = "1.0.0")] @@ -1430,6 +1426,10 @@ pub trait Iterator { /// Folding is useful whenever you have a collection of something, and want /// to produce a single value from it. /// + /// Note: `fold()`, and similar methods that traverse the entire iterator, + /// may not terminate for infinite iterators, even on traits for which a + /// result is determinable in finite time. + /// /// # Examples /// /// Basic usage: diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index ae10ac385ab50..d1fdedd1b235f 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -299,15 +299,17 @@ //! This will print the numbers `0` through `4`, each on their own line. //! //! Bear in mind that methods on infinite iterators, even those for which a -//! result can be computed in finite time, may not terminate. Specifically, -//! methods such as [`min`], which in the general case require traversing -//! every element in the iterator, are likely never to terminate for any -//! infinite iterators. +//! result can be determined mathematically in finite time, may not terminate. +//! Specifically, methods such as [`min`], which in the general case require +//! traversing every element in the iterator, are likely not to return +//! successfully for any infinite iterators. //! //! ```no_run //! let positives = 1..; //! let least = positives.min().unwrap(); // Oh no! An infinite loop! -//! // `positives.min` causes an infinite loop, so we won't reach this point! +//! // `positives.min` will either overflow and panic (in debug mode), +//! // or cause an infinite loop (in release mode), so we won't reach +//! // this point! //! println!("The least positive number is {}.", least); //! ``` //! From f129374d11d51ca23d85bc678fbc1ed4e7082ab1 Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 21 Jan 2018 19:45:27 +0000 Subject: [PATCH 04/26] Use repeat instead of RangeFrom --- src/libcore/iter/mod.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index d1fdedd1b235f..4490f15f446fe 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -305,12 +305,10 @@ //! successfully for any infinite iterators. //! //! ```no_run -//! let positives = 1..; -//! let least = positives.min().unwrap(); // Oh no! An infinite loop! -//! // `positives.min` will either overflow and panic (in debug mode), -//! // or cause an infinite loop (in release mode), so we won't reach -//! // this point! -//! println!("The least positive number is {}.", least); +//! let ones = std::iter::repeat(1); +//! let least = ones.min().unwrap(); // Oh no! An infinite loop! +//! // `ones.min()` causes an infinite loop, so we won't reach this point! +//! println!("The smallest number one is {}.", least); //! ``` //! //! [`take`]: trait.Iterator.html#method.take From 838ddbf908f63a0a3d8629d9dc16592a27a8ba30 Mon Sep 17 00:00:00 2001 From: tinaun Date: Fri, 26 Jan 2018 18:52:27 -0500 Subject: [PATCH 05/26] derive PartialEq and Eq for `ParseCharError` unlike the other Parse*Error types, ParseCharError didn't have these implemented for whatever reason --- src/libcore/char.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/char.rs b/src/libcore/char.rs index e8b81db07067c..7215bd2a47684 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -211,7 +211,7 @@ impl From for char { /// An error which can be returned when parsing a char. #[stable(feature = "char_from_str", since = "1.20.0")] -#[derive(Clone, Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct ParseCharError { kind: CharErrorKind, } From 505ef7bc069d9def137c3c469ee8bdd487882730 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 21 Jan 2018 19:18:57 -0700 Subject: [PATCH 06/26] Remove unused blake2b implementation --- src/librustc_data_structures/blake2b.rs | 363 ------------------------ src/librustc_data_structures/lib.rs | 1 - 2 files changed, 364 deletions(-) delete mode 100644 src/librustc_data_structures/blake2b.rs diff --git a/src/librustc_data_structures/blake2b.rs b/src/librustc_data_structures/blake2b.rs deleted file mode 100644 index 6b8bf8df0d33f..0000000000000 --- a/src/librustc_data_structures/blake2b.rs +++ /dev/null @@ -1,363 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -// An implementation of the Blake2b cryptographic hash function. -// The implementation closely follows: https://tools.ietf.org/html/rfc7693 -// -// "BLAKE2 is a cryptographic hash function faster than MD5, SHA-1, SHA-2, and -// SHA-3, yet is at least as secure as the latest standard SHA-3." -// according to their own website :) -// -// Indeed this implementation is two to three times as fast as our SHA-256 -// implementation. If you have the luxury of being able to use crates from -// crates.io, you can go there and find still faster implementations. - -use std::mem; -use std::slice; - -#[repr(C)] -struct Blake2bCtx { - b: [u8; 128], - h: [u64; 8], - t: [u64; 2], - c: usize, - outlen: u16, - finalized: bool, - - #[cfg(debug_assertions)] - fnv_hash: u64, -} - -#[cfg(debug_assertions)] -impl ::std::fmt::Debug for Blake2bCtx { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(fmt, "{:x}", self.fnv_hash) - } -} - -#[cfg(not(debug_assertions))] -impl ::std::fmt::Debug for Blake2bCtx { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { - write!(fmt, "Enable debug_assertions() for more info.") - } -} - -#[inline(always)] -fn b2b_g(v: &mut [u64; 16], - a: usize, - b: usize, - c: usize, - d: usize, - x: u64, - y: u64) -{ - v[a] = v[a].wrapping_add(v[b]).wrapping_add(x); - v[d] = (v[d] ^ v[a]).rotate_right(32); - v[c] = v[c].wrapping_add(v[d]); - v[b] = (v[b] ^ v[c]).rotate_right(24); - v[a] = v[a].wrapping_add(v[b]).wrapping_add(y); - v[d] = (v[d] ^ v[a]).rotate_right(16); - v[c] = v[c].wrapping_add(v[d]); - v[b] = (v[b] ^ v[c]).rotate_right(63); -} - -// Initialization vector -const BLAKE2B_IV: [u64; 8] = [ - 0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, - 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1, - 0x510E527FADE682D1, 0x9B05688C2B3E6C1F, - 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179 -]; - -fn blake2b_compress(ctx: &mut Blake2bCtx, last: bool) { - - const SIGMA: [[usize; 16]; 12] = [ - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], - [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ], - [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 ], - [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 ], - [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 ], - [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 ], - [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 ], - [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 ], - [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 ], - [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 ], - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], - [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 ] - ]; - - let mut v: [u64; 16] = [ - ctx.h[0], - ctx.h[1], - ctx.h[2], - ctx.h[3], - ctx.h[4], - ctx.h[5], - ctx.h[6], - ctx.h[7], - - BLAKE2B_IV[0], - BLAKE2B_IV[1], - BLAKE2B_IV[2], - BLAKE2B_IV[3], - BLAKE2B_IV[4], - BLAKE2B_IV[5], - BLAKE2B_IV[6], - BLAKE2B_IV[7], - ]; - - v[12] ^= ctx.t[0]; // low 64 bits of offset - v[13] ^= ctx.t[1]; // high 64 bits - if last { - v[14] = !v[14]; - } - - { - // Re-interpret the input buffer in the state as an array - // of little-endian u64s, converting them to machine - // endianness. It's OK to modify the buffer in place - // since this is the last time this data will be accessed - // before it's overwritten. - - let m: &mut [u64; 16] = unsafe { - let b: &mut [u8; 128] = &mut ctx.b; - ::std::mem::transmute(b) - }; - - if cfg!(target_endian = "big") { - for word in &mut m[..] { - *word = u64::from_le(*word); - } - } - - for i in 0 .. 12 { - b2b_g(&mut v, 0, 4, 8, 12, m[SIGMA[i][ 0]], m[SIGMA[i][ 1]]); - b2b_g(&mut v, 1, 5, 9, 13, m[SIGMA[i][ 2]], m[SIGMA[i][ 3]]); - b2b_g(&mut v, 2, 6, 10, 14, m[SIGMA[i][ 4]], m[SIGMA[i][ 5]]); - b2b_g(&mut v, 3, 7, 11, 15, m[SIGMA[i][ 6]], m[SIGMA[i][ 7]]); - b2b_g(&mut v, 0, 5, 10, 15, m[SIGMA[i][ 8]], m[SIGMA[i][ 9]]); - b2b_g(&mut v, 1, 6, 11, 12, m[SIGMA[i][10]], m[SIGMA[i][11]]); - b2b_g(&mut v, 2, 7, 8, 13, m[SIGMA[i][12]], m[SIGMA[i][13]]); - b2b_g(&mut v, 3, 4, 9, 14, m[SIGMA[i][14]], m[SIGMA[i][15]]); - } - } - - for i in 0 .. 8 { - ctx.h[i] ^= v[i] ^ v[i + 8]; - } -} - -fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx { - assert!(outlen > 0 && outlen <= 64 && key.len() <= 64); - - let mut ctx = Blake2bCtx { - b: [0; 128], - h: BLAKE2B_IV, - t: [0; 2], - c: 0, - outlen: outlen as u16, - finalized: false, - - #[cfg(debug_assertions)] - fnv_hash: 0xcbf29ce484222325, - }; - - ctx.h[0] ^= 0x01010000 ^ ((key.len() << 8) as u64) ^ (outlen as u64); - - if key.len() > 0 { - blake2b_update(&mut ctx, key); - ctx.c = ctx.b.len(); - } - - ctx -} - -fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8]) { - assert!(!ctx.finalized, "Blake2bCtx already finalized"); - - let mut bytes_to_copy = data.len(); - let mut space_in_buffer = ctx.b.len() - ctx.c; - - while bytes_to_copy > space_in_buffer { - checked_mem_copy(data, &mut ctx.b[ctx.c .. ], space_in_buffer); - - ctx.t[0] = ctx.t[0].wrapping_add(ctx.b.len() as u64); - if ctx.t[0] < (ctx.b.len() as u64) { - ctx.t[1] += 1; - } - blake2b_compress(ctx, false); - ctx.c = 0; - - data = &data[space_in_buffer .. ]; - bytes_to_copy -= space_in_buffer; - space_in_buffer = ctx.b.len(); - } - - if bytes_to_copy > 0 { - checked_mem_copy(data, &mut ctx.b[ctx.c .. ], bytes_to_copy); - ctx.c += bytes_to_copy; - } - - #[cfg(debug_assertions)] - { - // compute additional FNV hash for simpler to read debug output - const MAGIC_PRIME: u64 = 0x00000100000001b3; - - for &byte in data { - ctx.fnv_hash = (ctx.fnv_hash ^ byte as u64).wrapping_mul(MAGIC_PRIME); - } - } -} - -fn blake2b_final(ctx: &mut Blake2bCtx) -{ - assert!(!ctx.finalized, "Blake2bCtx already finalized"); - - ctx.t[0] = ctx.t[0].wrapping_add(ctx.c as u64); - if ctx.t[0] < ctx.c as u64 { - ctx.t[1] += 1; - } - - while ctx.c < 128 { - ctx.b[ctx.c] = 0; - ctx.c += 1; - } - - blake2b_compress(ctx, true); - - // Modify our buffer to little-endian format as it will be read - // as a byte array. It's OK to modify the buffer in place since - // this is the last time this data will be accessed. - if cfg!(target_endian = "big") { - for word in &mut ctx.h { - *word = word.to_le(); - } - } - - ctx.finalized = true; -} - -#[inline(always)] -fn checked_mem_copy(from: &[T1], to: &mut [T2], byte_count: usize) { - let from_size = from.len() * mem::size_of::(); - let to_size = to.len() * mem::size_of::(); - assert!(from_size >= byte_count); - assert!(to_size >= byte_count); - let from_byte_ptr = from.as_ptr() as * const u8; - let to_byte_ptr = to.as_mut_ptr() as * mut u8; - unsafe { - ::std::ptr::copy_nonoverlapping(from_byte_ptr, to_byte_ptr, byte_count); - } -} - -pub fn blake2b(out: &mut [u8], key: &[u8], data: &[u8]) -{ - let mut ctx = blake2b_new(out.len(), key); - blake2b_update(&mut ctx, data); - blake2b_final(&mut ctx); - checked_mem_copy(&ctx.h, out, ctx.outlen as usize); -} - -pub struct Blake2bHasher(Blake2bCtx); - -impl ::std::hash::Hasher for Blake2bHasher { - fn write(&mut self, bytes: &[u8]) { - blake2b_update(&mut self.0, bytes); - } - - fn finish(&self) -> u64 { - assert!(self.0.outlen == 8, - "Hasher initialized with incompatible output length"); - u64::from_le(self.0.h[0]) - } -} - -impl Blake2bHasher { - pub fn new(outlen: usize, key: &[u8]) -> Blake2bHasher { - Blake2bHasher(blake2b_new(outlen, key)) - } - - pub fn finalize(&mut self) -> &[u8] { - if !self.0.finalized { - blake2b_final(&mut self.0); - } - debug_assert!(mem::size_of_val(&self.0.h) >= self.0.outlen as usize); - let raw_ptr = (&self.0.h[..]).as_ptr() as * const u8; - unsafe { - slice::from_raw_parts(raw_ptr, self.0.outlen as usize) - } - } -} - -impl ::std::fmt::Debug for Blake2bHasher { - fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> { - write!(fmt, "{:?}", self.0) - } -} - -#[cfg(test)] -fn selftest_seq(out: &mut [u8], seed: u32) -{ - let mut a: u32 = 0xDEAD4BADu32.wrapping_mul(seed); - let mut b: u32 = 1; - - for i in 0 .. out.len() { - let t: u32 = a.wrapping_add(b); - a = b; - b = t; - out[i] = ((t >> 24) & 0xFF) as u8; - } -} - -#[test] -fn blake2b_selftest() -{ - use std::hash::Hasher; - - // grand hash of hash results - const BLAKE2B_RES: [u8; 32] = [ - 0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD, - 0x10, 0xF5, 0x06, 0xC6, 0x1E, 0x29, 0xDA, 0x56, - 0x03, 0xD7, 0x63, 0xB8, 0xBB, 0xAD, 0x2E, 0x73, - 0x7F, 0x5E, 0x76, 0x5A, 0x7B, 0xCC, 0xD4, 0x75 - ]; - - // parameter sets - const B2B_MD_LEN: [usize; 4] = [20, 32, 48, 64]; - const B2B_IN_LEN: [usize; 6] = [0, 3, 128, 129, 255, 1024]; - - let mut data = [0u8; 1024]; - let mut md = [0u8; 64]; - let mut key = [0u8; 64]; - - let mut hasher = Blake2bHasher::new(32, &[]); - - for i in 0 .. 4 { - let outlen = B2B_MD_LEN[i]; - for j in 0 .. 6 { - let inlen = B2B_IN_LEN[j]; - - selftest_seq(&mut data[.. inlen], inlen as u32); // unkeyed hash - blake2b(&mut md[.. outlen], &[], &data[.. inlen]); - hasher.write(&md[.. outlen]); // hash the hash - - selftest_seq(&mut key[0 .. outlen], outlen as u32); // keyed hash - blake2b(&mut md[.. outlen], &key[.. outlen], &data[.. inlen]); - hasher.write(&md[.. outlen]); // hash the hash - } - } - - // compute and compare the hash of hashes - let md = hasher.finalize(); - for i in 0 .. 32 { - assert_eq!(md[i], BLAKE2B_RES[i]); - } -} diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index a35ef2f7ce7ba..37afe1bb066af 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -57,7 +57,6 @@ pub mod small_vec; pub mod base_n; pub mod bitslice; pub mod bitvec; -pub mod blake2b; pub mod graph; pub mod indexed_set; pub mod indexed_vec; From caa42e11bb6b7aea210ced552a157fa7de100d68 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 21 Jan 2018 19:28:55 -0700 Subject: [PATCH 07/26] Remove VecCell --- src/librustc_data_structures/lib.rs | 1 - src/librustc_data_structures/veccell/mod.rs | 47 --------------------- 2 files changed, 48 deletions(-) delete mode 100644 src/librustc_data_structures/veccell/mod.rs diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 37afe1bb066af..33d760d0a1482 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -69,7 +69,6 @@ pub mod transitive_relation; pub mod unify; pub mod fx; pub mod tuple_slice; -pub mod veccell; pub mod control_flow_graph; pub mod flock; pub mod sync; diff --git a/src/librustc_data_structures/veccell/mod.rs b/src/librustc_data_structures/veccell/mod.rs deleted file mode 100644 index 054eee8829a4a..0000000000000 --- a/src/librustc_data_structures/veccell/mod.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::cell::UnsafeCell; -use std::mem; - -pub struct VecCell { - data: UnsafeCell>, -} - -impl VecCell { - pub fn with_capacity(capacity: usize) -> VecCell { - VecCell { data: UnsafeCell::new(Vec::with_capacity(capacity)) } - } - - #[inline] - pub fn push(&self, data: T) -> usize { - // The logic here, and in `swap` below, is that the `push` - // method on the vector will not recursively access this - // `VecCell`. Therefore, we can temporarily obtain mutable - // access, secure in the knowledge that even if aliases exist - // -- indeed, even if aliases are reachable from within the - // vector -- they will not be used for the duration of this - // particular fn call. (Note that we also are relying on the - // fact that `VecCell` is not `Sync`.) - unsafe { - let v = self.data.get(); - (*v).push(data); - (*v).len() - } - } - - pub fn swap(&self, mut data: Vec) -> Vec { - unsafe { - let v = self.data.get(); - mem::swap(&mut *v, &mut data); - } - data - } -} From 79d85dab88536a66efdf550d687591b1bc53c022 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 29 Jan 2018 16:31:14 +0000 Subject: [PATCH 08/26] Create a directory for --out-dir if it does not already exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently if `--out-dir` is set to a non-existent directory, the compiler will throw unfriendly messages like `error: could not write output to subdir/example.crate.allocator.rcgu.o: No such file or directory`, which, while not completely unreadable, isn’t very user-friendly either. This change creates the directory automatically if it does not yet exist. --- src/librustc_driver/driver.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index e97d83ed1ee5a..ed680feae0aa5 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -163,6 +163,13 @@ pub fn compile_input(trans: Box, return Ok(()) } + if let &Some(ref dir) = outdir { + if fs::create_dir_all(dir).is_err() { + sess.err("failed to find or create the directory specified by --out-dir"); + return Err(CompileIncomplete::Stopped); + } + } + let arenas = AllArenas::new(); // Construct the HIR map From 7be8e2fbb3745602ac864fc079a040dd3a80d91d Mon Sep 17 00:00:00 2001 From: O01eg Date: Mon, 5 Feb 2018 20:10:05 +0300 Subject: [PATCH 09/26] Add build.tools option to manage installation of extended rust tools. --- config.toml.example | 4 ++++ src/bootstrap/config.rs | 5 ++++- src/bootstrap/configure.py | 1 + src/bootstrap/install.rs | 21 ++++++++++++++------- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/config.toml.example b/config.toml.example index 75cab74258b6b..e69443f835d77 100644 --- a/config.toml.example +++ b/config.toml.example @@ -151,6 +151,10 @@ # default. #extended = false +# Installs choosen set of extended tools if enables. By default builds all. +# If choosen tool failed to build the installation fails. +#tools = ["cargo", "rls", "rustfmt", "analysis", "src"] + # Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose #verbose = 0 diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index be8910120ee19..4f4fd14ae8cab 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -13,7 +13,7 @@ //! This module implements parsing `config.toml` configuration files to tweak //! how the build runs. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::env; use std::fs::File; use std::io::prelude::*; @@ -52,6 +52,7 @@ pub struct Config { pub target_config: HashMap, Target>, pub full_bootstrap: bool, pub extended: bool, + pub tools: Option>, pub sanitizers: bool, pub profiler: bool, pub ignore_git: bool, @@ -191,6 +192,7 @@ struct Build { python: Option, full_bootstrap: Option, extended: Option, + tools: Option>, verbose: Option, sanitizers: Option, profiler: Option, @@ -395,6 +397,7 @@ impl Config { set(&mut config.vendor, build.vendor); set(&mut config.full_bootstrap, build.full_bootstrap); set(&mut config.extended, build.extended); + config.tools = build.tools; set(&mut config.verbose, build.verbose); set(&mut config.sanitizers, build.sanitizers); set(&mut config.profiler, build.profiler); diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index d51752a12d9e5..99a3ee4e4c369 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -144,6 +144,7 @@ def v(*args): o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two") o("extended", "build.extended", "build an extended rust tool set") +v("tools", "build.tools", "List of extended tools will be installed") v("build", "build.build", "GNUs ./configure syntax LLVM build triple") v("host", None, "GNUs ./configure syntax LLVM host triples") v("target", None, "GNUs ./configure syntax LLVM target triples") diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 743f32ece99c6..86df36f209e6b 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -185,32 +185,39 @@ install!((self, builder, _config), install_std(builder, self.stage, *target); } }; - Cargo, "cargo", _config.extended, only_hosts: true, { + Cargo, "cargo", _config.extended && + _config.tools.as_ref().map_or(true, |t| t.contains("cargo")), only_hosts: true, { builder.ensure(dist::Cargo { stage: self.stage, target: self.target }); install_cargo(builder, self.stage, self.target); }; - Rls, "rls", _config.extended, only_hosts: true, { - if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() { + Rls, "rls", _config.extended && + _config.tools.as_ref().map_or(true, |t| t.contains("rls")), only_hosts: true, { + if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() || + builder.config.tools.as_ref().map_or(false, |t| t.contains("rls")) { install_rls(builder, self.stage, self.target); } else { println!("skipping Install RLS stage{} ({})", self.stage, self.target); } }; - Rustfmt, "rustfmt", _config.extended, only_hosts: true, { - if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() { + Rustfmt, "rustfmt", _config.extended && + _config.tools.as_ref().map_or(true, |t| t.contains("rustfmt")), only_hosts: true, { + if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() || + builder.config.tools.as_ref().map_or(false, |t| t.contains("rustfmt")) { install_rustfmt(builder, self.stage, self.target); } else { println!("skipping Install Rustfmt stage{} ({})", self.stage, self.target); } }; - Analysis, "analysis", _config.extended, only_hosts: false, { + Analysis, "analysis", _config.extended && + _config.tools.as_ref().map_or(true, |t| t.contains("analysis")), only_hosts: false, { builder.ensure(dist::Analysis { compiler: builder.compiler(self.stage, self.host), target: self.target }); install_analysis(builder, self.stage, self.target); }; - Src, "src", _config.extended, only_hosts: true, { + Src, "src", _config.extended && + _config.tools.as_ref().map_or(true, |t| t.contains("src")), only_hosts: true, { builder.ensure(dist::Src); install_src(builder, self.stage); }, ONLY_BUILD; From daaa9a440ccbdcf12165165ca38eb80bdb9a6eff Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Wed, 7 Feb 2018 18:34:45 +1100 Subject: [PATCH 10/26] Fix ICE for mismatched args on target without span Commit 7ed00caacc improved our error reporting by including the target function in our error messages when there is an argument count mismatch. A simple example from the UI tests is: ``` error[E0593]: function is expected to take a single 2-tuple as argument, but it takes 0 arguments --> $DIR/closure-arg-count.rs:32:53 | 32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument ... 44 | fn foo() {} | -------- takes 0 arguments ``` However, this assumed the target span was always available. This does not hold true if the target function is in `std` or another crate. A simple example from #48046 is assigning `str::split` to a function type with a different number of arguments. Fix by removing all of the labels and suggestions related to the target span when it's not found. Fixes #48046 --- src/librustc/traits/error_reporting.rs | 93 ++++++++++--------- .../ui/mismatched_types/closure-arg-count.rs | 3 + .../mismatched_types/closure-arg-count.stderr | 12 ++- 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7b86791026b41..f58ac9f00e4cc 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -744,8 +744,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } else { let (closure_span, found) = found_did .and_then(|did| self.tcx.hir.get_if_local(did)) - .map(|node| self.get_fn_like_arguments(node)) - .unwrap_or((found_span.unwrap(), found)); + .map(|node| { + let (found_span, found) = self.get_fn_like_arguments(node); + (Some(found_span), found) + }).unwrap_or((found_span, found)); self.report_arg_count_mismatch(span, closure_span, @@ -855,7 +857,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { fn report_arg_count_mismatch( &self, span: Span, - found_span: Span, + found_span: Option, expected_args: Vec, found_args: Vec, is_closure: bool, @@ -893,48 +895,51 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { ); err.span_label(span, format!( "expected {} that takes {}", kind, expected_str)); - err.span_label(found_span, format!("takes {}", found_str)); - - if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] { - if fields.len() == expected_args.len() { - let sugg = fields.iter() - .map(|(name, _)| name.to_owned()) - .collect::>().join(", "); - err.span_suggestion(found_span, - "change the closure to take multiple arguments instead of \ - a single tuple", - format!("|{}|", sugg)); + + if let Some(found_span) = found_span { + err.span_label(found_span, format!("takes {}", found_str)); + + if let &[ArgKind::Tuple(_, ref fields)] = &found_args[..] { + if fields.len() == expected_args.len() { + let sugg = fields.iter() + .map(|(name, _)| name.to_owned()) + .collect::>().join(", "); + err.span_suggestion(found_span, + "change the closure to take multiple arguments instead of \ + a single tuple", + format!("|{}|", sugg)); + } } - } - if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] { - if fields.len() == found_args.len() && is_closure { - let sugg = format!( - "|({}){}|", - found_args.iter() - .map(|arg| match arg { - ArgKind::Arg(name, _) => name.to_owned(), - _ => "_".to_owned(), - }) - .collect::>() - .join(", "), - // add type annotations if available - if found_args.iter().any(|arg| match arg { - ArgKind::Arg(_, ty) => ty != "_", - _ => false, - }) { - format!(": ({})", - fields.iter() - .map(|(_, ty)| ty.to_owned()) - .collect::>() - .join(", ")) - } else { - "".to_owned() - }, - ); - err.span_suggestion(found_span, - "change the closure to accept a tuple instead of individual \ - arguments", - sugg); + if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] { + if fields.len() == found_args.len() && is_closure { + let sugg = format!( + "|({}){}|", + found_args.iter() + .map(|arg| match arg { + ArgKind::Arg(name, _) => name.to_owned(), + _ => "_".to_owned(), + }) + .collect::>() + .join(", "), + // add type annotations if available + if found_args.iter().any(|arg| match arg { + ArgKind::Arg(_, ty) => ty != "_", + _ => false, + }) { + format!(": ({})", + fields.iter() + .map(|(_, ty)| ty.to_owned()) + .collect::>() + .join(", ")) + } else { + "".to_owned() + }, + ); + err.span_suggestion(found_span, + "change the closure to accept a tuple instead of \ + individual arguments", + sugg); + } } } diff --git a/src/test/ui/mismatched_types/closure-arg-count.rs b/src/test/ui/mismatched_types/closure-arg-count.rs index 96e5201716c71..34232e81cbdee 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.rs +++ b/src/test/ui/mismatched_types/closure-arg-count.rs @@ -36,6 +36,9 @@ fn main() { //~^ ERROR closure is expected to take let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); //~^ ERROR function is expected to take + + let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); + //~^ ERROR function is expected to take } fn foo() {} diff --git a/src/test/ui/mismatched_types/closure-arg-count.stderr b/src/test/ui/mismatched_types/closure-arg-count.stderr index be00ee4d74e7e..d2a6d6da814ca 100644 --- a/src/test/ui/mismatched_types/closure-arg-count.stderr +++ b/src/test/ui/mismatched_types/closure-arg-count.stderr @@ -90,7 +90,7 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it 32 | let _it = vec![1, 2, 3].into_iter().enumerate().map(foo); | ^^^ expected function that takes a single 2-tuple as argument ... -41 | fn foo() {} +44 | fn foo() {} | -------- takes 0 arguments error[E0593]: closure is expected to take a single 2-tuple as argument, but it takes 3 distinct arguments @@ -107,8 +107,14 @@ error[E0593]: function is expected to take a single 2-tuple as argument, but it 37 | let _it = vec![1, 2, 3].into_iter().enumerate().map(qux); | ^^^ expected function that takes a single 2-tuple as argument ... -42 | fn qux(x: usize, y: usize) {} +45 | fn qux(x: usize, y: usize) {} | -------------------------- takes 2 distinct arguments -error: aborting due to 11 previous errors +error[E0593]: function is expected to take 1 argument, but it takes 2 arguments + --> $DIR/closure-arg-count.rs:40:41 + | +40 | let _it = vec![1, 2, 3].into_iter().map(usize::checked_add); + | ^^^ expected function that takes 1 argument + +error: aborting due to 12 previous errors From 528d6b65b69a163fd34450d3d8806f1a4f37412d Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 7 Feb 2018 13:14:37 +0000 Subject: [PATCH 11/26] rustdoc: Hide `-> ()` in cross crate inlined Fn* bounds --- src/librustdoc/clean/simplify.rs | 4 +++- src/test/rustdoc/auxiliary/unit-return.rs | 13 +++++++++++ src/test/rustdoc/unit-return.rs | 27 +++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/test/rustdoc/auxiliary/unit-return.rs create mode 100644 src/test/rustdoc/unit-return.rs diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 63ebb16e5e009..0eb4f9ba7e581 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -106,7 +106,9 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec) -> Vec { } PP::Parenthesized { ref mut output, .. } => { assert!(output.is_none()); - *output = Some(rhs.clone()); + if *rhs != clean::Type::Tuple(Vec::new()) { + *output = Some(rhs.clone()); + } } }; true diff --git a/src/test/rustdoc/auxiliary/unit-return.rs b/src/test/rustdoc/auxiliary/unit-return.rs new file mode 100644 index 0000000000000..1b30a6a43282f --- /dev/null +++ b/src/test/rustdoc/auxiliary/unit-return.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn f2(f: F) {} + +pub fn f3 () + Clone>(f: F) {} diff --git a/src/test/rustdoc/unit-return.rs b/src/test/rustdoc/unit-return.rs new file mode 100644 index 0000000000000..757e8979edd4f --- /dev/null +++ b/src/test/rustdoc/unit-return.rs @@ -0,0 +1,27 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:unit-return.rs + +#![crate_name = "foo"] + +extern crate unit_return; + +// @has 'foo/fn.f0.html' '//*[@class="rust fn"]' 'F: FnMut(u8) + Clone' +pub fn f0(f: F) {} + +// @has 'foo/fn.f1.html' '//*[@class="rust fn"]' 'F: FnMut(u16) + Clone' +pub fn f1 () + Clone>(f: F) {} + +// @has 'foo/fn.f2.html' '//*[@class="rust fn"]' 'F: FnMut(u32) + Clone' +pub use unit_return::f2; + +// @has 'foo/fn.f3.html' '//*[@class="rust fn"]' 'F: FnMut(u64) + Clone' +pub use unit_return::f3; From 78a0b7fd466093003841cec6fd20d65270cf2175 Mon Sep 17 00:00:00 2001 From: O01eg Date: Wed, 7 Feb 2018 20:57:02 +0300 Subject: [PATCH 12/26] Refactor checks on list of extended tools. --- src/bootstrap/install.rs | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 86df36f209e6b..20f7d379a6967 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -22,6 +22,7 @@ use dist::{self, pkgname, sanitize_sh, tmpdir}; use builder::{Builder, RunConfig, ShouldRun, Step}; use cache::Interned; +use config::Config; pub fn install_docs(builder: &Builder, stage: u32, host: Interned) { install_sh(builder, "docs", "rust-docs", stage, Some(host)); @@ -144,6 +145,19 @@ macro_rules! install { pub host: Interned, } + impl $name { + #[allow(dead_code)] + fn should_build(config: &Config) -> bool { + config.extended && config.tools.as_ref() + .map_or(true, |t| t.contains($path)) + } + + #[allow(dead_code)] + fn should_install(builder: &Builder) -> bool { + builder.config.tools.as_ref().map_or(false, |t| t.contains($path)) + } + } + impl Step for $name { type Output = (); const DEFAULT: bool = true; @@ -185,39 +199,34 @@ install!((self, builder, _config), install_std(builder, self.stage, *target); } }; - Cargo, "cargo", _config.extended && - _config.tools.as_ref().map_or(true, |t| t.contains("cargo")), only_hosts: true, { + Cargo, "cargo", Self::should_build(_config), only_hosts: true, { builder.ensure(dist::Cargo { stage: self.stage, target: self.target }); install_cargo(builder, self.stage, self.target); }; - Rls, "rls", _config.extended && - _config.tools.as_ref().map_or(true, |t| t.contains("rls")), only_hosts: true, { + Rls, "rls", Self::should_build(_config), only_hosts: true, { if builder.ensure(dist::Rls { stage: self.stage, target: self.target }).is_some() || - builder.config.tools.as_ref().map_or(false, |t| t.contains("rls")) { + Self::should_install(builder) { install_rls(builder, self.stage, self.target); } else { println!("skipping Install RLS stage{} ({})", self.stage, self.target); } }; - Rustfmt, "rustfmt", _config.extended && - _config.tools.as_ref().map_or(true, |t| t.contains("rustfmt")), only_hosts: true, { + Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, { if builder.ensure(dist::Rustfmt { stage: self.stage, target: self.target }).is_some() || - builder.config.tools.as_ref().map_or(false, |t| t.contains("rustfmt")) { + Self::should_install(builder) { install_rustfmt(builder, self.stage, self.target); } else { println!("skipping Install Rustfmt stage{} ({})", self.stage, self.target); } }; - Analysis, "analysis", _config.extended && - _config.tools.as_ref().map_or(true, |t| t.contains("analysis")), only_hosts: false, { + Analysis, "analysis", Self::should_build(_config), only_hosts: false, { builder.ensure(dist::Analysis { compiler: builder.compiler(self.stage, self.host), target: self.target }); install_analysis(builder, self.stage, self.target); }; - Src, "src", _config.extended && - _config.tools.as_ref().map_or(true, |t| t.contains("src")), only_hosts: true, { + Src, "src", Self::should_build(_config) , only_hosts: true, { builder.ensure(dist::Src); install_src(builder, self.stage); }, ONLY_BUILD; From 37b5af2600501ea1461f1361f2f690e24734e6df Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 7 Feb 2018 12:20:25 -0800 Subject: [PATCH 13/26] Update binaryen to fix -Werror with GCC 8 --- src/binaryen | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/binaryen b/src/binaryen index 1c9bf65aa0e37..17841e155edf8 160000 --- a/src/binaryen +++ b/src/binaryen @@ -1 +1 @@ -Subproject commit 1c9bf65aa0e371b84755a8ddd6e79497fac57171 +Subproject commit 17841e155edf858c8ea7802dd5f5ecbef54b989f From 04fde1c42f92491886272f50308bf1f095307629 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 7 Feb 2018 16:35:40 -0800 Subject: [PATCH 14/26] intra-doc-links: bail early for linky things --- src/librustdoc/clean/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7c9a49c82a939..66b5f3b5ea366 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1051,6 +1051,10 @@ impl Clean for [ast::Attribute] { if UnstableFeatures::from_environment().is_nightly_build() { let dox = attrs.collapsed_doc_value().unwrap_or_else(String::new); for link in markdown_links(&dox, cx.render_type) { + // bail early for real links + if link.contains('/') { + continue; + } let (def, fragment) = { let mut kind = PathKind::Unknown; let path_str = if let Some(prefix) = From 35dca7edd3e5181459c8e410a59a1b6e3e97a360 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 8 Feb 2018 12:48:25 -0800 Subject: [PATCH 15/26] Add `rustc_args_required_const` to the feature whitelist Unfortunately left out it means that when the `#![feature(proc_macro)]` flag is in effect it fails to find `rustc_args_required_const` for expansion. This version, however, is verified to work with stdsimd's requirements! --- src/libsyntax/feature_gate.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 9c6520cd874a8..ae0556320b0ef 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -984,6 +984,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG "wasm_import_memory attribute is currently unstable", cfg_fn!(wasm_import_memory))), + ("rustc_args_required_const", Whitelisted, Gated(Stability::Unstable, + "rustc_attrs", + "never will be stable", + cfg_fn!(rustc_attrs))), + // Crate level attributes ("crate_name", CrateLevel, Ungated), ("crate_type", CrateLevel, Ungated), From 7a20fc14ef255df1ce2c417943605015aba2b1ff Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 8 Feb 2018 13:11:13 -0800 Subject: [PATCH 16/26] Disallow function pointers to #[rustc_args_required_const] This commit disallows acquiring a function pointer to functions tagged as `#[rustc_args_required_const]`. This is intended to be used as future-proofing for the stdsimd crate to avoid taking a function pointer to any intrinsic which has a hard requirement that one of the arguments is a constant value. --- src/librustc_mir/interpret/eval_context.rs | 4 +++ src/librustc_trans/mir/constant.rs | 4 +++ src/librustc_trans/mir/rvalue.rs | 4 +++ src/librustc_typeck/check/mod.rs | 32 +++++++++++++++++++ .../rustc-args-required-const2.rs | 20 ++++++++++++ 5 files changed, 64 insertions(+) create mode 100644 src/test/compile-fail/rustc-args-required-const2.rs diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 02fcb69fef5ac..52b87282180c4 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -716,6 +716,10 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { ReifyFnPointer => { match self.eval_operand(operand)?.ty.sty { ty::TyFnDef(def_id, substs) => { + if self.tcx.has_attr(def_id, "rustc_args_required_const") { + bug!("reifying a fn ptr that requires \ + const arguments"); + } let instance = self.resolve(def_id, substs)?; let fn_ptr = self.memory.create_fn_alloc(instance); let valty = ValTy { diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index cd1975488a24a..ff9ea40073fce 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -714,6 +714,10 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { mir::CastKind::ReifyFnPointer => { match operand.ty.sty { ty::TyFnDef(def_id, substs) => { + if tcx.has_attr(def_id, "rustc_args_required_const") { + bug!("reifying a fn ptr that requires \ + const arguments"); + } callee::resolve_and_get_fn(self.cx, def_id, substs) } _ => { diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index d1bc4fe90014c..2e876ec118d57 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -195,6 +195,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { mir::CastKind::ReifyFnPointer => { match operand.layout.ty.sty { ty::TyFnDef(def_id, substs) => { + if bx.cx.tcx.has_attr(def_id, "rustc_args_required_const") { + bug!("reifying a fn ptr that requires \ + const arguments"); + } OperandValue::Immediate( callee::resolve_and_get_fn(bx.cx, def_id, substs)) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f044b2c711e20..8bb38332d0e67 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4877,6 +4877,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } + self.check_rustc_args_require_const(def.def_id(), node_id, span); + debug!("instantiate_value_path: type of {:?} is {:?}", node_id, ty_substituted); @@ -4884,6 +4886,36 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty_substituted } + fn check_rustc_args_require_const(&self, + def_id: DefId, + node_id: ast::NodeId, + span: Span) { + // We're only interested in functions tagged with + // #[rustc_args_required_const], so ignore anything that's not. + if !self.tcx.has_attr(def_id, "rustc_args_required_const") { + return + } + + // If our calling expression is indeed the function itself, we're good! + // If not, generate an error that this can only be called directly. + match self.tcx.hir.get(self.tcx.hir.get_parent_node(node_id)) { + Node::NodeExpr(expr) => { + match expr.node { + hir::ExprCall(ref callee, ..) => { + if callee.id == node_id { + return + } + } + _ => {} + } + } + _ => {} + } + + self.tcx.sess.span_err(span, "this function can only be invoked \ + directly, not through a function pointer"); + } + /// Report errors if the provided parameters are too few or too many. fn check_path_parameter_count(&self, span: Span, diff --git a/src/test/compile-fail/rustc-args-required-const2.rs b/src/test/compile-fail/rustc-args-required-const2.rs new file mode 100644 index 0000000000000..aa63019307b5b --- /dev/null +++ b/src/test/compile-fail/rustc-args-required-const2.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(attr_literals, rustc_attrs, const_fn)] + +#[rustc_args_required_const(0)] +fn foo(_a: i32) { +} + +fn main() { + let a = foo; //~ ERROR: this function can only be invoked directly + a(2); +} From e9bcb4eb89048a5f95c2355007e3b22a4ab38093 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 8 Feb 2018 23:47:49 +0100 Subject: [PATCH 17/26] Hide theme button under menu in mobile mode and fix top margin issue (in mobile too) --- src/librustdoc/html/static/main.js | 37 +++++--------------------- src/librustdoc/html/static/rustdoc.css | 2 +- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index ba9bcb7af7ae0..f688be89beebc 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -123,25 +123,9 @@ sidebar.appendChild(div); } } - var themeChoices = document.getElementById("theme-choices"); - if (themeChoices) { - if (!themesWidth) { - var savedState = themeChoices.style.display; - themeChoices.style.display = 'block'; - themesWidth = themeChoices.offsetWidth + 'px'; - themeChoices.style.display = savedState; - } - themeChoices.style.position = "fixed"; - themeChoices.style.width = themesWidth; - themeChoices.style.top = '78px'; - themeChoices.style.left = '250px'; - } - document.getElementsByTagName("body")[0].style.marginTop = '45px'; - var themePicker = document.getElementById("theme-picker"); - if (themePicker) { - themePicker.style.position = "fixed"; - themePicker.style.top = "50px"; - themePicker.style.left = "250px"; + var themePicker = document.getElementsByClassName("theme-picker"); + if (themePicker && themePicker.length > 0) { + themePicker[0].style.display = "none"; } } @@ -157,18 +141,9 @@ filler.remove(); } document.getElementsByTagName("body")[0].style.marginTop = ''; - var themePicker = document.getElementById("theme-picker"); - if (themePicker) { - themePicker.style.position = "absolute"; - themePicker.style.top = null; - themePicker.style.left = null; - } - var themeChoices = document.getElementById("theme-choices"); - if (themeChoices) { - themeChoices.style.position = 'absolute'; - themeChoices.style.width = null; - themeChoices.style.top = null; - themeChoices.style.left = null; + var themePicker = document.getElementsByClassName("theme-picker"); + if (themePicker && themePicker.length > 0) { + themePicker[0].style.display = null; } } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 53d57b672303e..cd4f2cfa678e6 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -899,7 +899,7 @@ span.since { } #main { - margin-top: 50px; + margin-top: 45px; padding: 0; } From 64a8730e171367e4979cd9c25f0e0fdc2c157446 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 7 Feb 2018 12:56:04 -0800 Subject: [PATCH 18/26] rustbuild: Pass `ccache` to build scripts Right now the ccache setting is only used for LLVM, but this tweaks it to also be used for build scripts so C++ builds like `librustc_llvm` can be a bit speedier. --- src/bootstrap/builder.rs | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index bf7b1015a4921..4ca45fbed6a20 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -600,9 +600,25 @@ impl<'a> Builder<'a> { // // FIXME: the guard against msvc shouldn't need to be here if !target.contains("msvc") { - let cc = self.cc(target); - cargo.env(format!("CC_{}", target), cc) - .env("CC", cc); + let ccache = self.config.ccache.as_ref(); + let ccacheify = |s: &Path| { + let ccache = match ccache { + Some(ref s) => s, + None => return s.display().to_string(), + }; + // FIXME: the cc-rs crate only recognizes the literal strings + // `ccache` and `sccache` when doing caching compilations, so we + // mirror that here. It should probably be fixed upstream to + // accept a new env var or otherwise work with custom ccache + // vars. + match &ccache[..] { + "ccache" | "sccache" => format!("{} {}", ccache, s.display()), + _ => s.display().to_string(), + } + }; + let cc = ccacheify(&self.cc(target)); + cargo.env(format!("CC_{}", target), &cc) + .env("CC", &cc); let cflags = self.cflags(target).join(" "); cargo.env(format!("CFLAGS_{}", target), cflags.clone()) @@ -617,8 +633,9 @@ impl<'a> Builder<'a> { } if let Ok(cxx) = self.cxx(target) { - cargo.env(format!("CXX_{}", target), cxx) - .env("CXX", cxx) + let cxx = ccacheify(&cxx); + cargo.env(format!("CXX_{}", target), &cxx) + .env("CXX", &cxx) .env(format!("CXXFLAGS_{}", target), cflags.clone()) .env("CXXFLAGS", cflags); } From 774997dab3c1a0a6e2ffa03d9d86c7048ec0481d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 9 Feb 2018 09:48:54 +0100 Subject: [PATCH 19/26] Fix visitation order of calls so that it matches execution order. Fixes #48048 --- src/librustc/hir/intravisit.rs | 2 +- src/test/ui/generator/issue-48048.rs | 23 +++++++++++++++++++++++ src/test/ui/generator/issue-48048.stderr | 10 ++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/generator/issue-48048.rs create mode 100644 src/test/ui/generator/issue-48048.stderr diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 97cf9b01410b1..b804cf7bf5a34 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -965,8 +965,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { walk_list!(visitor, visit_expr, subexpressions); } ExprCall(ref callee_expression, ref arguments) => { + visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); - visitor.visit_expr(callee_expression) } ExprMethodCall(ref segment, _, ref arguments) => { visitor.visit_path_segment(expression.span, segment); diff --git a/src/test/ui/generator/issue-48048.rs b/src/test/ui/generator/issue-48048.rs new file mode 100644 index 0000000000000..89739bd591cc8 --- /dev/null +++ b/src/test/ui/generator/issue-48048.rs @@ -0,0 +1,23 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(generators)] + +fn main() { + let x = (|_| {},); + + || { + let x = x; + + x.0({ //~ ERROR borrow may still be in use when generator yields + yield; + }); + }; +} diff --git a/src/test/ui/generator/issue-48048.stderr b/src/test/ui/generator/issue-48048.stderr new file mode 100644 index 0000000000000..fd1667128ab60 --- /dev/null +++ b/src/test/ui/generator/issue-48048.stderr @@ -0,0 +1,10 @@ +error[E0626]: borrow may still be in use when generator yields + --> $DIR/issue-48048.rs:19:9 + | +19 | x.0({ //~ ERROR borrow may still be in use when generator yields + | ^^^ +20 | yield; + | ----- possible yield occurs here + +error: aborting due to previous error + From 9c05babe25bd25db423c7f83c31de000ee4d4db7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 9 Feb 2018 10:12:32 -0800 Subject: [PATCH 20/26] ci: Actually bootstrap on i686 dist Right now the `--build` option was accidentally omitted, so we're bootstraping from `x86_64` to `i686`. In addition to being slower (more compiles) that's not actually bootstrapping! --- src/bootstrap/dist.rs | 7 +++++++ src/ci/docker/dist-i686-linux/Dockerfile | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6717b1cb09883..460fb016f16ea 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -31,6 +31,7 @@ use channel; use util::{cp_r, libdir, is_dylib, cp_filtered, copy, replace_in_file}; use builder::{Builder, RunConfig, ShouldRun, Step}; use compile; +use native; use tool::{self, Tool}; use cache::{INTERNER, Interned}; use time; @@ -898,6 +899,12 @@ impl Step for PlainSourceTarball { .arg("--vers").arg(CARGO_VENDOR_VERSION) .arg("cargo-vendor") .env("RUSTC", &build.initial_rustc); + if let Some(dir) = build.openssl_install_dir(build.config.build) { + builder.ensure(native::Openssl { + target: build.config.build, + }); + cmd.env("OPENSSL_DIR", dir); + } build.run(&mut cmd); } diff --git a/src/ci/docker/dist-i686-linux/Dockerfile b/src/ci/docker/dist-i686-linux/Dockerfile index 0fd6af6e10d34..5e405aa72e83d 100644 --- a/src/ci/docker/dist-i686-linux/Dockerfile +++ b/src/ci/docker/dist-i686-linux/Dockerfile @@ -86,7 +86,8 @@ ENV RUST_CONFIGURE_ARGS \ --enable-extended \ --enable-sanitizers \ --enable-profiler \ - --enable-emscripten + --enable-emscripten \ + --build=i686-unknown-linux-gnu ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS # This is the only builder which will create source tarballs From fe8e0d98f17c0603bd324c21468d163ed2dcadb5 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 9 Feb 2018 11:27:47 -0700 Subject: [PATCH 21/26] Update books for next release --- src/doc/book | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/book b/src/doc/book index a645960fe4894..ec5660820dea9 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit a645960fe48946153936dd5628df4a90bd837981 +Subproject commit ec5660820dea91df470dab0b9eb26ef798f20889 diff --git a/src/doc/nomicon b/src/doc/nomicon index fec3182d0b0a3..ad5ddd62c098d 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit fec3182d0b0a3cf8122e192b3270064a5b19be5b +Subproject commit ad5ddd62c098d5b424151beda574ae7df2154df1 diff --git a/src/doc/reference b/src/doc/reference index e6a5d5d10aa2f..254df654a9b75 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit e6a5d5d10aa2fde0baed7b29bf672bd9f3af8962 +Subproject commit 254df654a9b75abf6ca08806535dbe1fad41be3f diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index 4ebb8169dfe56..919980be7df4e 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit 4ebb8169dfe569b3dcbeab560607800bb717978a +Subproject commit 919980be7df4ea7d45a9dca8efc34da89bcf7d6b From 1335b3da5a80fa4b74b25642e1bb651388bac3a8 Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Fri, 9 Feb 2018 11:19:52 -0700 Subject: [PATCH 22/26] Add fetch_nand. cc #13226 (the tracking issue) --- src/libcore/sync/atomic.rs | 46 +++++++++++++++++++++++++++++++++++++ src/libcore/tests/atomic.rs | 14 +++++++++++ src/libcore/tests/lib.rs | 1 + 3 files changed, 61 insertions(+) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 8b47143f63caa..f22862ae70190 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -945,6 +945,7 @@ macro_rules! atomic_int { $stable_debug:meta, $stable_access:meta, $stable_from:meta, + $stable_nand:meta, $s_int_type:expr, $int_ref:expr, $int_type:ident $atomic_type:ident $atomic_init:ident) => { /// An integer type which can be safely shared between threads. @@ -1325,6 +1326,29 @@ macro_rules! atomic_int { unsafe { atomic_and(self.v.get(), val, order) } } + /// Bitwise "nand" with the current value. + /// + /// Performs a bitwise "nand" operation on the current value and the argument `val`, and + /// sets the new value to the result. + /// + /// Returns the previous value. + /// + /// # Examples + /// + /// ``` + /// #![feature(atomic_nand)] + /// + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let foo = AtomicIsize::new(0xf731); + /// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731); + /// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f)); + #[inline] + #[$stable_nand] + pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_nand(self.v.get(), val, order) } + } + /// Bitwise "or" with the current value. /// /// Performs a bitwise "or" operation on the current value and the argument `val`, and @@ -1377,6 +1401,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i8", "../../../std/primitive.i8.html", i8 AtomicI8 ATOMIC_I8_INIT } @@ -1387,6 +1412,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u8", "../../../std/primitive.u8.html", u8 AtomicU8 ATOMIC_U8_INIT } @@ -1397,6 +1423,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i16", "../../../std/primitive.i16.html", i16 AtomicI16 ATOMIC_I16_INIT } @@ -1407,6 +1434,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u16", "../../../std/primitive.u16.html", u16 AtomicU16 ATOMIC_U16_INIT } @@ -1417,6 +1445,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i32", "../../../std/primitive.i32.html", i32 AtomicI32 ATOMIC_I32_INIT } @@ -1427,6 +1456,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u32", "../../../std/primitive.u32.html", u32 AtomicU32 ATOMIC_U32_INIT } @@ -1437,6 +1467,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i64", "../../../std/primitive.i64.html", i64 AtomicI64 ATOMIC_I64_INIT } @@ -1447,6 +1478,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u64", "../../../std/primitive.u64.html", u64 AtomicU64 ATOMIC_U64_INIT } @@ -1457,6 +1489,7 @@ atomic_int!{ stable(feature = "atomic_debug", since = "1.3.0"), stable(feature = "atomic_access", since = "1.15.0"), stable(feature = "atomic_from", since = "1.23.0"), + unstable(feature = "atomic_nand", issue = "13226"), "isize", "../../../std/primitive.isize.html", isize AtomicIsize ATOMIC_ISIZE_INIT } @@ -1467,6 +1500,7 @@ atomic_int!{ stable(feature = "atomic_debug", since = "1.3.0"), stable(feature = "atomic_access", since = "1.15.0"), stable(feature = "atomic_from", since = "1.23.0"), + unstable(feature = "atomic_nand", issue = "13226"), "usize", "../../../std/primitive.usize.html", usize AtomicUsize ATOMIC_USIZE_INIT } @@ -1609,6 +1643,18 @@ unsafe fn atomic_and(dst: *mut T, val: T, order: Ordering) -> T { } } +#[inline] +unsafe fn atomic_nand(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_nand_acq(dst, val), + Release => intrinsics::atomic_nand_rel(dst, val), + AcqRel => intrinsics::atomic_nand_acqrel(dst, val), + Relaxed => intrinsics::atomic_nand_relaxed(dst, val), + SeqCst => intrinsics::atomic_nand(dst, val), + __Nonexhaustive => panic!("invalid memory ordering"), + } +} + #[inline] unsafe fn atomic_or(dst: *mut T, val: T, order: Ordering) -> T { match order { diff --git a/src/libcore/tests/atomic.rs b/src/libcore/tests/atomic.rs index 9babe24a98563..f634fabe50399 100644 --- a/src/libcore/tests/atomic.rs +++ b/src/libcore/tests/atomic.rs @@ -48,6 +48,13 @@ fn uint_and() { assert_eq!(x.load(SeqCst), 0xf731 & 0x137f); } +#[test] +fn uint_nand() { + let x = AtomicUsize::new(0xf731); + assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731); + assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f)); +} + #[test] fn uint_or() { let x = AtomicUsize::new(0xf731); @@ -69,6 +76,13 @@ fn int_and() { assert_eq!(x.load(SeqCst), 0xf731 & 0x137f); } +#[test] +fn int_nand() { + let x = AtomicIsize::new(0xf731); + assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731); + assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f)); +} + #[test] fn int_or() { let x = AtomicIsize::new(0xf731); diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1c32452f84635..9e90313bc0e9e 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -42,6 +42,7 @@ #![feature(try_from)] #![feature(try_trait)] #![feature(exact_chunks)] +#![feature(atomic_nand)] extern crate core; extern crate test; From e6f910e31e578301cc8608f049f1763172569ca8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Fri, 9 Feb 2018 22:18:06 +0100 Subject: [PATCH 23/26] fix typo: substract -> subtract. --- src/libcore/ops/arith.rs | 4 ++-- src/test/ui/mismatched_types/binops.rs | 2 +- src/test/ui/mismatched_types/binops.stderr | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/ops/arith.rs b/src/libcore/ops/arith.rs index d0d0c09869e9d..88db019b02f07 100644 --- a/src/libcore/ops/arith.rs +++ b/src/libcore/ops/arith.rs @@ -181,7 +181,7 @@ add_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "sub"] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented(message="cannot substract `{RHS}` from `{Self}`", +#[rustc_on_unimplemented(message="cannot subtract `{RHS}` from `{Self}`", label="no implementation for `{Self} - {RHS}`")] pub trait Sub { /// The resulting type after applying the `-` operator. @@ -716,7 +716,7 @@ add_assign_impl! { usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64 } /// ``` #[lang = "sub_assign"] #[stable(feature = "op_assign_traits", since = "1.8.0")] -#[rustc_on_unimplemented(message="cannot substract-assign `{Rhs}` from `{Self}`", +#[rustc_on_unimplemented(message="cannot subtract-assign `{Rhs}` from `{Self}`", label="no implementation for `{Self} -= {Rhs}`")] pub trait SubAssign { /// Performs the `-=` operation. diff --git a/src/test/ui/mismatched_types/binops.rs b/src/test/ui/mismatched_types/binops.rs index 5144b59955cc9..3f2cb59b11dee 100644 --- a/src/test/ui/mismatched_types/binops.rs +++ b/src/test/ui/mismatched_types/binops.rs @@ -10,7 +10,7 @@ fn main() { 1 + Some(1); //~ ERROR cannot add `std::option::Option<{integer}>` to `{integer}` - 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` + 2 as usize - Some(1); //~ ERROR cannot subtract `std::option::Option<{integer}>` from `usize` 3 * (); //~ ERROR cannot multiply `()` to `{integer}` 4 / ""; //~ ERROR cannot divide `{integer}` by `&str` 5 < String::new(); //~ ERROR is not satisfied diff --git a/src/test/ui/mismatched_types/binops.stderr b/src/test/ui/mismatched_types/binops.stderr index 1b7fba050636f..828cf636951ed 100644 --- a/src/test/ui/mismatched_types/binops.stderr +++ b/src/test/ui/mismatched_types/binops.stderr @@ -6,10 +6,10 @@ error[E0277]: cannot add `std::option::Option<{integer}>` to `{integer}` | = help: the trait `std::ops::Add>` is not implemented for `{integer}` -error[E0277]: cannot substract `std::option::Option<{integer}>` from `usize` +error[E0277]: cannot subtract `std::option::Option<{integer}>` from `usize` --> $DIR/binops.rs:13:16 | -13 | 2 as usize - Some(1); //~ ERROR cannot substract `std::option::Option<{integer}>` from `usize` +13 | 2 as usize - Some(1); //~ ERROR cannot subtract `std::option::Option<{integer}>` from `usize` | ^ no implementation for `usize - std::option::Option<{integer}>` | = help: the trait `std::ops::Sub>` is not implemented for `usize` From 7ee3e39f640a9532842e1441bf6bc98893b6a3ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sat, 10 Feb 2018 12:22:57 +0100 Subject: [PATCH 24/26] fix typos in src/{bootstrap,ci,etc,lib{backtrace,core,fmt_macros}} --- src/bootstrap/builder.rs | 2 +- src/bootstrap/lib.rs | 2 +- src/bootstrap/test.rs | 2 +- src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh | 2 +- src/etc/installer/msi/rust.wxs | 4 ++-- src/etc/platform-intrinsics/generator.py | 2 +- src/etc/test-float-parse/runtests.py | 2 +- src/libbacktrace/ltmain.sh | 2 +- src/libbacktrace/macho.c | 2 +- src/libcore/macros.rs | 2 +- src/libfmt_macros/lib.rs | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 6c68ee18506bb..03630dfbed3e0 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -570,7 +570,7 @@ impl<'a> Builder<'a> { // build scripts in that situation. // // If LLVM support is disabled we need to use the snapshot compiler to compile - // build scripts, as the new compiler doesnt support executables. + // build scripts, as the new compiler doesn't support executables. if mode == Mode::Libstd || !self.build.config.llvm_enabled { cargo.env("RUSTC_SNAPSHOT", &self.initial_rustc) .env("RUSTC_SNAPSHOT_LIBDIR", self.rustc_snapshot_libdir()); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index a84a6a8990bbd..83c270865c0b7 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -666,7 +666,7 @@ impl Build { } } - /// Returns the path to the linker for the given target if it needs to be overriden. + /// Returns the path to the linker for the given target if it needs to be overridden. fn linker(&self, target: Interned) -> Option<&Path> { if let Some(linker) = self.config.target_config.get(&target) .and_then(|c| c.linker.as_ref()) { diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index eae8ec1311df7..f6b95f0bf9744 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -902,7 +902,7 @@ impl Step for Compiletest { } } if suite == "run-make" && !build.config.llvm_enabled { - println!("Ignoring run-make test suite as they generally dont work without LLVM"); + println!("Ignoring run-make test suite as they generally don't work without LLVM"); return; } diff --git a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh index 5b4314d57e6cc..e730dd86087fb 100755 --- a/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh +++ b/src/ci/docker/dist-x86_64-netbsd/build-netbsd-toolchain.sh @@ -54,7 +54,7 @@ cd usr/src # The options, in order, do the following # * this is an unprivileged build # * output to a predictable location -# * disable various uneeded stuff +# * disable various unneeded stuff MKUNPRIVED=yes TOOLDIR=/x-tools/x86_64-unknown-netbsd \ MKSHARE=no MKDOC=no MKHTML=no MKINFO=no MKKMOD=no MKLINT=no MKMAN=no MKNLS=no MKPROFILE=no \ hide_output ./build.sh -j10 -m amd64 tools diff --git a/src/etc/installer/msi/rust.wxs b/src/etc/installer/msi/rust.wxs index d95b096d732f4..a471ccc6f5b48 100644 --- a/src/etc/installer/msi/rust.wxs +++ b/src/etc/installer/msi/rust.wxs @@ -18,7 +18,7 @@ - + @@ -129,7 +129,7 @@ - + diff --git a/src/etc/platform-intrinsics/generator.py b/src/etc/platform-intrinsics/generator.py index e9cf71c32fe9a..d9f78978a251e 100644 --- a/src/etc/platform-intrinsics/generator.py +++ b/src/etc/platform-intrinsics/generator.py @@ -591,7 +591,7 @@ def parse_args(): The X86 architecture is specified as multiple files (for the different instruction sets that x86 supports). To generate the compiler definitions one needs to pass the script a "platform information file" - (with the -i flag) next to the files of the different intruction sets. + (with the -i flag) next to the files of the different instruction sets. For example, to generate the X86 compiler-definitions for SSE4.2, just: python generator.py --format compiler-defs -i x86/info.json sse42.json diff --git a/src/etc/test-float-parse/runtests.py b/src/etc/test-float-parse/runtests.py index d520c9bd5c30a..e9f5bba2312d8 100644 --- a/src/etc/test-float-parse/runtests.py +++ b/src/etc/test-float-parse/runtests.py @@ -41,7 +41,7 @@ (as a fraction, using the ``fractions`` module). Given an input string and the corresponding float computed via Rust, simply -decode the float into f * 2^k (for intergers f, k) and the ULP. +decode the float into f * 2^k (for integers f, k) and the ULP. We can now easily compute the error and check if it is within 0.5 ULP as it should be. Zero and infinites are handled similarly: diff --git a/src/libbacktrace/ltmain.sh b/src/libbacktrace/ltmain.sh index eff9e62be8a05..fd23815fc617a 100644 --- a/src/libbacktrace/ltmain.sh +++ b/src/libbacktrace/ltmain.sh @@ -487,7 +487,7 @@ func_mkdir_p () # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. + # list in case some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done diff --git a/src/libbacktrace/macho.c b/src/libbacktrace/macho.c index 9af14e724b40d..ba7f94c079f8a 100644 --- a/src/libbacktrace/macho.c +++ b/src/libbacktrace/macho.c @@ -327,7 +327,7 @@ macho_get_commands (struct backtrace_state *state, int descriptor, goto end; file_header_view_valid = 1; - // The endianess of the slice may be different than the fat image + // The endianness of the slice may be different than the fat image switch (*(uint32_t *) file_header_view.data) { case MH_MAGIC: diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index f00128a8147de..cc5cf6523a9e7 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -327,7 +327,7 @@ macro_rules! debug_assert_ne { /// } /// } /// -/// // The prefered method of quick returning Errors +/// // The preferred method of quick returning Errors /// fn write_to_file_question() -> Result<(), MyError> { /// let mut file = File::create("my_best_friends.txt")?; /// file.write_all(b"This is a list of my best friends.")?; diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index 44cdb5e8a3676..71519ab21fef9 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -73,7 +73,7 @@ pub struct FormatSpec<'a> { /// Enum describing where an argument for a format can be located. #[derive(Copy, Clone, PartialEq)] pub enum Position<'a> { - /// The arugment is implied to be located at an index + /// The argument is implied to be located at an index ArgumentImplicitlyIs(usize), /// The argument is located at a specific index given in the format ArgumentIs(usize), From 49f7ccd35ff1522fc2479f4fcec06871f6d3dc80 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 8 Feb 2018 20:45:45 -0800 Subject: [PATCH 25/26] Update the dlmalloc submodule A bug was recently fixed in dlmalloc which meant that released memory to the system accidentally wasn't getting reused, causing programs to be far slower than they should be! --- src/dlmalloc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dlmalloc b/src/dlmalloc index a2b424b600235..9b2dcac06c3e2 160000 --- a/src/dlmalloc +++ b/src/dlmalloc @@ -1 +1 @@ -Subproject commit a2b424b600235af58f453577c2da1b0e1de2ffa5 +Subproject commit 9b2dcac06c3e23235f8997b3c5f2325a6d3382df From 3a967676f8f9c1d78d493b87c02490d78c5bc0f1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sat, 10 Feb 2018 07:03:35 -0800 Subject: [PATCH 26/26] Explain unusual debugging code in librustc Introduced in #47828 to help track down some bugs, it landed a bit hastily so this is intended on cleaning it up a bit. --- src/librustc_resolve/resolve_imports.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 95a507ab9e351..8cb25f449b667 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1026,9 +1026,14 @@ fn import_path_to_string(names: &[SpannedIdent], if names.is_empty() { import_directive_subclass_to_string(subclass) } else { - let x = format!("{}::{}", - names_to_string(names), - import_directive_subclass_to_string(subclass)); + // Note that this code looks a little wonky, it's currently here to + // hopefully help debug #48116, but otherwise isn't intended to + // cause any problems. + let x = format!( + "{}::{}", + names_to_string(names), + import_directive_subclass_to_string(subclass), + ); assert!(!names.is_empty()); assert!(!x.starts_with("::")); return x