{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/28419","repository_url":"https://api.github.com/repos/rust-lang/rust","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/28419/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/28419/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/28419/events","html_url":"https://github.com/rust-lang/rust/issues/28419","id":106572725,"number":28419,"title":"improve error message when resolution via Deref actually required DerefMut","user":{"login":"pnkfelix","id":173127,"avatar_url":"https://avatars.githubusercontent.com/u/173127?v=3","gravatar_id":"","url":"https://api.github.com/users/pnkfelix","html_url":"https://github.com/pnkfelix","followers_url":"https://api.github.com/users/pnkfelix/followers","following_url":"https://api.github.com/users/pnkfelix/following{/other_user}","gists_url":"https://api.github.com/users/pnkfelix/gists{/gist_id}","starred_url":"https://api.github.com/users/pnkfelix/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pnkfelix/subscriptions","organizations_url":"https://api.github.com/users/pnkfelix/orgs","repos_url":"https://api.github.com/users/pnkfelix/repos","events_url":"https://api.github.com/users/pnkfelix/events{/privacy}","received_events_url":"https://api.github.com/users/pnkfelix/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"},{"url":"https://api.github.com/repos/rust-lang/rust/labels/E-mentor","name":"E-mentor","color":"02E10C"}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":15,"created_at":"2015-09-15T14:47:50Z","updated_at":"2016-09-16T14:59:34Z","closed_at":null,"body":"If a type `B` implements `Deref` to get out `&A`, then auto-deref based method resolution of instances of `B` will include methods of `A` that require `&mut self`, even when there is no `DerefMut` that would be necessary for such auto-deref to work.\r\n\r\nWe still reject the code, with the message \"cannot borrow immutable borrowed content as mutable\"\r\n\r\nWhat I would prefer is for the message to say something like:\r\n> error: cannot do mutable borrow via Deref alone\r\n> note: would need (at least) impl DerefMut for A\r\n\r\n * (i included some weasel language in the above that might be better editted out of a good error report.)\r\n\r\n(I think @nikomatsakis is well aware of this problem; he's mentioned the issue about how the auto-deref code needs to use a conservative guess during method resolution and rely on later compiler stages to reject the method lookup.)\r\n\r\nHere is an example of code exhibiting the problem [playpen](http://is.gd/91nnYn):\r\n\r\n```rust\r\nuse std::ops::Deref;\r\n\r\nstruct A(i32);\r\nstruct B(A);\r\n\r\nimpl A {\r\n    fn yow(&mut self) { println!(\"Hi\"); }\r\n}\r\n\r\nimpl Deref for B {\r\n    type Target = A;\r\n    fn deref(&self) -> &Self::Target { &self.0 }\r\n}\r\n\r\nfn main() {\r\n    let mut b = B(A(3));\r\n    b.yow();\r\n}\r\n```\r\n\r\nThe error message when you run this (on nightly) is:\r\n```\r\n<anon>:17:5: 17:6 error: cannot borrow immutable borrowed content as mutable\r\n<anon>:17     b.yow();\r\n              ^\r\nerror: aborting due to previous error\r\n```\r\n\r\nThis message can be frustrating, especially when the content *appears* mutable at the point that is highlighted by the span of the error message; after all, I *did* use `let mut b = ...`"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/247623098","html_url":"https://github.com/rust-lang/rust/issues/28419#issuecomment-247623098","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/28419","id":247623098,"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":"2016-09-16T14:59:34Z","updated_at":"2016-09-16T14:59:34Z","body":"@nikomatsakis do you think this code is a symptom of the same problem, or should I file it separately?\r\n\r\n```rust\r\nfn main() {\r\n    let mut fns: Vec<Box<FnMut()>> = vec![Box::new(|| println!(\"called\"))];\r\n    \r\n    (fns[0])(); // error: expected function, found `Box<std::ops::FnMut()>`\r\n    (*&mut fns[0])();\r\n}\r\n```"}}
{"actor":{"display_login":"shepmaster"}}