{"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":72,"created_at":"2015-07-13T22:00:51Z","updated_at":"2015-08-11T20:18:12Z","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/130052181","html_url":"https://github.com/rust-lang/rfcs/pull/1210#issuecomment-130052181","issue_url":"https://api.github.com/repos/rust-lang/rfcs/issues/1210","id":130052181,"user":{"login":"stevenblenkinsop","id":3118803,"avatar_url":"https://avatars.githubusercontent.com/u/3118803?v=3","gravatar_id":"","url":"https://api.github.com/users/stevenblenkinsop","html_url":"https://github.com/stevenblenkinsop","followers_url":"https://api.github.com/users/stevenblenkinsop/followers","following_url":"https://api.github.com/users/stevenblenkinsop/following{/other_user}","gists_url":"https://api.github.com/users/stevenblenkinsop/gists{/gist_id}","starred_url":"https://api.github.com/users/stevenblenkinsop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevenblenkinsop/subscriptions","organizations_url":"https://api.github.com/users/stevenblenkinsop/orgs","repos_url":"https://api.github.com/users/stevenblenkinsop/repos","events_url":"https://api.github.com/users/stevenblenkinsop/events{/privacy}","received_events_url":"https://api.github.com/users/stevenblenkinsop/received_events","type":"User","site_admin":false},"created_at":"2015-08-11T20:18:12Z","updated_at":"2015-08-11T20:18:12Z","body":"Just a sketch of how I can see choosing a specific specialization level working:\r\n\r\n    <impl<T> ToString for T>::to_string(s)\r\n\r\nThe impl signature in the angle brackets needs to be exactly as generic and equally constrained as the impl it's specifying so the compiler knows you're choosing a potentially less specified impl. This can clearly get unwieldy, especially with `where` clauses, so `use` renaming could apply:\r\n\r\n    use <impl<T> ToString for T> as defaultToString;\r\n    defaultToString::to_string(s)\r\n\r\nOf course, this idea presents the same issue as accessing trait members does: if the compiler can't infer the specialized types for some reason, then you need some way of explicitly specifying those types, like UFCS can. This makes the syntax even more complex:\r\n\r\n    <impl<T> ToString for T>::<str as ToString>\r\n\r\nor\r\n\r\n    <str as ToString>::<impl<T> ToString for T>\r\n\r\nI'm not sure which order makes more sense. Note that the motivation for this syntax makes more sense if you consider that `ToString` could be replaced by a trait with type parameters.\r\n\r\nAs for whether to allow `super` in specialized impls, I think in that case it's important that it's always clear what ancestor you're referring to. `super` Has the benefit that it ensures you're guaranteed to use the next-most specialized impl, but at the cost that it might not be immediately clear which this is. So I'd potentially say that, in order to use `super` it should have to be declared:\r\n\r\n    use <impl<T> ToString for T> as super;\r\n\r\nThis use case seems important, but narrow enough that the added annotation burden doesn't seem unreasonable, considering that it might otherwise be non-obvious which ancestor is actually being denoted by `super`. The circumstances where this requirement might be loosened would be where there the next-most specialized impl is in another crate (which defines the trait), since here the particulars aren't as important and there's less potential for confusion. It's only when you're doing something more complex that I think there should be a way to demonstrate that you know what you're doing."}}