-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed
Labels
A-associated-itemsArea: Associated items (types, constants & functions)Area: Associated items (types, constants & functions)
Description
I'm hitting a bug in my math library due to associated types.
The compiler does not recognize that the associated type on the result of Add
is the same type as T
(well, it partly does, as the error message says that Item == T
, and as such, the expression c1+c2
does not typecheck.
Here is the error
error: type mismatch resolving `<core::iter::Map<(T, T), <T as core::ops::Add>::Output, core::iter::Zip<generic_vector::Components<'_, T>, generic_vector::Components<'_, T>>, closure[vector_test.rs:17:54: 17:69]> as core::iter::Iterator>::Item == T`: expected associated type, found type parameter
vector_test.rs:15:13: 15:47 note: required by `core::iter::FromIterator::from_iter`
vector_test.rs:15 std::iter::FromIterator::from_iter(self.components()
Code snippet (Playpen)
#![feature(associated_types)]
use std::ops::Add;
pub trait Vector<T: Copy + Add> : std::iter::FromIterator<T> + Sized
{
fn components<'a>(&'a self) -> Components<'a,T>;
fn add(self, rhs: Self) -> Self
{
std::iter::FromIterator::from_iter(self.components()
.zip(rhs.components())
.map( |(c1,c2)| c1+c2))
}
}
/// An efficent iterator for enumerating components.
///
/// Iterates over a collection of components in the order they exist in memory.
///
/// This iterator is designed to be as fast and efficent as possible.
/// For this iterator to work correctly, `ptr` must point to a linear, continuous
/// array in memory. If this requirement is not upheld, the result is undefined behaviour.
pub struct Components<'a, T>
{
ptr: *const T,
end: *const T,
}
impl<'a, T> Components<'a, T>
{
/// Creates a new iterator from a pointer to the first component and the number of components.
pub fn new(begin: *const T, len: uint) -> Components<'a, T>
{
let end: *const T = ((begin as uint) + (std::mem::size_of::<T>()*len)) as *const T;
Components::from_ptrs(begin, end)
}
pub fn from_ptrs(begin: *const T, end: *const T) -> Components<'a, T>
{
Components {
ptr: begin,
end: end,
}
}
}
impl<'a, T: Copy> Iterator for Components<'a, T>
{
type Item = T;
fn next(&mut self) -> Option<T>
{
// check if we have a next component
if self.ptr != self.end {
let component = unsafe { *self.ptr };
// increment the pointer to the next component.
self.ptr = ((self.ptr as uint) + (std::mem::size_of::<T>())) as *const T;
Some(component)
} else { // we reached the last component
None
}
}
}
fn main() { }
Metadata
Metadata
Assignees
Labels
A-associated-itemsArea: Associated items (types, constants & functions)Area: Associated items (types, constants & functions)