generate fewer basic blocks for variant switches
CC #33567
Adds a new field to TestKind::Switch that tracks the variants that are actually matched against. The other candidates target a common "otherwise" block.
Replace the obligation forest with a graph
In the presence of caching, arbitrary nodes in the obligation forest can be merged, which makes it a general graph. Handle it as such, using cycle-detection algorithms in the processing.
I should do performance measurements sometime.
This was pretty much written as a proof-of-concept. Please help me write this in a less-ugly way. I should also add comments explaining what is going on.
r? @nikomatsakis
Improve time complexity of equality relations
This PR adds a `UnificationTable` to the `TypeVariableTable` type which is used store information about variable equality instead of just storing them in a vector for later processing. By using a `UnificationTable` equality relations can be resolved in O(n) (for all realistic values of n) rather than O(n!) which can give massive speedups in certain cases (see combine as an example).
Link to combine: https://github.com/Marwes/combine
This PR adds a `UnificationTable` to the `TypeVariableTable` type which
is used store information about variable equality instead of just
storing them in a vector for later processing. By using a
`UnificationTable` equality relations can be resolved in O(n) (for all
realistic values of n) rather than O(n!) which can give massive
speedups in certain cases (see combine as an example).
Link to combine: https://github.com/Marwes/combine
projection sensitive to "mode" (most importantly, trans vs middle).
This commit introduces several pieces of iteration infrastructure in the
specialization graph data structure, as well as various helpers for
finding the definition of a given item, given its kind and name.
In addition, associated type projection is now *mode-sensitive*, with
three possible modes:
- **Topmost**. This means that projection is only possible if there is a
non-`default` definition of the associated type directly on the
selected impl. This mode is a bit of a hack: it's used during early
coherence checking before we have built the specialization
graph (and therefore before we can walk up the specialization
parents to find other definitions). Eventually, this should be
replaced with a less "staged" construction of the specialization
graph.
- **AnyFinal**. Projection succeeds for any non-`default` associated
type definition, even if it is defined by a parent impl. Used
throughout typechecking.
- **Any**. Projection always succeeds. Used by trans.
The lasting distinction here is between `AnyFinal` and `Any` -- we wish
to treat `default` associated types opaquely for typechecking purposes.
In addition to the above, the commit includes a few other minor review fixes.
Right now the primary hashing algorithm of the compiler isn't actually inlined
across crates, meaning that it may be missing out on some crucial optimizations
in a few places (perhaps unrolling smaller loops, etc).
This commit made the hashing function disappear from a profiled version of the
compiler, but that's likely because it was just inlined elsewhere. When
compiling winapi, however, this decreased compile time from 18.3 to 17.8 seconds
(a 3% improvement).
Have the `ObligationForest` keep some per-tree state (or type `T`) and have it give a mutable reference for use when processing obligations. In this case, it will be a hashmap. This obviously affects the work that @soltanmm has been doing on snapshotting. I partly want to toss this out there for discussion.
Fixes#31157. (The test in question goes to approx. 30s instead of 5 minutes for me.)
cc #30977.
cc @aturon @arielb1 @soltanmm
r? @aturon who reviewed original `ObligationForest`
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.
Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
This commit implements the stabilization of the custom hasher support intended
for 1.7 but left out due to some last-minute questions that needed some
decisions. A summary of the actions done in this PR are:
Stable
* `std:#️⃣:BuildHasher`
* `BuildHasher::Hasher`
* `BuildHasher::build_hasher`
* `std:#️⃣:BuildHasherDefault`
* `HashMap::with_hasher`
* `HashMap::with_capacity_and_hasher`
* `HashSet::with_hasher`
* `HashSet::with_capacity_and_hasher`
* `std::collections::hash_map::RandomState`
* `RandomState::new`
Deprecated
* `std::collections::hash_state`
* `std::collections::hash_state::HashState` - this trait was also moved into
`std::hash` with a reexport here to ensure that we can have a blanket impl to
prevent immediate breakage on nightly. Note that this is unstable in both
location.
* `HashMap::with_hash_state` - renamed
* `HashMap::with_capacity_and_hash_state` - renamed
* `HashSet::with_hash_state` - renamed
* `HashSet::with_capacity_and_hash_state` - renamed
Closes#27713
This commit implements the stabilization of the custom hasher support intended
for 1.7 but left out due to some last-minute questions that needed some
decisions. A summary of the actions done in this PR are:
Stable
* `std:#️⃣:BuildHasher`
* `BuildHasher::Hasher`
* `BuildHasher::build_hasher`
* `std:#️⃣:BuildHasherDefault`
* `HashMap::with_hasher`
* `HashMap::with_capacity_and_hasher`
* `HashSet::with_hasher`
* `HashSet::with_capacity_and_hasher`
* `std::collections::hash_map::RandomState`
* `RandomState::new`
Deprecated
* `std::collections::hash_state`
* `std::collections::hash_state::HashState` - this trait was also moved into
`std::hash` with a reexport here to ensure that we can have a blanket impl to
prevent immediate breakage on nightly. Note that this is unstable in both
location.
* `HashMap::with_hash_state` - renamed
* `HashMap::with_capacity_and_hash_state` - renamed
* `HashSet::with_hash_state` - renamed
* `HashSet::with_capacity_and_hash_state` - renamed
Closes#27713
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.
Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
Turns out that calling `resolve_type_variables_if_possible` in a O(n^2)
loop is a bad idea. Now we just resolve each copy of the region variable
to its lowest name each time (we resolve the region variable to its lowest
name, rather than to its unify-table name to avoid the risk of
the unify-table name changing infinitely many times. That may be
not a problem in practice, but I am not sure of it).