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 more associated types in core::iter. #23025

Merged
merged 1 commit into from
Mar 7, 2015
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
94 changes: 48 additions & 46 deletions src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1279,14 +1279,14 @@ pub struct Cloned<I> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, D, I> Iterator for Cloned<I> where
T: Clone,
D: Deref<Target=T>,
I: Iterator<Item=D>,
impl<I> Iterator for Cloned<I> where
I: Iterator,
I::Item: Deref,
<I::Item as Deref>::Target: Clone
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that resolution was fixed recently such that I::Item::Target: Clone should work. But perhaps the fix is not in a snapshot yet?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:O really??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately it doesn't seem to work: although, things did change recently, so that I::Item works even if the I: Iterator bound is in a where clause (which @nagisa thankfully pointed out on an earlier version of this PR, avoiding some unnecessary inconsistency).

{
type Item = T;
type Item = <I::Item as Deref>::Target;

fn next(&mut self) -> Option<T> {
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
self.it.next().cloned()
}

Expand All @@ -1296,36 +1296,36 @@ impl<T, D, I> Iterator for Cloned<I> where
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, D, I> DoubleEndedIterator for Cloned<I> where
T: Clone,
D: Deref<Target=T>,
I: DoubleEndedIterator<Item=D>,
impl<I> DoubleEndedIterator for Cloned<I> where
I: DoubleEndedIterator,
I::Item: Deref,
<I::Item as Deref>::Target: Clone
{
fn next_back(&mut self) -> Option<T> {
fn next_back(&mut self) -> Option<<Self as Iterator>::Item> {
self.it.next_back().cloned()
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, D, I> ExactSizeIterator for Cloned<I> where
T: Clone,
D: Deref<Target=T>,
I: ExactSizeIterator<Item=D>,
impl<I> ExactSizeIterator for Cloned<I> where
I: ExactSizeIterator,
I::Item: Deref,
<I::Item as Deref>::Target: Clone
{}

#[unstable(feature = "core", reason = "trait is experimental")]
impl<T, D, I> RandomAccessIterator for Cloned<I> where
T: Clone,
D: Deref<Target=T>,
I: RandomAccessIterator<Item=D>
impl<I> RandomAccessIterator for Cloned<I> where
I: RandomAccessIterator,
I::Item: Deref,
<I::Item as Deref>::Target: Clone
{
#[inline]
fn indexable(&self) -> usize {
self.it.indexable()
}

#[inline]
fn idx(&mut self, index: usize) -> Option<T> {
fn idx(&mut self, index: usize) -> Option<<Self as Iterator>::Item> {
self.it.idx(index).cloned()
}
}
Expand Down Expand Up @@ -1400,11 +1400,14 @@ pub struct Chain<A, B> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<Item=T> {
type Item = T;
impl<A, B> Iterator for Chain<A, B> where
A: Iterator,
B: Iterator<Item = A::Item>
{
type Item = A::Item;

#[inline]
fn next(&mut self) -> Option<T> {
fn next(&mut self) -> Option<A::Item> {
if self.flag {
self.b.next()
} else {
Expand Down Expand Up @@ -1434,12 +1437,12 @@ impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<It
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, A, B> DoubleEndedIterator for Chain<A, B> where
A: DoubleEndedIterator<Item=T>,
B: DoubleEndedIterator<Item=T>,
impl<A, B> DoubleEndedIterator for Chain<A, B> where
A: DoubleEndedIterator,
B: DoubleEndedIterator<Item=A::Item>,
{
#[inline]
fn next_back(&mut self) -> Option<T> {
fn next_back(&mut self) -> Option<A::Item> {
match self.b.next_back() {
Some(x) => Some(x),
None => self.a.next_back()
Expand All @@ -1448,9 +1451,9 @@ impl<T, A, B> DoubleEndedIterator for Chain<A, B> where
}

#[unstable(feature = "core", reason = "trait is experimental")]
impl<T, A, B> RandomAccessIterator for Chain<A, B> where
A: RandomAccessIterator<Item=T>,
B: RandomAccessIterator<Item=T>,
impl<A, B> RandomAccessIterator for Chain<A, B> where
A: RandomAccessIterator,
B: RandomAccessIterator<Item = A::Item>,
{
#[inline]
fn indexable(&self) -> usize {
Expand All @@ -1459,7 +1462,7 @@ impl<T, A, B> RandomAccessIterator for Chain<A, B> where
}

#[inline]
fn idx(&mut self, index: usize) -> Option<T> {
fn idx(&mut self, index: usize) -> Option<A::Item> {
let len = self.a.indexable();
if index < len {
self.a.idx(index)
Expand All @@ -1479,14 +1482,12 @@ pub struct Zip<A, B> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, U, A, B> Iterator for Zip<A, B> where
A: Iterator<Item = T>,
B: Iterator<Item = U>,
impl<A, B> Iterator for Zip<A, B> where A: Iterator, B: Iterator
{
type Item = (T, U);
type Item = (A::Item, B::Item);

#[inline]
fn next(&mut self) -> Option<(T, U)> {
fn next(&mut self) -> Option<(A::Item, B::Item)> {
match self.a.next() {
None => None,
Some(x) => match self.b.next() {
Expand Down Expand Up @@ -1515,12 +1516,12 @@ impl<T, U, A, B> Iterator for Zip<A, B> where
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where
A: DoubleEndedIterator + ExactSizeIterator<Item=T>,
B: DoubleEndedIterator + ExactSizeIterator<Item=U>,
impl<A, B> DoubleEndedIterator for Zip<A, B> where
A: DoubleEndedIterator + ExactSizeIterator,
B: DoubleEndedIterator + ExactSizeIterator,
{
#[inline]
fn next_back(&mut self) -> Option<(T, U)> {
fn next_back(&mut self) -> Option<(A::Item, B::Item)> {
let a_sz = self.a.len();
let b_sz = self.b.len();
if a_sz != b_sz {
Expand All @@ -1540,17 +1541,17 @@ impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where
}

#[unstable(feature = "core", reason = "trait is experimental")]
impl<T, U, A, B> RandomAccessIterator for Zip<A, B> where
A: RandomAccessIterator<Item=T>,
B: RandomAccessIterator<Item=U>,
impl<A, B> RandomAccessIterator for Zip<A, B> where
A: RandomAccessIterator,
B: RandomAccessIterator
{
#[inline]
fn indexable(&self) -> usize {
cmp::min(self.a.indexable(), self.b.indexable())
}

#[inline]
fn idx(&mut self, index: usize) -> Option<(T, U)> {
fn idx(&mut self, index: usize) -> Option<(A::Item, B::Item)> {
match self.a.idx(index) {
None => None,
Some(x) => match self.b.idx(index) {
Expand Down Expand Up @@ -2071,8 +2072,9 @@ pub struct Scan<I, St, F> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A, B, I: Iterator<Item=A>, St, F> Iterator for Scan<I, St, F> where
F: FnMut(&mut St, A) -> Option<B>,
impl<B, I, St, F> Iterator for Scan<I, St, F> where
I: Iterator,
F: FnMut(&mut St, I::Item) -> Option<B>,
{
type Item = B;

Expand Down
25 changes: 25 additions & 0 deletions src/test/run-pass/iter-cloned-type-inference.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Test to see that the element type of .cloned() can be inferred
// properly. Previously this would fail to deduce the type of `sum`.

#![feature(core)]

use std::iter::AdditiveIterator;

fn square_sum(v: &[i64]) -> i64 {
let sum = v.iter().cloned().sum();
sum * sum
}

fn main() {
assert_eq!(36, square_sum(&[1,2,3]));
}