Fix interface types and type lowering of DynamicSelf so archetypes don't creep in.

Allows us to invoke DynamicSelf methods of generic classes.


Swift SVN r13290
This commit is contained in:
Doug Gregor
2014-02-01 05:12:39 +00:00
parent 4269715437
commit fe2ef0e5c6
5 changed files with 25 additions and 10 deletions

View File

@@ -3126,6 +3126,11 @@ public:
/// this method does not have a \c DynamicSelf return type.
DynamicSelfType *getDynamicSelf() const;
/// Retrieve the \c DynamicSelf interface type for this method, or a
/// null type if this method does not have a \c DynamicSelf return
/// type.
DynamicSelfType *getDynamicSelfInterface() const;
/// Given that this is an Objective-C method declaration, produce
/// its selector in the given buffer (as UTF-8).
StringRef getObjCSelector(SmallVectorImpl<char> &buffer) const;

View File

@@ -134,6 +134,7 @@ struct ASTContext::Implementation {
llvm::DenseMap<std::pair<Type, Type>, SubstitutedType *> SubstitutedTypes;
llvm::DenseMap<std::pair<Type, void*>, DependentMemberType *>
DependentMemberTypes;
llvm::DenseMap<Type, DynamicSelfType *> DynamicSelfTypes;
llvm::FoldingSet<EnumType> EnumTypes;
llvm::FoldingSet<StructType> StructTypes;
llvm::FoldingSet<ClassType> ClassTypes;
@@ -170,7 +171,6 @@ struct ASTContext::Implementation {
llvm::FoldingSet<ProtocolCompositionType> ProtocolCompositionTypes;
llvm::FoldingSet<BuiltinVectorType> BuiltinVectorTypes;
llvm::FoldingSet<GenericSignature> GenericSignatures;
llvm::DenseMap<Type, DynamicSelfType *> DynamicSelfTypes;
/// \brief The permanent arena.
Arena Permanent;
@@ -1370,18 +1370,17 @@ ModuleType *ModuleType::get(Module *M) {
}
DynamicSelfType *DynamicSelfType::get(Type selfType, const ASTContext &ctx) {
assert(!selfType->hasTypeVariable() && "Type variable in DynamicSelfType");
auto known = ctx.Impl.DynamicSelfTypes.find(selfType);
if (known != ctx.Impl.DynamicSelfTypes.end())
return known->second;
auto properties = selfType->getRecursiveProperties()
- RecursiveTypeProperties::IsNotMaterializable;
auto arena = getArena(properties);
auto arena = getArena(properties);
auto &dynamicSelfTypes = ctx.Impl.getArena(arena).DynamicSelfTypes;
auto known = dynamicSelfTypes.find(selfType);
if (known != dynamicSelfTypes.end())
return known->second;
auto result = new (ctx, arena) DynamicSelfType(selfType, ctx, properties);
ctx.Impl.DynamicSelfTypes.insert({selfType, result});
dynamicSelfTypes.insert({selfType, result});
return result;
}

View File

@@ -1569,6 +1569,14 @@ DynamicSelfType *FuncDecl::getDynamicSelf() const {
return DynamicSelfType::get(getExtensionType(), getASTContext());
}
DynamicSelfType *FuncDecl::getDynamicSelfInterface() const {
if (!hasDynamicSelf())
return nullptr;
return DynamicSelfType::get(getDeclContext()->getDeclaredInterfaceType(),
getASTContext());
}
StringRef VarDecl::getObjCGetterSelector(SmallVectorImpl<char> &buffer) const {
llvm::raw_svector_ostream out(buffer);

View File

@@ -976,7 +976,8 @@ namespace {
}
const TypeLowering *visitDynamicSelfType(CanDynamicSelfType type) {
return LowerType(TC, type.getSelfType(), Dependent)
return LowerType(TC, cast<DynamicSelfType>(OrigType).getSelfType(),
Dependent)
.visit(type.getSelfType());
}

View File

@@ -652,6 +652,8 @@ bool TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
funcTy = fn->getBodyResultTypeLoc().getType();
if (!funcTy) {
funcTy = TupleType::getEmpty(Context);
} else if (funcTy->is<DynamicSelfType>()) {
funcTy = fn->getDynamicSelfInterface();
}
} else if (auto ctor = dyn_cast<ConstructorDecl>(func)) {
funcTy = ctor->getExtensionType()->getAnyNominal()