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

Tracking issue for libcore prelude traits #32110

Closed
alexcrichton opened this Issue Mar 8, 2016 · 22 comments

Comments

Projects
None yet
6 participants
@alexcrichton
Copy link
Member

alexcrichton commented Mar 8, 2016

These are currently all unstable but part of the libcore prelude.

This is currently intentional, but the fact that they need to be unstable is somewhat unsettling. Arguably all unstable features in libcore should be on the path to deprecation or stabilization at some point.

@Mark-Simulacrum

This comment has been minimized.

Copy link
Member

Mark-Simulacrum commented May 1, 2017

I believe that libcore is now mostly stable, aside from those below. As far as I can tell, none of these are directly in the prelude, though I may be wrong. Perhaps this can be closed?

   1 src/libcore/fmt/mod.rs: fmt_flags_align
   1 src/libcore/hash/mod.rs: sip_hash_13
   1 src/libcore/iter/range.rs: trusted_len
   1 src/libcore/iter/traits.rs: exact_size_is_empty
   1 src/libcore/iter/traits.rs: iter_rfind
   1 src/libcore/macros.rs: concat_idents_macro
   1 src/libcore/marker.rs: unsize
   1 src/libcore/slice/mod.rs: slice_get_slice
   1 src/libcore/sync/atomic.rs: compiler_fences
   1 src/libcore/sync/atomic.rs: future_atomic_orderings
   2 src/libcore/fmt/mod.rs: never_type_impls
   2 src/libcore/hash/mod.rs: i128
   2 src/libcore/iter/sources.rs: trusted_len
   2 src/libcore/iter/traits.rs: fused
   2 src/libcore/iter/traits.rs: trusted_len
   2 src/libcore/ops.rs: question_mark_carrier
   2 src/libcore/option.rs: option_entry
   2 src/libcore/ptr.rs: offset_to
   2 src/libcore/slice/mod.rs: trusted_len
   2 src/libcore/str/mod.rs: str_internals
   3 src/libcore/char.rs: try_from
   3 src/libcore/cmp.rs: reverse_cmp_key
   3 src/libcore/iter/sources.rs: fused
   3 src/libcore/ops.rs: fn_traits
   3 src/libcore/option.rs: fused
   3 src/libcore/option.rs: trusted_len
   3 src/libcore/result.rs: fused
   3 src/libcore/result.rs: trusted_len
   3 src/libcore/slice/mod.rs: sort_unstable
   3 src/libcore/str/mod.rs: str_mut_extras
   4 src/libcore/char.rs: decode_utf8
   4 src/libcore/char.rs: fused
   4 src/libcore/cmp.rs: never_type_impls
   4 src/libcore/convert.rs: try_from
   5 src/libcore/cell.rs: coerce_unsized
   5 src/libcore/char.rs: char_escape_debug
   5 src/libcore/num/mod.rs: try_from
   5 src/libcore/ops.rs: placement_new_protocol
   5 src/libcore/ptr.rs: unique
   6 src/libcore/iter/range.rs: fused
   7 src/libcore/iter/mod.rs: trusted_len
   7 src/libcore/mem.rs: manually_drop
   7 src/libcore/str/mod.rs: fused
   8 src/libcore/hash/sip.rs: sip_hash_13
   9 src/libcore/ptr.rs: shared
  10 src/libcore/ops.rs: coerce_unsized
  10 src/libcore/slice/mod.rs: fused
  10 src/libcore/str/mod.rs: str_checked_slicing
  14 src/libcore/slice/mod.rs: slice_rsplit
  20 src/libcore/iter/mod.rs: fused
@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented May 1, 2017

@Mark-Simulacrum How did you make this list? It’s missing at least core_slice_ext, core_str_ext, and core_char_ext for the core::slice::SliceExt, core::str::StrExt, and core::char::CharExt traits, which is what this issue is about. They are re-exported from libcore’s prelude, which is different from libstd’s prelude.

@Mark-Simulacrum

This comment has been minimized.

Copy link
Member

Mark-Simulacrum commented May 1, 2017

I can't find the command in my history right now for some reason. I guess I messed up with the ripgrep parameters, though. No need for the list now though, since you've provided it :).

@nagisa

This comment has been minimized.

Copy link
Contributor

nagisa commented May 11, 2017

We certainly should move non-allocating inherent slice methods into libcore as inherent methods, and not the trait mess we’re currently in.

I’m fairly sure we could hack the compiler enough to allow multiple inherent impl blocks across the libcore and libcollections crates with some attribute or something.

@vks vks referenced this issue May 30, 2017

Closed

Make subcrates `#![no_std]` #216

0 of 4 tasks complete
@Razican

This comment has been minimized.

Copy link
Contributor

Razican commented Mar 4, 2018

Hello, I'm seeing that the core_float feature redirects here. I found it out when trying to use f32::powi(). Why are float "power" methods not available in stable core? Do they need to allocate? Why?

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Mar 4, 2018

@alexcrichton Should core::num::Float be added to core::prelude::v1, following the same pattern as CharExt for example? This would make methods like powi available to no_std crates.

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Mar 5, 2018

In general yes, functionality stable in libstd is fine to ensure is available in libcore as well. Looking at the trait it also has a stable Bits associated constant though, which means the entire trait is probably not ready for stable reexportation.

@Razican

This comment has been minimized.

Copy link
Contributor

Razican commented Mar 5, 2018

I also see that for the cos(), sin(), sin_cos() and sqrt() functions in floats only use intrinsics readily available in core_intrinsics. Maybe those could be stabilized as well, right?

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Mar 6, 2018

Those are ones we'd specifically actually not want to stabilize as well because they require runtime support. Their definitions in libcore should likely be removed.

@michael-p

This comment has been minimized.

Copy link

michael-p commented Mar 6, 2018

So if one needs to use sin, cos etc on an embedded device (with implementations provided by libc/libm) one has to use core::intrinsics::sinf32 and friends, right? Or is there another (better) way of doing this, since core_intrinsics is probably never going to be stable? (meaning using trigonometric functions in the embedded world will never be stable)

@Razican

This comment has been minimized.

Copy link
Contributor

Razican commented Mar 6, 2018

I was thinking on porting parts of libm to Rust using corrode or something similar, since I also would like to have atan(), asin() and acos() too, and they use cmath in the standard library. I still don't know if I could make them work without heap allocation, though.

I ported most of some code to use core::intrinsics::sinf32 and friends, but @alexcrichton said they should likely be removed, so it's probably not a good idea to depend on them. I didn't try to compile them to bare metal, even though they compiled fine using #[no_std].

I haven't started any work on sqrt().

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Mar 6, 2018

@Razican for sure yeah it's useful to have in libcore but it should be explicitly improted. Something like core::intrinsics::sinf32 just calls sin, so that's why it's not exported.

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Apr 7, 2018

not want to stabilize as well because they require runtime support

@alexcrichton Does this also apply to the abs, signum, and powi methods of core::num::Float? Their impls are based on intrinsics.

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 8, 2018

@SimonSapin yes ideally anything requiring runtime support is only stabilized in libstd, although that ship may have already sailed.

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Apr 8, 2018

The Float trait is unstable and not in the prelude, so… maybe not?

To be clear, what does "runtime support" mean here exactly? You seem to be suggesting it includes anything that calls into an LLVM intrinsic but as far as I can tell plenty of things in libcore do that.

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 9, 2018

To me "runtime support" is "on any platform this lowers to a call to libm"

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Apr 9, 2018

Sounds good. Do you know how I can find out which intrinsics can lower to calls to libm?

@alexcrichton

This comment has been minimized.

Copy link
Member Author

alexcrichton commented Apr 9, 2018

Unfortunately I'm not sure there's a great way other than "compile it for a bunch of platforms and see what LLVM does"

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Apr 9, 2018

The relevant intrinsics are:

  • llvm.fabs.f32
  • llvm.fabs.f64
  • llvm.copysign.f32
  • llvm.copysign.f64
  • llvm.powi.f32
  • llvm.powi.f32

The compiler-builtins crate has Rust implementations of __powisf2 and __powidf2, but in LLVM code those are only mentioned in lib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp.

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Apr 10, 2018

#27823 moved a number of float methods (back) from libcore to libstd, but specifically left abs, signum and powi in libcore but doesn’t say why. (And the author hasn’t been active on github for several years.)

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 12, 2018

Add some f32 and f64 inherent methods in libcore
… previously in the unstable core::num::Float trait.

Per rust-lang#32110 (comment),
the `abs`, `signum`, and `powi` methods are *not* included for now
since they rely on LLVM intrinsics and we haven’t determined yet whether
those instrinsics lower to calls to libm functions on any platform.

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 12, 2018

@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented Apr 12, 2018

#49896 replaces these traits with inherent methods.

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 13, 2018

Add some f32 and f64 inherent methods in libcore
… previously in the unstable core::num::Float trait.

Per rust-lang#32110 (comment),
the `abs`, `signum`, and `powi` methods are *not* included for now
since they rely on LLVM intrinsics and we haven’t determined yet whether
those instrinsics lower to calls to libm functions on any platform.

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 13, 2018

bors added a commit that referenced this issue Apr 14, 2018

Auto merge of #49896 - SimonSapin:inherent, r=<try>
Add inherent methods in libcore for [T], [u8], str, f32, and f64

# Background

Primitive types are defined by the language, they don’t have a type definition like `pub struct Foo { … }` in any crate. So they don’t “belong” to any crate as far as `impl` coherence is concerned, and on principle no crate would be able to define inherent methods for them, without a trait. Since we want these types to have inherent methods anyway, the standard library (with cooperation from the compiler) bends this rule with code like [`#[lang = "u8"] impl u8 { /*…*/ }`](https://github.com/rust-lang/rust/blob/1.25.0/src/libcore/num/mod.rs#L2244-L2245). The `#[lang]` attribute is permanently-unstable and never intended to be used outside of the standard library.

Each lang item can only be defined once. Before this PR there is one impl-coherence-rule-bending lang item per primitive type (plus one for `[u8]`, which overlaps with `[T]`). And so one `impl` block each. These blocks for `str`, `[T]` and `[u8]` are in liballoc rather than libcore because *some* of the methods (like `<[T]>::to_vec(&self) -> Vec<T> where T: Clone`) need a global memory allocator which we don’t want to make a requirement in libcore. Similarly, `impl f32` and `impl f64` are in libstd because some of the methods are based on FFI calls to C’s `libm` and we want, as much as possible, libcore not to require “runtime support”.

In libcore, the methods of `str` and `[T]` that don’t allocate are made available through two **unstable traits** `StrExt` and `SliceExt` (so the traits can’t be *named* by programs on the Stable release channel) that have **stable methods** and are re-exported in the libcore prelude (so that programs on Stable can *call* these methods anyway). Non-allocating `[u8]` methods are not available in libcore: #45803. Some `f32` and `f64` methods are in an unstable `core::num::Float` trait with stable methods, but that one is **not in the libcore prelude**. (So as far as Stable programs are concerns it doesn’t exist, and I don’t know what the point was to mark these methods `#[stable]`.)

#32110 is the tracking issue for these unstable traits.

# High-level proposal

Since the standard library is already bending the rules, why not bend them *a little more*? By defining a few additional lang items, the compiler can allow the standard library to have *two* `impl` blocks (in different crates) for some primitive types.

The `StrExt` and `SliceExt` traits still exist for now so that we can bootstrap from a previous-version compiler that doesn’t have these lang items yet, but they can be removed in next release cycle. (`Float` is used internally and needs to be public for libcore unit tests, but was already `#[doc(hidden)]`.) I don’t know if #32110 should be closed by this PR, or only when the traits are entirely removed after we make a new bootstrap compiler.

# Float methods

Among the methods of the `core::num::Float` trait, three are based on LLVM intrinsics: `abs`, `signum`, and `powi`. PR #27823 “Remove dependencies on libm functions from libcore” moved a bunch of `core::num::Float` methods back to libstd, but left these three behind. However they aren’t specifically discussed in the PR thread. The `compiler_builtins` crate defines `__powisf2` and `__powidf2` functions that look like implementations of `powi`, but I couldn’t find a connection with the `llvm.powi.f32` and `llvm.powi.f32` intrinsics by grepping through LLVM’s code.

In discussion starting at #32110 (comment) Alex says that we do not want methods in libcore that require “runtime support”, but it’s not clear whether that applies to these `abs`, `signum`, or `powi`. In doubt, I’ve **removed** them for the trait and moved them to inherent methods in libstd for now. We can move them back later (or in this PR) if we decide that’s appropriate.

# Change details

For users on the Stable release channel:

* I believe this PR does not make any breaking change
* Some methods for `[u8]`, `f32`, and `f64` are newly available to `#![no_std]` users (fixes #45803)
* There should be no visible change for `std` users in terms of what programs compile or what their behavior is. (Only in compiler error messages, possibly.)

For Nightly users, additionally:

* The unstable `StrExt` and `SliceExt` traits are gone
* Their methods are now inherent methods of `str` and `[T]` (so only code that explicitly named the traits should be affected, not "normal" method calls)
* The `abs`, `signum` and `powi` methods of the `Float` trait are gone
* The `Float` trait’s unstable feature name changed to `float_internals` with no associated tracking issue, to reflect it being a permanently unstable implementation detail rather than a public API on a path to stabilization.
* Its remaining methods are now inherent methods of `f32` and `f64`.

-----

CC @rust-lang/libs for the API changes, @rust-lang/compiler for the new lang items

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 20, 2018

Add some f32 and f64 inherent methods in libcore
… previously in the unstable core::num::Float trait.

Per rust-lang#32110 (comment),
the `abs`, `signum`, and `powi` methods are *not* included for now
since they rely on LLVM intrinsics and we haven’t determined yet whether
those instrinsics lower to calls to libm functions on any platform.

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 20, 2018

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 20, 2018

Add some f32 and f64 inherent methods in libcore
… previously in the unstable core::num::Float trait.

Per rust-lang#32110 (comment),
the `abs`, `signum`, and `powi` methods are *not* included for now
since they rely on LLVM intrinsics and we haven’t determined yet whether
those instrinsics lower to calls to libm functions on any platform.

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 20, 2018

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 21, 2018

Add some f32 and f64 inherent methods in libcore
… previously in the unstable core::num::Float trait.

Per rust-lang#32110 (comment),
the `abs`, `signum`, and `powi` methods are *not* included for now
since they rely on LLVM intrinsics and we haven’t determined yet whether
those instrinsics lower to calls to libm functions on any platform.

SimonSapin added a commit to SimonSapin/rust that referenced this issue Apr 21, 2018

bors added a commit that referenced this issue Apr 22, 2018

Auto merge of #49896 - SimonSapin:inherent, r=alexcrichton
Add inherent methods in libcore for [T], [u8], str, f32, and f64

# Background

Primitive types are defined by the language, they don’t have a type definition like `pub struct Foo { … }` in any crate. So they don’t “belong” to any crate as far as `impl` coherence is concerned, and on principle no crate would be able to define inherent methods for them, without a trait. Since we want these types to have inherent methods anyway, the standard library (with cooperation from the compiler) bends this rule with code like [`#[lang = "u8"] impl u8 { /*…*/ }`](https://github.com/rust-lang/rust/blob/1.25.0/src/libcore/num/mod.rs#L2244-L2245). The `#[lang]` attribute is permanently-unstable and never intended to be used outside of the standard library.

Each lang item can only be defined once. Before this PR there is one impl-coherence-rule-bending lang item per primitive type (plus one for `[u8]`, which overlaps with `[T]`). And so one `impl` block each. These blocks for `str`, `[T]` and `[u8]` are in liballoc rather than libcore because *some* of the methods (like `<[T]>::to_vec(&self) -> Vec<T> where T: Clone`) need a global memory allocator which we don’t want to make a requirement in libcore. Similarly, `impl f32` and `impl f64` are in libstd because some of the methods are based on FFI calls to C’s `libm` and we want, as much as possible, libcore not to require “runtime support”.

In libcore, the methods of `str` and `[T]` that don’t allocate are made available through two **unstable traits** `StrExt` and `SliceExt` (so the traits can’t be *named* by programs on the Stable release channel) that have **stable methods** and are re-exported in the libcore prelude (so that programs on Stable can *call* these methods anyway). Non-allocating `[u8]` methods are not available in libcore: #45803. Some `f32` and `f64` methods are in an unstable `core::num::Float` trait with stable methods, but that one is **not in the libcore prelude**. (So as far as Stable programs are concerns it doesn’t exist, and I don’t know what the point was to mark these methods `#[stable]`.)

#32110 is the tracking issue for these unstable traits.

# High-level proposal

Since the standard library is already bending the rules, why not bend them *a little more*? By defining a few additional lang items, the compiler can allow the standard library to have *two* `impl` blocks (in different crates) for some primitive types.

The `StrExt` and `SliceExt` traits still exist for now so that we can bootstrap from a previous-version compiler that doesn’t have these lang items yet, but they can be removed in next release cycle. (`Float` is used internally and needs to be public for libcore unit tests, but was already `#[doc(hidden)]`.) I don’t know if #32110 should be closed by this PR, or only when the traits are entirely removed after we make a new bootstrap compiler.

# Float methods

Among the methods of the `core::num::Float` trait, three are based on LLVM intrinsics: `abs`, `signum`, and `powi`. PR #27823 “Remove dependencies on libm functions from libcore” moved a bunch of `core::num::Float` methods back to libstd, but left these three behind. However they aren’t specifically discussed in the PR thread. The `compiler_builtins` crate defines `__powisf2` and `__powidf2` functions that look like implementations of `powi`, but I couldn’t find a connection with the `llvm.powi.f32` and `llvm.powi.f32` intrinsics by grepping through LLVM’s code.

In discussion starting at #32110 (comment) Alex says that we do not want methods in libcore that require “runtime support”, but it’s not clear whether that applies to these `abs`, `signum`, or `powi`. In doubt, I’ve **removed** them for the trait and moved them to inherent methods in libstd for now. We can move them back later (or in this PR) if we decide that’s appropriate.

# Change details

For users on the Stable release channel:

* I believe this PR does not make any breaking change
* Some methods for `[u8]`, `f32`, and `f64` are newly available to `#![no_std]` users (fixes #45803)
* There should be no visible change for `std` users in terms of what programs compile or what their behavior is. (Only in compiler error messages, possibly.)

For Nightly users, additionally:

* The unstable `StrExt` and `SliceExt` traits are gone
* Their methods are now inherent methods of `str` and `[T]` (so only code that explicitly named the traits should be affected, not "normal" method calls)
* The `abs`, `signum` and `powi` methods of the `Float` trait are gone
* The `Float` trait’s unstable feature name changed to `float_internals` with no associated tracking issue, to reflect it being a permanently unstable implementation detail rather than a public API on a path to stabilization.
* Its remaining methods are now inherent methods of `f32` and `f64`.

-----

CC @rust-lang/libs for the API changes, @rust-lang/compiler for the new lang items
@SimonSapin

This comment has been minimized.

Copy link
Contributor

SimonSapin commented May 21, 2018

I’ve filed #50145 specifically for f32 and f64 methods in libcore.

SimonSapin added a commit to SimonSapin/rust that referenced this issue May 21, 2018

SimonSapin added a commit to SimonSapin/rust that referenced this issue May 21, 2018

SimonSapin added a commit to SimonSapin/rust that referenced this issue May 21, 2018

SimonSapin added a commit to SimonSapin/rust that referenced this issue May 21, 2018

SimonSapin added a commit to SimonSapin/rust that referenced this issue May 22, 2018

bors added a commit that referenced this issue May 23, 2018

Auto merge of #50933 - SimonSapin:anchorage, r=alexcrichton
Remove the unstable Float trait

Following up to #49896 and #50629. Fixes #32110.

@bors bors closed this in #50933 May 24, 2018

mark-i-m added a commit to mark-i-m/rust that referenced this issue May 24, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.