Skip to content

Associated types bug #20684

@dylanmckay

Description

@dylanmckay

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

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions