Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

library stabilization: allow inherent methods on primitive types #16862

Closed
aturon opened this issue Aug 29, 2014 · 12 comments
Closed

library stabilization: allow inherent methods on primitive types #16862

aturon opened this issue Aug 29, 2014 · 12 comments

Comments

@aturon
Copy link
Member

aturon commented Aug 29, 2014

Currently, the only way we can provide methods for primitive types like slices it through public extension traits (like Str). This approach has a few downsides:

  • Most important, people are tempted to use these traits for generic programming (taking Str-bounded types, and/or implementing Str on their own types), which is very much not the intention.
  • It clutters the exports of several modules in core and std.
  • It's harder for newcomers to understand what's going on, since it's not clear whether the type or the trait is important.

If we could allow inherent impl blocks for primitive types, we could avoid stabilizing these extension traits.

@aturon aturon added the A-libs label Aug 29, 2014
@reem
Copy link
Contributor

reem commented Aug 30, 2014

Why should people not write functions which accept Str, for instance? I've found this makes for much more ergonomic APIs in many cases. I know it increases the size of the binary, but in many cases that doesn't matter as much as ease of use.

@huonw
Copy link
Member

huonw commented Aug 30, 2014

(I think StrSlice is a better example of an extension trait; Str is actually somewhat designed with generic code in mind, while StrSlice is, atm, just to put methods on &str.)

@alexcrichton
Copy link
Member

cc #11409

This was initially attempted to also improve rustdoc output. The rustdoc issue has since been fixed as it was seen as too big of a hammer to add inherent methods to primitive types for that problem, but it's certainly another beneficiary!

@SiegeLord
Copy link
Contributor

Using/abusing traits to add inherent methods to types is necessary in more cases than just primitive types (e.g. imagine if rust-lang/rfcs#155 is accepted), so from my POV the primitive types are a red-herring and what is necessary here is to prevent users from deriving those traits (which can be done via private super-traits).

The second two points, in particular, are issues with all uses of such traits, and in some ways, of all uses of traits in general.

@aturon
Copy link
Member Author

aturon commented Mar 5, 2015

cc @japaric

@japaric
Copy link
Member

japaric commented Mar 6, 2015

If we could allow inherent impl blocks for primitive types, we could avoid stabilizing these extension traits.

@aturon Could you be more specific about which traits would get replaced with inherent impls? Int? Float? (I have a rough idea of how to do this. I don't know if it would ulimately work, and it involves one lang item per primitive impl)

@reem
Copy link
Contributor

reem commented Mar 6, 2015

This is also a backwards-compatability hazard since changing the signature of any trait method is a backwards incompatible change, even if that trait is meant to be "sealed."

@huonw
Copy link
Member

huonw commented Mar 6, 2015

We can "stability-seal" traits by having #[unstable] non-default methods on them, which means they cannot be implemented in stable code.

@aturon
Copy link
Member Author

aturon commented Mar 6, 2015

@japaric Also StrExt, CharExt, PtrExt.

@aturon
Copy link
Member Author

aturon commented Mar 6, 2015

@japaric oh and SliceExt.

This change would make the documentation much friendlier, would ease the back-compat story (as @reem points out), and help clarify the story about the numeric traits (by relegating all generics to external libraries for the time being).

bors added a commit that referenced this issue Mar 17, 2015
- Allow inherent implementations on `char`, `str`, `[T]`, `*const T`, `*mut T` and all the numeric primitives.
- copy `unicode::char::CharExt` methods into `impl char`
- remove `unicode::char::CharExt`, its re-export `std::char::CharExt` and `CharExt` from the prelude
- copy `collections::str::StrExt` methods into `impl str`
- remove `collections::str::StrExt` its re-export `std::str::StrExt`, and `StrExt` from the prelude
- copy `collections::slice::SliceExt` methods into `impl<T> [T]`
- remove `collections::slice::SliceExt` its re-export `std::slice::SliceExt`, and `SliceExt` from the prelude
- copy `core::ptr::PtrExt` methods into `impl<T> *const T`
- remove `core::ptr::PtrExt` its re-export `std::ptr::PtrExt`, and `PtrExt` from the prelude
- copy `core::ptr::PtrExt` and `core::ptr::MutPtrExt` methods into `impl<T> *mut T`
- remove `core::ptr::MutPtrExt` its re-export `std::ptr::MutPtrExt`, and `MutPtrExt` from the prelude
- copy `core::num::Int` and `core::num::SignedInt` methods into `impl i{8,16,32,64,size}`
- copy `core::num::Int` and `core::num::UnsignedInt` methods into `impl u{8,16,32,64,size}`
- remove `core::num::UnsignedInt` and its re-export `std::num::UnsignedInt`
- move `collections` tests into its own crate: `collectionstest`
- copy `core::num::Float` methods into `impl f{32,64}`

Because 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:

``` diff
  fn main() {
-     use std::num::UnsignedInt;  //~ error: unresolved import `std::num::UnsignedInt`.
-
      println!("{}", 8_usize.is_power_of_two());
  }
```

---

cc  #16862
[preview docs](http://japaric.github.io/inherent/std/index.html)
[unicode::char](http://japaric.github.io/inherent/unicode/primitive.char.html)
[collections::str](http://japaric.github.io/inherent/collections/primitive.str.html)
[std::f32](http://japaric.github.io/inherent/std/primitive.f32.html)
@tomjakubowski
Copy link
Contributor

Can this be closed? Seems like #23104 addressed this.

@alexcrichton
Copy link
Member

Indeed!

bors added a commit to rust-lang-ci/rust that referenced this issue Mar 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants