{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/34035","repository_url":"https://api.github.com/repos/rust-lang/rust","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/34035/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/34035/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/34035/events","html_url":"https://github.com/rust-lang/rust/issues/34035","id":158122990,"number":34035,"title":"Immutable borrow as argument for mutable borrow does not compile","user":{"login":"skiwi2","id":2961606,"avatar_url":"https://avatars.githubusercontent.com/u/2961606?v=3","gravatar_id":"","url":"https://api.github.com/users/skiwi2","html_url":"https://github.com/skiwi2","followers_url":"https://api.github.com/users/skiwi2/followers","following_url":"https://api.github.com/users/skiwi2/following{/other_user}","gists_url":"https://api.github.com/users/skiwi2/gists{/gist_id}","starred_url":"https://api.github.com/users/skiwi2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/skiwi2/subscriptions","organizations_url":"https://api.github.com/users/skiwi2/orgs","repos_url":"https://api.github.com/users/skiwi2/repos","events_url":"https://api.github.com/users/skiwi2/events{/privacy}","received_events_url":"https://api.github.com/users/skiwi2/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2016-06-02T11:54:41Z","updated_at":"2016-06-02T17:46:18Z","closed_at":null,"body":"I have the following piece of code which I expect to work but the borrow checker does not agree:\r\n\r\n    fn main() {\r\n        let mut data = vec![1; 100];\r\n        {\r\n            let (left, right) = data.split_at_mut(data.len() / 2);\r\n        }\r\n        println!(\"{:?}\", data);\r\n    }\r\n\r\nPlease note that the extra scope is in principle not related to the issue I'm describing, I'm just doing it such that I can use the `println!` macro to ensure that the compiler does not optimize the code away because I'm not using it thereafter. (I'm new to Rust so I don't know the exact rules)\r\n\r\nThe error I get is the following:\r\n\r\n> main.rs:4:47: 4:51 error: cannot borrow `data` as immutable because it is also borrowed as mutable [E0502]\r\nmain.rs:4         let (left, right) = data.split_at_mut(data.len() / 2);\r\n                                                        ^~~~\r\nmain.rs:4:29: 4:33 note: previous borrow of `data` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `data` until the borrow ends\r\nmain.rs:4         let (left, right) = data.split_at_mut(data.len() / 2);\r\n                                      ^~~~\r\nmain.rs:5:6: 5:6 note: previous borrow ends here\r\nmain.rs:3     {\r\nmain.rs:4         let (left, right) = data.split_at_mut(data.len() / 2);\r\nmain.rs:5     }\r\n              ^\r\n\r\nHowever what I would expect is the following:\r\n\r\n1. `data.len()` takes an immutable borrow.\r\n2. `data.len()` returns the immutable borrow and divides the obtained `u32` by `2`.\r\n3. `data.split_at_mut()` takes a mutable borrow.\r\n\r\nIt seems like the borrow checker currently evaluates the statement in the wrong order.\r\n\r\nThe following workaround is available, but it feels like this is a place where we should not have the need to (rightfully) fight the borrow checker.\r\n\r\n    fn main() {\r\n        let mut data = vec![1; 100];\r\n        {\r\n            let len = data.len();\r\n            let (left, right) = data.split_at_mut(len / 2);\r\n        }\r\n        println!(\"{:?}\", data);\r\n    }\r\n"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/223367688","html_url":"https://github.com/rust-lang/rust/issues/34035#issuecomment-223367688","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/34035","id":223367688,"user":{"login":"Stebalien","id":310393,"avatar_url":"https://avatars.githubusercontent.com/u/310393?v=3","gravatar_id":"","url":"https://api.github.com/users/Stebalien","html_url":"https://github.com/Stebalien","followers_url":"https://api.github.com/users/Stebalien/followers","following_url":"https://api.github.com/users/Stebalien/following{/other_user}","gists_url":"https://api.github.com/users/Stebalien/gists{/gist_id}","starred_url":"https://api.github.com/users/Stebalien/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Stebalien/subscriptions","organizations_url":"https://api.github.com/users/Stebalien/orgs","repos_url":"https://api.github.com/users/Stebalien/repos","events_url":"https://api.github.com/users/Stebalien/events{/privacy}","received_events_url":"https://api.github.com/users/Stebalien/received_events","type":"User","site_admin":false},"created_at":"2016-06-02T17:46:17Z","updated_at":"2016-06-02T17:46:17Z","body":"I'm not entirely sure that non-lexical borrows can fix this without being a breaking change. The above code desugars to:\r\n\r\n```rust\r\nfn main() {\r\n    let mut data = vec![1; 100];\r\n    {\r\n        let (left, right) = DerefMut::deref_mut(&mut data).split_at_mut(Deref::deref(&data).len() / 2);\r\n    }\r\n    println!(\"{:?}\", data);\r\n}\r\n```"}}
{"actor":{"display_login":"Stebalien"}}