Recognize and record conformance of an archetype to a protocol via its superclass requirement.

<rdar://problem/19495341> Can't upcast to parent types of type constraints without forcing

Swift SVN r25327
This commit is contained in:
Chris Willmore
2015-02-16 22:41:54 +00:00
parent 5b51620d1d
commit a85246fa09
4 changed files with 72 additions and 27 deletions

View File

@@ -867,7 +867,9 @@ LookupConformanceResult Module::lookupConformance(Type type,
return { nullptr, ConformanceKind::Conforms };
}
return { nullptr, ConformanceKind::DoesNotConform };
if (!archetype->getSuperclass()) {
return { nullptr, ConformanceKind::DoesNotConform };
}
}
// An existential conforms to a protocol if the protocol is listed in the
@@ -923,6 +925,24 @@ LookupConformanceResult Module::lookupConformance(Type type,
return { nullptr, ConformanceKind::DoesNotConform };
}
// Check for protocol conformance of archetype via superclass requirement.
if (auto archetype = type->getAs<ArchetypeType>()) {
if (auto super = archetype->getSuperclass()) {
auto inheritedConformance = lookupConformance(super, protocol, resolver);
switch (inheritedConformance.getInt()) {
case ConformanceKind::DoesNotConform:
return { nullptr, ConformanceKind::DoesNotConform };
case ConformanceKind::UncheckedConforms:
return inheritedConformance;
case ConformanceKind::Conforms:
auto result =
ctx.getInheritedConformance(type, inheritedConformance.getPointer());
ctx.setConformsTo(canType, protocol, ConformanceEntry(result, true));
return { result, ConformanceKind::Conforms };
}
}
}
auto nominal = type->getAnyNominal();
// If we don't have a nominal type, there are no conformances.