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) {
auto *ND = CD->getExtensionType()->getNominalOrBoundGenericNominal();
if (!isa<ClassDecl>(ND) && !isa<StructDecl>(ND) && !isa<EnumDecl>(ND) &&
!CD->isInvalid()) {
Out << "ConstructorDecls outside structs, classes or enums"
!isa<ProtocolDecl>(ND) && !CD->isInvalid()) {
Out << "ConstructorDecls outside structs, classes or enums "
"should be marked invalid";
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
// enum element to use.
assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>());
assert(ty->getNominalOrBoundGenericNominal() || ty->is<DynamicSelfType>() ||
ty->is<ArchetypeType>());
auto selected = getOverloadChoiceIfAvailable(
cs.getConstraintLocator(
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
// object, replace the result type with DynamicSelf.
else if (baseObjTy->is<DynamicSelfType>() && isa<ConstructorDecl>(value)) {
// object, or a constructor within a protocol, replace the result type with
// the base object type DynamicSelf.
else if (isa<ConstructorDecl>(value) &&
(baseObjTy->is<DynamicSelfType>() ||
isa<ProtocolDecl>(value->getDeclContext()))) {
auto outerFnType = openedType->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.
if (auto metaTy = type->getAs<MetatypeType>())
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.
if (isa<StructDecl>(nominalDecl) || isa<ClassDecl>(nominalDecl))
addImplicitConstructors(nominalDecl);
// For nominal types, make sure we have the right constructors available.
if (auto nominalDecl = type->getAnyNominal()) {
// 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
// elements.
// FIXME: This feels like a hack.
if (auto enumDecl = dyn_cast<EnumDecl>(nominalDecl)) {
for (auto member : enumDecl->getMembers()) {
if (auto element = dyn_cast<EnumElementDecl>(member))
result.addResult(element);
// If we're looking for constructors in an enum, return the enum
// elements.
// FIXME: This feels like a hack.
if (auto enumDecl = dyn_cast<EnumDecl>(nominalDecl)) {
for (auto member : enumDecl->getMembers()) {
if (auto element = dyn_cast<EnumElementDecl>(member))
result.addResult(element);
}
}
}