mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Rework witness matching for generic requirements.
Reimplement the witness matching logic used for generic requirements so that it properly models the expectations required of the witness, then captures the results in the AST. The new approach has a number of advantages over the existing hacks: * The constraint solver no longer requires hacks to try to tangle together the innermost archetypes from the requirement with the outer archetypes of the context of the protocol conformance. Instead, we create a synthetic set of archetypes that describes the requirement as it should be matched against witnesses. This eliminates the infamous 'SelfTypeVar' hack. * The type checker no longer records substitutions involving a weird mix of archetypes from different contexts (see above), so it's actually plausible to reason about the substitutions of a witness. A new `Witness` class contains the declaration, substitutions, and all other information required to interpret the witness. * SILGen now uses the substitution information for witnesses when building witness thunks, rather than computing all of it from scratch. ``substSelfTypeIntoProtocolRequirementType()` is now gone (absorbed into the type checker, and improved from there), and the witness-thunk emission code is simpler. A few other bits of SILGen got simpler because the substitutions can now be trusted. * Witness matching and thunk generation involving generic requirements and nested generics now works, based on some work @slavapestov was already doing in this area. * The AST verifier can now verify the archetypes that occur in witness substitutions. * Although it's not in this commit, the `Witness` structure is suitable for complete (de-)serialization, unlike the weird mix of archetypes previously present. Fixes rdar://problem/24079818 and cleans up an area that's been messy and poorly understood for a very, very long time.
This commit is contained in:
@@ -998,8 +998,7 @@ bool ModuleFile::readDefaultWitnessTable(ProtocolDecl *proto) {
|
||||
assert(witness && "unable to deserialize next witness");
|
||||
assert(requirement->getDeclContext() == proto);
|
||||
|
||||
// FIXME: substitutions
|
||||
proto->setDefaultWitness(requirement, ConcreteDeclRef(witness));
|
||||
proto->setDefaultWitness(requirement, witness);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -4214,7 +4213,10 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
|
||||
assert(second || first->getAttrs().hasAttribute<OptionalAttr>() ||
|
||||
first->getAttrs().isUnavailable(ctx));
|
||||
(void) ctx;
|
||||
witnesses.insert(std::make_pair(first, second));
|
||||
if (second)
|
||||
witnesses.insert(std::make_pair(first, second));
|
||||
else
|
||||
witnesses.insert(std::make_pair(first, Witness()));
|
||||
}
|
||||
assert(rawIDIter <= rawIDs.end() && "read too much");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user