Adds a basic assembly test checking that each target can produce assembly
and update the target tier policy to require this.
Signed-off-by: David Wood <david@davidtw.co>
Rework how diagnostic lints are stored.
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and
`Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be
redundant w.r.t. `Diagnostic::code`.
Seems simple. Except it's possible for a lint to have an error code, in
which case its `code` field is recorded as `Error`, and `is_lint` is
required to indicate that it's a lint. This is what happens with
`derive(LintDiagnostic)` lints. Which means those lints don't have a
lint name or a `has_future_breakage` field because those are stored in
the `DiagnosticId::Lint`.
It's all a bit messy and confused and seems unintentional.
This commit:
- removes `DiagnosticId`;
- changes `Diagnostic::code` to `Option<String>`, which means both
errors and lints can straightforwardly have an error code;
- changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a
new type containing a lint name and a `has_future_breakage` bool, so
all lints can have those, error code or not.
r? `@oli-obk`
fix fn/const items implied bounds and wf check (rebase)
A rebase of #104098, see that PR for discussion. This is pretty much entirely the work of `@aliemjay.` I received his permission for this rebase.
---
These are two distinct changes (edit: actually three, see below):
1. Wf-check all fn item args. This is a soundness fix.
Fixes#104005
2. Use implied bounds from impl header in borrowck of associated functions/consts. This strictly accepts more code and helps to mitigate the impact of other breaking changes.
Fixes#98852Fixes#102611
The first is a breaking change and will likely have a big impact without the the second one. See the first commit for how it breaks libstd.
Landing the second one without the first will allow more incorrect code to pass. For example an exploit of #104005 would be as simple as:
```rust
use core::fmt::Display;
trait ExtendLt<Witness> {
fn extend(self) -> Box<dyn Display>;
}
impl<T: Display> ExtendLt<&'static T> for T {
fn extend(self) -> Box<dyn Display> {
Box::new(self)
}
}
fn main() {
let val = (&String::new()).extend();
println!("{val}");
}
```
The third change is to to check WF of user type annotations before normalizing them (fixes#104764, fixes#104763). It is mutually dependent on the second change above: an attempt to land it separately in #104746 caused several crater regressions that can all be mitigated by using the implied from the impl header. It is also necessary for the soundness of associated consts that use the implied bounds of impl header. See #104763 and how the third commit fixes the soundness issue in `tests/ui/wf/wf-associated-const.rs` that was introduces by the previous commit.
r? types
Cache local DefId-keyed queries without hashing
This caches local DefId-keyed queries using just an IndexVec. This costs ~5% extra max-rss at most but brings significant runtime improvement, up to 13% cycle counts (mean: 4%) on primary benchmarks. It's possible that further tweaks could reduce the memory overhead further but this win seems worth landing despite the increased memory, particularly with regards to eliminating the present set in non-incr or storing it inline (skip list?) with the main data.
We tried applying this scheme to all keys in the [first perf run] but found that it carried a significant memory hit (50%). instructions/cycle counts were also much more mixed, though that may have been due to the lack of the present set optimization (needed for fast iter() calls in incremental scenarios).
Closes https://github.com/rust-lang/rust/issues/45275
[first perf run]: https://perf.rust-lang.org/compare.html?start=30dfb9e046aeb878db04332c74de76e52fb7db10&end=6235575300d8e6e2cc6f449cb9048722ef43f9c7&stat=instructions:u
Lint `overlapping_ranges_endpoints` directly instead of collecting into a Vec
In https://github.com/rust-lang/rust/pull/119396 I was a bit silly: I was trying to avoid any lints being fired from within the exhaustiveness algorithm for some vague aesthetic/reusability reason that doesn't really hold. This PR fixes that: instead of passing a `&mut Vec` around I just added a method to the `TypeCx` trait.
r? `@compiler-errors`
Simplify `closure_env_ty` and `closure_env_param`
Random cleanup that I found when working on async closures. This makes it easier to separate the latter into a new tykind.
Make sure to instantiate placeholders correctly in old solver
When creating the query substitution guess for an input placeholder type like `!1_T` (in universe 1), we were guessing the response substitution with something like `!0_T`. This failed to unify with `!1_T`, causing an ICE.
This PR reworks the query substitution guess code to work a bit more like the new solver. I'm *pretty* sure this is correct, though I'd really appreciate some scrutiny from someone (*cough* lcnr) who knows a bit more about query instantiation :)
Fixes#119941
r? lcnr
Sandwich MIR optimizations between DSE.
This PR reorders MIR optimization passes in an attempt to increase their efficiency.
- Stop running CopyProp before GVN, it's useless as GVN will do the same thing anyway. Instead, we perform CopyProp at the end of the pipeline, to ensure we do not emit copy/move chains.
- Run DSE before GVN, as it increases the probability to have single-assignment locals.
- Run DSE after the final CopyProp to turn copies into moves.
r? `@ghost`
Avoid some redundant work in GVN
The first 2 commits are about reducing the perf effect.
Third commit avoids doing redundant work: is a local is SSA, it already has been simplified, and the resulting value is in `self.locals`. No need to call any code on it.
The last commit avoids removing some storage statements.
r? wg-mir-opt
Foreign maps are used to cache external DefIds, typically backed by
metadata decoding. In the future we might skip caching `V` there (since
loading from metadata usually is already cheap enough), but for now this
cuts down on the impact to memory usage and time to None-init a bunch of
memory. Foreign data is usually much sparser, since we're not usually
loading *all* entries from the foreign crate(s).
never patterns: Check bindings wrt never patterns
Never patterns:
- Shouldn't contain bindings since they never match anything;
- Don't count when checking that or-patterns have consistent bindings.
r? `@compiler-errors`
Use `zip_eq` to enforce that things being zipped have equal sizes
Some `zip`s are best enforced to be equal, since size mismatches suggest deeper bugs in the compiler.
Fix `allow_internal_unstable` for `(min_)specialization`
Fixes#119950
Blocked on #119949 (comment doesn't make sense until that merges)
I'd like to follow this up and look for more instances of not properly checking spans for features but I wanted to fix the motivating issue.
`OutputTypeParameterMismatch` -> `SignatureMismatch`
I'm probably missing something that made this rename more complicated. What did you end up getting stuck on when renaming this selection error, `@lcnr?`
**also** I renamed the `FulfillmentErrorCode` variants. This is just churn but I wanted to do it forever. I can move it out of this PR if desired.
r? lcnr
Silence some follow-up errors [3/x]
this is one piece of the requested cleanups from https://github.com/rust-lang/rust/pull/117449
Keep error types around, even in obligations.
These help silence follow-up errors, as we now figure out that some types (most notably inference variables) are equal to an error type.
But it also allows figuring out more types in the presence of errors, possibly causing more errors.
coverage: Simplify building the coverage graph with `CoverageSuccessors`
This is a collection of simplifications to the code that builds the *basic coverage block* graph, which is a simplified view of the MIR control-flow graph that ignores panics and merges straight-line sequences of blocks into a single BCB node.
The biggest change is to how we determine the coverage-relevant successors of a block. Previously we would call `Terminator::successors` and apply some ad-hoc postprocessing, but with this PR we instead have our own `match` on the terminator kind that produces a coverage-specific enum `CoverageSuccessors`. That enum also includes information about whether a block has exactly one successor that it can be chained into as part of a single BCB.
Exhaustiveness: remove the need for arena-allocation within the algorithm
After https://github.com/rust-lang/rust/pull/119688, exhaustiveness checking doesn't need access to the arena anymore. This simplifies the lifetime story and makes it compile on stable without the extra dependency.
r? `@compiler-errors`
Inverting the condition lets us merge the two `Ok(false)` paths. I also
find the inverted condition easier to read: "all the things that must be
true for trimming to occur", instead of "any of the things that must be
true for trimming to not occur".
Don't ICE when noting GAT bounds in `report_no_match_method_error`
We can encounter `BindingObligation`s from GATs that we should handle in `report_no_match_method_error`. I assume we can encounter them from methods, though I didn't really feel like wasting my time creating a repro.
Fixes#119942
Make `InferCtxtExt::could_impl_trait` more precise, less ICEy
The implementation for `InferCtxtExt::could_impl_trait` was very wrong. Along with being pretty poorly named, way too specific to ADTs, it was also doing impl substitution wrong -- this caused an ICE (#119915).
This PR generalizes that code, gives it a clearer name, makes it stop using the new trait solver (lol), and fixes some fallout bad suggestions that are made worse with the code fix.
Fixes#119915
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and
`Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be
redundant w.r.t. `Diagnostic::code`.
Seems simple. Except it's possible for a lint to have an error code, in
which case its `code` field is recorded as `Error`, and `is_lint` is
required to indicate that it's a lint. This is what happens with
`derive(LintDiagnostic)` lints. Which means those lints don't have a
lint name or a `has_future_breakage` field because those are stored in
the `DiagnosticId::Lint`.
It's all a bit messy and confused and seems unintentional.
This commit:
- removes `DiagnosticId`;
- changes `Diagnostic::code` to `Option<String>`, which means both
errors and lints can straightforwardly have an error code;
- changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a
new type containing a lint name and a `has_future_breakage` bool, so
all lints can have those, error code or not.
This also switches from `split_off(0)` to `std::mem::take` when emptying the
accumulated list of blocks, because `split_off(0)` handles capacity in a way
that is unintuitive when used in a loop.
The old loop had two separate places where it would flush the acumulated list
of straight-line blocks into a new BCB. One occurred at the start of the loop
body when the current block couldn't be chained into, and the other occurred at
the end of the loop body when the current block couldn't be chained from.
The latter check can be hoisted to the start of the loop body by making it
examine the previous block (which has added itself to the list) instead of the
current block. With that done, we can combine the two separate flushes into one
flush with two possible trigger conditions.