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

Associated types bug #20684

Closed
dylanmckay opened this issue Jan 7, 2015 · 3 comments
Closed

Associated types bug #20684

dylanmckay opened this issue Jan 7, 2015 · 3 comments
Labels
A-associated-items Area: Associated items (types, constants & functions)

Comments

@dylanmckay
Copy link
Contributor

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() { }
@huonw
Copy link
Member

huonw commented Jan 7, 2015

This seems to work fine when the trait definition is changed to pub trait Vector<T: Copy + Add<Output = T>> : std::iter::FromIterator<T> + Sized (i.e. explicitly specify the result type) so I guess this may be a dupe of #19476.

@huonw huonw added the A-associated-items Area: Associated items (types, constants & functions) label Jan 7, 2015
@nikomatsakis
Copy link
Contributor

I think this is just... working as designed, actually. Even if defaults were implemented, they would only affect the impls of a trait, and usages would still need to explicitly bind the result. From what the compiler knows here, the result type of the adds is just T::Output and not T.

@nikomatsakis
Copy link
Contributor

Going to close for now as "working as designed" (for better or worse).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items (types, constants & functions)
Projects
None yet
Development

No branches or pull requests

3 participants