Skip to content

Commit 83e0f99

Browse files
committed
Auto merge of #57627 - Centril:rollup, r=Centril
Rollup of 7 pull requests Successful merges: - #57253 (Make privacy checking, intrinsic checking and liveness checking incremental) - #57352 (forbid manually impl'ing one of an object type's marker traits) - #57537 (Small perf improvement for fmt) - #57579 (Add core::iter::once_with()) - #57587 (Add 'rustc-env:RUST_BACKTRACE=0' to const-pat-ice test) - #57608 (Simplify 'product' factorial example) - #57614 ([rustdoc] Fix crates filtering box not being filled) Failed merges: r? @ghost
2 parents 33e6df4 + 94b4ab5 commit 83e0f99

27 files changed

+534
-29
lines changed

src/libcore/benches/fmt.rs

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use std::io::{self, Write as IoWrite};
2+
use std::fmt::{self, Write as FmtWrite};
3+
use test::Bencher;
4+
5+
#[bench]
6+
fn write_vec_value(bh: &mut Bencher) {
7+
bh.iter(|| {
8+
let mut mem = Vec::new();
9+
for _ in 0..1000 {
10+
mem.write_all("abc".as_bytes()).unwrap();
11+
}
12+
});
13+
}
14+
15+
#[bench]
16+
fn write_vec_ref(bh: &mut Bencher) {
17+
bh.iter(|| {
18+
let mut mem = Vec::new();
19+
let wr = &mut mem as &mut dyn io::Write;
20+
for _ in 0..1000 {
21+
wr.write_all("abc".as_bytes()).unwrap();
22+
}
23+
});
24+
}
25+
26+
#[bench]
27+
fn write_vec_macro1(bh: &mut Bencher) {
28+
bh.iter(|| {
29+
let mut mem = Vec::new();
30+
let wr = &mut mem as &mut dyn io::Write;
31+
for _ in 0..1000 {
32+
write!(wr, "abc").unwrap();
33+
}
34+
});
35+
}
36+
37+
#[bench]
38+
fn write_vec_macro2(bh: &mut Bencher) {
39+
bh.iter(|| {
40+
let mut mem = Vec::new();
41+
let wr = &mut mem as &mut dyn io::Write;
42+
for _ in 0..1000 {
43+
write!(wr, "{}", "abc").unwrap();
44+
}
45+
});
46+
}
47+
48+
#[bench]
49+
fn write_vec_macro_debug(bh: &mut Bencher) {
50+
bh.iter(|| {
51+
let mut mem = Vec::new();
52+
let wr = &mut mem as &mut dyn io::Write;
53+
for _ in 0..1000 {
54+
write!(wr, "{:?}", "☃").unwrap();
55+
}
56+
});
57+
}
58+
59+
#[bench]
60+
fn write_str_value(bh: &mut Bencher) {
61+
bh.iter(|| {
62+
let mut mem = String::new();
63+
for _ in 0..1000 {
64+
mem.write_str("abc").unwrap();
65+
}
66+
});
67+
}
68+
69+
#[bench]
70+
fn write_str_ref(bh: &mut Bencher) {
71+
bh.iter(|| {
72+
let mut mem = String::new();
73+
let wr = &mut mem as &mut dyn fmt::Write;
74+
for _ in 0..1000 {
75+
wr.write_str("abc").unwrap();
76+
}
77+
});
78+
}
79+
80+
#[bench]
81+
fn write_str_macro1(bh: &mut Bencher) {
82+
bh.iter(|| {
83+
let mut mem = String::new();
84+
for _ in 0..1000 {
85+
write!(mem, "abc").unwrap();
86+
}
87+
});
88+
}
89+
90+
#[bench]
91+
fn write_str_macro2(bh: &mut Bencher) {
92+
bh.iter(|| {
93+
let mut mem = String::new();
94+
let wr = &mut mem as &mut dyn fmt::Write;
95+
for _ in 0..1000 {
96+
write!(wr, "{}", "abc").unwrap();
97+
}
98+
});
99+
}
100+
101+
#[bench]
102+
fn write_str_macro_debug(bh: &mut Bencher) {
103+
bh.iter(|| {
104+
let mut mem = String::new();
105+
let wr = &mut mem as &mut dyn fmt::Write;
106+
for _ in 0..1000 {
107+
write!(wr, "{:?}", "☃").unwrap();
108+
}
109+
});
110+
}

src/libcore/benches/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ mod iter;
1111
mod num;
1212
mod ops;
1313
mod slice;
14+
mod fmt;

src/libcore/fmt/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -997,28 +997,30 @@ pub fn write(output: &mut dyn Write, args: Arguments) -> Result {
997997
curarg: args.args.iter(),
998998
};
999999

1000-
let mut pieces = args.pieces.iter();
1000+
let mut idx = 0;
10011001

10021002
match args.fmt {
10031003
None => {
10041004
// We can use default formatting parameters for all arguments.
1005-
for (arg, piece) in args.args.iter().zip(pieces.by_ref()) {
1005+
for (arg, piece) in args.args.iter().zip(args.pieces.iter()) {
10061006
formatter.buf.write_str(*piece)?;
10071007
(arg.formatter)(arg.value, &mut formatter)?;
1008+
idx += 1;
10081009
}
10091010
}
10101011
Some(fmt) => {
10111012
// Every spec has a corresponding argument that is preceded by
10121013
// a string piece.
1013-
for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
1014+
for (arg, piece) in fmt.iter().zip(args.pieces.iter()) {
10141015
formatter.buf.write_str(*piece)?;
10151016
formatter.run(arg)?;
1017+
idx += 1;
10161018
}
10171019
}
10181020
}
10191021

10201022
// There can be only one trailing string piece left.
1021-
if let Some(piece) = pieces.next() {
1023+
if let Some(piece) = args.pieces.get(idx) {
10221024
formatter.buf.write_str(*piece)?;
10231025
}
10241026

src/libcore/iter/iterator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2358,7 +2358,7 @@ pub trait Iterator {
23582358
///
23592359
/// ```
23602360
/// fn factorial(n: u32) -> u32 {
2361-
/// (1..).take_while(|&i| i <= n).product()
2361+
/// (1..=n).product()
23622362
/// }
23632363
/// assert_eq!(factorial(0), 1);
23642364
/// assert_eq!(factorial(1), 1);

src/libcore/iter/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,8 @@ pub use self::sources::{RepeatWith, repeat_with};
329329
pub use self::sources::{Empty, empty};
330330
#[stable(feature = "iter_once", since = "1.2.0")]
331331
pub use self::sources::{Once, once};
332+
#[unstable(feature = "iter_once_with", issue = "57581")]
333+
pub use self::sources::{OnceWith, once_with};
332334
#[unstable(feature = "iter_unfold", issue = "55977")]
333335
pub use self::sources::{Unfold, unfold, Successors, successors};
334336

src/libcore/iter/sources.rs

+113
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,119 @@ pub fn once<T>(value: T) -> Once<T> {
377377
Once { inner: Some(value).into_iter() }
378378
}
379379

380+
/// An iterator that repeats elements of type `A` endlessly by
381+
/// applying the provided closure `F: FnMut() -> A`.
382+
///
383+
/// This `struct` is created by the [`once_with`] function.
384+
/// See its documentation for more.
385+
///
386+
/// [`once_with`]: fn.once_with.html
387+
#[derive(Copy, Clone, Debug)]
388+
#[unstable(feature = "iter_once_with", issue = "57581")]
389+
pub struct OnceWith<F> {
390+
gen: Option<F>,
391+
}
392+
393+
#[unstable(feature = "iter_once_with", issue = "57581")]
394+
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
395+
type Item = A;
396+
397+
#[inline]
398+
fn next(&mut self) -> Option<A> {
399+
self.gen.take().map(|f| f())
400+
}
401+
402+
#[inline]
403+
fn size_hint(&self) -> (usize, Option<usize>) {
404+
self.gen.iter().size_hint()
405+
}
406+
}
407+
408+
#[unstable(feature = "iter_once_with", issue = "57581")]
409+
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
410+
fn next_back(&mut self) -> Option<A> {
411+
self.next()
412+
}
413+
}
414+
415+
#[unstable(feature = "iter_once_with", issue = "57581")]
416+
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
417+
fn len(&self) -> usize {
418+
self.gen.iter().len()
419+
}
420+
}
421+
422+
#[unstable(feature = "iter_once_with", issue = "57581")]
423+
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}
424+
425+
#[unstable(feature = "iter_once_with", issue = "57581")]
426+
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}
427+
428+
/// Creates an iterator that lazily generates a value exactly once by invoking
429+
/// the provided closure.
430+
///
431+
/// This is commonly used to adapt a single value generator into a [`chain`] of
432+
/// other kinds of iteration. Maybe you have an iterator that covers almost
433+
/// everything, but you need an extra special case. Maybe you have a function
434+
/// which works on iterators, but you only need to process one value.
435+
///
436+
/// Unlike [`once`], this function will lazily generate the value on request.
437+
///
438+
/// [`once`]: fn.once.html
439+
/// [`chain`]: trait.Iterator.html#method.chain
440+
///
441+
/// # Examples
442+
///
443+
/// Basic usage:
444+
///
445+
/// ```
446+
/// #![feature(iter_once_with)]
447+
///
448+
/// use std::iter;
449+
///
450+
/// // one is the loneliest number
451+
/// let mut one = iter::once_with(|| 1);
452+
///
453+
/// assert_eq!(Some(1), one.next());
454+
///
455+
/// // just one, that's all we get
456+
/// assert_eq!(None, one.next());
457+
/// ```
458+
///
459+
/// Chaining together with another iterator. Let's say that we want to iterate
460+
/// over each file of the `.foo` directory, but also a configuration file,
461+
/// `.foorc`:
462+
///
463+
/// ```no_run
464+
/// #![feature(iter_once_with)]
465+
///
466+
/// use std::iter;
467+
/// use std::fs;
468+
/// use std::path::PathBuf;
469+
///
470+
/// let dirs = fs::read_dir(".foo").unwrap();
471+
///
472+
/// // we need to convert from an iterator of DirEntry-s to an iterator of
473+
/// // PathBufs, so we use map
474+
/// let dirs = dirs.map(|file| file.unwrap().path());
475+
///
476+
/// // now, our iterator just for our config file
477+
/// let config = iter::once_with(|| PathBuf::from(".foorc"));
478+
///
479+
/// // chain the two iterators together into one big iterator
480+
/// let files = dirs.chain(config);
481+
///
482+
/// // this will give us all of the files in .foo as well as .foorc
483+
/// for f in files {
484+
/// println!("{:?}", f);
485+
/// }
486+
/// ```
487+
#[inline]
488+
#[unstable(feature = "iter_once_with", issue = "57581")]
489+
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
490+
OnceWith { gen: Some(gen) }
491+
}
492+
380493
/// Creates a new iterator where each iteration calls the provided closure
381494
/// `F: FnMut(&mut St) -> Option<T>`.
382495
///

src/libcore/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
#![feature(extern_types)]
8080
#![feature(fundamental)]
8181
#![feature(intrinsics)]
82+
#![feature(iter_once_with)]
8283
#![feature(lang_items)]
8384
#![feature(link_llvm_intrinsics)]
8485
#![feature(never_type)]

src/libcore/tests/iter.rs

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::cell::Cell;
12
use core::iter::*;
23
use core::{i8, i16, isize};
34
use core::usize;
@@ -1906,6 +1907,23 @@ fn test_once() {
19061907
assert_eq!(it.next(), None);
19071908
}
19081909

1910+
#[test]
1911+
fn test_once_with() {
1912+
let count = Cell::new(0);
1913+
let mut it = once_with(|| {
1914+
count.set(count.get() + 1);
1915+
42
1916+
});
1917+
1918+
assert_eq!(count.get(), 0);
1919+
assert_eq!(it.next(), Some(42));
1920+
assert_eq!(count.get(), 1);
1921+
assert_eq!(it.next(), None);
1922+
assert_eq!(count.get(), 1);
1923+
assert_eq!(it.next(), None);
1924+
assert_eq!(count.get(), 1);
1925+
}
1926+
19091927
#[test]
19101928
fn test_empty() {
19111929
let mut it = empty::<i32>();

src/libcore/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#![feature(hashmap_internals)]
1313
#![feature(iter_copied)]
1414
#![feature(iter_nth_back)]
15+
#![feature(iter_once_with)]
1516
#![feature(iter_unfold)]
1617
#![feature(pattern)]
1718
#![feature(range_is_empty)]

src/libfmt_macros/lib.rs

+9
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,15 @@ pub enum Position<'a> {
7272
ArgumentNamed(&'a str),
7373
}
7474

75+
impl Position<'_> {
76+
pub fn index(&self) -> Option<usize> {
77+
match self {
78+
ArgumentIs(i) | ArgumentImplicitlyIs(i) => Some(*i),
79+
_ => None,
80+
}
81+
}
82+
}
83+
7584
/// Enum of alignments which are supported.
7685
#[derive(Copy, Clone, PartialEq)]
7786
pub enum Alignment {

src/librustc/dep_graph/dep_node.rs

+3
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,9 @@ define_dep_nodes!( <'tcx>
476476
[] CheckModLoops(DefId),
477477
[] CheckModUnstableApiUsage(DefId),
478478
[] CheckModItemTypes(DefId),
479+
[] CheckModPrivacy(DefId),
480+
[] CheckModIntrinsics(DefId),
481+
[] CheckModLiveness(DefId),
479482
[] CollectModItemTypes(DefId),
480483

481484
[] Reachability,

src/librustc/hir/map/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,21 @@ impl<'hir> Map<'hir> {
509509
&self.forest.krate.attrs
510510
}
511511

512+
pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, NodeId)
513+
{
514+
let node_id = self.as_local_node_id(module).unwrap();
515+
self.read(node_id);
516+
match self.find_entry(node_id).unwrap().node {
517+
Node::Item(&Item {
518+
span,
519+
node: ItemKind::Mod(ref m),
520+
..
521+
}) => (m, span, node_id),
522+
Node::Crate => (&self.forest.krate.module, self.forest.krate.span, node_id),
523+
_ => panic!("not a module")
524+
}
525+
}
526+
512527
pub fn visit_item_likes_in_module<V>(&self, module: DefId, visitor: &mut V)
513528
where V: ItemLikeVisitor<'hir>
514529
{

0 commit comments

Comments
 (0)