Skip to content

Commit 5a56e05

Browse files
committed
Auto merge of #63744 - Centril:rollup-g4l3ra9, r=Centril
Rollup of 7 pull requests Successful merges: - #63216 (avoid unnecessary reservations in std::io::Take::read_to_end) - #63265 (Implement `nth_back` for ChunksExactMut) - #63691 (Fix bug in iter::Chain::size_hint) - #63722 (Don't use stage naming in RUSTFLAGS environment variables) - #63723 (Consolidate sigemptyset workarounds) - #63736 (Restore the rustc_plugin crate in the sysroot) - #63743 (Allow git to merge `Cargo.lock`) Failed merges: r? @ghost
2 parents 51879c3 + 218bcf2 commit 5a56e05

File tree

12 files changed

+198
-63
lines changed

12 files changed

+198
-63
lines changed

.gitattributes

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
src/etc/installer/gfx/* binary
99
*.woff binary
1010
src/vendor/** -text
11-
Cargo.lock -merge linguist-generated=false
11+
Cargo.lock linguist-generated=false
1212

1313
# Older git versions try to fix line endings on images, this prevents it.
1414
*.png binary

Cargo.lock

+8
Original file line numberDiff line numberDiff line change
@@ -3199,6 +3199,7 @@ dependencies = [
31993199
"rustc_interface",
32003200
"rustc_metadata",
32013201
"rustc_mir",
3202+
"rustc_plugin",
32023203
"rustc_plugin_impl",
32033204
"rustc_save_analysis",
32043205
"rustc_target",
@@ -3382,6 +3383,13 @@ dependencies = [
33823383
"syntax_pos",
33833384
]
33843385

3386+
[[package]]
3387+
name = "rustc_plugin"
3388+
version = "0.0.0"
3389+
dependencies = [
3390+
"rustc_plugin_impl",
3391+
]
3392+
33853393
[[package]]
33863394
name = "rustc_plugin_impl"
33873395
version = "0.0.0"

src/bootstrap/builder.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -859,12 +859,12 @@ impl<'a> Builder<'a> {
859859
stage = compiler.stage;
860860
}
861861

862-
let mut extra_args = env::var(&format!("RUSTFLAGS_STAGE_{}", stage)).unwrap_or_default();
862+
let mut extra_args = String::new();
863863
if stage != 0 {
864-
let s = env::var("RUSTFLAGS_STAGE_NOT_0").unwrap_or_default();
865-
if !extra_args.is_empty() {
866-
extra_args.push_str(" ");
867-
}
864+
let s = env::var("RUSTFLAGS_NOT_BOOTSTRAP").unwrap_or_default();
865+
extra_args.push_str(&s);
866+
} else {
867+
let s = env::var("RUSTFLAGS_BOOTSTRAP").unwrap_or_default();
868868
extra_args.push_str(&s);
869869
}
870870

src/libcore/iter/adapters/chain.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -173,17 +173,23 @@ impl<A, B> Iterator for Chain<A, B> where
173173

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

179-
let lower = a_lower.saturating_add(b_lower);
181+
let lower = a_lower.saturating_add(b_lower);
180182

181-
let upper = match (a_upper, b_upper) {
182-
(Some(x), Some(y)) => x.checked_add(y),
183-
_ => None
184-
};
183+
let upper = match (a_upper, b_upper) {
184+
(Some(x), Some(y)) => x.checked_add(y),
185+
_ => None
186+
};
185187

186-
(lower, upper)
188+
(lower, upper)
189+
}
190+
ChainState::Front => self.a.size_hint(),
191+
ChainState::Back => self.b.size_hint(),
192+
}
187193
}
188194
}
189195

src/libcore/slice/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -4637,6 +4637,22 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> {
46374637
Some(tail)
46384638
}
46394639
}
4640+
4641+
#[inline]
4642+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
4643+
let len = self.len();
4644+
if n >= len {
4645+
self.v = &mut [];
4646+
None
4647+
} else {
4648+
let start = (len - 1 - n) * self.chunk_size;
4649+
let end = start + self.chunk_size;
4650+
let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end);
4651+
let (head, nth_back) = temp.split_at_mut(start);
4652+
self.v = head;
4653+
Some(nth_back)
4654+
}
4655+
}
46404656
}
46414657

46424658
#[stable(feature = "chunks_exact", since = "1.31.0")]

src/libcore/tests/iter.rs

+48
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,54 @@ fn test_iterator_chain_find() {
152152
assert_eq!(iter.next(), None);
153153
}
154154

155+
#[test]
156+
fn test_iterator_chain_size_hint() {
157+
struct Iter {
158+
is_empty: bool,
159+
}
160+
161+
impl Iterator for Iter {
162+
type Item = ();
163+
164+
// alternates between `None` and `Some(())`
165+
fn next(&mut self) -> Option<Self::Item> {
166+
if self.is_empty {
167+
self.is_empty = false;
168+
None
169+
} else {
170+
self.is_empty = true;
171+
Some(())
172+
}
173+
}
174+
175+
fn size_hint(&self) -> (usize, Option<usize>) {
176+
if self.is_empty {
177+
(0, Some(0))
178+
} else {
179+
(1, Some(1))
180+
}
181+
}
182+
}
183+
184+
impl DoubleEndedIterator for Iter {
185+
fn next_back(&mut self) -> Option<Self::Item> {
186+
self.next()
187+
}
188+
}
189+
190+
// this chains an iterator of length 0 with an iterator of length 1,
191+
// so after calling `.next()` once, the iterator is empty and the
192+
// state is `ChainState::Back`. `.size_hint()` should now disregard
193+
// the size hint of the left iterator
194+
let mut iter = Iter { is_empty: true }.chain(once(()));
195+
assert_eq!(iter.next(), Some(()));
196+
assert_eq!(iter.size_hint(), (0, Some(0)));
197+
198+
let mut iter = once(()).chain(Iter { is_empty: true });
199+
assert_eq!(iter.next_back(), Some(()));
200+
assert_eq!(iter.size_hint(), (0, Some(0)));
201+
}
202+
155203
#[test]
156204
fn test_zip_nth() {
157205
let xs = [0, 1, 2, 4, 5];

src/libcore/tests/slice.rs

+19
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,25 @@ fn test_chunks_exact_mut_nth() {
374374
assert_eq!(c2.next(), None);
375375
}
376376

377+
#[test]
378+
fn test_chunks_exact_mut_nth_back() {
379+
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];
380+
let mut c = v.chunks_exact_mut(2);
381+
assert_eq!(c.nth_back(1).unwrap(), &[2, 3]);
382+
assert_eq!(c.next().unwrap(), &[0, 1]);
383+
assert_eq!(c.next(), None);
384+
385+
let v2: &mut [i32] = &mut [0, 1, 2, 3, 4];
386+
let mut c2 = v2.chunks_exact_mut(3);
387+
assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]);
388+
assert_eq!(c2.next(), None);
389+
assert_eq!(c2.next_back(), None);
390+
391+
let v3: &mut [i32] = &mut [0, 1, 2, 3, 4];
392+
let mut c3 = v3.chunks_exact_mut(10);
393+
assert_eq!(c3.nth_back(0), None);
394+
}
395+
377396
#[test]
378397
fn test_chunks_exact_mut_last() {
379398
let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5];

src/librustc_driver/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ rustc_data_structures = { path = "../librustc_data_structures" }
2020
errors = { path = "../librustc_errors", package = "rustc_errors" }
2121
rustc_metadata = { path = "../librustc_metadata" }
2222
rustc_mir = { path = "../librustc_mir" }
23+
rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the sysroot
2324
rustc_plugin_impl = { path = "../librustc_plugin" }
2425
rustc_save_analysis = { path = "../librustc_save_analysis" }
2526
rustc_codegen_utils = { path = "../librustc_codegen_utils" }

src/librustc_plugin/deprecated/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
22
#![feature(staged_api)]
3-
#![unstable(feature = "rustc_plugin", issue = "29597")]
3+
#![unstable(feature = "rustc_private", issue = "27812")]
44
#![rustc_deprecated(since = "1.38.0", reason = "\
55
import this through `rustc_driver::plugin` instead to make TLS work correctly. \
66
See https://github.com/rust-lang/rust/issues/62717")]

src/libstd/io/mod.rs

+58-8
Original file line numberDiff line numberDiff line change
@@ -353,20 +353,25 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize>
353353
// Because we're extending the buffer with uninitialized data for trusted
354354
// readers, we need to make sure to truncate that if any of this panics.
355355
fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> {
356-
read_to_end_with_reservation(r, buf, 32)
356+
read_to_end_with_reservation(r, buf, |_| 32)
357357
}
358358

359-
fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
360-
buf: &mut Vec<u8>,
361-
reservation_size: usize) -> Result<usize>
359+
fn read_to_end_with_reservation<R, F>(
360+
r: &mut R,
361+
buf: &mut Vec<u8>,
362+
mut reservation_size: F,
363+
) -> Result<usize>
364+
where
365+
R: Read + ?Sized,
366+
F: FnMut(&R) -> usize,
362367
{
363368
let start_len = buf.len();
364369
let mut g = Guard { len: buf.len(), buf: buf };
365370
let ret;
366371
loop {
367372
if g.len == g.buf.len() {
368373
unsafe {
369-
g.buf.reserve(reservation_size);
374+
g.buf.reserve(reservation_size(r));
370375
let capacity = g.buf.capacity();
371376
g.buf.set_len(capacity);
372377
r.initializer().initialize(&mut g.buf[g.len..]);
@@ -2253,9 +2258,10 @@ impl<T: Read> Read for Take<T> {
22532258
}
22542259

22552260
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
2256-
let reservation_size = cmp::min(self.limit, 32) as usize;
2257-
2258-
read_to_end_with_reservation(self, buf, reservation_size)
2261+
// Pass in a reservation_size closure that respects the current value
2262+
// of limit for each read. If we hit the read limit, this prevents the
2263+
// final zero-byte read from allocating again.
2264+
read_to_end_with_reservation(self, buf, |self_| cmp::min(self_.limit, 32) as usize)
22592265
}
22602266
}
22612267

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

23792385
#[cfg(test)]
23802386
mod tests {
2387+
use crate::cmp;
23812388
use crate::io::prelude::*;
23822389
use super::{Cursor, SeekFrom, repeat};
23832390
use crate::io::{self, IoSlice, IoSliceMut};
@@ -2651,6 +2658,49 @@ mod tests {
26512658
Ok(())
26522659
}
26532660

2661+
// A simple example reader which uses the default implementation of
2662+
// read_to_end.
2663+
struct ExampleSliceReader<'a> {
2664+
slice: &'a [u8],
2665+
}
2666+
2667+
impl<'a> Read for ExampleSliceReader<'a> {
2668+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
2669+
let len = cmp::min(self.slice.len(), buf.len());
2670+
buf[..len].copy_from_slice(&self.slice[..len]);
2671+
self.slice = &self.slice[len..];
2672+
Ok(len)
2673+
}
2674+
}
2675+
2676+
#[test]
2677+
fn test_read_to_end_capacity() -> io::Result<()> {
2678+
let input = &b"foo"[..];
2679+
2680+
// read_to_end() generally needs to over-allocate, both for efficiency
2681+
// and so that it can distinguish EOF. Assert that this is the case
2682+
// with this simple ExampleSliceReader struct, which uses the default
2683+
// implementation of read_to_end. Even though vec1 is allocated with
2684+
// exactly enough capacity for the read, read_to_end will allocate more
2685+
// space here.
2686+
let mut vec1 = Vec::with_capacity(input.len());
2687+
ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?;
2688+
assert_eq!(vec1.len(), input.len());
2689+
assert!(vec1.capacity() > input.len(), "allocated more");
2690+
2691+
// However, std::io::Take includes an implementation of read_to_end
2692+
// that will not allocate when the limit has already been reached. In
2693+
// this case, vec2 never grows.
2694+
let mut vec2 = Vec::with_capacity(input.len());
2695+
ExampleSliceReader { slice: input }
2696+
.take(input.len() as u64)
2697+
.read_to_end(&mut vec2)?;
2698+
assert_eq!(vec2.len(), input.len());
2699+
assert_eq!(vec2.capacity(), input.len(), "did not allocate more");
2700+
2701+
Ok(())
2702+
}
2703+
26542704
#[test]
26552705
fn io_slice_mut_advance() {
26562706
let mut buf1 = [1; 8];

src/libstd/sys/unix/process/process_common.rs

+24-30
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,30 @@ cfg_if::cfg_if! {
2020
}
2121
}
2222

23+
// Android with api less than 21 define sig* functions inline, so it is not
24+
// available for dynamic link. Implementing sigemptyset and sigaddset allow us
25+
// to support older Android version (independent of libc version).
26+
// The following implementations are based on https://git.io/vSkNf
27+
cfg_if::cfg_if! {
28+
if #[cfg(target_os = "android")] {
29+
pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
30+
set.write_bytes(0u8, 1);
31+
return 0;
32+
}
33+
#[allow(dead_code)]
34+
pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
35+
use crate::{slice, mem};
36+
37+
let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
38+
let bit = (signum - 1) as usize;
39+
raw[bit / 8] |= 1 << (bit % 8);
40+
return 0;
41+
}
42+
} else {
43+
pub use libc::{sigemptyset, sigaddset};
44+
}
45+
}
46+
2347
////////////////////////////////////////////////////////////////////////////////
2448
// Command
2549
////////////////////////////////////////////////////////////////////////////////
@@ -429,36 +453,6 @@ mod tests {
429453
}
430454
}
431455

432-
// Android with api less than 21 define sig* functions inline, so it is not
433-
// available for dynamic link. Implementing sigemptyset and sigaddset allow us
434-
// to support older Android version (independent of libc version).
435-
// The following implementations are based on https://git.io/vSkNf
436-
437-
#[cfg(not(target_os = "android"))]
438-
extern {
439-
#[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
440-
fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int;
441-
442-
#[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
443-
fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
444-
}
445-
446-
#[cfg(target_os = "android")]
447-
unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
448-
set.write_bytes(0u8, 1);
449-
return 0;
450-
}
451-
452-
#[cfg(target_os = "android")]
453-
unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
454-
use crate::slice;
455-
456-
let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
457-
let bit = (signum - 1) as usize;
458-
raw[bit / 8] |= 1 << (bit % 8);
459-
return 0;
460-
}
461-
462456
// See #14232 for more information, but it appears that signal delivery to a
463457
// newly spawned process may just be raced in the macOS, so to prevent this
464458
// test from being flaky we ignore it on macOS.

0 commit comments

Comments
 (0)