This iterator can be hot, and chained iterators are slow. The second
half of the chain is almost always empty, so this commit changes the
code to avoid the chained iteration.
This change reduces instruction counts for the `wg-grammar` benchmark by
up to 1.5%.
Optimize try_eval_bits to avoid layout queries
This specifically targets match checking, but is possibly more widely
useful as well. In code with large, single-value match statements, we
were previously spending a lot of time running layout_of for the
primitive types (integers, chars) -- which is essentially useless. This
optimizes the code to avoid those query calls by directly obtaining the
size for these types, when possible.
It may be worth considering adding a `size_of` query in the future which
might be far faster, especially if specialized for "const" cases --
match arms being the most obvious example. It's possibly such a function
would benefit from *not* being a query as well, since it's trivially
evaluatable from the sty for many cases whereas a query needs to hash
the input and such.
This specifically targets match checking, but is possibly more widely
useful as well. In code with large, single-value match statements, we
were previously spending a lot of time running layout_of for the
primitive types (integers, chars) -- which is essentially useless. This
optimizes the code to avoid those query calls by directly obtaining the
size for these types, when possible.
It may be worth considering adding a `size_of` query in the future which
might be far faster, especially if specialized for "const" cases --
match arms being the most obvious example. It's possibly such a function
would benefit from *not* being a query as well, since it's trivially
evaluatable from the sty for many cases whereas a query needs to hash
the input and such.
By collecting the done obligations (when necessary) in the main loop.
This makes the code cleaner.
The commit also changes the order in which successful obligations are
returned -- they are now returned in the registered order, rather than
reversed. Because this order doesn't actually matter, being only used by
tests, the commit uses `sort()` to make the test agnostic w.r.t. the
order.
It's not necessary; cycles (which are rare) can be detected by looking
at the node stack.
This change speeds things up slightly, as well as simplifying the code a
little.
Rollup of 6 pull requests
Successful merges:
- #64691 (Point at definition when misusing ADT)
- #64735 (Add long error explanation for E0533)
- #64825 (Point at enclosing match when expecting `()` in arm)
- #64858 (Add support for relating slices in `super_relate_consts`)
- #64894 (syntax: fix dropping of attribute on first param of non-method assocated fn)
- #64898 (fixed typo)
Failed merges:
r? @ghost
syntax: fix dropping of attribute on first param of non-method assocated fn
Fixes#64682.
The general idea is that we bake parsing of `self` into `parse_param_general` and then we just use standard list parsing. Overall, this simplifies the parsing and makes it more consistent.
r? @petrochenkov cc @c410-f3r
Point at enclosing match when expecting `()` in arm
When encountering code like the following:
```rust
fn main() {
match 3 {
4 => 1,
3 => {
println!("Yep it maches.");
2
}
_ => 2
}
println!("Bye!")
}
```
point at the enclosing `match` expression and suggest ignoring the
returned value:
```
error[E0308]: mismatched types
--> $DIR/match-needing-semi.rs:8:13
|
LL | / match 3 {
LL | | 4 => 1,
LL | | 3 => {
LL | | 2
| | ^ expected (), found integer
LL | | }
LL | | _ => 2
LL | | }
| | -- help: consider using a semicolon here
| |_____|
| expected this to be `()`
|
= note: expected type `()`
found type `{integer}
```
Fix#40799.
panic=abort support in libtest
Add experimental support for tests compiled with panic=abort. Enabled with `-Z panic_abort_tests`.
r? @alexcrichton
cc @cramertj
https://github.com/rust-lang/rust/pull/49496 introduced specialization based on:
```
unsafe impl<T: ?Sized> IsZero for *mut T {
fn is_zero(&self) -> bool {
(*self).is_null()
}
}
```
… to call `RawVec::with_capacity_zeroed` for creating `Vec<*mut T>`,
which is incorrect for fat pointers
since `<*mut T>::is_null` only looks at the data component.
That is, a fat pointer can be “null” without being made entirely of zero bits.
This commit fixes it by removing the `?Sized` bound on this impl
(and the corresponding `*const T` one).
This regresses `vec![x; n]` with `x` a null raw slice of length zero,
but that seems exceptionally uncommon.
(Vtable pointers are never null, so raw trait objects would not take
the fast path anyway.
An alternative to keep the `?Sized` bound
(or even generalize to `impl<U: Copy> IsZero for U`)
would be to cast to `&[u8]` of length `size_of::<U>()`,
but the optimizer seems not to be able to propagate alignment information
and sticks with comparing one byte at a time:
https://rust.godbolt.org/z/xQFkwL
----
Without the library change, the new test fails as follows:
```
---- vec::vec_macro_repeating_null_raw_fat_pointer stdout ----
[src/liballoc/tests/vec.rs:1301] ptr_metadata(raw_dyn) = 0x00005596ef95f9a8
[src/liballoc/tests/vec.rs:1306] ptr_metadata(vec[0]) = 0x0000000000000000
thread 'vec::vec_macro_repeating_null_raw_fat_pointer' panicked at 'assertion failed: vec[0] == null_raw_dyn', src/liballoc/tests/vec.rs:1307:5
```
Rollup of 5 pull requests
Successful merges:
- #63492 (Remove redundancy from the implementation of C variadics.)
- #64589 (Differentiate AArch64 bare-metal targets between hf and non-hf.)
- #64799 (Fix double panic when printing query stack during an ICE)
- #64824 (No StableHasherResult everywhere)
- #64884 (Add pkg-config to dependency list if building for Linux on Linux)
Failed merges:
r? @ghost