{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/15479","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/15479/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/15479/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/15479/events","html_url":"https://github.com/rust-lang/rust/issues/15479","id":37219396,"number":15479,"title":"Error snake for moving out of an &-pointer is wrong sometimes","user":{"login":"Manishearth","id":1617736,"avatar_url":"https://avatars.githubusercontent.com/u/1617736?v=3","gravatar_id":"","url":"https://api.github.com/users/Manishearth","html_url":"https://github.com/Manishearth","followers_url":"https://api.github.com/users/Manishearth/followers","following_url":"https://api.github.com/users/Manishearth/following{/other_user}","gists_url":"https://api.github.com/users/Manishearth/gists{/gist_id}","starred_url":"https://api.github.com/users/Manishearth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Manishearth/subscriptions","organizations_url":"https://api.github.com/users/Manishearth/orgs","repos_url":"https://api.github.com/users/Manishearth/repos","events_url":"https://api.github.com/users/Manishearth/events{/privacy}","received_events_url":"https://api.github.com/users/Manishearth/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rust/labels/A-diagnostics","name":"A-diagnostics","color":"d7e102"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2014-07-06T13:34:39Z","updated_at":"2015-04-20T23:09:57Z","closed_at":null,"body":"Minimal-ish working example:\r\n\r\n```\r\nuse std::string::String;\r\nstruct Foo {\r\n a: String,\r\n b: String,\r\n // Possibly some more fields here\r\n}\r\nstruct FooThing(Vec<Foo>);\r\nimpl FooThing {\r\n  fn filter(&mut self, bar: &Foo) {\r\n    let FooThing(ref buf) = self.clone(); // Oops. Shouldn't be a `ref` there\r\n    let new_buf: Vec<Foo> = buf.move_iter().filter(|f| f.a == bar.a && f.b == bar.b).collect();\r\n  }\r\n}\r\nfn main() {\r\n\r\n}\r\n```\r\n\r\nThe usage of `ref buf` means that `buf.move_iter` won't work, since `buf` is an &-pointer now. An error is expected.\r\n\r\nHowever, the error shown is:\r\n```\r\ntest.rs:12:53: 12:56 error: the type of this value must be known in this context\r\ntest.rs:12 \tlet new_buf: Vec<Foo> = buf.move_iter().filter(|f| f.a == bar.a && f.b == bar.b).collect();\r\n           \t                                                   ^~~\r\n```\r\n\r\nFor some reason, the red caret points at `f.a`. Swapping `f.a` and `bar.a`, it still points at `f.a`. Swapping the two equality checks, it now points at `f.b`. I don't know what the difference was, but in my real-world case it was the second equality check that had the pointer on it.\r\n\r\n\r\nThe error snake goes to `buf.move_iter()` correctly if you replace `self.clone()` with `*self`."},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/94589617","html_url":"https://github.com/rust-lang/rust/issues/15479#issuecomment-94589617","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/15479","id":94589617,"user":{"login":"nham","id":546409,"avatar_url":"https://avatars.githubusercontent.com/u/546409?v=3","gravatar_id":"","url":"https://api.github.com/users/nham","html_url":"https://github.com/nham","followers_url":"https://api.github.com/users/nham/followers","following_url":"https://api.github.com/users/nham/following{/other_user}","gists_url":"https://api.github.com/users/nham/gists{/gist_id}","starred_url":"https://api.github.com/users/nham/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nham/subscriptions","organizations_url":"https://api.github.com/users/nham/orgs","repos_url":"https://api.github.com/users/nham/repos","events_url":"https://api.github.com/users/nham/events{/privacy}","received_events_url":"https://api.github.com/users/nham/received_events","type":"User","site_admin":false},"created_at":"2015-04-20T23:09:57Z","updated_at":"2015-04-20T23:09:57Z","body":"I made an attempt at reproducing this. Here is the updated code:\r\n\r\n    use std::string::String;\r\n\r\n    #[derive(Clone)]\r\n    struct Foo {\r\n     a: String,\r\n     b: String,\r\n     // Possibly some more fields here\r\n    }\r\n\r\n    #[derive(Clone)]\r\n    struct FooThing(Vec<Foo>);\r\n\r\n    impl FooThing {\r\n        fn filter(&mut self, bar: &Foo) {\r\n            // Oops. Shouldn't be a `ref` there\r\n            let FooThing(ref buf) = self.clone();\r\n\r\n            let new_buf: Vec<Foo> = buf.into_iter()\r\n                                       .filter(|f| f.a == bar.a && f.b == bar.b)\r\n                                       .collect();\r\n        }\r\n    }\r\n\r\n    fn main() {}\r\n\r\nThis fails to compile now, but with this error:\r\n\r\n    test_15479.rs:18:33: 18:36 error: cannot move out of borrowed content\r\n    test_15479.rs:18         let new_buf: Vec<Foo> = buf.into_iter()\r\n                                                     ^~~\r\n    error: aborting due to previous error\r\n\r\n(Version is `rustc 1.0.0-nightly (07560d233 2015-04-20) (built 2015-04-20)`)\r\n\r\nThis appears to not have the problem described above.\r\n\r\n"}}