| Age | Commit message (Collapse) | Author | Lines |
|
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: https://github.com/rust-lang/rust/issues/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]`.)
https://github.com/rust-lang/rust/issues/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 https://github.com/rust-lang/rust/issues/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 https://github.com/rust-lang/rust/pull/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 https://github.com/rust-lang/rust/issues/32110#issuecomment-370647922 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 https://github.com/rust-lang/rust/issues/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
|
|
`Float` still needs to be public for libcore unit tests.
|
|
|
|
|
|
|
|
And the UnicodeStr trait into StrExt
|
|
|
|
|
|
Stabilize std::ops::RangeInclusive and std::ops::RangeInclusiveTo.
|
|
|
|
FusedIterator is a marker trait that promises that the implementing
iterator continues to return `None` from `.next()` once it has returned
`None` once (and/or `.next_back()`, if implemented).
The effects of FusedIterator are already widely available through
`.fuse()`, but with stable `FusedIterator`, stable Rust users can
implement this trait for their iterators when appropriate.
|
|
|
|
|
|
Correct a few stability attributes
* The extra impls for `ManuallyDrop` were added in #44310 which was only stabilised in 1.22.0.
* The impls for `SliceIndex` were stabilised in #43373 but as `RangeInclusive` and `RangeToInclusive` are still unstable the impls should remain unstable.
* The `From` impls for atomic integers were added in #45610 but most atomic integers are still unstable.
* The `shared_from_slice2` impls were added in #45990 but they won't be stable until 1.24.0.
* The `Mutex` and `RwLock` impls were added in #46082 but won't be stable until 1.24.0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
It's the only use of the function.
|
|
Add blanket TryFrom impl when From is implemented.
Adds `impl<T, U> TryFrom<T> for U where U: From<T>`.
Removes `impl<'a, T> TryFrom<&'a str> for T where T: FromStr` (originally added in #40281) due to overlapping impls caused by the new blanket impl. This removal is to be discussed further on the tracking issue for TryFrom.
Refs #33417.
/cc @sfackler, @scottmcm (thank you for the help!), and @aturon
|
|
This verifies that TrustedRandomAccess has no side effects when the
iterator item implements Copy. This also implements TrustedLen and
TrustedRandomAccess for str::Bytes.
|
|
Remove str_eq lang item
It's not really a lang item. Also remove outdated note. The reference uses this as an example so it has to be updated.
|
|
Replace str's transmute() calls with pointer casts
After the following conversation in #rust-lang:
```
[14:43:50] <Ixrec> TIL the implementation of from_utf_unchecked is literally just "mem::transmute(x)"
[14:43:59] <Ixrec> no wonder people keep saying transmute is overpowered
[15:15:30] <eddyb> Ixrec: it should be a pointer cast lol
[15:15:46] <eddyb> unless it doesn't let you
[16:50:34] <Ixrec> https://play.rust-lang.org/?gist=d1e6b629ad9ec1baf64ce261c63845e6&version=stable seems like it does let me
[16:52:35] <eddyb> Ixrec: yeah that's the preferred impl
[16:52:46] <eddyb> Ixrec: it just wasn't in 1.0
[16:52:50] <eddyb> IIRC
[16:53:00] <eddyb> (something something fat pointers)
```
Since I already wrote half of the preferred impls in the playground, might as well make an actual PR.
|
|
|
|
|
|
It's not a lang item anymore. Also remove outdated note.
|
|
After the following conversation in #rust-lang:
```
[14:43:50] <Ixrec> TIL the implementation of from_utf_unchecked is literally just "mem::transmute(x)"
[14:43:59] <Ixrec> no wonder people keep saying transmute is overpowered
[15:15:30] <eddyb> Ixrec: it should be a pointer cast lol
[15:15:46] <eddyb> unless it doesn't let you
[16:50:34] <Ixrec> https://play.rust-lang.org/?gist=d1e6b629ad9ec1baf64ce261c63845e6&version=stable seems like it does let me
[16:52:35] <eddyb> Ixrec: yeah that's the preferred impl
[16:52:46] <eddyb> Ixrec: it just wasn't in 1.0
[16:52:50] <eddyb> IIRC
[16:53:00] <eddyb> (something something fat pointers)
```
Since I already wrote half of the preferred impls in the playground, might as well make an actual PR.
|
|
Add doc examples to str::from_utf8_unchecked_mut
Fixes #44461
|
|
|
|
Fixes #44461
|
|
|
|
|
|
|
|
|
|
|
|
Add align_offset intrinsic
see https://github.com/rust-lang/rfcs/pull/2043 for details and the plan towards stabilization (reexport in `core::mem` via various convenience functions)
as per @scottmcm 's [comment](https://github.com/rust-lang/rfcs/pull/2043#issuecomment-316818169), this is just the intrinsic (which is obviously unstable).
|
|
Adds `impl<T, U> TryFrom<T> for U where U: From<T>`.
Removes `impl<'a, T> TryFrom<&'a str> for T where T: FromStr` due to
overlapping impls caused by the new blanket impl. This removal is to
be discussed further on the tracking issue for TryFrom.
Refs #33417.
|
|
see https://github.com/rust-lang/rfcs/pull/2043 for details
|
|
Like #43008 (f668999), but _much more aggressive_.
|
|
Stabilizes
* `<&mut str>::as_bytes_mut`
* `<Box<str>>::into_boxed_bytes`
* `std::str::from_boxed_utf8_unchecked`
* `std::str::from_utf8_mut`
* `std::str::from_utf8_unchecked_mut`
Closes #41119
|
|
Stabilizes:
* `Utf8Error::error_len`
Closes #40494
|
|
Stabilized
* `<str>::get`
* `<str>::get_mut`
* `<str>::get_unchecked`
* `<str>::get_unchecked_mut`
Closes #39932
|
|
|
|
This PR cuts down on a large number of `#[inline(always)]` and `#[inline]`
annotations in libcore for various core functions. The `#[inline(always)]`
annotation is almost never needed and is detrimental to debug build times as it
forces LLVM to perform inlining when it otherwise wouldn't need to in debug
builds. Additionally `#[inline]` is an unnecessary annoation on almost all
generic functions because the function will already be monomorphized into other
codegen units and otherwise rarely needs the extra "help" from us to tell LLVM
to inline something.
Overall this PR cut the compile time of a [microbenchmark][1] by 30% from 1s to
0.7s.
[1]: https://gist.github.com/alexcrichton/a7d70319a45aa60cf36a6a7bf540dd3a
|