Skip to content

Conversation

@slavapestov
Copy link
Contributor

@slavapestov slavapestov commented Feb 2, 2022

The property map performed unification of concrete type terms, so that for example if you had T == G<Int> and T == G<U>, we would infer that U == Int. This worked for generic signature queries, however minimization did not understand concrete type unification because the new rules were not given a rewrite path expressing them in terms of existing rules.

In our example, any two of the requirements T == G<Int>, T == G<U> and U == Int imply the third. This means we need rewrite loops relating them. There are two loops:

  1. The first loop has U == Int in empty context, and T == G<Int> and T == G<U> in non-empty context. This means if chosen, the first loop allows U == Int to be eliminated.
  2. The second loop has T == G<Int> and T == G<U> in empty context, with U == Int appearing in context. This means that if chosen, the second loop allows either of those two rules can be eliminated.

The first loop is introduced when property unification records the rule U == Int.

The second loop is introduced by a new simplification pass that runs after property map construction. This pass replaces type parameters with concrete types in concrete type rules, so for example T == G<U> is simplified down to T == G<Int>. This will record the new rule T == G<Int> if it doesn't exist already, and record a rewrite loop relating T == G<Int> and T == G<U>.

A priori, there's no reason for homotopy reduction to pick either T == G<Int> or T == G<U> over the other for elimination, however the simplification pass marks T == G<U> as simplified, which means we try to eliminate it earlier.

The relation between two different instantiations of a concrete type symbol, like G<U> and G<Int> is recorded in a new uniqued TypeDifference object in the RewriteSystem. The TypeDifference describes a set of transformations for converting a less-specific left hand side (G<U>) into a more-specific right hand side (G<Int>) via a series of concrete type rules (in this case, U == Int).

The new LeftConcreteProjection and RightConcreteProjection rewrite steps relate the left hand side and right hand side of an induced rule with the two concrete type rules that induced it. This rewrite step kind appears in the first type of rewrite loop described above.

The new DecomposeConcrete rewrite step kind transforms the left hand side of a TypeDifference into the right hand side, or vice versa. This rewrite step kind appears in the second type of rewrite loop described above.

This is the concrete type part of rdar://problem/88134910. Superclass unification still needs additional work to model intersections between a derived class and a base class.

@slavapestov slavapestov force-pushed the concrete-unification-vs-rewrite-loop branch 5 times, most recently from c9e3a5f to 9549444 Compare February 4, 2022 22:00
@slavapestov
Copy link
Contributor Author

@swift-ci Please test source compatibility

@slavapestov slavapestov force-pushed the concrete-unification-vs-rewrite-loop branch 4 times, most recently from a3ada4e to da94bf0 Compare February 6, 2022 06:10
@slavapestov slavapestov marked this pull request as ready for review February 6, 2022 06:10
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor Author

@swift-ci Please test source compatibility

@slavapestov slavapestov force-pushed the concrete-unification-vs-rewrite-loop branch from da94bf0 to abeeb79 Compare February 7, 2022 05:24
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

…o use computeTypeDifference()

This doesn't record rewrite loops from most concrete unifications just yet,
only handling a case where two concrete types were identical except for an
adjustment.
- Rename StepLimit to MaxRuleCount, DepthLimit to MaxRuleLength
- Rename command line flags to -requirement-machine-max-rule-{count,length}=
- Check limits outside of PropertyMap::buildPropertyMap()
- Simplify the logic in RequirementMachine::computeCompletion()
Configured with -requirement-machine-max-concrete-nesting= frontend flag.
… rule if completion failed

This surfaces an implementation detail, but it might be better
than nothing.
@slavapestov slavapestov force-pushed the concrete-unification-vs-rewrite-loop branch from abeeb79 to 729dfc7 Compare February 7, 2022 13:21
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant