`QueryStackFrame<I>` is a generic type, and the `I` parameter leaks out
to many other related types. However, it only has two instantiations in
practice:
- `QueryStackFrame<QueryStackFrameExtra>`
- `QueryStackFrame<QueryStackDeferred<'tcx>>`
And most of the places that currently use `QueryStackFrame<I>` are
actually specific to one of the instantiations. This commit removes the
unneeded genericity.
The following types are only ever used with `QueryStackDeferred<'tcx>`:
- QueryMap
- QueryJobInfo
- QueryJob
- QueryWaiter
- QueryLatchInfo
- QueryLatch
- QueryState
- QueryResult
and their `<I>` parameter is changed to `<'tcx>`.
Also, the `QueryContext::QueryInfo` associated type is removed.
`CycleError<I>` and `QueryInfo<I>` are still generic over type, because
they are used with both instantiations.
This required also adding a `<'tcx>` parameter to the traits
`QueryDispatcher` and `QueryContext`, which is annoying but I can't see
how to avoid it.
Rename, clarify, and document code for "erasing" query values
In order to reduce compile times and code size for the compiler itself, the query system has a mechanism for “erasing” and ”restoring” query values in certain contexts. See https://github.com/rust-lang/rust/pull/109333 for the original implementation.
Unfortunately, the erasure system has very little documentation, and involves a dizzying assortment of similarly-named types, traits, and functions.
This PR therefore renames several parts of the erasure API and implementation to hopefully be clearer, and adds comments to better explain the purpose and mechanism behind value erasure.
Summary of renames:
- fn `erase` → `erase_val` (avoiding ambiguity with module `erase`)
- fn `restore` → `restore_val`
- type `Erase<T>` → `Erased<T>` (for actual erased values of `T`)
- trait `EraseType` → `Erasable` (for types that can be erased and restored)
- associated type `EraseType::Result` → `Erasable::Storage`
- implementation-detail struct `Erased<T>` → `ErasedData<Storage>`
There should be no change to compiler behaviour.
Use an associated type default for `Key::Cache`.
They currently aren't used because r-a didn't support them, but r-a support was recently merged in
https://github.com/rust-lang/rust-analyzer/pull/21243.
r? @Noratrieb
I tried removing it in #151203, to replace it with something simpler.
But a couple of fuzzing failures have come up and I don't have a clear
picture on how to fix them. So I'm reverting the main part of #151203.
This commit also adds the two fuzzing tests.
Fixes#151226, #151358.
Revert `QueryStackFrame` split
PR rust-lang/rust#138672 fixed a query cycle OOM reported in rust-lang/rust#124901. The fix involved delaying computation of some query stack frame elements and was very complex. It involved the addition of two new types, the addition of a generic `I` parameter to eleven(!) other types, a `PhantomData` field, and even required an unsafe transmute of a closure. [This comment](https://github.com/rust-lang/rust/issues/124901#issuecomment-2104852065) had suggested a much simpler fix, but it was ignored. The PR also failed to add a test case.
This PR adds a test case, reverts the complex fix, applies the simpler fix, and does a few other minor cleanups.
r? @oli-obk
PR #138672 introduced a complex and invasive split of `QueryStackFrame`
to avoid a query cycle. This commit reverts that change because there is
a much simpler change that fixes the problem, which will be in the next
commit.
Also hash spans inside the same file as relative (V2)
Hashes spans relatively to their parent, even if they are not contained inside their parent.
Fixes https://github.com/rust-lang/rust/issues/150400
Closes https://github.com/rust-lang/rust/pull/143882, as this is a successor PR
This PR is very closely based on that PR with a few minor changes, so to give proper credit I made @cjgillot coauthor of the commit.
Detect cases where `?` is applied on a type that could be coming from a different crate version than expected
```
error[E0277]: `?` couldn't convert the error to `dependency::Error`
--> replaced
|
LL | fn main() -> Result<(), Error> {
| ----------------- expected `dependency::Error` because of this
...
LL | Err(Error2)?;
| -----------^ the trait `From<Error2>` is not implemented for `dependency::Error`
| |
| this can't be annotated with `?` because it has type `Result<_, Error2>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
help: the trait `From<Error2>` is not implemented for `dependency::Error`
but trait `From<()>` is implemented for it
--> replaced
|
LL | impl From<()> for Error {
| ^^^^^^^^^^^^^^^^^^^^^^^
= help: for that trait implementation, expected `()`, found `Error2`
= note: there are multiple different versions of crate `dependency` in the dependency graph
= help: you can use `cargo tree` to explore your dependency tree
```
The existing checks rely on having access to the actual types/traits that diverged to detect they are called the same, come from different crates with the same name. The new check is less specific, merely looking to see if the crate name the involved type belongs has multiple crates.
CC rust-lang/rust#78552.
```
error[E0277]: `?` couldn't convert the error to `dependency::Error`
--> replaced
|
LL | fn main() -> Result<(), Error> {
| ----------------- expected `dependency::Error` because of this
...
LL | Err(Error2)?;
| -----------^ the trait `From<Error2>` is not implemented for `dependency::Error`
| |
| this can't be annotated with `?` because it has type `Result<_, Error2>`
|
= note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
help: the trait `From<Error2>` is not implemented for `dependency::Error`
but trait `From<()>` is implemented for it
--> replaced
|
LL | impl From<()> for Error {
| ^^^^^^^^^^^^^^^^^^^^^^^
= help: for that trait implementation, expected `()`, found `Error2`
= note: there are multiple different versions of crate `dependency` in the dependency graph
= help: you can use `cargo tree` to explore your dependency tree
```
The existing checks rely on having access to the actual types/traits that diverged to detect they are called the same, come from different crates with the same name. The new check is less specific, merely looking to see if the crate name the involved type belongs has multiple crates.
mgca: Add ConstArg representation for const items
tracking issue: rust-lang/rust#132980fixesrust-lang/rust#131046fixesrust-lang/rust#134641
As part of implementing `min_generic_const_args`, we need to distinguish const items that can be used in the type system, such as in associated const equality projections, from const items containing arbitrary const code, which must be kept out of the type system. Specifically, all "type consts" must be either concrete (no generics) or generic with a trivial expression like `N` or a path to another type const item.
To syntactically distinguish these cases, we require, for now at least, that users annotate all type consts with the `#[type_const]` attribute. Then, we validate that the const's right-hand side is indeed eligible to be a type const and represent it differently in the HIR.
We accomplish this representation using a new `ConstItemRhs` enum in the HIR, and a similar but simpler enum in the AST. When `#[type_const]` is **not** applied to a const (e.g. on stable), we represent const item right-hand sides (rhs's) as HIR bodies, like before. However, when the attribute is applied, we instead lower to a `hir::ConstArg`. This syntactically distinguishes between trivial const args (paths) and arbitrary expressions, which are represented using `AnonConst`s. Then in `generics_of`, we can take advantage of the existing machinery to bar the `AnonConst` rhs's from using parent generics.
Rollup of 7 pull requests
Successful merges:
- rust-lang/rust#146573 (Constify Range functions)
- rust-lang/rust#146699 (Add `is_ascii` function optimized for LoongArch64 for [u8])
- rust-lang/rust#148026 (std: don't leak the thread closure if destroying the thread attributes fails)
- rust-lang/rust#148135 (Ignore unix socket related tests for VxWorks)
- rust-lang/rust#148211 (clippy fixes and code simplification)
- rust-lang/rust#148395 (Generalize branch references)
- rust-lang/rust#148405 (Fix suggestion when there were a colon already in generics)
r? `@ghost`
`@rustbot` modify labels: rollup
Generalize branch references
It should be safe to merge this before the rename, and I'd like to do that, so we can test if beta/stable PRs work.
r? ``@marcoieni``
"running analysis passes on this crate" -> "running analysis passes on crate `foo`"
This message is displayed in cycle errors in particular, and in some cases without any spans or any other identifiable information to determine which dependency introduced the cycle.
Issue-125323: ICE non-ADT in struct pattern when long time constant evaluation is in for loop
This PR fixes#125323
## Context
According to the issue, the ICE happens since #121206.
In the PR, some error methods were reorganized. For example, has_errors() was renamed to has_errors_exclude_lint_errors(). However, some codes which used the original has_errors() were not switched to has_errors_exclude_lint_errors(). I finally found that report_error() in writeback.rs causes this ICE. Currently the method uses tainted_by_errors() to get guar (ErrorGuaranteed), but originally it used dcx().has_errors() but it wasn't changed to has_errors_exclude_lint_errors() when changes in #121206 were merged. I don't think I fully understand how an error is propagated, but I suppose that the error from long time constant evaluation is unexpectedly propagated other parts (in this ICE, for loop), then cause the non-ADT in struct pattern ICE.
## Change
- Fix report_error() in writeback.rs: use dcx().has_errors_exclude_lint_errors() instead of tainted_by_errors() to prevent error propagation from constant evaluation.
- Add test for the ICE
- Modify some tests to align the change: Due to this fix, E0282 error happens (or not happen anymore) in some tests.
## NOTE
The 4th commit aims to revert the fix in #123516 because I confirmed that the ICE solved by the PR doesn't happen if I modify report_error(). I think the root cause of that ICE is the same as #125323 . But I can discard this commit since we can fix#125323 without it.
deduced_param_attrs: check Freeze on monomorphic types.
`deduced_param_attrs` currently checks `Freeze` bound on polymorphic MIR. This pessimizes the deduction, as generic types are not `Freeze` by default.
This moves the check to the ABI adjustment.
error from const eval lint causes ICE at check_pat in late_lint, because the function expects the typeck result isn't tainted by error but it is.
To avoid the ICE, check_pat returns earlier if the typeck_result is tainted.
check_mod_deathness also has an issue from the same reason. visit_body for making live symbols expects the typeck result has no error.
So this commit adds a check in visit_nested_body to avoid the ICE.
However, if visit_nested_body just returns without doing anything, all codes with the error are marked as dead, because live_symbols is empty.
To avoid this side effect, visit_nested_body and other visit_* functions in MarkSymbolVistior should return appropriate error.
If a function returns ControlFlow::Break, live_symbols_and_ignore_derived_traits returns earlier with error,
then check_mod_deathness, the caller of the function returns earlier without pushing everything into dead_codes.
Fix normalization overflow ICEs in monomorphization
Fixesrust-lang/rust#92004Fixesrust-lang/rust#92470Fixesrust-lang/rust#95134Fixesrust-lang/rust#105275Fixesrust-lang/rust#105937
Fixes rust-lang/rust#117696-2
Fixesrust-lang/rust#118590Fixesrust-lang/rust#122823Fixesrust-lang/rust#131342Fixesrust-lang/rust#139659
## Analysis:
The causes of these issues are similar. They contain generic recursive functions that can be instantiated with different args infinitely at monomorphization stage.
Ideally this should be caught by the [`check_recursion_limit`](https://github.com/rust-lang/rust/blob/c0bb3b98bb7aac24a37635e5d36d961e0b14f435/compiler/rustc_monomorphize/src/collector.rs#L468) function. The reality is that normalization can reach recursion limit earlier than monomorphization's check because they calculate depths in different ways.
Since normalization is called everywhere, ICEs appear in different locations.
## Fix:
If we abort on overflow with `TypingMode::PostAnalysis` in the trait solver, it would also catch these errors.
The main challenge is providing good diagnostics for them. So it's quite natural to put the check right before these normalization happening.
I first tried to check the whole MIR body's normalization and `references_error`. (As elaborate_drop handles normalization failure by [returning `ty::Error`](https://github.com/rust-lang/rust/blob/c0bb3b98bb7aac24a37635e5d36d961e0b14f435/compiler/rustc_mir_transform/src/elaborate_drop.rs#L514-L519).)
It turns out that checking all `Local`s seems sufficient.
These types are gonna be normalized anyway. So with cache, these checks shouldn't be expensive.
This fixes these ICEs for both the next and old solver, though I'm not sure the change I made to the old solver is proper. Its overflow handling looks convoluted thus I didn't try to fix it more "upstream".
Perform unused assignment and unused variables lints on MIR.
Rebase of https://github.com/rust-lang/rust/pull/101500
Fixes https://github.com/rust-lang/rust/issues/51003.
The first commit moves detection of uninhabited types from the current liveness pass to MIR building.
In order to keep the same level of diagnostics, I had to instrument MIR a little more:
- keep for which original local a guard local is created;
- store in the `VarBindingForm` the list of introducer places and whether this was a shorthand pattern.
I am not very proud of the handling of self-assignments. The proposed scheme is in two parts: first detect probable self-assignments, by pattern matching on MIR, and second treat them specially during dataflow analysis. I welcome ideas.
Please review carefully the changes in tests. There are many small changes to behaviour, and I'm not sure all of them are desirable.