{"action":"created","issue":{"url":"https://api.github.com/repos/rust-lang/rust/issues/23104","labels_url":"https://api.github.com/repos/rust-lang/rust/issues/23104/labels{/name}","comments_url":"https://api.github.com/repos/rust-lang/rust/issues/23104/comments","events_url":"https://api.github.com/repos/rust-lang/rust/issues/23104/events","html_url":"https://github.com/rust-lang/rust/pull/23104","id":60056522,"number":23104,"title":"allow inherent implementations on primitives, remove some extension traits","user":{"login":"japaric","id":5018213,"avatar_url":"https://avatars.githubusercontent.com/u/5018213?v=3","gravatar_id":"","url":"https://api.github.com/users/japaric","html_url":"https://github.com/japaric","followers_url":"https://api.github.com/users/japaric/followers","following_url":"https://api.github.com/users/japaric/following{/other_user}","gists_url":"https://api.github.com/users/japaric/gists{/gist_id}","starred_url":"https://api.github.com/users/japaric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/japaric/subscriptions","organizations_url":"https://api.github.com/users/japaric/orgs","repos_url":"https://api.github.com/users/japaric/repos","events_url":"https://api.github.com/users/japaric/events{/privacy}","received_events_url":"https://api.github.com/users/japaric/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"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},"milestone":null,"comments":24,"created_at":"2015-03-06T04:04:18Z","updated_at":"2015-03-12T17:33:27Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/rust-lang/rust/pulls/23104","html_url":"https://github.com/rust-lang/rust/pull/23104","diff_url":"https://github.com/rust-lang/rust/pull/23104.diff","patch_url":"https://github.com/rust-lang/rust/pull/23104.patch"},"body":"- Allow inherent implementations on `char`, `str`, `[T]`, `*const T`, `*mut T` and all the numeric primitives.\r\n- copy `unicode::char::CharExt` methods into `impl char`\r\n- remove `unicode::char::CharExt`, its re-export `std::char::CharExt` and `CharExt` from the prelude\r\n- copy `collections::str::StrExt` methods into `impl str`\r\n- remove `collections::str::StrExt` its re-export `std::str::StrExt`, and `StrExt` from the prelude\r\n- copy `collections::slice::SliceExt` methods into `impl<T> [T]`\r\n- remove `collections::slice::SliceExt` its re-export `std::slice::SliceExt`, and `SliceExt` from the prelude\r\n- copy `core::ptr::PtrExt` methods into `impl<T> *const T`\r\n- remove `core::ptr::PtrExt` its re-export `std::ptr::PtrExt`, and `PtrExt` from the prelude\r\n- copy `core::ptr::PtrExt` and `core::ptr::MutPtrExt` methods into `impl<T> *mut T`\r\n- remove `core::ptr::MutPtrExt` its re-export `std::ptr::MutPtrExt`, and `MutPtrExt` from the prelude\r\n- copy `core::num::Int` and `core::num::SignedInt` methods into `impl i{8,16,32,64,size}`\r\n- copy `core::num::Int` and `core::num::UnsignedInt` methods into `impl u{8,16,32,64,size}`\r\n- remove `core::num::UnsignedInt` and its re-export `std::num::UnsignedInt`\r\n- move `collections` tests into its own crate: `collectionstest`\r\n- copy `core::num::Float` methods into `impl f{32,64}`\r\n\r\nBecause this PR removes several traits, this is a [breaking-change], however functionality remains unchanged and breakage due to unresolved imports should be minimal. If you encounter an error due to an unresolved import, simply remove the import:\r\n\r\n``` diff\r\n  fn main() {\r\n-     use std::num::UnsignedInt;  //~ error: unresolved import `std::num::UnsignedInt`.\r\n-\r\n      println!(\"{}\", 8_usize.is_power_of_two());\r\n  }\r\n```\r\n\r\n---\r\n\r\ncc  #16862\r\n[preview docs](http://japaric.github.io/inherent/std/index.html)\r\n[unicode::char](http://japaric.github.io/inherent/unicode/primitive.char.html)\r\n[collections::str](http://japaric.github.io/inherent/collections/primitive.str.html)"},"comment":{"url":"https://api.github.com/repos/rust-lang/rust/issues/comments/78539940","html_url":"https://github.com/rust-lang/rust/pull/23104#issuecomment-78539940","issue_url":"https://api.github.com/repos/rust-lang/rust/issues/23104","id":78539940,"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},"created_at":"2015-03-12T17:33:26Z","updated_at":"2015-03-12T17:33:26Z","body":"@alexcrichton \r\n\r\nI respectfully disagree.\r\n\r\n> I'm starting to somewhat have second thoughts about this from a compiler implementation perspective. From an API standpoint I think this change is fine largely because it doesn't really change much. Overall, however, this seems like it's all a bit of a hack.\r\n\r\nI think it is quite valuable from an API perspective, but more on that below.\r\n\r\n> We're basically bending the language to our whim to enable this sort of functionality because we control the compiler, but from the perspective of some other hypothetical compiler implementor this becomes quite a pain. We're adding all these special cases for these very implementation-specific set of `impl` blocks for each primitive. Put another way, we've found the language inadequate for our desires so we're getting around that with some slight of hand that doesn't come up too much but likely will at some point.\r\n\r\nI think this is overstated in several ways.\r\n\r\nWhile we've moved many things into the libraries, the problem here is precisely to do with *primitive types*, which are specifically types that cannot be defined in the language itself and must be taken as given. In particular, I see adding inherent impls for these types as *bringing them up to parity* with other library types; currently, we cannot follow standard conventions or API design for these special types! That is, this isn't \"bending the language to our whim\", it's making sure that primitive types and user-defined types work in more similar ways.\r\n\r\n> I think the biggest pain points for me when reading this are:\r\n\r\n> * Such a huge number of lang items were added.\r\n\r\nThat by itself doesn't seem like a problem to me. The point here is to uniformly add the ability to give inherent methods for primitive types, and there are many primitive types.\r\n\r\n> * Multiple inherent implementations on primitives is allowed\r\n\r\nI can see how this aspect feels a bit more hacky/implementation-specific. It's basically tied to the facade setup. But see below.\r\n\r\n> The lang item problem can probably be considered an implementation detail of the compiler, but allowing multiple inherent implementations makes me feel like something has gone awry somewhere. We don't have the luxury of always being able to bend the language so API design is a little easier, and I felt that the previous trait-per-primitive-in-the-prelude solution was quite adequate: it worked out well in terms of documentation, functionality, extensibility, and it was also consistent with the rest of the language.  \r\n\r\nIt's a little difficult to tease apart the various concerns here. It seems like you're making a slippery slope kind of argument that this is \"bending the language\" but as I argued above, at least the idea of having inherent impls for primitive types it just making the language more internally consistent between primitive and user-defined types.\r\n\r\nAs to the question of having multiple inherent impls, that is indeed one sense in which this PR goes beyond what the language provides elsewhere. However, I consider this, like all other aspects of the facade, a hidden and changeable implementation detail. The commitment here is just to have *some* inherent methods visible in `std`, but the precise way that is broken down is up for grabs. (I personally don't mind the inherent split, but we could certainly discuss changing it; however, I don't think it should block this PR since it can be tweaked later.)\r\n\r\nAs to the status quo: I personally disagree that it worked out quite well. In particular, it is already difficult for newcomers to Rust to understand how Deref and dispatch work together to make methods show up for things like `Vec`, but then the fact that the relevant methods were defined on an extension trait add that much more of a barrier. In addition, for the numeric types, the traits are routinely misunderstood as being intended for full-blown generic programming over numerics, and they aren't suited for that. (That latter could be addressed by introducing separate extension traits for each type.)\r\n\r\nI think that when it comes to the primitive types of the language, we should make things as simple and transparent as possible. People have to learn a lot of things when they come to Rust, and not having inherent methods on our basic types is both inconsistent with other types and adds yet another indirection for something very basic."}}