rust/library/core/src
bors 547f2ba06b Auto merge of #86988 - thomcc:chunky-splitz-says-no-checking, r=the8472
Carefully remove bounds checks from some chunk iterator functions

So, I was writing code that requires the equivalent of `rchunks(N).rev()` (which isn't the same as forward `chunks(N)` — in particular, if the buffer length is not a multiple of `N`, I must handle the "remainder" first).

I happened to look at the codegen output of the function (I was actually interested in whether or not a nested loop was being unrolled — it was), and noticed that in the outer `rchunks(n).rev()` loop, LLVM seemed to be unable to remove the bounds checks from the iteration: https://rust.godbolt.org/z/Tnz4MYY8f (this panic was from the split_at in `RChunks::next_back`).

After doing some experimentation, it seems all of the `next_back` in the non-exact chunk iterators have the issue: (`Chunks::next_back`, `RChunks::next_back`, `ChunksMut::next_back`, and `RChunksMut::next_back`)...

Even worse, the forward `rchunks` iterators sometimes have the issue as well (... but only sometimes). For example https://rust.godbolt.org/z/oGhbqv53r has bounds checks, but if I uncomment the loop body, it manages to remove the check (which is bizarre, since I'd expect the opposite...). I suspect it's highly dependent on the surrounding code, so I decided to remove the bounds checks from them anyway. Overall, this change includes:
- All `next_back` functions on the non-`Exact` iterators (e.g. `R?Chunks(Mut)?`).
- All `next` functions on the non-exact rchunks iterators (e.g. `RChunks(Mut)?`).

I wasn't able to catch any of the other chunk iterators failing to remove the bounds checks (I checked iterations over `r?chunks(_exact)?(_mut)?` with constant chunk sizes under `-O3`, `-Os`, and `-Oz`), which makes sense, since these were the cases where it was harder to prove the bounds check correct to remove...

In fact, it took quite a bit of thinking to convince myself that using unchecked_ here was valid — so I'm not really surprised that LLVM had trouble (although compilers are slightly better at this sort of reasoning than humans). A consequence of that is the fact that the `// SAFETY` comment for these are... kinda long...

---

I didn't do this for, or even think about it for, any of the other iteration methods; just `next` and `next_back` (where it mattered). If this PR is accepted, I'll file a follow up for someone (possibly me) to look at the others later (in particular, `nth`/`nth_back` looked like they had similar logic), but I wanted to do this now, as IMO `next`/`next_back` are the most important here, since they're what gets used by the iteration protocol.

---

Note: While I don't expect this to impact performance directly, the panic is a side effect, which would otherwise not exist in these loops. That is, this could prevent the compiler from being able to move/remove/otherwise rework a loop over these iterators (as an example, it could not delete the code for a loop whose body computes a value which doesn't get used).

Also, some like to be able to have confidence this code has no panicking branches in the optimized code, and "no bounds checks" is kinda part of the selling point of Rust's iterators anyway.
2022-02-01 10:11:59 +00:00
..
alloc Fix a bunch of typos 2021-12-14 16:40:43 +01:00
array Switch all libraries to the 2021 edition 2021-12-23 19:03:47 +08:00
char Rollup merge of #93392 - GKFX:char-docs, r=scottmcm 2022-01-31 06:58:32 +01:00
convert Rollup merge of #92382 - clarfonthey:const_convert, r=scottmcm 2022-01-15 02:25:14 +01:00
fmt Create core::fmt::ArgumentV1 with generics instead of fn pointer 2022-01-29 13:52:19 +00:00
future Rollup merge of #92887 - pietroalbini:pa-bootstrap-update, r=Mark-Simulacrum 2022-01-30 08:37:46 -08:00
hash change PhantomData type for BuildHasherDefault 2022-01-07 00:39:48 +01:00
iter Fix a typo from #92899 2022-01-28 01:35:33 +00:00
macros update cfg(bootstrap)s 2022-01-28 15:01:07 +01:00
mem Add MaybeUninit::as_bytes 2022-01-19 21:27:29 +00:00
num review the total_cmp documentation 2022-01-30 23:20:54 +02:00
ops Add a minimal working append_const_msg argument 2022-01-26 00:48:08 +11:00
panic Add PanicInfo::can_unwind which indicates whether a panic handler is 2022-01-17 00:39:28 +00:00
prelude update cfg(bootstrap)s 2022-01-28 15:01:07 +01:00
ptr Make NonNull::new const 2022-01-23 23:04:39 +09:00
slice Auto merge of #86988 - thomcc:chunky-splitz-says-no-checking, r=the8472 2022-02-01 10:11:59 +00:00
str Fix a bunch of typos 2021-12-14 16:40:43 +01:00
stream Remove P: Unpin bound on impl Stream for Pin 2021-12-17 11:14:02 +08:00
sync Add rustc_diagnostic_item attribute to AtomicBool 2022-01-13 23:32:49 +01:00
task Rollup merge of #89897 - jkugelman:must-use-core, r=joshtriplett 2021-10-31 09:20:26 +01:00
unicode Regenerate tables for Unicode 14.0.0 2021-10-06 17:49:33 -07:00
any.rs Reverts #92135 because perf regression 2021-12-26 16:02:33 +03:00
ascii.rs Add #[must_use] to remaining core functions 2021-10-30 18:21:29 -04:00
bool.rs Constify bool::then{,_some} 2021-12-15 00:11:23 +08:00
borrow.rs Make Borrow and BorrowMut impls const 2021-12-04 21:57:39 +09:00
cell.rs update cfg(bootstrap)s 2022-01-28 15:01:07 +01:00
clone.rs Update Copy/Clone documentation WRT arrays 2021-11-08 13:11:59 -05:00
cmp.rs Edit docs introduction for std::cmp::PartialOrd 2022-01-28 00:46:04 -06:00
default.rs Add #[must_use] to remaining core functions 2021-10-30 18:21:29 -04:00
ffi.rs Use target_family = "wasm" 2021-11-10 08:35:42 -08:00
hint.rs Add is_riscv_feature_detected!; modify impl of hint::spin_loop 2022-01-05 15:44:52 +08:00
internal_macros.rs Added docs to internal_macro const 2021-10-22 10:07:35 +13:00
intrinsics.rs Document about some behaviors of const_(de)allocate and add some tests. 2022-01-29 19:13:23 +09:00
lazy.rs Use UnsafeCell::get_mut() in core::lazy::OnceCell::get_mut() 2021-12-30 05:04:44 +02:00
lib.rs Rollup merge of #92887 - pietroalbini:pa-bootstrap-update, r=Mark-Simulacrum 2022-01-30 08:37:46 -08:00
marker.rs Update Copy/Clone documentation WRT arrays 2021-11-08 13:11:59 -05:00
option.rs Fix is_some_with tests. 2022-01-19 00:12:35 +01:00
panic.rs Allow panic!("{}", computed_str) in const fn. 2021-09-15 21:56:43 +01:00
panicking.rs Change TerminatorKind::Abort to call the panic handler instead of 2022-01-17 00:39:34 +00:00
pin.rs Add #[must_use] to remaining core functions 2021-10-30 18:21:29 -04:00
primitive.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
primitive_docs.rs Update docs. 2021-12-04 19:40:33 +01:00
result.rs Fix is_some_with tests. 2022-01-19 00:12:35 +01:00
time.rs Improve Duration::try_from_secs_f32/64 accuracy by directly processing exponent and mantissa 2022-01-26 18:14:25 +03:00
tuple.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
unit.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00