Allow construction of archetype values via archetype metatypes.

Swift SVN r14325
This commit is contained in:
Doug Gregor
2014-02-25 00:11:24 +00:00
parent c4cc906210
commit 6a532e05c6
4 changed files with 22 additions and 20 deletions

View File

@@ -1236,8 +1236,8 @@ struct ASTNodeBase {};
void verifyChecked(ConstructorDecl *CD) { void verifyChecked(ConstructorDecl *CD) {
auto *ND = CD->getExtensionType()->getNominalOrBoundGenericNominal(); auto *ND = CD->getExtensionType()->getNominalOrBoundGenericNominal();
if (!isa<ClassDecl>(ND) && !isa<StructDecl>(ND) && !isa<EnumDecl>(ND) && if (!isa<ClassDecl>(ND) && !isa<StructDecl>(ND) && !isa<EnumDecl>(ND) &&
!CD->isInvalid()) { !isa<ProtocolDecl>(ND) && !CD->isInvalid()) {
Out << "ConstructorDecls outside structs, classes or enums" Out << "ConstructorDecls outside structs, classes or enums "
"should be marked invalid"; "should be marked invalid";
abort(); abort();
} }

View File

@@ -3415,7 +3415,8 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
// We're constructing a value of nominal type. Look for the constructor or // We're constructing a value of nominal type. Look for the constructor or
// enum element to use. // enum element to use.
assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>()); assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
ty->is<ArchetypeType>());
auto selected = getOverloadChoiceIfAvailable( auto selected = getOverloadChoiceIfAvailable(
cs.getConstraintLocator( cs.getConstraintLocator(
locator.withPathElement( locator.withPathElement(

View File

@@ -941,8 +941,11 @@ ConstraintSystem::getTypeOfMemberReference(Type baseTy, ValueDecl *value,
} }
} }
// Alternatively, if this is a constructor referenced from a DynamicSelf base // Alternatively, if this is a constructor referenced from a DynamicSelf base
// object, replace the result type with DynamicSelf. // object, or a constructor within a protocol, replace the result type with
else if (baseObjTy->is<DynamicSelfType>() && isa<ConstructorDecl>(value)) { // the base object type DynamicSelf.
else if (isa<ConstructorDecl>(value) &&
(baseObjTy->is<DynamicSelfType>() ||
isa<ProtocolDecl>(value->getDeclContext()))) {
auto outerFnType = openedType->castTo<FunctionType>(); auto outerFnType = openedType->castTo<FunctionType>();
auto innerFnType = outerFnType->getResult()->castTo<FunctionType>(); auto innerFnType = outerFnType->getResult()->castTo<FunctionType>();

View File

@@ -51,23 +51,21 @@ LookupResult TypeChecker::lookupMember(Type type, Identifier name,
// Look through the metatype. // Look through the metatype.
if (auto metaTy = type->getAs<MetatypeType>()) if (auto metaTy = type->getAs<MetatypeType>())
type = metaTy->getInstanceType(); type = metaTy->getInstanceType();
// We only have constructors for nominal declarations.
auto nominalDecl = type->getAnyNominal();
if (!nominalDecl)
return result;
// Define implicit default constructor for a struct/class. // For nominal types, make sure we have the right constructors available.
if (isa<StructDecl>(nominalDecl) || isa<ClassDecl>(nominalDecl)) if (auto nominalDecl = type->getAnyNominal()) {
addImplicitConstructors(nominalDecl); // Define implicit default constructor for a struct/class.
if (isa<StructDecl>(nominalDecl) || isa<ClassDecl>(nominalDecl))
addImplicitConstructors(nominalDecl);
// If we're looking for constructors in an enum, return the enum // If we're looking for constructors in an enum, return the enum
// elements. // elements.
// FIXME: This feels like a hack. // FIXME: This feels like a hack.
if (auto enumDecl = dyn_cast<EnumDecl>(nominalDecl)) { if (auto enumDecl = dyn_cast<EnumDecl>(nominalDecl)) {
for (auto member : enumDecl->getMembers()) { for (auto member : enumDecl->getMembers()) {
if (auto element = dyn_cast<EnumElementDecl>(member)) if (auto element = dyn_cast<EnumElementDecl>(member))
result.addResult(element); result.addResult(element);
}
} }
} }