Fix overflow checking in unsigned pow()
The pow() method for unsigned integers produced 0 instead of trapping overflow for certain inputs. Calls such as 2u32.pow(1024) produced 0 when they should trap an overflow. This also adds tests for the correctly handling overflow in unsigned pow().
This was previously fixed for signed integers in #28248, but it seems unsigned integers got missed that time.
For issue number #34913
Remove data structure specialization for .zip() iterator
Go back on half the specialization, the part that changed the Zip
struct's fields themselves depending on the types of the iterators.
Previous PR: #33090
This means that the Zip iterator will always carry two usize fields,
which are sometimes unused. If a whole for loop using a .zip() iterator is
inlined, these are simply removed and have no effect.
The same improvement for Zip of for example slice iterators remain, and
they still optimize well. However, like when the specialization of zip
was merged, the compiler is still very sensistive to the exact context.
For example this code only autovectorizes if the function is used, not
if the code in zip_sum_i32 is inserted inline where it was called:
```rust
fn zip_sum_i32(xs: &[i32], ys: &[i32]) -> i32 {
let mut s = 0;
for (&x, &y) in xs.iter().zip(ys) {
s += x * y;
}
s
}
fn zipdot_i32_default_zip(b: &mut test::Bencher)
{
let xs = vec![1; 1024];
let ys = vec![1; 1024];
b.iter(|| {
zip_sum_i32(&xs, &ys)
})
}
```
Include a test that checks that `Zip<T, U>` is covariant w.r.t. T and U.
Fixes#35727
Use primitive indexing in slice's Index/IndexMut
[T]'s Index implementation is normally not used for indexing, instead
the compiler supplied indexing is used.
Use the compiler supplied version in Index/IndexMut.
This removes an inconsistency:
Compiler supplied bound check failures look like this:
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4'
If you convince Rust to use the Index impl for slices, bounds check
failure looks like this instead:
thread 'main' panicked at 'assertion failed: index < self.len()'
The latter is used if you for example use Index generically:
```rust
use std::ops::Index;
fn foo<T: ?Sized>(x: &T) where T: Index<usize> { &x[4]; }
foo(&[1, 2, 3][..])
```
Improve shallow `Clone` deriving
`Copy` unions now support `#[derive(Clone)]`.
Less code is generated for `#[derive(Clone, Copy)]`.
+
Unions now support `#[derive(Eq)]`.
Less code is generated for `#[derive(Eq)]`.
---
Example of code reduction:
```
enum E {
A { a: u8, b: u16 },
B { c: [u8; 100] },
}
```
Before:
```
fn clone(&self) -> E {
match (&*self,) {
(&E::A { a: ref __self_0, b: ref __self_1 },) => {
::std::clone::assert_receiver_is_clone(&(*__self_0));
::std::clone::assert_receiver_is_clone(&(*__self_1));
*self
}
(&E::B { c: ref __self_0 },) => {
::std::clone::assert_receiver_is_clone(&(*__self_0));
*self
}
}
}
```
After:
```
fn clone(&self) -> E {
{
let _: ::std::clone::AssertParamIsClone<u8>;
let _: ::std::clone::AssertParamIsClone<u16>;
let _: ::std::clone::AssertParamIsClone<[u8; 100]>;
*self
}
}
```
All the matches are removed, bound assertions are more lightweight.
`let _: Checker<CheckMe>;`, unlike `checker(&check_me);`, doesn't have to be translated by rustc_trans and then inlined by LLVM, it doesn't even exist in MIR, this means faster compilation.
---
Union impls are generated like this:
```
union U {
a: u8,
b: u16,
c: [u8; 100],
}
```
```
fn clone(&self) -> U {
{
let _: ::std::clone::AssertParamIsCopy<Self>;
*self
}
}
```
Fixes https://github.com/rust-lang/rust/issues/36043
cc @durka
r? @alexcrichton
Go back on half the specialization, the part that changed the Zip
struct's fields themselves depending on the types of the iterators.
This means that the Zip iterator will always carry two usize fields,
which are unused. If a whole for loop using a .zip() iterator is
inlined, these are simply removed and have no effect.
The same improvement for Zip of for example slice iterators remain, and
they still optimize well. However, like when the specialization of zip
was merged, the compiler is still very sensistive to the exact context.
For example this code only autovectorizes if the function is used, not
if the code in zip_sum_i32 is inserted inline it was called:
```
fn zip_sum_i32(xs: &[i32], ys: &[i32]) -> i32 {
let mut s = 0;
for (&x, &y) in xs.iter().zip(ys) {
s += x * y;
}
s
}
fn zipdot_i32_default_zip(b: &mut test::Bencher)
{
let xs = vec![1; 1024];
let ys = vec![1; 1024];
b.iter(|| {
zip_sum_i32(&xs, &ys)
})
}
```
Include a test that checks that Zip<T, U> is covariant w.r.t. T and U.
Inherit overflow checks for sum and product
We have previously documented the fact that these will panic on overflow, but I think this behavior is what people actually want/expect. `#[rustc_inherit_overflow_checks]` didn't exist when we discussed these for stabilization.
r? @alexcrichton
Closes#35807
[T]'s Index implementation is normally not used for indexing, instead
the compiler supplied indexing is used.
Use the compiler supplied version in Index/IndexMut.
This removes an inconsistency:
Compiler supplied bound check failures look like this:
thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4'
If you convince Rust to use the Index impl for slices, bounds check
failure looks like this instead:
thread 'main' panicked at 'assertion failed: index < self.len()'
The latter is used if you for example use Index generically::
use std::ops::Index;
fn foo<T: ?Sized>(x: &T) where T: Index<usize> { &x[4]; }
foo(&[1, 2, 3][..])
Documentation of what Default does for each type
Addresses #36265
I haven't changed the following types due to doubts:
1)src/libstd/ffi/c_str.rs
2)src/libcore/iter/sources.rs
3)src/libcore/hash/mod.rs
4)src/libcore/hash/mod.rs
5)src/librustc/middle/privacy.rs
r? @steveklabnik
core: add likely and unlikely intrinsics
I'm no good at reading assembly, but I have tried a stage1 compiler with this patch, and it does cause different asm output. Additionally, testing this compiler on my httparse crate with some `likely` usage added in to the branches does affect benchmarks. However, I'm sure a codegen test should be included, if anyone knows what it should look like.
There isn't an entry in `librustc_trans/context.rs` in this diff, because it already exists (`llvm.expect.i1` is used for array indices).
----
Even though this does affect httparse benchmarks, it doesn't seem to affect it the same way GCC's `__builtin_expect` affects picohttpparser. I was confused that the deviation on the benchmarks grew hugely when testing this, especially since I'm absolutely certain that the branchs where I added `likely` were always `true`. I chalk that up to GCC and LLVM handle branch prediction differently.
cc #26179
Introduce max_by/min_by on iterators
See https://github.com/rust-lang/rfcs/issues/1722 for reference.
It seems that there is `min`, `max` (simple computation of min/max), `min_by_key`, `max_by_key` (min/max by comparing mapped values) but no `min_by` and `max_by` (min/max according to comparison function). However, e.g. on vectors or slices there is `sort`, `sort_by_key` and `sort_by`.
Document try!'s error conversion behaviour
try!'s documentation currently doesn't document the error conversion behaviour of the macro. This patch extends the documentation.
Open questions:
* is it worthwhile to have seperate examples with and without wrapping behaviour? It's not immediately obvious that From<T> for T is always defined. Though this is necessary for the macro to work in any case, is this the place to expect that knowledge.
Implement std::convert traits for char
This is motivated by avoiding the `as` operator, which sometimes silently truncates, and instead use conversions that are explicitly lossless and infallible.
I’m less certain that `From<u8> for char` should be implemented: while it matches an existing behavior of `as`, it’s not necessarily the right thing to use for non-ASCII bytes. It effectively decodes bytes as ISO/IEC 8859-1 (since Unicode designed its first 256 code points to be compatible with that encoding), but that is not apparent in the API name.