{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/24660","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/24660/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/24660/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/24660/events","html_url":"https://github.com/rust-lang/rust/issues/24660","id":69853837,"number":24660,"title":"Conditional mutation in Iterator::next doesn't optimise well","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},"labels":[{"url":"https://api.github.com/repos/rust-lang/rust/labels/A-iterators","name":"A-iterators","color":"d7e102"},{"url":"https://api.github.com/repos/rust-lang/rust/labels/I-slow","name":"I-slow","color":"e10c02"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2015-04-21T14:01:12Z","updated_at":"2015-04-22T22:08:30Z","closed_at":null,"body":"```rust\r\n#![crate_type = \"lib\"]\r\n\r\nstruct R {\r\n    start: i32,\r\n    end: i32\r\n}\r\n\r\nimpl Iterator for R\r\n{\r\n    type Item = i32;\r\n\r\n    fn next(&mut self) -> Option<i32> {\r\n        if self.start < self.end {\r\n            let old = self.start;\r\n            self.start += 1;\r\n            Some(old)\r\n        } else {\r\n            None\r\n        }\r\n    }\r\n}\r\n\r\n\r\npub fn test() -> usize {\r\n    R { start: 0, end: 100000}.count()\r\n}\r\n```\r\n\r\nCompiles to:\r\n\r\n```asm\r\n_ZN4test20h08046f2c32b9b146kaaE:\r\n\t.cfi_startproc\r\n\txorl\t%ecx, %ecx\r\n\tmovq\t$-1, %rax\r\n\t.align\t16, 0x90\r\n.LBB0_1:\r\n\tcmpl\t$100000, %ecx\r\n\tsetl\t%dl\r\n\tmovzbl\t%dl, %edx\r\n\taddl\t%ecx, %edx\r\n\tincq\t%rax\r\n\tcmpl\t$100000, %ecx\r\n\tmovl\t%edx, %ecx\r\n\tjl\t.LBB0_1\r\n\tretq\r\n```\r\n\r\nIt should at least look something like:\r\n\r\n```asm\r\n\txorl\t%eax, %eax\r\n\tmovl\t$100000, %ecx\r\n.LBB0_1: \r\n\tincl\t%eax\r\n\tdecl\t%ecx\r\n\tjne\t.LBB0_1\r\n```\r\n\r\nBut really that case should be constant folded (clang folds the equivalent C `for` loop).\r\n\r\n(NB. `count` is currently implemented as `self.fold(0, |c, _| c + 1)`, and the bad codegen occurs if that is definition is used directly, and also if one uses the mutating for loop: `let mut c = 0; for _ in ... { c += 1 }`.)\r\n\r\nThis previously affected `std::ops::Range` (i.e. `x..y`), but #24705 implemented a work-around."},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/95353079","html_url":"https://github.com/rust-lang/rust/issues/24660#issuecomment-95353079","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/24660","id":95353079,"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-04-22T22:08:30Z","updated_at":"2015-04-22T22:08:30Z","body":"I've submitted https://github.com/rust-lang/rust/pull/24705 with the intention that it's a temporary work-around."}}