{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/52130","repository_url":"https://api.github.com/repos/rust-lang/rust","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/52130/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/52130/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/52130/events","html_url":"https://github.com/rust-lang/rust/issues/52130","id":339147056,"node_id":"MDU6SXNzdWUzMzkxNDcwNTY=","number":52130,"title":"`&self` sugar is not consistent with other `&identifier` bindings","user":{"login":"danielhenrymantilla","id":9920355,"node_id":"MDQ6VXNlcjk5MjAzNTU=","avatar_url":"https://avatars0.githubusercontent.com/u/9920355?v=4","gravatar_id":"","url":"https://api.github.com/users/danielhenrymantilla","html_url":"https://github.com/danielhenrymantilla","followers_url":"https://api.github.com/users/danielhenrymantilla/followers","following_url":"https://api.github.com/users/danielhenrymantilla/following{/other_user}","gists_url":"https://api.github.com/users/danielhenrymantilla/gists{/gist_id}","starred_url":"https://api.github.com/users/danielhenrymantilla/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danielhenrymantilla/subscriptions","organizations_url":"https://api.github.com/users/danielhenrymantilla/orgs","repos_url":"https://api.github.com/users/danielhenrymantilla/repos","events_url":"https://api.github.com/users/danielhenrymantilla/events{/privacy}","received_events_url":"https://api.github.com/users/danielhenrymantilla/received_events","type":"User","site_admin":false},"labels":[{"id":630652267,"node_id":"MDU6TGFiZWw2MzA2NTIyNjc=","url":"https://api.github.com/repos/rust-lang/rust/labels/C-feature-request","name":"C-feature-request","color":"f5f1fd","default":false},{"id":211668019,"node_id":"MDU6TGFiZWwyMTE2NjgwMTk=","url":"https://api.github.com/repos/rust-lang/rust/labels/T-lang","name":"T-lang","color":"bfd4f2","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2018-07-07T13:44:36Z","updated_at":"2018-07-08T16:10:38Z","closed_at":null,"author_association":"NONE","body":"Rust's `&self` sugar is equivalent to `self: &Self`. But in any other scenario, binding to a variable (let's call it `slf` in the examples) with `&slf` idiom actually performs a pattern-match against a reference so that the value of the `slf` variable ends up being an owned value instead of a reference.\r\n\r\nOr at least that's what my [test code](https://play.rust-lang.org/?gist=95189c68e15f1f2b252a71dce132d2b2) seems to indicate (I strongly encourage you to have a look at it: https://gist.github.com/danielhenrymantilla/95189c68e15f1f2b252a71dce132d2b2)\r\n\r\nHere is an example that should illustrate this point :\r\n```rust\r\n/* compiler ensures that check_ref::<T>(x) can only be called iff x: &T */\r\nfn check_ref<T> (_: &T) {}\r\n\r\n#[derive(Clone, Copy, PartialEq)]\r\nstruct Slf;\r\n\r\n#[test]\r\nfn ampself_notation ()              // &slf\r\n{\r\n    let &slf = &Slf;             // <-- &self logic here */\r\n    // check_ref::<Slf>(slf);    // does not compile!\r\n    check_ref::<Slf>(&slf);      // this does\r\n    assert!(&slf == &Slf);\r\n    assert!(slf == Slf);\r\n    /* => slf is NOT a ref /!\\ */\r\n}\r\n\r\n#[test]\r\nfn ampself_notation_equivalent ()   // Explanation:\r\n{\r\n//  let &slf =  (&Slf);          // does a pattern-match equivalent to:\r\n    let  slf = *(&Slf);          // move borrowed value => requires Copy\r\n    // check_ref::<Slf>(slf);    // Can't compile => slf isn't a ref\r\n    check_ref::<Slf>(&slf);      // &slf is.\r\n    assert!(slf == Slf);\r\n}\r\n\r\n/* ===== (&slf) vs (slf: &Slf) -> NOT THE SAME TYPE ===== */\r\n\r\n#[test]\r\nfn function_case ()\r\n{\r\n//  let ampself_notation_wrong = |&slf| {\r\n//      check_ref::<Slf>(slf);          // Can't compile => slf isn't a ref\r\n//  }\r\n\r\n    let ampself_notation_right = |&slf| { \r\n        check_ref::<Slf>(&slf);\r\n        assert!(slf == Slf);\r\n        /* => slf is NOT a ref /!\\ */\r\n    };\r\n\r\n    ampself_notation_right(&Slf);    // borrowed input\r\n    /* ===== (&slf) vs (slf: &Slf) -> NOT THE SAME TYPE ===== */\r\n}\r\n\r\n/* self functions / (static) methods */\r\nimpl Slf {\r\n    fn ampself_notation_wrong (&self) {\r\n        check_ref::<Slf>(self);\r\n        assert!(self == &Slf);\r\n        /* => self is a ref */\r\n    }\r\n\r\n//  fn ampself_notation_right (&self) {\r\n//      check_ref::<Slf>(&self);\r\n//      /* Can't compile => self is indeed a ref */\r\n//  }\r\n}\r\n\r\n#[test]\r\nfn self_method_case ()\r\n{\r\n    Slf::ampself_notation_wrong(&Slf);  // borrowed input\r\n    /* ===== (&self) vs (self: &Self) -> THE SAME TYPE !?? ===== */\r\n}\r\n```\r\n\r\n### TL,DR:\r\n- **for a non-special identifier like `slf`, the binding `&slf <- expr` where `expr: &Slf` does not lead to `slf: &Slf` but to `slf: Slf` following the expected \"pattern-matching\" rules.**\r\n- **for the special identifier `self`, however, the first-arg-of-the-method binding does not lead to `self: Self` but to `self: &Self` instead.**\r\n\r\nNB: Although not tested, I guess the same could be said of `&mut identifier`"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/403298169","html_url":"https://github.com/rust-lang/rust/issues/52130#issuecomment-403298169","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/52130","id":403298169,"node_id":"MDEyOklzc3VlQ29tbWVudDQwMzI5ODE2OQ==","user":{"login":"Ixrec","id":5285357,"node_id":"MDQ6VXNlcjUyODUzNTc=","avatar_url":"https://avatars2.githubusercontent.com/u/5285357?v=4","gravatar_id":"","url":"https://api.github.com/users/Ixrec","html_url":"https://github.com/Ixrec","followers_url":"https://api.github.com/users/Ixrec/followers","following_url":"https://api.github.com/users/Ixrec/following{/other_user}","gists_url":"https://api.github.com/users/Ixrec/gists{/gist_id}","starred_url":"https://api.github.com/users/Ixrec/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Ixrec/subscriptions","organizations_url":"https://api.github.com/users/Ixrec/orgs","repos_url":"https://api.github.com/users/Ixrec/repos","events_url":"https://api.github.com/users/Ixrec/events{/privacy}","received_events_url":"https://api.github.com/users/Ixrec/received_events","type":"User","site_admin":false},"created_at":"2018-07-08T16:10:38Z","updated_at":"2018-07-08T16:10:38Z","author_association":"CONTRIBUTOR","body":"Hypothetically, if we could change this, what would the \"consistent\" sugar for `self` arguments even be? `self&`? `&(self)`? `self:&`? `self as &`?"}}
{"actor":{"display_login":"Ixrec"}}