{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/2357","repository_url":"https://api.github.com/repos/rust-lang/rfcs","labels_url":"https://api.github.com/repos/rust-lang/rfcs/issues/2357/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/issues/2357/comments","events_url":"https://api.github.com/repos/rust-lang/rfcs/issues/2357/events","html_url":"https://github.com/rust-lang/rfcs/pull/2357","id":302066387,"number":2357,"title":"RFC: Ghost Busting","user":{"login":"Centril","id":855702,"avatar_url":"https://avatars2.githubusercontent.com/u/855702?v=4","gravatar_id":"","url":"https://api.github.com/users/Centril","html_url":"https://github.com/Centril","followers_url":"https://api.github.com/users/Centril/followers","following_url":"https://api.github.com/users/Centril/following{/other_user}","gists_url":"https://api.github.com/users/Centril/gists{/gist_id}","starred_url":"https://api.github.com/users/Centril/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Centril/subscriptions","organizations_url":"https://api.github.com/users/Centril/orgs","repos_url":"https://api.github.com/users/Centril/repos","events_url":"https://api.github.com/users/Centril/events{/privacy}","received_events_url":"https://api.github.com/users/Centril/received_events","type":"User","site_admin":false},"labels":[{"id":211667886,"url":"https://api.github.com/repos/rust-lang/rfcs/labels/T-lang","name":"T-lang","color":"bfd4f2","default":false}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":112,"created_at":"2018-03-04T08:09:16Z","updated_at":"2018-03-10T22:47:01Z","closed_at":null,"author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/2357","html_url":"https://github.com/rust-lang/rfcs/pull/2357","diff_url":"https://github.com/rust-lang/rfcs/pull/2357.diff","patch_url":"https://github.com/rust-lang/rfcs/pull/2357.patch"},"body":"### [🖼️ Rendered](https://github.com/Centril/rfcs/blob/rfc/ghost-busting/text/0000-ghost-busting.md)\r\n\r\n### 📝 Summary\r\n\r\n[`PhantomData<T>`]: https://doc.rust-lang.org/nightly/nomicon/phantom-data.html\r\n[variance]: https://doc.rust-lang.org/nightly/nomicon/subtyping.html\r\n[drop checking]: https://doc.rust-lang.org/nightly/nomicon/dropck.html\r\n\r\n1. **Defines unused type parameters to act as if they are logically owned and covariant.**\r\n\r\n2. **Introduces `phantom T` pseudo-fields which improves the ergonomics of changing\r\n    [variance] and [drop checking] behavior when it is needed.** A `phantom T` field also has\r\n    the same behavior with respect to auto traits as [`PhantomData<T>`] does.\r\n\r\n3. [`PhantomData<T>`] is redefined as `struct PhantomData<T: ?Sized>;` and deprecated.\r\n\r\n4. The lang item `phantom_data` is removed.\r\n\r\n5. Derive macros for derivable standard library traits will take advantage of statically known\r\n   phantom types and fields to generate more permissive `impl`s.\r\n\r\nThat's it folks; Happy 👻👤!\r\n\r\n### 💖 Thanks\r\n\r\nThanks to @nikomatsakis and @eddyb for interesting discussions."},"comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/comments/372073383","html_url":"https://github.com/rust-lang/rfcs/pull/2357#issuecomment-372073383","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/2357","id":372073383,"user":{"login":"Centril","id":855702,"avatar_url":"https://avatars2.githubusercontent.com/u/855702?v=4","gravatar_id":"","url":"https://api.github.com/users/Centril","html_url":"https://github.com/Centril","followers_url":"https://api.github.com/users/Centril/followers","following_url":"https://api.github.com/users/Centril/following{/other_user}","gists_url":"https://api.github.com/users/Centril/gists{/gist_id}","starred_url":"https://api.github.com/users/Centril/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Centril/subscriptions","organizations_url":"https://api.github.com/users/Centril/orgs","repos_url":"https://api.github.com/users/Centril/repos","events_url":"https://api.github.com/users/Centril/events{/privacy}","received_events_url":"https://api.github.com/users/Centril/received_events","type":"User","site_admin":false},"created_at":"2018-03-10T22:47:01Z","updated_at":"2018-03-10T22:47:01Z","author_association":"CONTRIBUTOR","body":"@mark-i-m \r\n\r\n> That makes me dislike attributes or extra keywords in the `<T1, ..., TN>` list.\r\n\r\nI agree; we should avoid the rightward drift as much as possible. Fortunately, `phantom` clauses and fields do not add any extra attributes or keywords in that list.\r\n\r\n> Along the same lines, I think we should be very careful about adding more and more data into rustdocs.\r\n\r\nThis is why I think hiding the information behind tooltips and hidden-by-default sections is a good strategy to only show the data to those that care.\r\n\r\n> I am somewhat against accepting unused type parameters. I think that doing weird things with variance or dropck should be very clearly stated somewhere in the declaration.\r\n\r\nI think overwhelmingly, `PhantomData<P>` for a type parameter `P` is the sane default since it arises frequently due to traits and the \"unconstrained type parameter\" error.\r\n\r\n> rather, it usually means I refactored my code and forgot to remove a type parameter somewhere. This sort of implicit phantom field would decrease productivity for me by introducing strange and hard-to-understand bugs.\r\n\r\nWe can introduce lints `#![deny(unused_type_parameter)]` which you can enable during refactoring.\r\n\r\n> And I suspect that most users of rust are not knowledgeable enough about type theory to know that a weird compiler message about variance really means \"dude, you forgot to delete T from the list\".\r\n\r\nWe should try to emit non-weird messages that are as natural as possible.\r\n\r\n> The main ergonomics cost, in my experience, is the annoyance of initializing `_phantom` fields everywhere the struct is created.\r\n\r\nI think you are mostly right, but the different annoyances have a tendency to enhance each other. Initializing the phantom field is also a direct consequence of having a real field.\r\n\r\n> Probably my biggest concern: playing with dropck and variance sounds like a really dangerous game. Are we more likely to introduce unsoundness bugs into the type system by adding this?\r\n\r\nNo; a `phantom T` clause or field is functionally equivalent to `PhantomData<T>` wrt. variance, dropck, and auto-trait behavior - this can only lead to unsoundness if `PhantomData<T>` does. Of course there's always the possibility of bugs in the implementation; but this is true of all new features we add to the language.\r\n\r\n> Also, are we making it easier for users to write subtly unsafe code by making a variance error?\r\n\r\nI don't see why... Unsafety flows from uses of `unsafe` - if you also have generics, you will have to think about variance regardless of this RFC or not. Folks who use `unsafe` should always consult the rustonomicon, today and tomorrow.\r\n\r\n> As I see it the biggest way to improve ergonomics would be to avoid having to initialize _phantom fields. To that end, maybe a much more conservative alternative would be to simply allow omission of initialization for zero-sized fields in struct literals?\r\n\r\nThis has been discussed previously in the RFC and in the alternatives. I don't think it is more conservative; but rather more radical. I think having this special behavior wrt. ZSTs is too special. I think the more consistent approach is using the `Default` trait.\r\n\r\n@glaebhoerl \r\n\r\n> Presumably the fleshed-out version of the proposal would be more like \"the compiler automatically inserts the literal to construct the ZST, and then checks that for errors normally\", e.g. if the ZST had private fields you'd get a privacy error. (Inventing ZST values \"out of thin air\" would of course be a bad idea because it would violate the soundness of APIs.)\r\n\r\nJust to make sure we're on the same page... This would be the behavior?\r\n\r\n```rust\r\nmod boundary {\r\n  pub struct Foo {\r\n    priv: (),\r\n  }\r\n\r\n  pub fn make_foo() -> Foo {\r\n      Foo {} // OK; expanded to:  Foo { priv: () }\r\n  }\r\n}\r\n\r\npub fn make_foo() -> Foo {\r\n  Foo {} // ERR! expands to: Foo { priv: () }   ==> privacy error.\r\n}\r\n```"}}
{"actor":{"display_login":"Centril"}}