Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #63744

Merged
merged 14 commits into from
Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
src/etc/installer/gfx/* binary
*.woff binary
src/vendor/** -text
Cargo.lock -merge linguist-generated=false
Cargo.lock linguist-generated=false

# Older git versions try to fix line endings on images, this prevents it.
*.png binary
Expand Down
8 changes: 8 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3189,6 +3189,7 @@ dependencies = [
"rustc_interface",
"rustc_metadata",
"rustc_mir",
"rustc_plugin",
"rustc_plugin_impl",
"rustc_save_analysis",
"rustc_target",
Expand Down Expand Up @@ -3372,6 +3373,13 @@ dependencies = [
"syntax_pos",
]

[[package]]
name = "rustc_plugin"
version = "0.0.0"
dependencies = [
"rustc_plugin_impl",
]

[[package]]
name = "rustc_plugin_impl"
version = "0.0.0"
Expand Down
10 changes: 5 additions & 5 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -859,12 +859,12 @@ impl<'a> Builder<'a> {
stage = compiler.stage;
}

let mut extra_args = env::var(&format!("RUSTFLAGS_STAGE_{}", stage)).unwrap_or_default();
let mut extra_args = String::new();
if stage != 0 {
let s = env::var("RUSTFLAGS_STAGE_NOT_0").unwrap_or_default();
if !extra_args.is_empty() {
extra_args.push_str(" ");
}
let s = env::var("RUSTFLAGS_NOT_BOOTSTRAP").unwrap_or_default();
extra_args.push_str(&s);
} else {
let s = env::var("RUSTFLAGS_BOOTSTRAP").unwrap_or_default();
extra_args.push_str(&s);
}

Expand Down
22 changes: 14 additions & 8 deletions src/libcore/iter/adapters/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,23 @@ impl<A, B> Iterator for Chain<A, B> where

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let (a_lower, a_upper) = self.a.size_hint();
let (b_lower, b_upper) = self.b.size_hint();
match self.state {
ChainState::Both => {
let (a_lower, a_upper) = self.a.size_hint();
let (b_lower, b_upper) = self.b.size_hint();

let lower = a_lower.saturating_add(b_lower);
let lower = a_lower.saturating_add(b_lower);

let upper = match (a_upper, b_upper) {
(Some(x), Some(y)) => x.checked_add(y),
_ => None
};
let upper = match (a_upper, b_upper) {
(Some(x), Some(y)) => x.checked_add(y),
_ => None
};

(lower, upper)
(lower, upper)
}
ChainState::Front => self.a.size_hint(),
ChainState::Back => self.b.size_hint(),
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4637,6 +4637,22 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
Some(tail)
}
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.len();
if n >= len {
self.v = &mut [];
None
} else {
let start = (len - 1 - n) * self.chunk_size;
let end = start + self.chunk_size;
let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
let (head, nth_back) = temp.split_at_mut(start);
self.v = head;
Some(nth_back)
}
}
}

#[stable(feature = "chunks_exact", since = "1.31.0")]
Expand Down
48 changes: 48 additions & 0 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,54 @@ fn test_iterator_chain_find() {
assert_eq!(iter.next(), None);
}

#[test]
fn test_iterator_chain_size_hint() {
struct Iter {
is_empty: bool,
}

impl Iterator for Iter {
type Item = ();

// alternates between `None` and `Some(())`
fn next(&mut self) -> Option<Self::Item> {
if self.is_empty {
self.is_empty = false;
None
} else {
self.is_empty = true;
Some(())
}
}

fn size_hint(&self) -> (usize, Option<usize>) {
if self.is_empty {
(0, Some(0))
} else {
(1, Some(1))
}
}
}

impl DoubleEndedIterator for Iter {
fn next_back(&mut self) -> Option<Self::Item> {
self.next()
}
}

// this chains an iterator of length 0 with an iterator of length 1,
// so after calling `.next()` once, the iterator is empty and the
// state is `ChainState::Back`. `.size_hint()` should now disregard
// the size hint of the left iterator
let mut iter = Iter { is_empty: true }.chain(once(()));
assert_eq!(iter.next(), Some(()));
assert_eq!(iter.size_hint(), (0, Some(0)));

let mut iter = once(()).chain(Iter { is_empty: true });
assert_eq!(iter.next_back(), Some(()));
assert_eq!(iter.size_hint(), (0, Some(0)));
}

#[test]
fn test_zip_nth() {
let xs = [0, 1, 2, 4, 5];
Expand Down
19 changes: 19 additions & 0 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,25 @@ fn test_chunks_exact_mut_nth() {
assert_eq!(c2.next(), None);
}

#[test]
fn test_chunks_exact_mut_nth_back() {
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
let mut c = v.chunks_exact_mut(2);
assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
assert_eq!(c.next().unwrap(), &[0, 1]);
assert_eq!(c.next(), None);

let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
let mut c2 = v2.chunks_exact_mut(3);
assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]);
assert_eq!(c2.next(), None);
assert_eq!(c2.next_back(), None);

let v3: &mut [i32] = &mut [0, 1, 2, 3, 4];
let mut c3 = v3.chunks_exact_mut(10);
assert_eq!(c3.nth_back(0), None);
}

#[test]
fn test_chunks_exact_mut_last() {
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
Expand Down
1 change: 1 addition & 0 deletions src/librustc_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ rustc_data_structures = { path = "../librustc_data_structures" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
rustc_metadata = { path = "../librustc_metadata" }
rustc_mir = { path = "../librustc_mir" }
rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the sysroot
rustc_plugin_impl = { path = "../librustc_plugin" }
rustc_save_analysis = { path = "../librustc_save_analysis" }
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_plugin/deprecated/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
#![feature(staged_api)]
#![unstable(feature = "rustc_plugin", issue = "29597")]
#![unstable(feature = "rustc_private", issue = "27812")]
#![rustc_deprecated(since = "1.38.0", reason = "\
import this through `rustc_driver::plugin` instead to make TLS work correctly. \
See https://github.com/rust-lang/rust/issues/62717")]
Expand Down
66 changes: 58 additions & 8 deletions src/libstd/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,20 +353,25 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
// Because we're extending the buffer with uninitialized data for trusted
// readers, we need to make sure to truncate that if any of this panics.
fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
read_to_end_with_reservation(r, buf, 32)
read_to_end_with_reservation(r, buf, |_| 32)
}

fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
buf: &mut Vec<u8>,
reservation_size: usize) -> Result<usize>
fn read_to_end_with_reservation<R, F>(
r: &mut R,
buf: &mut Vec<u8>,
mut reservation_size: F,
) -> Result<usize>
where
R: Read + ?Sized,
F: FnMut(&R) -> usize,
{
let start_len = buf.len();
let mut g = Guard { len: buf.len(), buf: buf };
let ret;
loop {
if g.len == g.buf.len() {
unsafe {
g.buf.reserve(reservation_size);
g.buf.reserve(reservation_size(r));
let capacity = g.buf.capacity();
g.buf.set_len(capacity);
r.initializer().initialize(&mut g.buf[g.len..]);
Expand Down Expand Up @@ -2253,9 +2258,10 @@ impl<T: Read> Read for Take<T> {
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
let reservation_size = cmp::min(self.limit, 32) as usize;

read_to_end_with_reservation(self, buf, reservation_size)
// Pass in a reservation_size closure that respects the current value
// of limit for each read. If we hit the read limit, this prevents the
// final zero-byte read from allocating again.
read_to_end_with_reservation(self, buf, |self_| cmp::min(self_.limit, 32) as usize)
}
}

Expand Down Expand Up @@ -2378,6 +2384,7 @@ impl<B: BufRead> Iterator for Lines<B> {

#[cfg(test)]
mod tests {
use crate::cmp;
use crate::io::prelude::*;
use super::{Cursor, SeekFrom, repeat};
use crate::io::{self, IoSlice, IoSliceMut};
Expand Down Expand Up @@ -2651,6 +2658,49 @@ mod tests {
Ok(())
}

// A simple example reader which uses the default implementation of
// read_to_end.
struct ExampleSliceReader<'a> {
slice: &'a [u8],
}

impl<'a> Read for ExampleSliceReader<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let len = cmp::min(self.slice.len(), buf.len());
buf[..len].copy_from_slice(&self.slice[..len]);
self.slice = &self.slice[len..];
Ok(len)
}
}

#[test]
fn test_read_to_end_capacity() -> io::Result<()> {
let input = &b"foo"[..];

// read_to_end() generally needs to over-allocate, both for efficiency
// and so that it can distinguish EOF. Assert that this is the case
// with this simple ExampleSliceReader struct, which uses the default
// implementation of read_to_end. Even though vec1 is allocated with
// exactly enough capacity for the read, read_to_end will allocate more
// space here.
let mut vec1 = Vec::with_capacity(input.len());
ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
assert_eq!(vec1.len(), input.len());
assert!(vec1.capacity() > input.len(), "allocated more");

// However, std::io::Take includes an implementation of read_to_end
// that will not allocate when the limit has already been reached. In
// this case, vec2 never grows.
let mut vec2 = Vec::with_capacity(input.len());
ExampleSliceReader { slice: input }
.take(input.len() as u64)
.read_to_end(&mut vec2)?;
assert_eq!(vec2.len(), input.len());
assert_eq!(vec2.capacity(), input.len(), "did not allocate more");

Ok(())
}

#[test]
fn io_slice_mut_advance() {
let mut buf1 = [1; 8];
Expand Down
54 changes: 24 additions & 30 deletions src/libstd/sys/unix/process/process_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ cfg_if::cfg_if! {
}
}

// Android with api less than 21 define sig* functions inline, so it is not
// available for dynamic link. Implementing sigemptyset and sigaddset allow us
// to support older Android version (independent of libc version).
// The following implementations are based on https://git.io/vSkNf
cfg_if::cfg_if! {
if #[cfg(target_os = "android")] {
pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
set.write_bytes(0u8, 1);
return 0;
}
#[allow(dead_code)]
pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
use crate::{slice, mem};

let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
let bit = (signum - 1) as usize;
raw[bit / 8] |= 1 << (bit % 8);
return 0;
}
} else {
pub use libc::{sigemptyset, sigaddset};
}
}

////////////////////////////////////////////////////////////////////////////////
// Command
////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -429,36 +453,6 @@ mod tests {
}
}

// Android with api less than 21 define sig* functions inline, so it is not
// available for dynamic link. Implementing sigemptyset and sigaddset allow us
// to support older Android version (independent of libc version).
// The following implementations are based on https://git.io/vSkNf

#[cfg(not(target_os = "android"))]
extern {
#[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;

#[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
}

#[cfg(target_os = "android")]
unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
set.write_bytes(0u8, 1);
return 0;
}

#[cfg(target_os = "android")]
unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
use crate::slice;

let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
let bit = (signum - 1) as usize;
raw[bit / 8] |= 1 << (bit % 8);
return 0;
}

// See #14232 for more information, but it appears that signal delivery to a
// newly spawned process may just be raced in the macOS, so to prevent this
// test from being flaky we ignore it on macOS.
Expand Down
Loading