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
This flag is a debugging measure designed to detect cases where we start
a snapshot, create type variables, register obligations involving those
type variables in the fulfillment cx, and then have to unroll the
snapshot, leaving "dangling type variables" behind. HOWEVER, in some
cases the flag is wrong. In particular, we sometimes create a
"mini-fulfilment-cx" in which we enroll obligations. As long as this
fulfillment cx is fully drained before we return, this is not a problem,
as there won't be any escaping obligations in the main cx. So we add a
fn to save/restore the flag.
rustdoc: Don't add extra newlines for fully opaque structs
Changes the definition for braced structs with only private or hidden fields to save space on the page.
Before:
```
pub struct Vec<T> {
// some fields omitted
}
```
After:
```
pub struct Vec<T> { /* fields omitted */ }
```
This also cleans up empty braced structs.
Before:
```
pub struct Foo {
}
```
After:
```
pub struct Foo {}
```
[before](https://doc.rust-lang.org/nightly/std/vec/struct.Vec.html) [after](https://ollie27.github.io/rust_doc_test/std/vec/struct.Vec.html)
cc #34713
crate-ify compiler-rt into compiler-builtins
libcompiler-rt.a is dead, long live libcompiler-builtins.rlib
This commit moves the logic that used to build libcompiler-rt.a into a
compiler-builtins crate on top of the core crate and below the std crate.
This new crate still compiles the compiler-rt instrinsics using gcc-rs
but produces an .rlib instead of a static library.
Also, with this commit rustc no longer passes -lcompiler-rt to the
linker. This effectively makes the "no-compiler-rt" field of target
specifications a no-op. Users of `no_std` will have to explicitly add
the compiler-builtins crate to their crate dependency graph *if* they
need the compiler-rt intrinsics - this is a [breaking-change]. Users
of the `std` have to do nothing extra as the std crate depends
on compiler-builtins.
Finally, this a step towards lazy compilation of std with Cargo as the
compiler-rt intrinsics can now be built by Cargo instead of having to
be supplied by the user by some other method.
closes#34400
---
r? @alexcrichton
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
Zero first byte of CString on drop
Hi! This is one more attempt to ameliorate `CString::new("...").unwrap().as_ptr()` problem (related RFC: https://github.com/rust-lang/rfcs/pull/1642).
One of the biggest problems with this code is that it may actually work in practice, so the idea of this PR is to proactively break such invalid code.
Looks like writing a `null` byte at the start of the CString should do the trick, and I think is an affordable cost: zeroing a single byte in `Drop` should be cheap enough compared to actual memory deallocation which would follow.
I would actually prefer to do something like
```Rust
impl Drop for CString {
fn drop(&mut self) {
let pattern = b"CTHULHU FHTAGN ";
let bytes = self.inner[..self.inner.len() - 1];
for (d, s) in bytes.iter_mut().zip(pattern.iter().cycle()) {
*d = *s;
}
}
}
```
because Cthulhu error should be much easier to google, but unfortunately this would be too expensive in release builds, and we can't implement things `cfg(debug_assertions)` conditionally in stdlib.
Not sure if the whole idea or my implementation (I've used ~~`transmute`~~ `mem::unitialized` to workaround move out of Drop thing) makes sense :)