Commit Graph

840 Commits

Author SHA1 Message Date
Slava Pestov
aa210d29ae RequirementMachine: Prefer to eliminate concrete type requirements over superclass requirements again
If you have something like this:

    protocol P {
      associatedtype A : Q where Self == Self.A.B
    }

    protocol Q {
      associatedtype B
    }

    class C : P {
      typealias A = D
    }

    class D : P {
      typealias B = C
    }

The GSB would minimize the generic signature <T where T : P, T : C>
to <T where T == C>, because of the same-type requirement in
protocol P.

However in reality, the conformance 'C : P' is unsound, because it
is no longer covariant. I added a warning in commit d831eff74879cb.

Because the upcoming 'concrete contraction' pass eliminates 'T : P'
before homotopy reduction gets a chance to run, I'm changing the
Requirement Machine to produce a different minimization from the
GSB. This is technically an ABI break, but it should not impact any
real code in practice. If it does, I'll need to come up with a
different workaround in concrete contraction.
2022-02-25 11:48:38 -05:00
Slava Pestov
ae1ef6d50d RequirementMachine: Eliminate RequirementMachine::initWithAbstractRequirements() 2022-02-23 00:20:57 -05:00
Slava Pestov
e326c01f9b RequirementMachine: Write some comments 2022-02-23 00:20:57 -05:00
Slava Pestov
a3ab5f4cd4 RequirementMachine: Remove no-longer used DebugFlags::Merge 2022-02-23 00:17:56 -05:00
Slava Pestov
c75337c986 RequirementMachine: Remove lookupMemberType() in favor of existing substBaseType() 2022-02-18 22:24:25 -05:00
Slava Pestov
d7f8f2067a Sema: Generalize ProtocolDecl::getPrimaryAssociatedType() to ProtocolDecl::getPrimaryAssociatedTypes() 2022-02-18 22:24:25 -05:00
Slava Pestov
7e5d6f4cb0 AST: Rework ParameterizedProtocolTypes to store multiple argument types
For now, this is NFC since we still assume one argument elsewhere.
2022-02-18 18:22:20 -05:00
Slava Pestov
a69ac78482 RequirementMachine: Rework PropertyMap::recordConflict() for GSB compatibility
We want to prefer explicit rules when an explicit rule and non-explicit
rule conflict. Since the explicit bit hasn't been computed yet when
building the property map, save conflicting rule pairs in a side table,
and then process them later in homotopy reduction.

The side table will also be useful for diagnostics later.
2022-02-17 19:40:58 -05:00
Slava Pestov
966620bbaa RequirementMachine: Swap reduction order of ConcreteType and Superclass symbols
This ensures we produce the same minimal signature as the GSB
in a couple of really silly examples where a superclass requirement
and a concrete type requirement imply each other.
2022-02-17 19:40:58 -05: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
ee410b4fe3 RequirementMachine: Another elimination order hack 2022-02-17 19:40:58 -05:00
Slava Pestov
86d47d951d RequirementMachine: Re-visit substitution-simplified rules for concrete unification 2022-02-17 19:40:58 -05:00
Slava Pestov
46d07fc739 RequirementMachine: Add new assertion to ConcreteTypeMatcher::verify() 2022-02-17 19:40:58 -05:00
Slava Pestov
e8503021fd RequirementMachine: Add a check to RewriteSystem::verifyMinimizedRules() 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
6509eff0f2 Merge pull request #41412 from slavapestov/rqm-preserve-redundant-rule-paths
RequirementMachine: Preserve replacement paths for redundant rules
2022-02-16 22:26:50 -05:00
Slava Pestov
991fe1dbd8 RequirementMachine: Preserve replacement paths for redundant rules 2022-02-16 16:28:08 -05:00
Slava Pestov
5404754cb7 RequirementMachine: More concise printed output for concrete type and superclass symbols
Types cannot contain Terms, so the Symbol representation uses
GenericTypeParameterTypes whose index refers to an array of
"substitution" Terms.

We can (ab)use the PrintOptions.AlternateTypeNames mechanism
to print those GenericTypeParamTypes as if they were Terms.
2022-02-16 16:27:40 -05:00
Holly Borla
1dddd9c047 [RequirementMachine] Move gating emitting diagnostics on the requirement
macine flags to callers.

Callers gate this decision on different flags; InferredGenericSignatureRequestRQM
needs RequirementMachineInferredSignatures to be enabled, and the other
callsites need RequirementMachineProtocolSignatures to be enabled.
2022-02-16 13:11:57 -08:00
Holly Borla
04a91fe61d [RequirementMachine] Suppress requirement diagnostics when one of the
types already has an error.
2022-02-16 13:11:57 -08:00
Holly Borla
d5814ae3e5 [RequirementMachine] Only emit a redundancy warning for layout constraints
if the type is constrained to a class layout, and add a few more test cases
for type requirement conflicts.
2022-02-16 13:11:57 -08:00
Holly Borla
a992917f1c [NFC][RequirementMachine] Rename some of the RequirementError::Kind cases,
add documentation for each case, and move RequirementError to
lib/AST/RequirementMachine/Diagnostics.h.
2022-02-16 13:11:57 -08:00
Holly Borla
1f1125098b [NFC][RequirementMachine] Add documentation for diagnoseRequirementErrors. 2022-02-16 13:11:57 -08:00
Holly Borla
e6dc7e69c1 [RequirementMachine] Emit diagnostics for structural requirements in protocol
and typealias requirement signatures.
2022-02-16 13:11:57 -08:00
Holly Borla
ec45d960d8 [RequirementMachine] Always store an invalid requirement in RequirementError. 2022-02-16 13:11:57 -08:00
Holly Borla
3837b4def4 [RequirementMachine] Diagnose early redundant requirements. 2022-02-16 13:11:57 -08:00
Holly Borla
203734bea4 [RequirementMachine] Diagnose conformance, layout, and superclass constraints
on non-type-parameters in the requirement machine.
2022-02-16 13:11:57 -08:00
Holly Borla
e4cba889c2 [RequirementMachine] Diagnose concrete same-type mismatches, such as
`where String == Int`.
2022-02-16 13:11:57 -08:00
Holly Borla
3c2b588037 [RequirementMachine] Plumb the requirement errors vector through desugarRequirement. 2022-02-16 13:11:57 -08:00
Holly Borla
a74717ab69 [RequirementMachine] Diagnose non-protocol, non-class conformance/subtype
constraints in the requirement machine.
2022-02-16 13:11:56 -08:00
Slava Pestov
426df360b0 RequirementMachine: More elimination order tweaking
- Prefer rewrite loops not involving Decompose
- Prefer more deeply nested concrete types
2022-02-15 04:02:46 -05:00
Slava Pestov
57d89a6f11 RequirementMachine: Use processTypeDifference() in simplifyLeftHandSideSubstitutions() 2022-02-15 04:02:46 -05:00
Slava Pestov
f32b545283 RequirementMachine: Move RewriteSystem::processTypeDifference() and friends from PropertyUnification.cpp to RewriteSystem.cpp 2022-02-15 04:02:46 -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
eab371d8c5 RequirementMachine: Simplify RewriteStep::Decompose
The inverted form no longer has to replace substitutions; we use
the inverted form of DecomposeConcrete for that. So just assert
that the substitutions are equal.
2022-02-15 04:02:46 -05:00
Slava Pestov
41a6f9e118 RequirementMachine: Remove old implementation of simplifySubstitutions() 2022-02-15 04:02:46 -05:00
Slava Pestov
5e54a52c0e RequirementMachine: Remove old implementation of simplifyLeftHandSideSubstitutions()
Now that the PropertyMap to the concrete simplification version is optional,
we can just pass nullptr here to get the old behavior where type terms are
simplified to canonical anchors and no concrete simplification is performed.
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
e478ced1ce RequirementMachine: Move some code into a new SimplifySubstitutions.cpp 2022-02-15 04:02:46 -05:00
Slava Pestov
0deacdc7b1 RequirementMachine: Fix silly typo in RewriteSystem::findRuleToDelete()
This was regressing a couple of validation tests after the
seemingly-unrelated introduction of protocol typealias support.
2022-02-13 09:50:16 -05:00
Slava Pestov
530bee5235 RequirementMachine: Loosen check in RewriteSystem::verifyRewriteRules() to allow protocol typealias rules 2022-02-13 00:24:23 -05:00
Slava Pestov
4a06e21bf9 RequirementMachine: Introduce rules for protocol typealiases from requirement signatures
When building a rewrite system for a generic signature or protocol,
we would add requirements from the requirement signature of every
protocol dependency. Now, also add protocol typealias rules as well.
2022-02-13 00:24:23 -05:00
Slava Pestov
a1c03db381 AST: Generalize ProtocolDecl::getRequirementSignature() to a new RequirementSignature type
The RequirementSignature generalizes the old ArrayRef<Requirement>
which stores the minimal requirements that a conforming type's
witnesses must satisfy, to also record the protocol typealiases
defined in the protocol.
2022-02-13 00:24:23 -05:00
Slava Pestov
c58d9d8974 Sema: StructuralRequirementsRequest collects protocol typealiases
Introduces rewrite rules for typealiases defined inside the protocol
itself.

Typealiases defined in protocol extensions do not participate
in the rewrite system, except for when they have the same name as
an associated type, as per the weird rule codified in the
TypeAliasRequirementsRequest for GSB compatibility.
2022-02-13 00:24:23 -05:00
Slava Pestov
fa65fd0e05 RequirementMachine: Plumb protocol typealiases through minimization
Now that we can detect protocol typealias rules, collect and keep
track of them so that they can be recorded in protocol requirement
signatures.

For now, this is all NFC since nothing introduces such rules into
the rewrite system, except for invalid requirements which are
diagnosed anyway.
2022-02-13 00:24:23 -05:00
Slava Pestov
f9c2d9fd7c RequirementMachine: Introduce Rule::isProtocolTypeAliasRule()
There are two kinds of protocol typealiases:

1) The underlying type is a type parameter. These rules look like
   [P].A => X where X is the underlying type.

2) The underlying type is a concrete type. These rules look like
   [P].A.[concrete: C] => [P].A.

The isProtocolTypeAliasRule() predicate detects both cases and
returns the type alias name ('A', in the above examples). For now
it's not used anywhere, since we don't actually introduce these
rules for any reason.
2022-02-13 00:24:23 -05:00
Slava Pestov
cc3d02b975 RequirementMachine: Reduction order on terms compares number of name symbols first
We want a term with more name symbols to order after a term with
fewer name symbols, even if the term with more name symbols is
shorter. That is,

    [P].A > [P:X].[Q:Y].[R:Z]

This is in support of handling protocol typealiases.
2022-02-13 00:24:23 -05:00