SIL: Lower dependent member types when substituted into context.

AST context substitution may produce a metatype, function type, or other type that requires lowering. Handle this special case to fix a crash when emitting protocol conformances with metatypes or functions as associated types. <rdar://problem/17501507>

Swift SVN r19580
This commit is contained in:
Joe Groff
2014-07-05 17:48:05 +00:00
parent 6b45c481eb
commit af160e9c7b
4 changed files with 87 additions and 6 deletions

View File

@@ -21,6 +21,7 @@
#include "llvm/Support/GraphWriter.h"
using namespace swift;
using namespace Lowering;
SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
StringRef name,
@@ -122,6 +123,68 @@ Type SILFunction::mapTypeIntoContext(Type type) const {
type);
}
namespace {
struct MapSILTypeIntoContext : CanTypeVisitor<MapSILTypeIntoContext, CanType> {
const SILFunction *ContextFn;
MapSILTypeIntoContext(const SILFunction *ContextFn) : ContextFn(ContextFn) {}
CanType visitDependentMemberType(CanDependentMemberType t) {
// If a dependent member type appears in lowered position, we need to lower
// its context substitution against the associated type's abstraction
// pattern.
CanType astTy = ContextFn->mapTypeIntoContext(t)->getCanonicalType();
AbstractionPattern origTy(t->getAssocType()->getArchetype());
return ContextFn->getModule().Types.getLoweredType(origTy, astTy)
.getSwiftRValueType();
}
CanType visitTupleType(CanTupleType t) {
// Dependent members can appear in lowered position inside tuples.
SmallVector<TupleTypeElt, 4> elements;
for (auto &elt : t->getFields())
elements.push_back(elt.getWithType(visit(CanType(elt.getType()))));
return TupleType::get(elements, t->getASTContext())
->getCanonicalType();
}
CanType visitSILFunctionType(CanSILFunctionType t) {
// Dependent members can appear in lowered position inside SIL functions.
SmallVector<SILParameterInfo, 4> params;
for (auto &param : t->getInterfaceParameters())
params.push_back(param.transform([&](CanType pt) -> CanType {
return visit(pt);
}));
SILResultInfo result = t->getInterfaceResult()
.transform([&](CanType elt) -> CanType {
return visit(elt);
});
return SILFunctionType::get(t->getGenericSignature(),
t->getExtInfo(),
t->getCalleeConvention(),
params, result,
t->getASTContext());
}
CanType visitType(CanType t) {
// Other types get substituted into context normally.
return ContextFn->mapTypeIntoContext(t)->getCanonicalType();
}
};
} // end anonymous namespace
SILType SILFunction::mapTypeIntoContext(SILType type) const {
CanType astTy = MapSILTypeIntoContext(this).visit(type.getSwiftRValueType());
return SILType::getPrimitiveType(astTy, type.getCategory());
}
SILBasicBlock *SILFunction::createBasicBlock() {
return new (getModule()) SILBasicBlock(this);
}