{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/26308","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/26308/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/26308/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/26308/events","html_url":"https://github.com/rust-lang/rust/issues/26308","id":88332317,"number":26308,"title":"\"`vin` does not live long enough\" (bad lifetime inference?)","user":{"login":"eefriedman","id":12769964,"avatar_url":"https://avatars.githubusercontent.com/u/12769964?v=3","gravatar_id":"","url":"https://api.github.com/users/eefriedman","html_url":"https://github.com/eefriedman","followers_url":"https://api.github.com/users/eefriedman/followers","following_url":"https://api.github.com/users/eefriedman/following{/other_user}","gists_url":"https://api.github.com/users/eefriedman/gists{/gist_id}","starred_url":"https://api.github.com/users/eefriedman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eefriedman/subscriptions","organizations_url":"https://api.github.com/users/eefriedman/orgs","repos_url":"https://api.github.com/users/eefriedman/repos","events_url":"https://api.github.com/users/eefriedman/events{/privacy}","received_events_url":"https://api.github.com/users/eefriedman/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rust/labels/A-lifetimes","name":"A-lifetimes","color":"d7e102"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-06-15T06:21:20Z","updated_at":"2015-06-15T23:49:31Z","closed_at":null,"body":"Testcase (sorry it's a little on the long side):\r\n```rust\r\nstruct ChunkIter<T: Iterator>{\r\n    iter : T,\r\n    saved_item : Option<T::Item>,\r\n    cur_chunk_left : usize\r\n}\r\n\r\nstruct Chunks<T: Iterator> {\r\n    chunk_size : usize,\r\n    chunk_iter : ChunkIter<T>\r\n}\r\n\r\nimpl<T: Iterator> Chunks<T> {\r\n    fn new(iter: T, chunk_size: usize) -> Chunks<T>\r\n    {\r\n        Chunks { chunk_size: chunk_size, chunk_iter: ChunkIter { iter: iter, saved_item: None, cur_chunk_left: 0 } }\r\n    }\r\n}\r\n\r\nstruct Map<T:Iterator, F> {\r\n    iter: Chunks<T>,\r\n    f: F\r\n}\r\n\r\nimpl<T:Iterator, F, B> Iterator for Map<T, F> where F: FnMut(&mut ChunkIter<T>) -> B {\r\n    type Item = B;\r\n    fn next(&mut self) -> Option<B> {\r\n        let x = (&mut self.iter).next();\r\n        match x {\r\n            None => None,\r\n            Some(x) => Some((self.f)(x))\r\n        }\r\n    }\r\n}\r\n\r\nimpl<T:Iterator> Chunks<T>\r\n{\r\n    fn next(&mut self) -> Option<&mut ChunkIter<T>> {\r\n        while self.chunk_iter.cur_chunk_left > 0\r\n        {\r\n            <Iterator<Item=T::Item>>::next(&mut self.chunk_iter);\r\n        }\r\n        assert!(self.chunk_iter.saved_item.is_none());\r\n        \r\n        match self.chunk_iter.iter.next() {\r\n            None => None,\r\n            Some(item) => {\r\n                self.chunk_iter.saved_item = Some(item);\r\n                self.chunk_iter.cur_chunk_left = self.chunk_size;\r\n                Some(&mut self.chunk_iter)\r\n            }\r\n        }\r\n    }\r\n    fn map<B, F>(self, f: F) -> Map<T, F> where F: FnMut(&mut ChunkIter<T>) -> B\r\n    {\r\n        Map{iter: self, f: f}\r\n    }\r\n}\r\n\r\nimpl<T:Iterator> Iterator for ChunkIter<T>\r\n{\r\n    type Item = T::Item;\r\n    fn next(&mut self) -> Option<Self::Item> {\r\n        if self.cur_chunk_left == 0 { return None; }\r\n        self.cur_chunk_left -= 1;\r\n        if let Some(saved) = self.saved_item.take() {\r\n            Some(saved)\r\n        } else {\r\n            self.iter.next()\r\n        }\r\n    }\r\n}\r\n\r\nfn main() {\r\n    let vin = (0..10).collect::<Vec<i32>>();\r\n    let input = vin.iter();\r\n    let c = Chunks::new(input, 2);\r\n    let v : Vec<i32> = c.map(|i/*:&mut ChunkIter<std::slice::Iter<_>>*/| {\r\n        i.fold(0, |a,b|a+b)\r\n    }).collect();\r\n    println!(\"{:?}\", v);\r\n}\r\n```\r\nCurrently gives:\r\n```\r\n<anon>:75:17: 75:20 error: `vin` does not live long enough\r\n<anon>:75     let input = vin.iter();\r\n                          ^~~\r\nnote: reference must be valid for the static lifetime...\r\n<anon>:74:45: 81:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 74:44\r\n<anon>:74     let vin = (0..10).collect::<Vec<i32>>();\r\n<anon>:75     let input = vin.iter();\r\n<anon>:76     let c = Chunks::new(input, 2);\r\n<anon>:77     let v : Vec<i32> = c.map(|i/*:&mut ChunkIter<std::slice::Iter<_>>*/| {\r\n<anon>:78         i.fold(0, |a,b|a+b)\r\n<anon>:79     }).collect();\r\n          ...\r\nerror: aborting due to previous error\r\n```\r\nIf you uncomment the type annotation on line 77, the testcase compiles and successfully prints `[1, 5, 9, 13, 17]`.  It doesn't seem like the annotation should be necessary, though."},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/112239404","html_url":"https://github.com/rust-lang/rust/issues/26308#issuecomment-112239404","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/26308","id":112239404,"user":{"login":"shepmaster","id":174509,"avatar_url":"https://avatars.githubusercontent.com/u/174509?v=3","gravatar_id":"","url":"https://api.github.com/users/shepmaster","html_url":"https://github.com/shepmaster","followers_url":"https://api.github.com/users/shepmaster/followers","following_url":"https://api.github.com/users/shepmaster/following{/other_user}","gists_url":"https://api.github.com/users/shepmaster/gists{/gist_id}","starred_url":"https://api.github.com/users/shepmaster/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/shepmaster/subscriptions","organizations_url":"https://api.github.com/users/shepmaster/orgs","repos_url":"https://api.github.com/users/shepmaster/repos","events_url":"https://api.github.com/users/shepmaster/events{/privacy}","received_events_url":"https://api.github.com/users/shepmaster/received_events","type":"User","site_admin":false},"created_at":"2015-06-15T23:49:31Z","updated_at":"2015-06-15T23:49:31Z","body":"The error goes away if you remove the `Iterator` restriction on the first struct:\r\n\r\n```rust\r\nstruct ChunkIter<T> {\r\n    iter: T,\r\n}\r\n```"}}