{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/27031","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/27031/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/27031/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/27031/events","html_url":"https://github.com/rust-lang/rust/issues/27031","id":94873283,"number":27031,"title":"Rust does not allow narrowing the mutable references","user":{"login":"uzytkownik","id":5706,"avatar_url":"https://avatars.githubusercontent.com/u/5706?v=3","gravatar_id":"","url":"https://api.github.com/users/uzytkownik","html_url":"https://github.com/uzytkownik","followers_url":"https://api.github.com/users/uzytkownik/followers","following_url":"https://api.github.com/users/uzytkownik/following{/other_user}","gists_url":"https://api.github.com/users/uzytkownik/gists{/gist_id}","starred_url":"https://api.github.com/users/uzytkownik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/uzytkownik/subscriptions","organizations_url":"https://api.github.com/users/uzytkownik/orgs","repos_url":"https://api.github.com/users/uzytkownik/repos","events_url":"https://api.github.com/users/uzytkownik/events{/privacy}","received_events_url":"https://api.github.com/users/uzytkownik/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"},{"url":"https://api.github.com/repos/rust-lang/rust/labels/A-typesystem","name":"A-typesystem","color":"d7e102"},{"url":"https://api.github.com/repos/rust-lang/rust/labels/I-papercut","name":"I-papercut","color":"e10c02"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":12,"created_at":"2015-07-14T05:50:00Z","updated_at":"2015-07-18T11:13:26Z","closed_at":null,"body":"Currently rust does allow to narrow the immutable references as long as the don't appear in contravariant position:\r\n\r\n```rust\r\n// This compiles\r\nstruct Foo1<'a> {\r\n    a: &'a Fn(&'static str) -> u32\r\n}\r\n\r\nfn foo1<'a : 'b, 'b>(foo: Foo1<'a>) -> Foo1<'b> {\r\n    foo\r\n}\r\n\r\n// This, correctly, does not compile\r\nstruct Foo2<'a> {\r\n    a: &'a Fn(&'a str) -> u32\r\n}\r\n\r\n\r\nfn foo2<'a : 'b, 'b>(foo: Foo2<'a>) -> Foo1<'b> {\r\n    foo\r\n}\r\n```\r\nIt seems that if I have a mutable reference for `'a` lifetime I should be able to turn it into mutable reference for `'b` lifetime as long as the `'b` is narrower then `'a` however the following code is not allowed in Rust:\r\n\r\n```rust\r\nstruct Foo3<'a> {\r\n    a: &'a mut Fn(&'static str) -> u32\r\n}\r\n\r\nfn foo3<'a : 'b, 'b>(foo: Foo3<'a>) -> Foo3<'b> {\r\n    foo\r\n}\r\n```"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/122530742","html_url":"https://github.com/rust-lang/rust/issues/27031#issuecomment-122530742","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/27031","id":122530742,"user":{"login":"nikomatsakis","id":155238,"avatar_url":"https://avatars.githubusercontent.com/u/155238?v=3","gravatar_id":"","url":"https://api.github.com/users/nikomatsakis","html_url":"https://github.com/nikomatsakis","followers_url":"https://api.github.com/users/nikomatsakis/followers","following_url":"https://api.github.com/users/nikomatsakis/following{/other_user}","gists_url":"https://api.github.com/users/nikomatsakis/gists{/gist_id}","starred_url":"https://api.github.com/users/nikomatsakis/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nikomatsakis/subscriptions","organizations_url":"https://api.github.com/users/nikomatsakis/orgs","repos_url":"https://api.github.com/users/nikomatsakis/repos","events_url":"https://api.github.com/users/nikomatsakis/events{/privacy}","received_events_url":"https://api.github.com/users/nikomatsakis/received_events","type":"User","site_admin":false},"created_at":"2015-07-18T11:13:26Z","updated_at":"2015-07-18T11:13:26Z","body":"It is not a question of traits (in fact, my point was that traits are not special cased, which is why you get an error here). The point is that you have the reference to 'a inside the referent type in both cases (that is, the type that the &mut points at). That makes it \"invariant\", meaning it cannot be shortened (or else the language would be unsound). In the trait case however this is less obvious because it appears due to the implicit lifetime bound. \n\n\nNiko\n\n<div>-------- Original message --------</div><div>From: Maciej Piechotka <notifications@github.com> </div><div>Date:07/18/2015  01:58  (GMT-05:00) </div><div>To: rust-lang/rust <rust@noreply.github.com> </div><div>Cc: Niko Matsakis <niko@alum.mit.edu> </div><div>Subject: Re: [rust] Rust does not allow narrowing the mutable references\r  (#27031) </div><div>\n</div>@nikomatsakis Initally I didn't have traits at all - it was closer to:\n\nenum Tree<T> {\n   Bin(*mut Tree<T>, T, *mut Tree<T>),\n   Leaf\n}\n\nenum TreeZipper<'a, T : 'a> {\n    Top,\n    Left(&'a mut TreeZipper<'a, T>, T, Tree<T>),\n    Right(Tree<T>, T, &'a mut TreeZipper<'a, T>)\n}\n\nfn cast<'a : 'b, 'b, T : 'a>(foo: TreeZipper<'a, T>) -> TreeZipper<'b, T> {\n    foo\n}\n@arielb1 This still does no compile:\n\nenum BL<'a> {\n    Root,\n    Link(&'a mut BLLike, &'a mut u32)\n}\n\ntrait BLLike {\n    fn val(&mut self) -> BL;\n}\n\nfn cast<'a : 'b, 'b>(foo: BL<'a>) -> BL<'b> {foo}\n—\nReply to this email directly or view it on GitHub.\n\n"}}