Devirtualizer: work around partially implemented feature in the type system

We fail devirtualizing a specialized protocol method because the number (1) of
substitutions obtained from looking in the witness table does not match up with
the number (2) of substitutions expected by the function signature substitution
code.

As a workaround until the type code is fixed, check for this condition and bail.

rdar://17399536

Swift SVN r19137
This commit is contained in:
Arnold Schwaighofer
2014-06-24 20:09:27 +00:00
parent 2017259870
commit 00e1e0c6cb
2 changed files with 41 additions and 0 deletions

View File

@@ -444,6 +444,23 @@ bool WitnessMethodDevirtualizer::processInheritedProtocolConformance() {
return processNormalProtocolConformance();
}
/// The substitution is going to fail if there are more dependent types than
/// substitutions.
static bool isSubstitutionGoingToFailHack(ArrayRef<Substitution> Subs,
CanSILFunctionType GenCalleeType) {
auto *GenSig = GenCalleeType->getGenericSignature();
unsigned NumSubsNeccessary = 0;
for (auto depTy : GenSig->getAllDependentTypes()) {
if (depTy->getAs<SubstitutableType>() ||
depTy->getAs<DependentMemberType>()) {
++NumSubsNeccessary;
}
}
if (NumSubsNeccessary > Subs.size())
return true;
return false;
}
bool
WitnessMethodDevirtualizer::
processSpecializedProtocolConformance(SpecializedProtocolConformance *SPC,
@@ -453,6 +470,12 @@ processSpecializedProtocolConformance(SpecializedProtocolConformance *SPC,
// updated.
SILModule &M = F->getModule();
CanSILFunctionType GenCalleeType = F->getLoweredFunctionType();
// HACK: work around the fact that the substitution below might fail (there
// are more dependent types than substitutions).
if (isSubstitutionGoingToFailHack(Subs, GenCalleeType))
return false;
CanSILFunctionType SubstCalleeType =
GenCalleeType->substInterfaceGenericArgs(M, M.getSwiftModule(),
Subs);