uniquify root goals during HIR typeck
We need to rely on region identity to deal with hangs such as https://github.com/rust-lang/trait-system-refactor-initiative/issues/210 and to keep the current behavior of `fn try_merge_responses`.
This is a problem as borrowck starts by replacing each *occurrence* of a region with a unique inference variable. This frequently splits a single region during HIR typeck into multiple distinct regions. As we assume goals to always succeed during borrowck, relying on two occurances of a region being identical during HIR typeck causes ICE. See the now fixed examples in https://github.com/rust-lang/trait-system-refactor-initiative/issues/27 and rust-lang/rust#139409.
We've previously tried to avoid this issue by always *uniquifying* regions when canonicalizing goals. This prevents caching subtrees during canonicalization which resulted in hangs for very large types. People rely on such types in practice, which caused us to revert our attempt to reinstate `#[type_length_limit]` in https://github.com/rust-lang/rust/pull/127670. The complete list of changes here:
- rust-lang/rust#107981
- rust-lang/rust#110180
- rust-lang/rust#114117
- rust-lang/rust#130821
After more consideration, all occurrences of such large types need to happen outside of typeck/borrowck. We know this as we already walk over all types in the MIR body when replacing their regions with nll vars.
This PR therefore enables us to rely on region identity inside of the trait solver by exclusively **uniquifying root goals during HIR typeck**. These are the only goals we assume to hold during borrowck. This is insufficient as type inference variables may "hide" regions we later uniquify. Because of this, we now stash proven goals which depend on inference variables in HIR typeck and reprove them after writeback. This closes https://github.com/rust-lang/trait-system-refactor-initiative/issues/127.
This was originally part of rust-lang/rust#144258 but I've moved it into a separate PR. While I believe we need to rely on region identity to fix the performance issues in some way, I don't know whether rust-lang/rust#144258 is the best approach to actually do so. Regardless of how we deal with the hangs however, this change is necessary and desirable regardless.
r? `@compiler-errors` or `@BoxyUwU`
MIR-build: No longer emit assumes in enum-as casting
This just uses the `valid_range` from the backend, so it's duplicating the range metadata that now we include on parameters and loads, and thus no longer seems to be useful -- notably there's no codegen test failures from removing it.
(Because it's using data from the same source as the backend annotations, it doesn't do anything to mitigate things like rust-lang/rust#144388 where the range in the layout is more permissive than the actual possible discriminants. A variant of this that actually checked the discriminants more specifically might be useful, so could potentially be added in future, but I don't think the *current* checks are actually providing value.)
r? mir
Randomly turns out that this
Fixes https://github.com/rust-lang/rust/issues/121097
Store the type of each GVN value
MIR is fully typed, so type information is an integral part of what defines a value. GVN currently tries to circumvent storing types, which creates all sorts of complexities.
This PR stores the type along with the enum `Value` when defining a value index. This allows to simplify a lot of code.
Fixesrust-lang/rust#128094Fixesrust-lang/rust#135128
r? ``````@ghost`````` for perf
Dont collect assoc ty item bounds from trait where clause for host effect predicates
For background, we uplift `where Self::Assoc: Trait` bounds in a trait's where clauses into *item bounds* on `type Assoc;`. This is because before we *had* syntactical item bounds, users would express their item bounds like so.
Let's opt out of doing this same behavior for `HostEffect` predicates like `where Self::Assoc: [const] Trait`. I left a comment in the code:
```rust
// FIXME(const_trait_impl): We *could* uplift the
// `where Self::Assoc: [const] Trait` bounds from the parent trait
// here too, but we'd need to split `const_conditions` into two
// queries (like we do for `trait_explicit_predicates_and_bounds`)
// since we need to also filter the predicates *out* of the const
// conditions or they lead to cycles in the trait solver when
// utilizing these bounds. For now, let's do nothing.
```
As an aside, this was an ICE that was only triggerable when building libraries and not binaries because we never were calling `tcx.ensure_ok().explicit_implied_const_bounds(def_id);` on associated types like we should have been. I adjusted the calls to `ensure_ok` to make sure this happens, so we catch bugs like this in the future more easily.
As another aside, I fixed the bound uplifting logic for *always const* predicates, since those act like normal clauses and have no notion of conditional constness.
r? ```@oli-obk``` ```@fee1-dead``` or anyone really
Fixesrust-lang/rust#133275
[perf] Compute hard errors without diagnostics in impl_intersection_has_impossible_obligation
First compute hard errors without diagnostics, then ambiguities with diagnostics since we need to know if any of them overflowed.
Don't give APITs names with macro expansion placeholder fragments in it
The `DefCollector` previously called `pprust::ty_to_string` to construct a name for APITs (arg-position impl traits). The `ast::Ty` that was being formatted however has already had its macro calls replaced with "placeholder fragments", which end up rendering like `!()` (or ICEing, in the case of rust-lang/rust#140333, since it led to a placeholder struct field with no name).
Instead, collect the name of the APIT *before* we visit its macros and replace them with placeholders in the macro expander. This makes the implementation a bit more involved, but AFAICT there's no better way to do this since we can't do a reverse mapping from placeholder fragment -> original macro call AST.
Fixesrust-lang/rust#140333
We have fairly different error messages now and handle more cases,
so we augment the test in tests/ui/abi/unsupported.rs with more examples
to handle structs, traits, and impls on same when those feature
the unsupported ABIs of interest.
Only traverse reachable blocks in JumpThreading.
Fixes https://github.com/rust-lang/rust/issues/131451
We only compute loop headers for reachable blocks. We shouldn't try to perform an opt on unreachable blocks anyway.
Don't build `ParamEnv` and do trait solving in `ItemCtxt`s when lowering IATs
Fixesrust-lang/rust#108491Fixesrust-lang/rust#125879
This was due to updating inhabited predicate stuff which I had to do to make constructing ADTs with IATs in fields not ICE
Fixesrust-lang/rust#136678 (but no test added, I don't rly care about weird IAT edge cases under GCE)
Fixesrust-lang/rust#138131
Avoids doing "fully correct" candidate selection for IATs during hir ty lowering when in item signatures as it almost always leads to a query cycle from trying to build a `ParamEnv`. I replaced it with a use `DeepRejectCtxt` which should be able to handle this kind of conservative "could these types unify" while in a context where we don't want to do type equality.
This is a relatively simple scheme and should be forwards compatible with doing something more complex/powerful.
I'm not really sure how this interacts with rust-lang/rust#126651, though I'm also not really sure its super important to support projecting IATs from IAT self types given we don't even support `T::Assoc::Other` for trait-associated types so didn't give much thought to how this might fit in with that.
r? `@compiler-errors`
cc `@fmease`
Unimplement unsized_locals
Implements https://github.com/rust-lang/compiler-team/issues/630
Tracking issue here: https://github.com/rust-lang/rust/issues/111942
Note that this just removes the feature, not the implementation, and does not touch `unsized_fn_params`. This is because it is required to support `Box<dyn FnOnce()>: FnOnce()`.
There may be more that should be removed (possibly in follow up prs)
- the `forget_unsized` function and `forget` intrinsic.
- the `unsized_locals` test directory; I've just fixed up the tests for now
- various codegen support for unsized values and allocas
cc ``@JakobDegen`` ``@oli-obk`` ``@Noratrieb`` ``@programmerjake`` ``@bjorn3``
``@rustbot`` label F-unsized_locals
Fixesrust-lang/rust#79409
deduplicate the rest of AST walker functions
After this, we can tidy things up and deduplicate the visitor traits themselves too.
Fixesrust-lang/rust#139825, apparently
r? ``@oli-obk``
Remove CollectItemTypesVisitor
I always felt like we were very unnecessarily walking the HIR, let's see if perf agrees
There is lots to ~~improve~~ consolidate further here, as we still have 3 item wfchecks:
* check_item (matching on the hir::ItemKind)
* actually doing trait solver based checks (by using HIR spans)
* lower_item (matching on the hir::ItemKind after loading it again??)
* just ensure_ok-ing a bunch of queries
* check_item_type (matching on DefKind)
* some type based checks, mostly ensure_ok-ing a bunch of queries
fixesrust-lang/rust#121429
Fix for async drop inside async gen fn
Return value (for yield) is corrected for async drop inside async gen function.
In CFG, when internal async drop future is polled and returned `Poll<()>::Pending`, then async gen resume function returns `Poll<(OptRet)>::Pending`.
Fixesrust-lang/rust#140530