| Age | Commit message (Collapse) | Author | Lines |
|
Specialize .zip() for efficient slice and slice iteration
The idea is to introduce a private trait TrustedRandomAccess and specialize .zip() for random access iterators into a counted loop.
The implementation in the PR is internal and has no visible effect in the API
Why a counted loop? To have each slice iterator compile to just a pointer, and both pointers are indexed with the same loop counter value in the generated code. When this succeeds, copying loops are readily recognized and replaced with memcpy and addition loops autovectorize well.
The TrustedRandomAccess approach works very well on the surface. Microbenchmarks optimize well, following the ideas above, and that is a dramatic improvement of .zip()'s codegen.
```rust
// old zip before this PR: bad, byte-for-byte loop
// with specialized zip: memcpy
pub fn copy_zip(xs: &[u8], ys: &mut [u8]) {
for (a, b) in ys.iter_mut().zip(xs) {
*a = *b;
}
}
// old zip before this PR: single addition per iteration
// with specialized zip: vectorized
pub fn add_zip(xs: &[f32], ys: &mut [f32]) {
for (a, b) in ys.iter_mut().zip(xs) { *a += *b; }
}
// old zip before this PR: single addition per iteration
// with specialized zip: vectorized (!!)
pub fn add_zip3(xs: &[f32], ys: &[f32], zs: &mut [f32]) {
for ((a, b), c) in zs.iter_mut().zip(xs).zip(ys) { *a += *b * *c; }
}
```
Yet in more complex situations, the .zip() loop can still fall back to its old behavior where phantom null checks throw in fake premature end of the loop conditionals. Remember that a NULL inside
Option<(&T, &T)> makes it a `None` value and a premature (in this case)
end of the loop.
So even if we have 1) an explicit `Some` in the code and 2) the types of the pointers are `&T` or `&mut T` which are nonnull, we can still get a phantom null check at that point.
One example that illustrates the difference is `copy_zip` with slice versus Vec arguments. The involved iterator types are exactly the same, but the Vec version doesn't compile down to memcpy. Investigating into this, the function argument metadata emitted to llvm plays the biggest role. As eddyb summarized, we need nonnull for the loop to autovectorize and noalias for it to replace with memcpy.
There was an experiment to use `assume` to add a non-null assumption on each of the two elements in the specialized zip iterator, but this only helped in some of the test cases and regressed others. Instead I think the nonnull/noalias metadata issue is something we need to solve separately anyway.
These have conditionally implemented TrustedRandomAccess
- Enumerate
- Zip
These have not implemented it
- Map is sideeffectful. The forward case would be workable, but the double ended case is complicated.
- Chain, exact length semantics unclear
- Filter, FilterMap, FlatMap and many others don't offer random access and/or exact length
|
|
Simplify gated cfg checking
r? @nrc
|
|
|
|
Add regression tests for #23122
This PR adds two regression tests for #23122.
Closes #23122.
|
|
Revert a change in the scope of macros imported from crates to fix a regression
Fixes #34212.
The regression was caused by #34032, which changed the scope of macros imported from extern crates to match the scope of macros imported from modules.
r? @nrc
|
|
Support nested `cfg_attr` attributes
Support arbitrarily deeply nested `cfg_attr` attributes (e.g. `#[cfg_attr(foo, cfg_attr(bar, baz))]`).
This makes configuration idempotent.
Currently, the nighties do not support any `cfg_attr` nesting. Stable and beta support just one level of `cfg_attr` nesting (expect for attributes on macro-expanded nodes, where no nesting is supported).
This is a [breaking-change]. For example, the following would break:
```rust
macro_rules! m { () => {
#[cfg_attr(all(), cfg_attr(all(), cfg(foo)))]
fn f() {}
} }
m!();
fn main() { f() } //~ ERROR unresolved name `f`
```
r? @nrc
|
|
don't generate drop ladder steps for fields that don't need dropping
cc @eddyb
This should help with #34166
|
|
|
|
|
|
Show types of all args when missing args
When there're missing arguments in a function call, present a list of
all the expected types:
```rust
fn main() {
t("");
}
fn t(a: &str, x: String) {}
```
```bash
% rustc file.rs
file.rs:3:5: 2:8 error: this function takes 2 parameters but 0
parameters were supplied [E0061]
file.rs:3 t();
^~~
file.rs:3:5: 2:8 help: run `rustc --explain E0061` to see a detailed explanation
file.rs:3:5: 2:8 note: the following parameter types were expected: &str, std::string::String
error: aborting due to previous error
```
Fixes #33649
|
|
When there're missing arguments in a function call, present a list of
all the expected types:
```rust
fn main() {
t("");
}
fn t(a: &str, x: String) {}
```
```bash
% rustc file.rs
file.rs:3:5: 2:8 error: this function takes 2 parameters but 0
parameters were supplied [E0061]
file.rs:3 t();
^~~
file.rs:3:5: 2:8 help: run `rustc --explain E0061` to see a detailed explanation
file.rs:3:5: 2:8 note: the following parameter types were expected: &str, std::string::String
error: aborting due to previous error
```
Fixes #33649
|
|
derive Hash (and not Copy) for ranges
Fixes #34170.
Also, `RangeInclusive` was `Copy` by mistake -- fix that, which is a [breaking-change] to that unstable type.
|
|
rustdoc: Fix redirect pages for renamed reexports
We need to use the name of the target not the name of the current item
when creating the link.
An example in `std` is [`std::sys::ext`](https://doc.rust-lang.org/nightly/std/sys/ext/index.html).
|
|
We need to use the name of the target not the name of the current item
when creating the link.
|
|
|
|
rustdoc: Don't inline #[doc(hidden)] pub use
Currently if a `#[doc(hidden)] pub use` item is inlined the `hidden`
attribute is ignored so the item can appear in the docs. By never inlining
such imports, they can be stripped.
An example in `std` is [`__OsLocalKeyInner`](https://doc.rust-lang.org/nightly/std/thread/struct.__OsLocalKeyInner.html) which clearly should not be documented.
|
|
Fix macro call site spans
Fix macro call site spans.
r? @nrc
|
|
Add regression test for #33293
This PR adds a regression test for #33293.
Closes #33293.
r? @eddyb
|
|
debuginfo test
|
|
Add test case for issue #23477
My first pull request, any feedback welcome.
Fixes #23477
|
|
|
|
|
|
Add regression test for #32364
This PR adds a regression test for #32364.
r? @eddyb
|
|
|
|
|
|
add a test case for issue #32031
I propose a test case to finish the fix for issue #32031. Please review this commit thoroughly, as I have never written a codegen test before.
r? @eddyb
|
|
|
|
rustdoc: Don't generate empty files for stripped items
We need to traverse stripped modules to generate redirect pages, but we shouldn't generate
anything else for them.
This now renders the file contents to a Vec before writing it to a file in one go. I think
that's probably a better strategy anyway.
Fixes: #34025
|
|
|
|
Currently if a `#[doc(hidden)] pub use` item is inlined the `hidden`
attribute is ignored so the item can appear in the docs. By never inlining
such imports, they can be stripped.
|
|
|
|
|
|
|
|
r=alexcrichton
Fix ICE regression caused by configuring interpolated AST
Fixes #34171.
r? @nrc
|
|
Visit statement and expression attributes in the AST visitor
Currently, these attributes are not visited, so they are not gated feature checked in the post expansion visitor. This only affects crates using `#![feature(stmt_expr_attributes)]`.
r? @nrc
|
|
Test case for borrowk ICE #25579
r? @nikomatsakis
Fixes #25579
|
|
|
|
|
|
|
|
|
|
MIR cleanups and predecessor cache
This PR cleans up a few things in MIR and adds a predecessor cache to allow graph algorithms to be run easily.
r? @nikomatsakis
|
|
|
|
|
|
Fix issue #34101
Fix issue #34101: do not track subcontent of type with dtor nor gather flags for untracked content.
(Includes a regression test, which needed to go into `compile-fail/`
due to weaknesses when combining `#[deny(warnings)]` with
`tcx.sess.span_warn(..)`)
|
|
Support `#[macro_use]` on macro-expanded crates
This PR loads macros from `#[macro_use]` crates during expansion so that
- macro-expanded `#[macro_use]` crates work (fixes #33936, fixes #28071), and
- macros imported from crates have the same scope as macros imported from modules.
This is a [breaking-change]. For example, this will break:
```rust
macro_rules! m {
() => { #[macro_use(foo)] extern crate core; } //~ ERROR imported macro not found
}
m!();
```
Also, this will break:
```rust
macro_rules! try { () => {} }
// #[macro_use] mod bar { macro_rules! try { ... } } //< ... just like this would ...
fn main() { try!(); } //< ... making this an error
```
r? @nrc
|
|
Implement RFC495 semantics for slice patterns
non-MIR translation is still not supported for these and will happily ICE.
This is a [breaking-change] for many uses of slice_patterns.
[RFC 495 text](https://github.com/rust-lang/rfcs/blob/master/text/0495-array-pattern-changes.md)
|
|
|
|
|
|
|
|
trans: don't misuse C_nil for ZSTs other than ().
`C_nil` is actually `C_null` for `()` so `TempRef::new_operand` was treating all ZSTs as `()`.
This should allow running Servo with `RUSTFLAGS=-Zorbit`, assuming there are no other bugs.
|