rust/library/core/src
bors 28928c750c Auto merge of #77617 - AnthonyMikh:slice_windows_no_bounds_checking, r=lcnr
Eliminate bounds checking in slice::Windows

This is how `<core::slice::Windows as Iterator>::next` looks right now:

```rust
fn next(&mut self) -> Option<&'a [T]> {
    if self.size > self.v.len() {
        None
    } else {
        let ret = Some(&self.v[..self.size]);
        self.v = &self.v[1..];
        ret
    }
}
```

The line with `self.v = &self.v[1..];` relies on assumption that `self.v` is definitely not empty at this point. Else branch is taken when `self.size <= self.v.len()`, so `self.v` can be empty if `self.size` is zero. In practice, since `Windows` is never created directly but rather trough `[T]::windows` which panics when `size` is zero, `self.size` is never zero. However, the compiler doesn't know about this check, so it keeps the code which checks bounds and panics.

Using `NonZeroUsize` lets the compiler know about this invariant and reliably eliminate bounds checking without `unsafe` on `-O2`. Here is assembly of `Windows<'a, u32>::next` before and after this change ([goldbolt](https://godbolt.org/z/xrefzx)):

<details>
<summary>Before</summary>

```
example::next:
        push    rax
        mov     rcx, qword ptr [rdi + 8]
        mov     rdx, qword ptr [rdi + 16]
        cmp     rdx, rcx
        jbe     .LBB0_2
        xor     eax, eax
        pop     rcx
        ret
.LBB0_2:
        test    rcx, rcx
        je      .LBB0_5
        mov     rax, qword ptr [rdi]
        mov     rsi, rax
        add     rsi, 4
        add     rcx, -1
        mov     qword ptr [rdi], rsi
        mov     qword ptr [rdi + 8], rcx
        pop     rcx
        ret
.LBB0_5:
        lea     rdx, [rip + .L__unnamed_1]
        mov     edi, 1
        xor     esi, esi
        call    qword ptr [rip + core::slice::slice_index_order_fail@GOTPCREL]
        ud2

.L__unnamed_2:
        .ascii  "./example.rs"

.L__unnamed_1:
        .quad   .L__unnamed_2
        .asciz  "\f\000\000\000\000\000\000\000\016\000\000\000\027\000\000"
```

</details>

<details>
<summary>After</summary>

```
example::next:
        mov     rcx, qword ptr [rdi + 8]
        mov     rdx, qword ptr [rdi + 16]
        cmp     rdx, rcx
        jbe     .LBB0_2
        xor     eax, eax
        ret
.LBB0_2:
        mov     rax, qword ptr [rdi]
        lea     rsi, [rax + 4]
        add     rcx, -1
        mov     qword ptr [rdi], rsi
        mov     qword ptr [rdi + 8], rcx
        ret
```

</details>

Note the lack of call to `core::slice::slice_index_order_fail` in second snippet.

#### Possible reasons _not_ to merge this PR:

* this changes the error message on panic in `[T]::windows`. However, AFAIK this messages are not covered by backwards compatibility policy.
2020-10-07 17:31:56 +00:00
..
alloc Rollup merge of #77315 - exrook:rename-allocerror, r=joshtriplett 2020-10-01 02:13:39 +02:00
array add tracking issue 2020-09-23 13:48:21 +02:00
char Use matches! for core::char methods 2020-10-05 22:29:07 +08:00
convert add i32::MAX link 2020-08-30 17:07:50 +05:30
fmt Use more intra-doc-links in core::fmt 2020-10-04 22:33:22 +02:00
future Update library functions with stability attributes 2020-09-22 10:05:58 -07:00
hash Switch to intra-doc links in core::hash 2020-08-27 12:09:50 -07:00
iter Auto merge of #77594 - timvermeulen:chain_advance_by, r=scottmcm 2020-10-06 10:17:48 +00:00
macros core::global_allocator docs link to std::alloc::GlobalAlloc 2020-09-29 14:39:44 +07:00
mem Rollup merge of #77228 - GuillaumeGomez:maybeuninit-examples, r=pickfire 2020-10-06 16:26:00 +09:00
num Implement as_ne_bytes for floats and integers 2020-09-20 22:20:06 +08:00
ops Use Self more in core in doc when possible 2020-09-23 00:16:16 +02:00
prelude mv std libs to library/ 2020-07-27 19:51:13 -05:00
ptr Rename AllocErr to AllocError 2020-09-28 14:51:03 -04:00
slice Eliminate bounds checking in slice::Windows 2020-10-06 18:23:37 +03:00
str Remove unneeded tidy comment 2020-09-26 05:20:53 +00:00
sync Move use align_of in atomic.rs into the places where it is used. 2020-09-21 20:44:45 +02:00
task Remove rustc_allow_const_fn_ptr 2020-09-27 10:46:41 -07:00
unicode mv std libs to library/ 2020-07-27 19:51:13 -05:00
any.rs update tracking issue for const_type_id 2020-09-24 09:00:04 +10:00
ascii.rs Fixed some intra-docs links in library/core 2020-09-18 07:49:29 +08:00
bool.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
borrow.rs Remove AsRef link as it is in the prelude 2020-08-10 20:29:20 +02:00
cell.rs Rollup merge of #77055 - est31:more_track_caller, r=Mark-Simulacrum 2020-09-23 14:54:15 +02:00
clone.rs Improve readability 2020-09-01 19:56:32 +02:00
cmp.rs Use Self more in core/src/cmp.rs 2020-09-22 23:36:08 +02:00
default.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
ffi.rs Use intra-doc-links in core::{raw, ffi, pin} 2020-08-22 22:25:27 +02:00
hint.rs hint doc use intra-doc links 2020-10-05 23:29:43 +08:00
internal_macros.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
intrinsics.rs Clean up on example doc fixes for ptr::copy 2020-10-02 14:44:01 +08:00
lazy.rs Capitalize safety comments 2020-09-08 22:26:44 -04:00
lib.rs Assume slice len is bounded by allocation size 2020-10-04 20:43:36 +02:00
marker.rs Use Self more in core in doc when possible 2020-09-23 00:16:16 +02:00
option.rs Rollup merge of #75454 - ltratt:option_optimisation_guarantees, r=dtolnay 2020-09-26 12:58:12 +02:00
panic.rs Auto merge of #76157 - ArekPiekarz:const_caller_location_tracking_issue, r=joshtriplett 2020-09-06 20:27:51 +00:00
panicking.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
pin.rs Make some methods of Pin<&mut T> unstable const 2020-09-18 19:23:50 +02:00
primitive.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
raw.rs Use intra-doc-links in core::{raw, ffi, pin} 2020-08-22 22:25:27 +02:00
result.rs Stabilize some Result methods as const 2020-08-31 02:43:17 +02:00
time.rs Make all methods of Duration const 2020-09-12 15:14:58 +02: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