Commit Graph

49 Commits

Author SHA1 Message Date
Slava Pestov
3cfbe037ee RequirementMachine: Simplify getTypeForSymbolRange() a bit 2022-03-29 00:43:41 -04:00
Slava Pestov
2f727d6b47 RequirementMachine: Opaque archetype support (sort of)
Complete support is behind a flag, because it can result in a non-convergent
rewrite system if the opaque result type has a recursive conformance of its
own (eg, `some View` for SwiftUI's View protocol).

Without the flag, it's good enough for simple examples; you just can't have
a requirement that mentions a nested type of a type parameter equated to
the concrete type.

Fixes rdar://problem/88135291, https://bugs.swift.org/browse/SR-15983.
2022-03-17 17:45:59 -04:00
Slava Pestov
4d531aea9c RequirementMachine: Remove PropertyMap::ConcreteConformances 2022-03-17 17:45:52 -04:00
Slava Pestov
93727490df RequirementMachine: Remove old PropertyMap::unifyConcreteTypes() 2022-02-17 19:40:58 -05:00
Slava Pestov
b90dae1f15 RequirementMachine: Unify every pair of superclass requirements that apply to a term 2022-02-17 19:40:58 -05:00
Slava Pestov
2f16ca38e5 RequirementMachine: Unify every pair of concrete type rules that apply to a term
Instead of keeping track of the best one so far, and unifying subsequent rules
against it.

This allows us to record more identities, fixing a regression from an earlier
change where we were unable to eliminate an obviously-redundant rule.
2022-02-17 19:40:58 -05:00
Slava Pestov
ef1292e1ce RequirementMachine: Don't filter out redundant superclass conformances when building archetypes
This was a hack to maintain exact compatibility with the GSB's
results when constructing archetypes, but it no longer appears
to be necessary.
2022-02-17 19:40:58 -05:00
Slava Pestov
12ba9bf1ab RequirementMachine: Move processTypeDifference() method and friends from PropertyMap to RewriteSystem 2022-02-15 04:02:46 -05:00
Slava Pestov
c6119acb8f RequirementMachine: Generalize concrete unification a bit to allow sharing code with concrete simplification 2022-02-15 04:02:46 -05:00
Slava Pestov
2e3cb17666 RequirementMachine: Refactor concrete substitution pass 2022-02-15 04:02:46 -05:00
Slava Pestov
e445335eb3 RequirementMachine: Record rewrite loops during superclass unification
This is the second half of rdar://problem/88134910.

Also addresses rdar://problem/25065503.
2022-02-09 22:44:06 -05:00
Slava Pestov
94b55bd408 RequirementMachine: Factor out PropertyMap::unifyConcreteTypes() from ::addConcreteTypeProperty() 2022-02-09 16:49:24 -05:00
Slava Pestov
60db9174e6 RequirementMachine: Factor out PropertyMap::processTypeDifference() 2022-02-07 08:20:59 -05:00
Slava Pestov
00d226fd2f RequirementMachine: Store the base term in the TypeDifference 2022-02-07 08:20:59 -05:00
Slava Pestov
634ca55764 RequirementMachine: Rework completion limits a bit
- 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()
2022-02-07 08:20:59 -05:00
Slava Pestov
730941b3ea RequirementMachine: Implement PropertyMap::concretelySimplifyLeftHandSideSubstitutions() 2022-02-07 08:20:58 -05:00
Slava Pestov
0c777e7534 RequirementMachine: Split up PropertyMap::addProperty() 2022-02-07 08:20:58 -05:00
Slava Pestov
4f3d05f502 RequirementMachine: Remove Symbol::getSuperclass() 2022-02-04 22:47:19 -05:00
Slava Pestov
eb9f12109e RequirementMachine: Conditional requirement inference
If a type parameter is subject to both a conformance requirement
and a concrete type requirement, the concrete type might conform
conditionally.

In this case, introduce new requirements to satisfy the conditional
conformance.

Since this can add new hitherto-unseen protocols to the rewrite
system, restrict this feature to top-level generic signatures, and
not protocol requirement signatures. Allowing this to occur in
protocol requirement signatures would change the connectivity of
the protocol dependency graph (and hence the connected components)
during completion, which would be a major complication in the
design. The GSB already enforces this restriction.

I changed the existing conditional_requirement_inference.swift test
to run with -requirement-machine-inferred-signatures=verify. Since
one of the test cases there triggers an unrelated bug in the
Requirement Machine, I split it off into a new file named
conditional_requirement_inference_2.swift which still runs with
the GSB. Once the bug is fixed I'll merge the files again.
2022-01-25 00:35:16 -05:00
Slava Pestov
41e3292015 RequirementMachine: Remove 'induced rules' mechanism from the property map 2022-01-25 00:35:11 -05:00
Slava Pestov
275af8d0fd RequirementMachine: getTypeForSymbolRange() maps canonical terms to canonical types
Previously this would only be true with merged associated types,
but I want to get rid of those.
2022-01-20 14:18:25 -05:00
Slava Pestov
8468c14dbc RequirementMachine: Add overload of PropertyMap::lookUpProperties() that takes a pair of iterators 2022-01-20 12:48:48 -05:00
Slava Pestov
fa30159130 RequirementMachine: Move term to type methods from RewriteContext to PropertyMap 2022-01-20 00:18:47 -05:00
Slava Pestov
f674ca95bd RequirementMachine: Remove the older 'concrete type in domain' hack 2022-01-11 21:43:56 -05:00
Slava Pestov
a3c230e436 RequirementMachine: PropertyBag::{getConcreteType,getSuperclassBound}() should return CanType 2022-01-11 21:43:55 -05:00
Slava Pestov
9bb497c866 RequirementMachine: Concrete class requirements imply superclass requirements 2022-01-05 22:41:03 -05:00
Slava Pestov
be772cc74b RequirementMachine: Layout requirement implied by superclass is now handled in the property map 2022-01-05 22:41:03 -05:00
Slava Pestov
5ced0f8c2e RequirementMachine: Avoid some wasted work when re-building the property map 2022-01-05 22:41:03 -05:00
Slava Pestov
380dba1a9f RequirementMachine: Fold PropertyBag::addProperty() into PropertyMap::addProperty() 2022-01-05 22:41:03 -05:00
Slava Pestov
66cf913d68 RequirementMachine: Minimization understands 'relations' among layout requirements
A superclass requirement 'T : C' implies a layout requirement
'T : AnyObject' (if the class is @objc) or 'T : _NativeObject'
(if the class is not @objc).

In the latter case, there might already be a 'T : AnyObject'
requirement, in which case the type parameter 'T' is subject
to two layout requirements:

    T : AnyObject
    T : _NativeObject

The second requirement implies the first however. To encode this
in the world of rewrite loops, we the notion of a 'relation'
between property symbols, and a 'Relation' rewrite step.

Here, the relation is that _NativeObject < AnyObject. Once this
relation is recorded, the Relation rewrite step will transform

    T.[layout: _NativeObject].[layout: AnyObject]

into

    T.[layout: _NativeObject]

and vice versa.

This rewrite step allows us to construct a rewrite loop which
makes the first rewrite rule redundant via the second.
2022-01-04 22:35:58 -05:00
Slava Pestov
5c11f36354 RequirementMachine: Mark rules as conflicting more aggressively 2021-12-20 17:59:31 -05:00
Slava Pestov
22816b0b41 RequirementMachine: Skip more work in concretizeNestedTypesFromConcreteParent() 2021-12-17 10:04:51 -05:00
Slava Pestov
5a2b19393c RequirementMachine: Refactor PropertyMap::computeConstraintTermForTypeWitness() 2021-12-14 02:16:46 -05:00
Slava Pestov
17664c0c59 RequirementMachine: Use RewriteStep::ConcreteTypeWitness in nested type concretization 2021-12-14 02:16:46 -05:00
Slava Pestov
56fb3cc937 RequirementMachine: Refactor nested type concretization a bit 2021-12-13 18:48:48 -05:00
Slava Pestov
d25b0db75c RequirementMachine: Fold recordConcreteConformanceRules() into concretizeNestedTypesFromConcreteParent() 2021-12-13 18:48:48 -05:00
Slava Pestov
d07812e479 RequirementMachine: Factor out PropertyMap::concretizeTypeWitnessInConformance() 2021-12-13 18:48:48 -05:00
Slava Pestov
7a56ab8c18 RequirementMachine: Mark conflicting rules
This isn't quite right, because we really want the longer (more
specific) of the two rules to be conflicting, not the most-recently
added rule.
2021-12-13 18:48:23 -05:00
Slava Pestov
d1cda342ed RequirementMachine: Property map construction introduces concrete conformance rules 2021-12-07 15:31:47 -05:00
Slava Pestov
2aab4bb773 RequirementMachine: Stub out logic for property map to record rewrite loops
For homotopy reduction to properly deal with new rules introduced
while bulding the property map, rewrite loops must be recorded
relating these to existing rules.
2021-12-07 15:31:45 -05:00
Slava Pestov
e9b50f00f2 RequirementMachine: Record property rule IDs in property bags
For homotopy reduction to properly deal with rewrite rules
introduced by property map construction, we need to keep
track of the original property rules when recording properties
in property bags.

For now, this doesn't even attempt to handle unification or
conflicts; we only record the first rule for each kind of
property on a fixed key.

This isn't actually used for anything yet, except a new
verify pass that runs after property map construction.
2021-12-06 23:04:46 -05:00
Slava Pestov
5ac83e2819 RequirementMachine: Move buildPropertyMap() from RewriteSystem to PropertyMap
Now that the property map stores a reference to the RewriteSystem,
defining the buildPropertyMap() method on PropertyMap feels cleaner,
and allows more of the property map's internals to be private.
2021-11-01 22:51:26 -04:00
Slava Pestov
0571b65cb8 RequirementMachine: Move protocol linear order from ProtocolGraph to RewriteContext 2021-10-21 19:00:10 -04:00
Slava Pestov
4d5e641b4e RequirementMachine: Store the rewrite system in the property map 2021-10-10 00:20:19 -04:00
Slava Pestov
399a600e32 RequirementMachine: Add -debug-requirement-machine= flag to control debug output 2021-08-20 01:29:22 -04:00
Slava Pestov
9738d4eef6 RequirementMachine: PropertyMap can use Terms instead of MutableTerms as keys
Also, we don't have to sort rules in term order before adding them to
the map; a bucket sort by term length is sufficient.
2021-08-06 14:17:20 -04:00
Slava Pestov
47fc3d87ad RequirementMachine: Speed up PropertyMap lookups with a suffix trie
Whereas term simplification uses a prefix trie with shortest matching,
the PropertyMap uses a suffix trie with longest matching.
2021-08-06 14:17:20 -04:00
Slava Pestov
9a8ee6017a RequirementMachine: Fix silly oversight when resolving concrete types and superclass bounds
The property map stores the concrete type or superclass bound for all
terms whose suffix is equal to some key, so eg if you have

  protocol P {
    associatedtype T where T == U?
    associatedtype U
  }

Then you have this rewrite system

  [P].T => [P:T]
  [P].U => [P:U]
  [P:T].[concrete: Optional<τ_0_0> with <[P:U]>] => [P:T]

Which creates this property map

  [P:T] => { [concrete: Optional<τ_0_0> with <[P:U]>] }

Now if I start with a generic signature like

  <T, U where U : P>

This produces the following rewrite system:

  τ_0_1.[U] => τ_0_1
  τ_0_1.T => τ_0_1.[P:T]
  τ_0_1.U => τ_0_1.[P:U]

Consider the computation of the canonical type of τ_0_1.T. This term
reduces to τ_0_1.[P:T]. The suffix [P:T] has a concrete type symbol in
the property map, [concrete: Optional<τ_0_0> with <[P:U]>].

However it would not be correct to canonicalize τ_0_1.[P:T] to
Optional<τ_0_0>.subst { τ_0_0 => getTypeForTerm([P:T]) }; this
produces the type Optional<τ_0_0.T>, and not Optional<τ_0_1.T> as
expected.

The reason is that the substitution τ_0_0 => getTypeForTerm([P:T])
is "relative" to the protocol Self type of P, since domain([P:T]) = {P}.

Indeed, the right solution here is to note that τ_0_1.[P:T] has a suffix
equal to the key of the property map entry, [P:T]. If we strip off the
suffix, we get τ_0_1. If we then prepend τ_0_1 to the substitution term,
we get the term τ_0_1.[P:U], whose canonical type is τ_0_1.U.

Now, applying the substitution τ_0_0 => τ_0_1.U to Optional<τ_0_0>
produces the desired result, Optional<τ_0_1.U>.

Note that this is the same "prepend a prefix to each substitution of
a concrete type symbol" operation that is performed in checkForOverlap()
and PropertyBag::copyPropertiesFrom(), however we can simplify things
slightly by open-coding it instead of calling the utility method
prependPrefixToConcreteSubstitutions(), since the latter creates a
new symbol, which we don't actually need.
2021-08-04 01:21:21 -04:00
Slava Pestov
d3db1b6753 RequirementMachine: EquivalenceClassMap => PropertyMap
EquivalenceClass is now PropertyBag.
2021-07-23 17:21:57 -04:00