Skip to content

Commit

Permalink
Auto merge of #57627 - Centril:rollup, r=Centril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Jan 15, 2019
2 parents 33e6df4 + 94b4ab5 commit 83e0f99
Show file tree
Hide file tree
Showing 27 changed files with 534 additions and 29 deletions.
110 changes: 110 additions & 0 deletions src/libcore/benches/fmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use std::io::{self, Write as IoWrite};
use std::fmt::{self, Write as FmtWrite};
use test::Bencher;

#[bench]
fn write_vec_value(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
for _ in 0..1000 {
mem.write_all("abc".as_bytes()).unwrap();
}
});
}

#[bench]
fn write_vec_ref(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
wr.write_all("abc".as_bytes()).unwrap();
}
});
}

#[bench]
fn write_vec_macro1(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
write!(wr, "abc").unwrap();
}
});
}

#[bench]
fn write_vec_macro2(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
write!(wr, "{}", "abc").unwrap();
}
});
}

#[bench]
fn write_vec_macro_debug(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = Vec::new();
let wr = &mut mem as &mut dyn io::Write;
for _ in 0..1000 {
write!(wr, "{:?}", "☃").unwrap();
}
});
}

#[bench]
fn write_str_value(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = String::new();
for _ in 0..1000 {
mem.write_str("abc").unwrap();
}
});
}

#[bench]
fn write_str_ref(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = String::new();
let wr = &mut mem as &mut dyn fmt::Write;
for _ in 0..1000 {
wr.write_str("abc").unwrap();
}
});
}

#[bench]
fn write_str_macro1(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = String::new();
for _ in 0..1000 {
write!(mem, "abc").unwrap();
}
});
}

#[bench]
fn write_str_macro2(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = String::new();
let wr = &mut mem as &mut dyn fmt::Write;
for _ in 0..1000 {
write!(wr, "{}", "abc").unwrap();
}
});
}

#[bench]
fn write_str_macro_debug(bh: &mut Bencher) {
bh.iter(|| {
let mut mem = String::new();
let wr = &mut mem as &mut dyn fmt::Write;
for _ in 0..1000 {
write!(wr, "{:?}", "☃").unwrap();
}
});
}
1 change: 1 addition & 0 deletions src/libcore/benches/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ mod iter;
mod num;
mod ops;
mod slice;
mod fmt;
10 changes: 6 additions & 4 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -997,28 +997,30 @@ pub fn write(output: &mut dyn Write, args: Arguments) -> Result {
curarg: args.args.iter(),
};

let mut pieces = args.pieces.iter();
let mut idx = 0;

match args.fmt {
None => {
// We can use default formatting parameters for all arguments.
for (arg, piece) in args.args.iter().zip(pieces.by_ref()) {
for (arg, piece) in args.args.iter().zip(args.pieces.iter()) {
formatter.buf.write_str(*piece)?;
(arg.formatter)(arg.value, &mut formatter)?;
idx += 1;
}
}
Some(fmt) => {
// Every spec has a corresponding argument that is preceded by
// a string piece.
for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
for (arg, piece) in fmt.iter().zip(args.pieces.iter()) {
formatter.buf.write_str(*piece)?;
formatter.run(arg)?;
idx += 1;
}
}
}

// There can be only one trailing string piece left.
if let Some(piece) = pieces.next() {
if let Some(piece) = args.pieces.get(idx) {
formatter.buf.write_str(*piece)?;
}

Expand Down
2 changes: 1 addition & 1 deletion src/libcore/iter/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2358,7 +2358,7 @@ pub trait Iterator {
///
/// ```
/// fn factorial(n: u32) -> u32 {
/// (1..).take_while(|&i| i <= n).product()
/// (1..=n).product()
/// }
/// assert_eq!(factorial(0), 1);
/// assert_eq!(factorial(1), 1);
Expand Down
2 changes: 2 additions & 0 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ pub use self::sources::{RepeatWith, repeat_with};
pub use self::sources::{Empty, empty};
#[stable(feature = "iter_once", since = "1.2.0")]
pub use self::sources::{Once, once};
#[unstable(feature = "iter_once_with", issue = "57581")]
pub use self::sources::{OnceWith, once_with};
#[unstable(feature = "iter_unfold", issue = "55977")]
pub use self::sources::{Unfold, unfold, Successors, successors};

Expand Down
113 changes: 113 additions & 0 deletions src/libcore/iter/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,119 @@ pub fn once<T>(value: T) -> Once<T> {
Once { inner: Some(value).into_iter() }
}

/// An iterator that repeats elements of type `A` endlessly by
/// applying the provided closure `F: FnMut() -> A`.
///
/// This `struct` is created by the [`once_with`] function.
/// See its documentation for more.
///
/// [`once_with`]: fn.once_with.html
#[derive(Copy, Clone, Debug)]
#[unstable(feature = "iter_once_with", issue = "57581")]
pub struct OnceWith<F> {
gen: Option<F>,
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> Iterator for OnceWith<F> {
type Item = A;

#[inline]
fn next(&mut self) -> Option<A> {
self.gen.take().map(|f| f())
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.gen.iter().size_hint()
}
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> DoubleEndedIterator for OnceWith<F> {
fn next_back(&mut self) -> Option<A> {
self.next()
}
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> ExactSizeIterator for OnceWith<F> {
fn len(&self) -> usize {
self.gen.iter().len()
}
}

#[unstable(feature = "iter_once_with", issue = "57581")]
impl<A, F: FnOnce() -> A> FusedIterator for OnceWith<F> {}

#[unstable(feature = "iter_once_with", issue = "57581")]
unsafe impl<A, F: FnOnce() -> A> TrustedLen for OnceWith<F> {}

/// Creates an iterator that lazily generates a value exactly once by invoking
/// the provided closure.
///
/// This is commonly used to adapt a single value generator into a [`chain`] of
/// other kinds of iteration. Maybe you have an iterator that covers almost
/// everything, but you need an extra special case. Maybe you have a function
/// which works on iterators, but you only need to process one value.
///
/// Unlike [`once`], this function will lazily generate the value on request.
///
/// [`once`]: fn.once.html
/// [`chain`]: trait.Iterator.html#method.chain
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// #![feature(iter_once_with)]
///
/// use std::iter;
///
/// // one is the loneliest number
/// let mut one = iter::once_with(|| 1);
///
/// assert_eq!(Some(1), one.next());
///
/// // just one, that's all we get
/// assert_eq!(None, one.next());
/// ```
///
/// Chaining together with another iterator. Let's say that we want to iterate
/// over each file of the `.foo` directory, but also a configuration file,
/// `.foorc`:
///
/// ```no_run
/// #![feature(iter_once_with)]
///
/// use std::iter;
/// use std::fs;
/// use std::path::PathBuf;
///
/// let dirs = fs::read_dir(".foo").unwrap();
///
/// // we need to convert from an iterator of DirEntry-s to an iterator of
/// // PathBufs, so we use map
/// let dirs = dirs.map(|file| file.unwrap().path());
///
/// // now, our iterator just for our config file
/// let config = iter::once_with(|| PathBuf::from(".foorc"));
///
/// // chain the two iterators together into one big iterator
/// let files = dirs.chain(config);
///
/// // this will give us all of the files in .foo as well as .foorc
/// for f in files {
/// println!("{:?}", f);
/// }
/// ```
#[inline]
#[unstable(feature = "iter_once_with", issue = "57581")]
pub fn once_with<A, F: FnOnce() -> A>(gen: F) -> OnceWith<F> {
OnceWith { gen: Some(gen) }
}

/// Creates a new iterator where each iteration calls the provided closure
/// `F: FnMut(&mut St) -> Option<T>`.
///
Expand Down
1 change: 1 addition & 0 deletions src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
#![feature(extern_types)]
#![feature(fundamental)]
#![feature(intrinsics)]
#![feature(iter_once_with)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(never_type)]
Expand Down
18 changes: 18 additions & 0 deletions src/libcore/tests/iter.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use core::cell::Cell;
use core::iter::*;
use core::{i8, i16, isize};
use core::usize;
Expand Down Expand Up @@ -1906,6 +1907,23 @@ fn test_once() {
assert_eq!(it.next(), None);
}

#[test]
fn test_once_with() {
let count = Cell::new(0);
let mut it = once_with(|| {
count.set(count.get() + 1);
42
});

assert_eq!(count.get(), 0);
assert_eq!(it.next(), Some(42));
assert_eq!(count.get(), 1);
assert_eq!(it.next(), None);
assert_eq!(count.get(), 1);
assert_eq!(it.next(), None);
assert_eq!(count.get(), 1);
}

#[test]
fn test_empty() {
let mut it = empty::<i32>();
Expand Down
1 change: 1 addition & 0 deletions src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(hashmap_internals)]
#![feature(iter_copied)]
#![feature(iter_nth_back)]
#![feature(iter_once_with)]
#![feature(iter_unfold)]
#![feature(pattern)]
#![feature(range_is_empty)]
Expand Down
9 changes: 9 additions & 0 deletions src/libfmt_macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ pub enum Position<'a> {
ArgumentNamed(&'a str),
}

impl Position<'_> {
pub fn index(&self) -> Option<usize> {
match self {
ArgumentIs(i) | ArgumentImplicitlyIs(i) => Some(*i),
_ => None,
}
}
}

/// Enum of alignments which are supported.
#[derive(Copy, Clone, PartialEq)]
pub enum Alignment {
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,9 @@ define_dep_nodes!( <'tcx>
[] CheckModLoops(DefId),
[] CheckModUnstableApiUsage(DefId),
[] CheckModItemTypes(DefId),
[] CheckModPrivacy(DefId),
[] CheckModIntrinsics(DefId),
[] CheckModLiveness(DefId),
[] CollectModItemTypes(DefId),

[] Reachability,
Expand Down
15 changes: 15 additions & 0 deletions src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,21 @@ impl<'hir> Map<'hir> {
&self.forest.krate.attrs
}

pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, NodeId)
{
let node_id = self.as_local_node_id(module).unwrap();
self.read(node_id);
match self.find_entry(node_id).unwrap().node {
Node::Item(&Item {
span,
node: ItemKind::Mod(ref m),
..
}) => (m, span, node_id),
Node::Crate => (&self.forest.krate.module, self.forest.krate.span, node_id),
_ => panic!("not a module")
}
}

pub fn visit_item_likes_in_module<V>(&self, module: DefId, visitor: &mut V)
where V: ItemLikeVisitor<'hir>
{
Expand Down
Loading

0 comments on commit 83e0f99

Please sign in to comment.