Document wf constraints on control flow in cleanup blocks
Was recently made aware of [this code](a377893da2/compiler/rustc_codegen_ssa/src/mir/analyze.rs (L247-L368)), which has this potential ICE: a377893da2/compiler/rustc_codegen_ssa/src/mir/analyze.rs (L308-L314)
Roughly speaking, the code there is attempting to partition the cleanup blocks into funclets that satisfy a "unique successor" property, and the ICE is set off if that's not possible. This PR documents the well-formedness constraints that MIR must satisfy to avoid setting off that ICE.
The constraints documented are slightly stronger than the cases in which the ICE would have been set off in that code. This is necessary though, since whether or not that ICE gets set off can depend on iteration order in some graphs.
This sort of constraint is kind of ugly, but I don't know a better alternative at the moment. It's worth knowing that two important optimizations are still correct:
- Removing edges in the cfg: Fewer edges => fewer paths => stronger dominance relations => more contractions, and more contractions can't turn a forest into not-a-forest.
- Contracting an edge u -> v when u only has one successor and v only has one predecessor: u already dominated v, so this contraction was going to happen anyway.
There is definitely a MIR opt somewhere that can run afoul of this, but I don't know where it is. `@saethlin` was able to set it off though, so maybe he'll be able to shed some light on it.
r? `@RalfJung` I suppose, and cc `@tmiasko` who might have insight/opinions on this
Document `EarlyBinder::subst_identity` and `skip_binder`
Finishing implementing #105779 will change several commonly used queries to return `EarlyBinder` by default. This PR adds documentation for two of the methods used to access data inside the `EarlyBinder`. I tried to summarize some of the [discussion from the issue](https://github.com/rust-lang/rust/issues/105779#issuecomment-1375512647) in writing this.
r? `@lcnr`
Unify `Opaque`/`Projection` handling in region outlives code
They share basically identical paths in most places which are even easier to unify now that they're both `ty::Alias`
r? types
Rework some `predicates_of`/`{Generic,Instantiated}Predicates` code
1. Make `instantiate_own` return an iterator, since it's a bit more efficient and easier to work with
2. Remove `bound_{explicit,}_predicates_of` -- these `bound_` methods in particular were a bit awkward to work with since `ty::GenericPredicates` *already* acts kinda like an `EarlyBinder` with its own `instantiate_*` methods, and had only a few call sites anyways.
3. Implement `IntoIterator` for `InstantiatedPredicates`, since it's *very* commonly being `zip`'d together.
Implement some FIXME methods in the new trait solver
Implement just enough of the solver's response logic to make it not ICE.
Also, fix a bug with `no_bound_vars` call failing due to canonical bound vars.
r? `@lcnr`
Rename `Ty::is_ty_infer` -> `Ty::is_ty_or_numeric_infer`
Makes sure people are aware that they may have a type variable *or* an int/float variable.
r? `@oli-obk` https://github.com/rust-lang/rust/pull/106322#issuecomment-1376913539 but I could instead implement your solution, let me know.
(This will conflict with #106322 for now, ignore that 😄)
Polymorphization cleanup
Split out of #106233
Use a newtype instead of a bitset directly. This makes the code way easier to read and easier to adapt for future changes.
Simplify some canonical type alias names
* delete the `Canonicalized<'tcx>` type alias in favor for `Canonical<'tcx>`
* `CanonicalizedQueryResponse` -> `CanonicalQueryResponse`
I don't particularly care about the latter, but it should be consistent. We could alternatively delete the first alias and rename the struct to `Canonicalized`, and then keep the name of `CanonicalizedQueryResponse` untouched.
Projection types in user annotations may contain inference variables.
This makes the normalization depend on the unification with the actual
type and thus requires a separate TypeOp to track the obligations.
Otherwise simply calling `TypeChecker::normalize` would ICE with
"unexpected ambiguity"
Rename `hir::Map::{get_,find_}parent_node` to `hir::Map::{,opt_}parent_id`, and add `hir::Map::{get,find}_parent`
The `hir::Map::get_parent_node` function doesn't return a `Node`, and I think that's quite confusing. Let's rename it to something that sounds more like something that gets the parent hir id => `hir::Map::parent_id`. Same with `find_parent_node` => `opt_parent_id`.
Also, combine `hir.get(hir.parent_id(hir_id))` and similar `hir.find(hir.parent_id(hir_id))` function into new functions that actually retrieve the parent node in one call. This last commit is the only one that might need to be looked at closely.
Encode spans relative to the enclosing item -- enable on nightly
Follow-up to #84373 with the flag `-Zincremental-relative-spans` set by default.
This PR seeks to remove one of the main shortcomings of incremental: the handling of spans.
Changing the contents of a function may require redoing part of the compilation process for another function in another file because of span information is changed.
Within one file: all the spans in HIR change, so typechecking had to be re-done.
Between files: spans of associated types/consts/functions change, so type-based resolution needs to be re-done (hygiene information is stored in the span).
The flag `-Zincremental-relative-spans` encodes local spans relative to the span of an item, stored inside the `source_span` query.
Trap: stashed diagnostics are referenced by the "raw" span, so stealing them requires to remove the span's parent.
In order to avoid too much traffic in the span interner, span encoding uses the `ctxt_or_tag` field to encode:
- the parent when the `SyntaxContext` is 0;
- the `SyntaxContext` when the parent is `None`.
Even with this, the PR creates a lot of traffic to the Span interner, when a Span has both a LocalDefId parent and a non-root SyntaxContext. They appear in lowering, when we add a parent to all spans, including those which come from macros, and during inlining when we mark inlined spans.
The last commit changes how queries of `LocalDefId` manage their cache. I can put this in a separate PR if required.
Possible future directions:
- validate that all spans are marked in HIR validation;
- mark macro-expanded spans relative to the def-site and not the use-site.
Some `compare_method` tweaks
1. Make some of the comparison functions' names more regular
2. Reduce pub scope of some of the things in `compare_method`
~3. Remove some unnecessary opaque type handling code -- `InferCtxt` already is in a mode that doesn't define opaque types~
* moved to a different PR
4. Bubble up `ErrorGuaranteed` for region constraint errors in `compare_method` - Improves a redundant error message in one unit test.
5. Move the `compare_method` module to have a more general name, since it's more like `compare_impl_item` :)
6. Rename `collect_trait_impl_trait_tys`
Rollup of 6 pull requests
Successful merges:
- #105661 (implement the skeleton of the updated trait solver)
- #105853 (Make the pre-push script work on directories with spaces)
- #106043 (Move tests)
- #106048 (Run `tidy` in its own job in PR CI)
- #106055 (Check arg expressions properly on error in `confirm_builtin_call`)
- #106067 (A few metadata nits)
Failed merges:
r? `@ghost`
`@rustbot` modify labels: rollup
implement the skeleton of the updated trait solver
cc ```@rust-lang/initiative-trait-system-refactor```
This is mostly following the architecture discussed in the types team meetup.
After discussing the desired changes for the trait solver, we encountered cyclic dependencies between them. Most notably between changing evaluate to be canonical and returning inference constraints. We cannot canonicalize evaluate without returning inference constraints due to coinductive cycles. However, caching inference constraints also relies on canonicalization. Implementing both of these changes at once in-place is not feasible.
This somewhat closely mirrors the current `evaluate` implementation with the following notable differences:
- it moves `project` into the core solver, allowing us to correctly deal with coinductive projections (will be required for implied bounds, perfect derive)
- it changes trait solver overflow to be non-fatal (required to backcompat breakage from changes to the iteration order of nested goals, deferred projection equality, generally very useful)
- it returns inference constraints and canonicalizes inputs and outputs (required for a lot things, most notably merging fulfill and evaluate, and deferred projection equality)
- it is implemented to work with lazy normalization
A lot of things aren't yet implemented, but the remaining FIXMEs should all be fairly self-contained and parallelizable. If the architecture looks correct and is what we want here, I would like to quickly merge this and then split the work.
r? ```@compiler-errors``` / ```@rust-lang/types``` :3
Retag as FnEntry on `drop_in_place`
This commit changes the mir drop shim to always retag its argument as if it were a `&mut`.
cc rust-lang/unsafe-code-guidelines#373
Clarify that raw retags are not permitted in Mir
Not sure when this changed, but documentation and the validator needed to be updated. This also removes raw retags from custom mir.
cc rust-lang/miri#2735
r? `@RalfJung`
Avoid going through the happy path in case of non-fn builtin calls
No functional change, just doing an early return. The removed comment is not applicable anymore, not every node needs type bindings in the error case. At best this would have been needed to avoid ICEs, but afaict this can't happen anymore today, as we do fallible checks.