optimize `superset` method of `IntervalSet`
Given that intervals in the `IntervalSet` are sorted and strictly separated( it means the `end` of the previous interval will not be equal to the `start` of the next interval), we can reduce the complexity of the `superset` method from O(NMlogN) to O(2N) (N is the number of intervals and M is the length of each interval)
use precise spans for recursive const evaluation
This fixes https://github.com/rust-lang/rust/issues/73283 by using a `TyCtxtAt` with a more precise span when the interpreter recursively calls itself. Hopefully such calls are sufficiently rare that this does not cost us too much performance.
(In theory, cycles can also arise through layout computation, as layout can depend on consts -- but layout computation happens all the time so we'd have to do something to not make this terrible for performance.)
Don't suggest adding `let` in certain `if` conditions
Avoid being too eager to suggest `let` in an `if` condition with an `=`, namely when the LHS of the `=` isn't even valid as a pattern (to a first degree approximation).
This heustic I came up with kinda sucks. Let me know if it needs to be refined.
Fix indices and remove some unwraps in arg mismatch algorithm
This is a more conservative fix than #97542, addressing some indices which were used incorectly and unwraps which are bound to panic (e.g. when the provided and expected arg counts differ). Beta nominating this as it's quite easy to cause ICEs -- I wrote a fuzzer and found hundreds of examples of ICEs.
cc `@jackh726` as author of #92364, and `@estebank` as reviewer of that PR.
fixes#97484
r? `@jackh726` this should be _much_ easier to review than the other PR 😅
Impl Traits lowering minor refactors
This are unrelated changes on my RPIT refactor that may be better to merge before opening the main PR.
r? `@cjgillot`
cc `@nikomatsakis`
Specify DWARF alignment in bits, not bytes.
In DWARF, alignment of types is specified in bits, as is made clear by the
parameter name `AlignInBits`. However, `rustc` was incorrectly passing a byte
alignment. This commit fixes that.
This was noticed in upstream LLVM when I tried to check in a test consisting of
LLVM IR generated from `rustc` and it triggered assertions [1].
[1]: https://reviews.llvm.org/D126835
Recover missing comma after match arm
If we're missing a comma after a match arm expression, try parsing another pattern and a following `=>`. If we find both of those, then recover by suggesting to insert a `,`.
Fixes#80112
Recover `import` instead of `use` in item
When we definitely don't have a macro invocation (i.e. when we don't have `import ::`), then it's more productive to parse `import` as if it was incorrectly mistaken for `use`.
Not sure if this needs to be a verbose suggestion, but it renders strangely when it's not verbose:
```
error: expected item, found `import`
--> /home/michael/test.rs:1:1
|
1 | import std::{io::{self, Write}, rc::Rc};
| ^^^^^^ help: items are imported using the `use` keyword: `use`
```
Happy to change it to `span_suggestion` instead of `span_suggestion_verbose` though.
Fixes#97788
Remove unwrap from get_vtable
This avoids ICE on issue #97381 I think the bug is a bit deeper though, it compiles fine when `v` is `&v` which makes me think `Deref` is causing some issue with borrowck but it's fine I guess since this thing crashes since `nightly-2020-09-17` 😅
This avoids the name clash with `rustc_serialize::Encoder` (a trait),
and allows lots qualifiers to be removed and imports to be simplified
(e.g. fewer `as` imports).
This commit makes type folding more like the way chalk does it.
Currently, `TypeFoldable` has `fold_with` and `super_fold_with` methods.
- `fold_with` is the standard entry point, and defaults to calling
`super_fold_with`.
- `super_fold_with` does the actual work of traversing a type.
- For a few types of interest (`Ty`, `Region`, etc.) `fold_with` instead
calls into a `TypeFolder`, which can then call back into
`super_fold_with`.
With the new approach, `TypeFoldable` has `fold_with` and
`TypeSuperFoldable` has `super_fold_with`.
- `fold_with` is still the standard entry point, *and* it does the
actual work of traversing a type, for all types except types of
interest.
- `super_fold_with` is only implemented for the types of interest.
Benefits of the new model.
- I find it easier to understand. The distinction between types of
interest and other types is clearer, and `super_fold_with` doesn't
exist for most types.
- With the current model is easy to get confused and implement a
`super_fold_with` method that should be left defaulted. (Some of the
precursor commits fixed such cases.)
- With the current model it's easy to call `super_fold_with` within
`TypeFolder` impls where `fold_with` should be called. The new
approach makes this mistake impossible, and this commit fixes a number
of such cases.
- It's potentially faster, because it avoids the `fold_with` ->
`super_fold_with` call in all cases except types of interest. A lot of
the time the compile would inline those away, but not necessarily
always.
We already have `visit_unevaluated`, so this improves consistency.
Also, define `TypeFoldable for Unevaluated<'tcx, ()>` in terms of
`TypeFoldable for Unevaluated<'tcx>`, which is neater.
Because `TypeFoldable::try_fold_mir_const` exists, and even though
`visit_mir_const` isn't needed right now, the consistency makes the code
easier to understand.
RustWrapper: adapt to APInt API changes in LLVM 15
In https://reviews.llvm.org/D125556 upstream changed sext() and zext()
to allow some no-op cases, which previously required use of the *OrSelf()
methods, which I assume is what was going on here. The *OrSelf() methods
got removed in https://reviews.llvm.org/D125559 after two weeks of
deprecation because they came with some bonus (probably-undesired)
behavior. Since the behavior of sext() and zext() changed slightly, I
kept the old *OrSelf() calls in LLVM 14 and earlier, and only use the
new version in LLVM 15.
r? `@nikic`
Change `Direction::{is_forward,is_backward}` functions into constants
Make it explicit that the analysis direction is constant.
This also makes the value immediately available for optimizations.
Previously those functions were neither inline nor generic and so their
definition was unavailable when using data flow framework from other
crates.
There are two impls of the `Encoder` trait: `opaque::Encoder` and
`opaque::FileEncoder`. The former encodes into memory and is infallible, the
latter writes to file and is fallible.
Currently, standard `Result`/`?`/`unwrap` error handling is used, but this is a
bit verbose and has non-trivial cost, which is annoying given how rare failures
are (especially in the infallible `opaque::Encoder` case).
This commit changes how `Encoder` fallibility is handled. All the `emit_*`
methods are now infallible. `opaque::Encoder` requires no great changes for
this. `opaque::FileEncoder` now implements a delayed error handling strategy.
If a failure occurs, it records this via the `res` field, and all subsequent
encoding operations are skipped if `res` indicates an error has occurred. Once
encoding is complete, the new `finish` method is called, which returns a
`Result`. In other words, there is now a single `Result`-producing method
instead of many of them.
This has very little effect on how any file errors are reported if
`opaque::FileEncoder` has any failures.
Much of this commit is boring mechanical changes, removing `Result` return
values and `?` or `unwrap` from expressions. The more interesting parts are as
follows.
- serialize.rs: The `Encoder` trait gains an `Ok` associated type. The
`into_inner` method is changed into `finish`, which returns
`Result<Vec<u8>, !>`.
- opaque.rs: The `FileEncoder` adopts the delayed error handling
strategy. Its `Ok` type is a `usize`, returning the number of bytes
written, replacing previous uses of `FileEncoder::position`.
- Various methods that take an encoder now consume it, rather than being
passed a mutable reference, e.g. `serialize_query_result_cache`.