{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/20684","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/20684/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/20684/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/20684/events","html_url":"https://github.com/rust-lang/rust/issues/20684","id":53604805,"number":20684,"title":"Associated types bug","user":{"login":"dylanmckay","id":7722159,"avatar_url":"https://avatars.githubusercontent.com/u/7722159?v=3","gravatar_id":"","url":"https://api.github.com/users/dylanmckay","html_url":"https://github.com/dylanmckay","followers_url":"https://api.github.com/users/dylanmckay/followers","following_url":"https://api.github.com/users/dylanmckay/following{/other_user}","gists_url":"https://api.github.com/users/dylanmckay/gists{/gist_id}","starred_url":"https://api.github.com/users/dylanmckay/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dylanmckay/subscriptions","organizations_url":"https://api.github.com/users/dylanmckay/orgs","repos_url":"https://api.github.com/users/dylanmckay/repos","events_url":"https://api.github.com/users/dylanmckay/events{/privacy}","received_events_url":"https://api.github.com/users/dylanmckay/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-01-07T07:15:39Z","updated_at":"2015-01-07T07:42:51Z","closed_at":null,"body":"I'm hitting a bug in my math library due to associated types.\r\n\r\nThe 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.\r\n\r\nHere is the error\r\n```\r\nerror: 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\r\n\r\nvector_test.rs:15:13: 15:47 note: required by `core::iter::FromIterator::from_iter`\r\nvector_test.rs:15             std::iter::FromIterator::from_iter(self.components()\r\n\r\n```\r\n\r\nCode snippet ([Playpen](http://is.gd/owgsk7))\r\n``` rust\r\n#![feature(associated_types)]\r\n\r\nuse std::ops::Add;\r\n\r\npub trait Vector<T: Copy + Add> : std::iter::FromIterator<T> + Sized\r\n{\r\n    fn components<'a>(&'a self) -> Components<'a,T>;\r\n    \r\n    fn add(self, rhs: Self) -> Self\r\n    {\r\n        std::iter::FromIterator::from_iter(self.components()\r\n                                           .zip(rhs.components())\r\n                                           .map( |(c1,c2)| c1+c2))\r\n                                           \r\n    }\r\n}\r\n\r\n\r\n/// An efficent iterator for enumerating components.\r\n///\r\n/// Iterates over a collection of components in the order they exist in memory.\r\n///\r\n/// This iterator is designed to be as fast and efficent as possible.\r\n/// For this iterator to work correctly, `ptr` must point to a linear, continuous\r\n/// array in memory. If this requirement is not upheld, the result is undefined behaviour.\r\npub struct Components<'a, T>\r\n{\r\n    ptr: *const T,\r\n    end: *const T,\r\n}\r\n\r\nimpl<'a, T> Components<'a, T>\r\n{\r\n    /// Creates a new iterator from a pointer to the first component and the number of components.\r\n    pub fn new(begin: *const T, len: uint) -> Components<'a, T>\r\n    {\r\n        let end: *const T = ((begin as uint) + (std::mem::size_of::<T>()*len)) as *const T;\r\n        \r\n        Components::from_ptrs(begin, end)\r\n    }\r\n    \r\n    pub fn from_ptrs(begin: *const T, end: *const T) -> Components<'a, T>\r\n    {\r\n        Components {\r\n            ptr: begin,\r\n            end: end,\r\n        }\r\n    }\r\n}\r\n\r\nimpl<'a, T: Copy> Iterator for Components<'a, T>\r\n{\r\n    type Item = T;\r\n    \r\n    fn next(&mut self) -> Option<T>\r\n    {\r\n        // check if we have a next component\r\n        if self.ptr != self.end {\r\n            \r\n            let component = unsafe { *self.ptr };\r\n            \r\n            // increment the pointer to the next component.\r\n            self.ptr = ((self.ptr as uint) + (std::mem::size_of::<T>())) as *const T;\r\n            \r\n            Some(component)\r\n            \r\n        } else { // we reached the last component\r\n            None\r\n        }\r\n    }\r\n}\r\n\r\nfn main() { }\r\n```"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/68988501","html_url":"https://github.com/rust-lang/rust/issues/20684#issuecomment-68988501","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/20684","id":68988501,"user":{"login":"huonw","id":1203825,"avatar_url":"https://avatars.githubusercontent.com/u/1203825?v=3","gravatar_id":"","url":"https://api.github.com/users/huonw","html_url":"https://github.com/huonw","followers_url":"https://api.github.com/users/huonw/followers","following_url":"https://api.github.com/users/huonw/following{/other_user}","gists_url":"https://api.github.com/users/huonw/gists{/gist_id}","starred_url":"https://api.github.com/users/huonw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/huonw/subscriptions","organizations_url":"https://api.github.com/users/huonw/orgs","repos_url":"https://api.github.com/users/huonw/repos","events_url":"https://api.github.com/users/huonw/events{/privacy}","received_events_url":"https://api.github.com/users/huonw/received_events","type":"User","site_admin":false},"created_at":"2015-01-07T07:42:51Z","updated_at":"2015-01-07T07:42:51Z","body":"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 https://github.com/rust-lang/rust/issues/19476."}}