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

Use copy/clone closures to simplify calendar test #47305

Merged
merged 1 commit into from
Jan 12, 2018
Merged
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
61 changes: 14 additions & 47 deletions src/test/run-pass/impl-trait/example-calendar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
universal_impl_trait,
fn_traits,
step_trait,
unboxed_closures
unboxed_closures,
copy_closures,
clone_closures
)]

//! Derived from: <https://raw.githubusercontent.com/quickfur/dcal/master/dcal.d>.
Expand Down Expand Up @@ -234,54 +236,22 @@ impl Weekday {
}
}

/// Wrapper for zero-sized closures.
// HACK(eddyb) Only needed because closures can't implement Copy.
struct Fn0<F>(std::marker::PhantomData<F>);

impl<F> Copy for Fn0<F> {}
impl<F> Clone for Fn0<F> {
fn clone(&self) -> Self { *self }
}

impl<F: FnOnce<A>, A> FnOnce<A> for Fn0<F> {
type Output = F::Output;

extern "rust-call" fn call_once(self, args: A) -> Self::Output {
let f = unsafe { std::mem::uninitialized::<F>() };
f.call_once(args)
}
}

impl<F: FnMut<A>, A> FnMut<A> for Fn0<F> {
extern "rust-call" fn call_mut(&mut self, args: A) -> Self::Output {
let mut f = unsafe { std::mem::uninitialized::<F>() };
f.call_mut(args)
}
}

trait AsFn0<A>: Sized {
fn copyable(self) -> Fn0<Self>;
}

impl<F: FnMut<A>, A> AsFn0<A> for F {
fn copyable(self) -> Fn0<Self> {
assert_eq!(std::mem::size_of::<F>(), 0);
Fn0(std::marker::PhantomData)
}
}

/// GroupBy implementation.
struct GroupBy<It: Iterator, F> {
it: std::iter::Peekable<It>,
f: F,
}

impl<It, F> Clone for GroupBy<It, F>
where It: Iterator + Clone, It::Item: Clone, F: Clone {
fn clone(&self) -> GroupBy<It, F> {
where
It: Iterator + Clone,
It::Item: Clone,
F: Clone,
{
fn clone(&self) -> Self {
GroupBy {
it: self.it.clone(),
f: self.f.clone()
f: self.f.clone(),
}
}
}
Expand Down Expand Up @@ -331,14 +301,11 @@ impl<It: Iterator, F: FnMut(&It::Item) -> G, G: Eq> Iterator for InGroup<It, F,
}

trait IteratorExt: Iterator + Sized {
fn group_by<G, F>(self, f: F) -> GroupBy<Self, Fn0<F>>
where F: FnMut(&Self::Item) -> G,
fn group_by<G, F>(self, f: F) -> GroupBy<Self, F>
where F: Clone + FnMut(&Self::Item) -> G,
G: Eq
{
GroupBy {
it: self.peekable(),
f: f.copyable(),
}
GroupBy { it: self.peekable(), f }
}

fn join(mut self, sep: &str) -> String
Expand Down Expand Up @@ -382,7 +349,7 @@ fn test_spaces() {
fn dates_in_year(year: i32) -> impl Iterator<Item=NaiveDate>+Clone {
InGroup {
it: NaiveDate::from_ymd(year, 1, 1)..,
f: (|d: &NaiveDate| d.year()).copyable(),
f: |d: &NaiveDate| d.year(),
g: year
}
}
Expand Down