Record the value-witness-of relationship in the ASTContext as we assign witnesses.

Previously, this was being handled when we set conformances. We want
something lazier.


Swift SVN r11339
This commit is contained in:
Doug Gregor
2013-12-16 02:49:37 +00:00
parent 93c15bed50
commit 292192efac
3 changed files with 3 additions and 32 deletions

View File

@@ -251,35 +251,8 @@ ImportDecl::findBestImportKind(ArrayRef<ValueDecl *> Decls) {
return FirstKind;
}
/// Associates the decls that are conforming, to the protocol decls.
static void associateConformingValueDecls(ProtocolConformance *Conformance,
ASTContext &Ctx) {
if (!Conformance)
return;
// FIXME: Walking the full value witness table at this point is
// really, really unfortunate.
Conformance->forEachValueWitness(nullptr,
[&](ValueDecl *req,
ConcreteDeclRef witness) {
if (witness)
Ctx.recordConformingDecl(witness.getDecl(), req);
});
for (auto InheritedConf: Conformance->getInheritedConformances())
associateConformingValueDecls(InheritedConf.second, Ctx);
}
static void associateConformingValueDecls(
ArrayRef<ProtocolConformance *> Conformances, ASTContext &Ctx) {
for (auto Conf: Conformances) {
associateConformingValueDecls(Conf, Ctx);
}
}
void ExtensionDecl::setConformances(ArrayRef<ProtocolConformance *> c) {
Conformances = c;
associateConformingValueDecls(c, getASTContext());
}
SourceRange PatternBindingDecl::getSourceRange() const {
@@ -539,10 +512,6 @@ bool TypeDecl::derivesProtocolConformance(ProtocolDecl *protocol) const {
void TypeDecl::setConformances(ArrayRef<ProtocolConformance *> c) {
Conformances = c;
// A typealias should not affect the conformance bit of members of the
// original; mark conformances only if this is a nominal type decl.
if (isa<NominalTypeDecl>(this))
associateConformingValueDecls(c, getASTContext());
}
GenericSignature::GenericSignature(ArrayRef<GenericTypeParamType *> params,

View File

@@ -922,6 +922,7 @@ checkConformsToProtocol(TypeChecker &TC, Type T, ProtocolDecl *Proto,
else
Mapping[Requirement] = ConcreteDeclRef(TC.Context, best.Witness,
best.WitnessSubstitutions);
TC.Context.recordConformingDecl(best.Witness, Requirement);
// If we deduced any associated types, record them now.
if (!best.AssociatedTypeDeductions.empty()) {
@@ -968,7 +969,7 @@ checkConformsToProtocol(TypeChecker &TC, Type T, ProtocolDecl *Proto,
if (matchWitness(TC, Proto, DC, Requirement, T, derived,
TypeWitnesses).isViable()) {
Mapping[Requirement] = derived;
numViable = 1;
TC.Context.recordConformingDecl(derived, Requirement);
continue;
}
didDerive = true;

View File

@@ -410,6 +410,7 @@ Optional<ConformancePair> ModuleFile::maybeReadConformance(Type conformingType,
witness = ConcreteDeclRef(ctx, second, substitutions);
witnesses.insert(std::make_pair(first, witness));
ctx.recordConformingDecl(second, first);
}
assert(rawIDIter <= rawIDs.end() && "read too much");