{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/1210","labels_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1210/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1210/comments","events_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1210/events","html_url":"https://github.com/rust-lang/rfcs/pull/1210","id":94822300,"number":1210,"title":"RFC: impl specialization","user":{"login":"aturon","id":709807,"avatar_url":"https://avatars.githubusercontent.com/u/709807?v=3","gravatar_id":"","url":"https://api.github.com/users/aturon","html_url":"https://github.com/aturon","followers_url":"https://api.github.com/users/aturon/followers","following_url":"https://api.github.com/users/aturon/following{/other_user}","gists_url":"https://api.github.com/users/aturon/gists{/gist_id}","starred_url":"https://api.github.com/users/aturon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aturon/subscriptions","organizations_url":"https://api.github.com/users/aturon/orgs","repos_url":"https://api.github.com/users/aturon/repos","events_url":"https://api.github.com/users/aturon/events{/privacy}","received_events_url":"https://api.github.com/users/aturon/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rust-lang/rfcs/labels/T-lang","name":"T-lang","color":"bfd4f2"}],"state":"open","locked":false,"assignee":{"login":"aturon","id":709807,"avatar_url":"https://avatars.githubusercontent.com/u/709807?v=3","gravatar_id":"","url":"https://api.github.com/users/aturon","html_url":"https://github.com/aturon","followers_url":"https://api.github.com/users/aturon/followers","following_url":"https://api.github.com/users/aturon/following{/other_user}","gists_url":"https://api.github.com/users/aturon/gists{/gist_id}","starred_url":"https://api.github.com/users/aturon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aturon/subscriptions","organizations_url":"https://api.github.com/users/aturon/orgs","repos_url":"https://api.github.com/users/aturon/repos","events_url":"https://api.github.com/users/aturon/events{/privacy}","received_events_url":"https://api.github.com/users/aturon/received_events","type":"User","site_admin":false},"milestone":null,"comments":170,"created_at":"2015-07-13T22:00:51Z","updated_at":"2016-01-08T10:39:16Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rust-lang/rfcs/pulls/1210","html_url":"https://github.com/rust-lang/rfcs/pull/1210","diff_url":"https://github.com/rust-lang/rfcs/pull/1210.diff","patch_url":"https://github.com/rust-lang/rfcs/pull/1210.patch"},"body":"This RFC proposes a design for *specialization*, which permits multiple `impl`\r\nblocks to apply to the same type/trait, so long as one of the blocks is clearly\r\n\"more specific\" than the other. The more specific `impl` block is used in a case\r\nof overlap. The design proposed here also supports refining default trait\r\nimplementations based on specifics about the types involved.\r\n\r\nAltogether, this relatively small extension to the trait system yields benefits\r\nfor performance and code reuse, and it lays the groundwork for an \"efficient\r\ninheritance\" scheme that is largely based on the trait system (described in a\r\nforthcoming companion RFC).\r\n\r\n[Rendered](https://github.com/aturon/rfcs/blob/impl-specialization/text/0000-impl-specialization.md)"},"comment":{"url":"https://api.github.com/repos/rust-lang/rfcs/issues/comments/169959250","html_url":"https://github.com/rust-lang/rfcs/pull/1210#issuecomment-169959250","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1210","id":169959250,"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":"2016-01-08T10:39:16Z","updated_at":"2016-01-08T10:39:16Z","body":"@aturon I have two responses, which I will separate into two comments. This one just kind of rephrases your conclusions about `impl Trait` and `Iterator` (or, at least, I think that it does). The next one will discuss the question of removing `default type` from the RFC.\r\n\r\nThe way I see it is, in the \"featherweight Rust model\" of traits, we **are** trying an alternative to the all-or-nothing approach to defaults. That is, rather than marking individual *items* as default, you have *groups of items* that are marked as `default`, and those groups must be specialized collectively or not at all. However, rather then expose these groups directly to the end user, we choose to package up the groups using `impl Trait`. \r\n\r\nSo you can think of `impl Trait` as sugar. Thus:\r\n\r\n```rust\r\npub trait Iterator {\r\n    type Item;\r\n\r\n    fn map(self) -> impl Iterator<Self::Item> {\r\n        Map::new(self)\r\n    }\r\n}\r\n```\r\n\r\nbecomes something like (again, not actual syntax we expose to the user):\r\n\r\n```rust\r\npub trait Iterator {\r\n    type Item;\r\n    type Map: Iterator<Self::Item>;\r\n    fn map(self) -> Self::Map;\r\n}\r\n\r\n// FIXME if we don't permit this syntax, we probably should\r\npartial impl Iterator {\r\n    default { // create a \"default group\"\r\n        type Map = Map<Self::Item>;\r\n        fn map(self) -> Map<Self::Item> {\r\n            Map::new(self)\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nAnd now if someone chose to impl `Iterator` manually, they could make use of the `partial impl` in general, but if they specialize `map()` they must also specialize `Map`."}}