Commit Graph

130 Commits

Author SHA1 Message Date
Pietro Albini 3975d55d98 remove cfg(bootstrap) 2022-09-26 10:14:45 +02:00
onestacked 449326aaad Added const Default impls for Arrays and Tuples. 2022-09-23 17:53:59 +02:00
bors 4ecfdfac51 Auto merge of #100214 - scottmcm:strict-range, r=thomcc
Optimize `array::IntoIter`

`.into_iter()` on arrays was slower than it needed to be (especially compared to slice iterator) since it uses `Range<usize>`, which needs to handle degenerate ranges like `10..4`.

This PR adds an internal `IndexRange` type that's like `Range<usize>` but with a safety invariant that means it doesn't need to worry about those cases -- it only handles `start <= end` -- and thus can give LLVM more information to optimize better.

I added one simple demonstration of the improvement as a codegen test.

(`vec::IntoIter` uses pointers instead of indexes, so doesn't have this problem, but that only works because its elements are boxed.  `array::IntoIter` can't use pointers because that would keep it from being movable.)
2022-09-21 00:41:33 +00:00
Scott McMurray 6dbd9a29c2 Optimize array::IntoIter
`.into_iter()` on arrays was slower than it needed to be (especially compared to slice iterator) since it uses `Range<usize>`, which needs to handle degenerate ranges like `10..4`.

This PR adds an internal `IndexRange` type that's like `Range<usize>` but with a safety invariant that means it doesn't need to worry about those cases -- it only handles `start <= end` -- and thus can give LLVM more information to optimize better.

I added one simple demonstration of the improvement as a codegen test.
2022-09-19 23:24:34 -07:00
Doug Cook (WINDOWS) 705a7667c5 array docs - advertise how to get array from slice
On my first Rust project, I spent more time than I care to admit
figuring out how to efficiently get an array from a slice. Update the
array documentation to explain this a bit more clearly.

(As a side note, it's a bit unfortunate that get-array-from-slice is
only available via trait since that means it can't be used from const
functions yet.)
2022-09-10 19:37:07 -07:00
Jane Losare-Lusby bf7611d55e Move error trait into core 2022-08-22 13:28:25 -07:00
Cameron Steffen 17ddcb434b Improve primitive/std docs separation and headers 2022-08-20 16:50:29 -05:00
Ralf Jung 338d7c2fb0 more typos
Co-authored-by: Nicholas Nethercote <n.nethercote@gmail.com>
2022-08-11 07:37:22 -04:00
Ralf Jung 2d1c683112 fix typo
Co-authored-by: Marco Colombo <mar.colombo13@gmail.com>
2022-07-20 10:39:21 -04:00
Ralf Jung 5848c27c79 make raw_eq precondition more restrictive 2022-07-20 10:22:16 -04:00
Ross MacArthur bbdff1fff4 Add Iterator::next_chunk 2022-06-21 08:57:02 +02:00
Maybe Waffle 7a09b8a7b5 Stabilize {slice,array}::from_ref 2022-05-24 22:33:31 +04:00
Caio d917112606 Stabilize core::array::from_fn 2022-05-20 11:04:13 -03:00
bors 9fbbe75fd7 Auto merge of #95602 - scottmcm:faster-array-intoiter-fold, r=the8472
Fix `array::IntoIter::fold` to use the optimized `Range::fold`

It was using `Iterator::by_ref` in the implementation, which ended up pessimizing it enough that, for example, it didn't vectorize when we tried it in the <https://rust-lang.zulipchat.com/#narrow/stream/257879-project-portable-simd/topic/Reducing.20sum.20into.20wider.20types> conversation.

Demonstration that the codegen test doesn't pass on the current nightly: <https://rust.godbolt.org/z/Taxev5eMn>
2022-05-14 03:12:53 +00:00
Jacob Pratt 4fbe73e0b7 Remove use of #[rustc_deprecated] 2022-04-14 01:33:13 -04:00
Pietro Albini 181d28bb61 trivial cfg(bootstrap) changes 2022-04-05 23:18:40 +02:00
Scott McMurray 83595f9242 Fix array::IntoIter::fold to use the optimized Range::fold
It was using `Iterator::by_ref` in the implementation, which ended up pessimizing it enough that, for example, it didn't vectorize when we tried it in the <https://rust-lang.zulipchat.com/#narrow/stream/257879-project-portable-simd/topic/Reducing.20sum.20into.20wider.20types> conversation.

Demonstration that the codegen test doesn't pass on the current nightly: <https://rust.godbolt.org/z/Taxev5eMn>
2022-04-02 14:29:41 -07:00
lcnr afbecc0f68 remove now unnecessary lang items 2022-03-30 11:23:58 +02:00
Matthias Krüger fe034cb43b Rollup merge of #94657 - fee1-dead:const_slice_index, r=oli-obk
Constify `Index{,Mut}` for `[T]`, `str`, and `[T; N]`

Several panic functions were rewired (via `const_eval_select`) to simpler implementations that do not require formatting for compile-time usage.

r? ```@oli-obk```
2022-03-10 12:20:52 +01:00
Deadbeef 4654a91001 Constify slice index for strings 2022-03-06 17:28:50 +11:00
Waffle Maybe 715262f151 Fix a typo in documentation of array::IntoIter::new_unchecked 2022-02-23 21:10:04 +03:00
Jacob Pratt 1911eb8b61 Add missing const stability attributes 2022-02-03 19:15:57 -05:00
Deadbeef 06a1c14d52 Switch all libraries to the 2021 edition 2021-12-23 19:03:47 +08:00
Scott McMurray a0b96902e4 Do array-slice equality via arrays, rather than always via slices
This'll still go via slices eventually for large arrays, but this way slice comparisons to short arrays can use the same memcmp-avoidance tricks.

Added some tests for all the combinations to make sure I didn't accidentally infinitely-recurse something.
2021-12-14 13:15:15 -08:00
bors 83b32f27fc Auto merge of #91766 - scottmcm:more-array-raw-eq, r=yaahc
Allow `memcmp` for more array comparisons

This way comparing `[NonZeroU8; 8]` is just as fast as comparing `[u8; 8]`.
2021-12-14 08:22:31 +00:00
Matthias Krüger 42f8d4833f Rollup merge of #91086 - rhysd:issue-91085, r=m-ou-se
Implement `TryFrom<&'_ mut [T]>` for `[T; N]`

Fixes #91085.
2021-12-13 00:20:06 +01:00
Matthias Krüger 40482bb539 Rollup merge of #90270 - woppopo:const_borrow_trait, r=dtolnay
Make `Borrow` and `BorrowMut` impls `const`

Tracking issue: #91522
2021-12-11 17:35:24 +01:00
Scott McMurray 24affba02e Allow memcmp for more array comparisons
This way comparing `[NonZeroU8; 8]` is just as fast as comparing `[u8; 8]`.
2021-12-10 17:30:39 -08:00
Jethro Beekman 203cf2d366 Add rsplit_array variants to slices and arrays 2021-12-10 21:34:19 +01:00
bors ce0f7baf56 Auto merge of #91512 - scottmcm:array-intoiter-advance, r=Mark-Simulacrum
Override `Iterator::advance(_back)_by` for `array::IntoIter`

Because I happened to notice that `nth` is currently getting codegen'd as a loop even for `Copy` types: <https://rust.godbolt.org/z/fPqv7Gvs7>

<details>
<summary>LLVM before and after</summary>

Rust:

```rust
#[no_mangle]
pub fn array_intoiter_nth(it: &mut std::array::IntoIter<i32, 100>, n: usize) -> Option<i32> {
    it.nth(n)
}
```

Current nightly:
```llvmir
define { i32, i32 } `@array_intoiter_nth(%"core::array::iter::IntoIter<i32,` 100_usize>"* noalias nocapture align 8 dereferenceable(416) %it, i64 %n) unnamed_addr #0 personality i32 (i32, i32, i64, %"unwind::libunwind::_Unwind_Exception"*, %"unwind::libunwind::_Unwind_Context"*)* `@rust_eh_personality` !dbg !6 {
start:
  %_3.i.i.i4.i.i = getelementptr inbounds %"core::array::iter::IntoIter<i32, 100_usize>", %"core::array::iter::IntoIter<i32, 100_usize>"* %it, i64 0, i32 0, i32 0
  %_4.i.i.i5.i.i = getelementptr inbounds %"core::array::iter::IntoIter<i32, 100_usize>", %"core::array::iter::IntoIter<i32, 100_usize>"* %it, i64 0, i32 0, i32 1
  %_4.i.i.i.i.i.i = load i64, i64* %_4.i.i.i5.i.i, align 8, !alias.scope !10
  %.not.i.i = icmp eq i64 %n, 0, !dbg !15
  %_3.i.i.i.i.pre.i = load i64, i64* %_3.i.i.i4.i.i, align 8, !dbg !40, !alias.scope !41
  br i1 %.not.i.i, label %bb4.i, label %bb4.preheader.i.i, !dbg !42

bb4.preheader.i.i:                                ; preds = %start
  %umax.i = tail call i64 `@llvm.umax.i64(i64` %_3.i.i.i.i.pre.i, i64 %_4.i.i.i.i.i.i) #3, !dbg !43
  %0 = sub i64 %umax.i, %_3.i.i.i.i.pre.i, !dbg !43
  br label %bb4.i.i, !dbg !43

bb4.i.i:                                          ; preds = %bb3.i.i.i.i, %bb4.preheader.i.i
  %_3.i.i.i.i.i.i = phi i64 [ %2, %bb3.i.i.i.i ], [ %_3.i.i.i.i.pre.i, %bb4.preheader.i.i ], !dbg !52
  %iter.sroa.0.016.i.i = phi i64 [ %1, %bb3.i.i.i.i ], [ 0, %bb4.preheader.i.i ]
  %1 = add nuw i64 %iter.sroa.0.016.i.i, 1, !dbg !54
  %exitcond.not.i = icmp eq i64 %iter.sroa.0.016.i.i, %0, !dbg !52
  br i1 %exitcond.not.i, label %core::iter::traits::iterator::Iterator::nth.exit, label %bb3.i.i.i.i, !dbg !43

bb3.i.i.i.i:                                      ; preds = %bb4.i.i
  %2 = add nuw i64 %_3.i.i.i.i.i.i, 1, !dbg !63
  store i64 %2, i64* %_3.i.i.i4.i.i, align 8, !dbg !66, !alias.scope !75
  %exitcond.not.i.i = icmp eq i64 %1, %n, !dbg !15
  br i1 %exitcond.not.i.i, label %bb4.i, label %bb4.i.i, !dbg !42

bb4.i:                                            ; preds = %bb3.i.i.i.i, %start
  %_3.i.i.i.i.i = phi i64 [ %_3.i.i.i.i.pre.i, %start ], [ %2, %bb3.i.i.i.i ], !dbg !84
  %3 = icmp ult i64 %_3.i.i.i.i.i, %_4.i.i.i.i.i.i, !dbg !84
  br i1 %3, label %bb3.i.i.i, label %core::iter::traits::iterator::Iterator::nth.exit, !dbg !89

bb3.i.i.i:                                        ; preds = %bb4.i
  %4 = add nuw i64 %_3.i.i.i.i.i, 1, !dbg !90
  store i64 %4, i64* %_3.i.i.i4.i.i, align 8, !dbg !93, !alias.scope !96
  %5 = getelementptr inbounds %"core::array::iter::IntoIter<i32, 100_usize>", %"core::array::iter::IntoIter<i32, 100_usize>"* %it, i64 0, i32 1, i64 %_3.i.i.i.i.i, !dbg !105
  %6 = load i32, i32* %5, align 4, !dbg !131, !alias.scope !141, !noalias !144
  br label %core::iter::traits::iterator::Iterator::nth.exit, !dbg !149

core::iter::traits::iterator::Iterator::nth.exit: ; preds = %bb4.i.i, %bb4.i, %bb3.i.i.i
  %.sroa.3.0.i = phi i32 [ %6, %bb3.i.i.i ], [ undef, %bb4.i ], [ undef, %bb4.i.i ], !dbg !40
  %.sroa.0.0.i = phi i32 [ 1, %bb3.i.i.i ], [ 0, %bb4.i ], [ 0, %bb4.i.i ], !dbg !40
  %7 = insertvalue { i32, i32 } undef, i32 %.sroa.0.0.i, 0, !dbg !150
  %8 = insertvalue { i32, i32 } %7, i32 %.sroa.3.0.i, 1, !dbg !150
  ret { i32, i32 } %8, !dbg !151
}
```

With this PR:
```llvmir
define { i32, i32 } `@array_intoiter_nth(%"core::array::iter::IntoIter<i32,` 100_usize>"* noalias nocapture align 8 dereferenceable(416) %it, i64 %n) unnamed_addr #0 personality i32 (...)* `@__CxxFrameHandler3` {
start:
  %0 = getelementptr inbounds %"core::array::iter::IntoIter<i32, 100_usize>", %"core::array::iter::IntoIter<i32, 100_usize>"* %it, i64 0, i32 0, i32 1
  %_2.i.i.i.i = load i64, i64* %0, align 8, !alias.scope !6, !noalias !13
  %1 = getelementptr inbounds %"core::array::iter::IntoIter<i32, 100_usize>", %"core::array::iter::IntoIter<i32, 100_usize>"* %it, i64 0, i32 0, i32 0
  %_3.i.i.i.i = load i64, i64* %1, align 8, !alias.scope !16
  %2 = sub i64 %_2.i.i.i.i, %_3.i.i.i.i
  %3 = icmp ult i64 %2, %n
  %.0.sroa.speculated.i.i.i.i.i = select i1 %3, i64 %2, i64 %n
  %_10.i.i = add i64 %.0.sroa.speculated.i.i.i.i.i, %_3.i.i.i.i
  store i64 %_10.i.i, i64* %1, align 8, !alias.scope !16
  %.not.i = xor i1 %3, true
  %4 = icmp ult i64 %_10.i.i, %_2.i.i.i.i
  %or.cond.i = select i1 %.not.i, i1 %4, i1 false
  br i1 %or.cond.i, label %bb3.i.i.i, label %_ZN4core4iter6traits8iterator8Iterator3nth17hcbc727011e9e2a3bE.exit

bb3.i.i.i:                                        ; preds = %start
  %5 = add nuw i64 %_10.i.i, 1
  store i64 %5, i64* %1, align 8, !alias.scope !17
  %6 = getelementptr inbounds %"core::array::iter::IntoIter<i32, 100_usize>", %"core::array::iter::IntoIter<i32, 100_usize>"* %it, i64 0, i32 1, i64 %_10.i.i
  %7 = load i32, i32* %6, align 4, !alias.scope !26, !noalias !29
  br label %_ZN4core4iter6traits8iterator8Iterator3nth17hcbc727011e9e2a3bE.exit

_ZN4core4iter6traits8iterator8Iterator3nth17hcbc727011e9e2a3bE.exit: ; preds = %start, %bb3.i.i.i
  %.sroa.3.0.i = phi i32 [ undef, %start ], [ %7, %bb3.i.i.i ]
  %.sroa.0.0.i = phi i32 [ 0, %start ], [ 1, %bb3.i.i.i ]
  %8 = insertvalue { i32, i32 } undef, i32 %.sroa.0.0.i, 0
  %9 = insertvalue { i32, i32 } %8, i32 %.sroa.3.0.i, 1
  ret { i32, i32 } %9
}
```
</details>
2021-12-08 07:54:30 +00:00
Scott McMurray 9b86c5998c s/from_raw_parts/new_unchecked/ 2021-12-06 22:59:04 -08:00
Scott McMurray 0b90204bc8 Add tracking issue; make empty const too (unstably) 2021-12-06 01:12:59 -08:00
Scott McMurray ef7c833c20 Move the doc test to edition2021 2021-12-06 00:58:40 -08:00
Scott McMurray a30f96311a Add array::IntoIter::{empty, from_raw_parts}
`array::IntoIter` has a bunch of really handy logic for dealing with partial arrays, but it's currently hamstrung by only being creatable from a fully-initialized array.

This PR adds two new constructors:
- a safe & const `empty`, since `[].into_iter()` gives `<T, 0>`, not `<T, N>`.
- an unsafe `from_raw_parts`, to allow experimentation with new uses.

(Slice & vec iterators don't need `from_raw_parts` because you `from_raw_parts` the slice or vec instead, but there's no useful way to made a `<[T; N]>::from_raw_parts`, so I think this is a reasonable place to have one.)
2021-12-06 00:58:40 -08:00
Mara Bos 27d39357b7 Update array::IntoIter::new deprecation version. 2021-12-04 19:42:37 +01:00
Mara Bos b34cf1a9e1 Swap body of array::IntoIter::new and IntoIterator::new. 2021-12-04 19:15:47 +01:00
Mara Bos 911ee9403e Deprecate array::IntoIter::new. 2021-12-04 19:15:44 +01:00
Mara Bos 16711fe076 Update stabilization version of try_from_mut_slice_to_array 2021-12-04 17:17:12 +01:00
woppopo 8f68bdc380 Make Borrow and BorrowMut impls const 2021-12-04 21:57:39 +09:00
Scott McMurray eb846dbaca Override Iterator::advance(_back)_by for array::IntoIter
Because I happened to notice that `nth` is currently getting codegen'd as a loop even for `Copy` types: <https://rust.godbolt.org/z/fPqv7Gvs7>
2021-12-03 21:36:51 -08:00
Scott McMurray b96b9b4093 Make array::{try_from_fn, try_map} and Iterator::try_find generic over Try
Fixes 85115

This only updates unstable functions.

`array::try_map` didn't actually exist before, despite the tracking issue 79711 still being open from the old PR 79713.
2021-12-02 11:23:50 -08:00
Mark Rousskov b221c877e8 Apply cfg-bootstrap switch 2021-11-30 10:51:42 -05:00
Linda_pp ac083c6b45 Reborrow mut slice instead of converting it with as_ref
Co-authored-by: Noah Lev <camelidcamel@gmail.com>
2021-11-21 11:01:31 +09:00
Linda_pp 66e0523d09 Update version in stable attribute
Co-authored-by: Joshua Nelson <github@jyn.dev>
2021-11-20 23:35:28 +09:00
rhysd 72b411fd89 Implement TryFrom<&'_ mut [T]> for [T; N] 2021-11-20 23:05:08 +09:00
Scott McMurray 5b115fcb68 Moar #[inline] 2021-11-10 11:57:14 -08:00
Scott McMurray cc7d8014d7 Specialize array cloning for Copy types
Because after PR 86041, the optimizer no longer load-merges at the LLVM IR level, which might be part of the perf loss.  (I'll run perf and see if this makes a difference.)

Also I added a codegen test so this hopefully won't regress in future -- it passes on stable and with my change here, but not on the 2021-11-09 nightly.
2021-11-09 21:43:20 -08:00
bstrie 61b1394ac7 Attempt to address perf regressions with #[inline] 2021-11-08 15:51:56 -05:00
bstrie ce1143e94d impl Copy/Clone for arrays in std, not in compiler 2021-11-08 13:11:58 -05:00
Matthias Krüger c16ee19dd4 Rollup merge of #90162 - WaffleLapkin:const_array_slice_from_ref_mut, r=oli-obk
Mark `{array, slice}::{from_ref, from_mut}` as const fn

This PR marks the following APIs as `const`:
```rust
// core::array
pub const fn from_ref<T>(s: &T) -> &[T; 1];
pub const fn from_mut<T>(s: &mut T) -> &mut [T; 1];

// core::slice
pub const fn from_ref<T>(s: &T) -> &[T];
pub const fn from_mut<T>(s: &mut T) -> &mut [T];
```

Note that `from_ref` methods require `const_raw_ptr_deref` feature (which seems totally fine, since it's being stabilized, see #89551), `from_mut` methods require `const_mut_refs` (which seems fine too since this PR marks `from_mut` functions as const unstable).

r? ````@oli-obk````
2021-10-24 15:48:44 +02:00