Revert "Sema: Make derived conformances work from extensions"

Speculatively revert; this looks like it is breaking the iOS bots.

Swift SVN r28963
This commit is contained in:
Ted Kremenek
2015-05-23 15:26:55 +00:00
parent 9917e74533
commit a575727a2b
18 changed files with 163 additions and 321 deletions

View File

@@ -38,7 +38,6 @@ namespace swift {
class CanType;
class Decl;
class DeclContext;
class EnumDecl;
class ExtensionDecl;
class Expr;
class GenericParamList;
@@ -245,10 +244,6 @@ public:
/// ClassDecl, otherwise return null.
ClassDecl *isClassOrClassExtensionContext() const;
/// If this DeclContext is a enum, or an extension on a enum, return the
/// EnumDecl, otherwise return null.
EnumDecl *isEnumOrEnumExtensionContext() const;
/// If this DeclContext is a protocol, or an extension on a
/// protocol, return the ProtocolDecl, otherwise return null.
ProtocolDecl *isProtocolOrProtocolExtensionContext() const;

View File

@@ -1142,9 +1142,6 @@ NOTE(enum_raw_value_incrementing_from_here,sema_tcd,none,
"raw value auto-incremented from here",())
NOTE(enum_raw_value_incrementing_from_zero,sema_tcd,none,
"raw value implicitly auto-incremented from zero",())
// Derived conformances
ERROR(broken_raw_representable_requirement,sema_tcd,none,
"RawRepresentable protocol is broken: unexpected requirement", ())
ERROR(broken_equatable_requirement,sema_tcd,none,

View File

@@ -74,11 +74,6 @@ ClassDecl *DeclContext::isClassOrClassExtensionContext() const {
isNominalTypeOrNominalTypeExtensionContext());
}
EnumDecl *DeclContext::isEnumOrEnumExtensionContext() const {
return dyn_cast_or_null<EnumDecl>(
isNominalTypeOrNominalTypeExtensionContext());
}
ProtocolDecl *DeclContext::isProtocolOrProtocolExtensionContext() const {
return dyn_cast_or_null<ProtocolDecl>(
isNominalTypeOrNominalTypeExtensionContext());

View File

@@ -48,20 +48,18 @@ static bool canDeriveConformance(NominalTypeDecl *type) {
/// Create AST statements which convert from an enum to an Int with a switch.
/// \p stmts The generated statements are appended to this vector.
/// \p parentDC Either an extension or the enum itself.
/// \p enumDecl The enum declaration.
/// \p enumVarDecl The enum input variable.
/// \p funcDecl The parent function.
/// \p indexName The name of the output variable.
/// \return A DeclRefExpr of the output variable (of type Int).
static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
DeclContext *parentDC,
EnumDecl *enumDecl,
VarDecl *enumVarDecl,
AbstractFunctionDecl *funcDecl,
const char *indexName) {
ASTContext &C = enumDecl->getASTContext();
Type enumType = enumVarDecl->getType();
auto enumType = enumDecl->getDeclaredTypeInContext();
Type intType = C.getIntDecl()->getDeclaredType();
auto indexVar = new (C) VarDecl(/*static*/false, /*let*/false,
@@ -125,9 +123,6 @@ static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
/// Derive the body for an '==' operator for an enum
static void deriveBodyEquatable_enum_eq(AbstractFunctionDecl *eqDecl) {
auto parentDC = eqDecl->getDeclContext();
ASTContext &C = parentDC->getASTContext();
auto args = cast<TuplePattern>(eqDecl->getBodyParamPatterns().back());
auto aPattern = args->getElement(0).getPattern();
auto aParamPattern =
@@ -138,16 +133,16 @@ static void deriveBodyEquatable_enum_eq(AbstractFunctionDecl *eqDecl) {
cast<NamedPattern>(bPattern->getSemanticsProvidingPattern());
auto bParam = bParamPattern->getDecl();
CanType boolTy = C.getBoolDecl()->getDeclaredType().getCanonicalTypeOrNull();
auto enumDecl = cast<EnumDecl>(aParam->getType()->getAnyNominal());
ASTContext &C = enumDecl->getASTContext();
CanType boolTy = C.getBoolDecl()->getDeclaredType().getCanonicalTypeOrNull();
// Generate the conversion from the enums to integer indices.
SmallVector<ASTNode, 6> statements;
DeclRefExpr *aIndex = convertEnumToIndex(statements, parentDC, enumDecl,
aParam, eqDecl, "index_a");
DeclRefExpr *bIndex = convertEnumToIndex(statements, parentDC, enumDecl,
bParam, eqDecl, "index_b");
DeclRefExpr *aIndex = convertEnumToIndex(statements, enumDecl, aParam, eqDecl,
"index_a");
DeclRefExpr *bIndex = convertEnumToIndex(statements, enumDecl, bParam, eqDecl,
"index_b");
// Generate the compare of the indices.
FuncDecl *cmpFunc = C.getEqualIntDecl(nullptr);
@@ -174,7 +169,7 @@ static void deriveBodyEquatable_enum_eq(AbstractFunctionDecl *eqDecl) {
/// Derive an '==' operator implementation for an enum.
static ValueDecl *
deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
deriveEquatable_enum_eq(TypeChecker &tc, EnumDecl *enumDecl) {
// enum SomeEnum<T...> {
// case A, B, C
// }
@@ -197,8 +192,7 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
ASTContext &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
auto enumTy = parentDC->getDeclaredTypeInContext();
auto enumTy = enumDecl->getDeclaredTypeInContext();
auto getParamPattern = [&](StringRef s) -> std::pair<VarDecl*, Pattern*> {
VarDecl *aDecl = new (C) ParamDecl(/*isLet*/ true,
@@ -207,7 +201,7 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
SourceLoc(),
C.getIdentifier(s),
enumTy,
parentDC);
enumDecl);
aDecl->setImplicit();
Pattern *aParam = new (C) NamedPattern(aDecl, /*implicit*/ true);
aParam->setType(enumTy);
@@ -235,12 +229,10 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
params->setImplicit();
params->setType(paramsTy);
auto genericParams = parentDC->getGenericParamsOfContext();
auto genericParams = enumDecl->getGenericParamsOfContext();
auto boolTy = C.getBoolDecl()->getDeclaredType();
auto moduleDC = parentDecl->getModuleContext();
DeclName name(C, C.Id_EqualsOperator, { Identifier(), Identifier() });
auto eqDecl = FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None,
SourceLoc(), name,
@@ -248,17 +240,17 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
genericParams,
Type(), params,
TypeLoc::withoutLoc(boolTy),
&moduleDC->getDerivedFileUnit());
&enumDecl->getModuleContext()->getDerivedFileUnit());
eqDecl->setImplicit();
eqDecl->getAttrs().add(new (C) InfixAttr(/*implicit*/false));
auto op = C.getStdlibModule()->lookupInfixOperator(C.Id_EqualsOperator);
if (!op) {
tc.diagnose(parentDecl->getLoc(),
tc.diagnose(enumDecl->getLoc(),
diag::broken_equatable_eq_operator);
return nullptr;
}
if (!C.getEqualIntDecl(nullptr)) {
tc.diagnose(parentDecl->getLoc(), diag::no_equal_overload_for_int);
tc.diagnose(enumDecl->getLoc(), diag::no_equal_overload_for_int);
return nullptr;
}
@@ -271,14 +263,14 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
if (genericParams) {
fnTy = PolymorphicFunctionType::get(paramsTy, boolTy, genericParams);
auto enumIfaceTy = parentDC->getDeclaredInterfaceType();
auto enumIfaceTy = enumDecl->getDeclaredInterfaceType();
TupleTypeElt ifaceParamElts[] = {
enumIfaceTy, enumIfaceTy,
};
auto ifaceParamsTy = TupleType::get(ifaceParamElts, C);
interfaceTy = GenericFunctionType::get(
parentDC->getGenericSignatureOfContext(),
enumDecl->getGenericSignatureOfContext(),
ifaceParamsTy, boolTy,
AnyFunctionType::ExtInfo());
} else {
@@ -296,11 +288,10 @@ deriveEquatable_enum_eq(TypeChecker &tc, Decl *parentDecl, EnumDecl *enumDecl) {
tc.implicitlyDefinedFunctions.push_back(eqDecl);
// Since it's an operator we insert the decl after the type at global scope.
return insertOperatorDecl(C, cast<IterableDeclContext>(parentDecl), eqDecl);
return insertOperatorDecl(C, enumDecl, eqDecl);
}
ValueDecl *DerivedConformance::deriveEquatable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement) {
// Check that we can actually derive Equatable for this type.
@@ -310,7 +301,7 @@ ValueDecl *DerivedConformance::deriveEquatable(TypeChecker &tc,
// Build the necessary decl.
if (requirement->getName().str() == "==") {
if (auto theEnum = dyn_cast<EnumDecl>(type))
return deriveEquatable_enum_eq(tc, parentDecl, theEnum);
return deriveEquatable_enum_eq(tc, theEnum);
else
llvm_unreachable("todo");
}
@@ -321,10 +312,8 @@ ValueDecl *DerivedConformance::deriveEquatable(TypeChecker &tc,
static void
deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) {
auto parentDC = hashValueDecl->getDeclContext();
ASTContext &C = parentDC->getASTContext();
auto enumDecl = parentDC->isEnumOrEnumExtensionContext();
auto enumDecl = cast<EnumDecl>(hashValueDecl->getDeclContext());
ASTContext &C = enumDecl->getASTContext();
SmallVector<ASTNode, 3> statements;
@@ -333,8 +322,8 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) {
cast<NamedPattern>(curriedArgs->getSemanticsProvidingPattern());
auto selfDecl = selfPattern->getDecl();
DeclRefExpr *indexRef = convertEnumToIndex(statements, parentDC, enumDecl,
selfDecl, hashValueDecl, "index");
DeclRefExpr *indexRef = convertEnumToIndex(statements, enumDecl, selfDecl,
hashValueDecl, "index");
auto memberRef = new (C) UnresolvedDotExpr(indexRef, SourceLoc(),
C.getIdentifier("hashValue"),
@@ -349,8 +338,7 @@ deriveBodyHashable_enum_hashValue(AbstractFunctionDecl *hashValueDecl) {
/// Derive a 'hashValue' implementation for an enum.
static ValueDecl *
deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
EnumDecl *enumDecl) {
deriveHashable_enum_hashValue(TypeChecker &tc, EnumDecl *enumDecl) {
// enum SomeEnum {
// case A, B, C
// @derived var hashValue: Int {
@@ -368,9 +356,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
// }
ASTContext &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
Type enumType = parentDC->getDeclaredTypeInContext();
Type enumType = enumDecl->getDeclaredTypeInContext();
Type intType = C.getIntDecl()->getDeclaredType();
// We can't form a Hashable conformance if Int isn't Hashable or
@@ -398,7 +384,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
SourceLoc(),
C.Id_self,
enumType,
parentDC);
enumDecl);
selfDecl->setImplicit();
Pattern *selfParam = new (C) NamedPattern(selfDecl, /*implicit*/ true);
selfParam->setType(enumType);
@@ -411,7 +397,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
FuncDecl *getterDecl =
FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(),
Identifier(), SourceLoc(), SourceLoc(), nullptr, Type(),
params, TypeLoc::withoutLoc(intType), parentDC);
params, TypeLoc::withoutLoc(intType), enumDecl);
getterDecl->setImplicit();
getterDecl->setBodySynthesizer(deriveBodyHashable_enum_hashValue);
@@ -430,7 +416,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
// Compute the interface type of hashValue().
Type interfaceType;
Type selfIfaceType = getterDecl->computeInterfaceSelfType(false);
if (auto sig = parentDC->getGenericSignatureOfContext())
if (auto sig = enumDecl->getGenericSignatureOfContext())
interfaceType = GenericFunctionType::get(sig, selfIfaceType, methodType,
AnyFunctionType::ExtInfo());
else
@@ -446,7 +432,7 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
VarDecl *hashValueDecl = new (C) VarDecl(/*static*/ false,
/*let*/ false,
SourceLoc(), C.Id_hashValue,
intType, parentDC);
intType, enumDecl);
hashValueDecl->setImplicit();
hashValueDecl->makeComputed(SourceLoc(), getterDecl,
nullptr, nullptr, SourceLoc());
@@ -462,18 +448,16 @@ deriveHashable_enum_hashValue(TypeChecker &tc, Decl *parentDecl,
auto patDecl = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(), hashValuePat, nullptr,
parentDC);
enumDecl);
patDecl->setImplicit();
auto dc = cast<IterableDeclContext>(parentDecl);
dc->addMember(getterDecl);
dc->addMember(hashValueDecl);
dc->addMember(patDecl);
enumDecl->addMember(getterDecl);
enumDecl->addMember(hashValueDecl);
enumDecl->addMember(patDecl);
return hashValueDecl;
}
ValueDecl *DerivedConformance::deriveHashable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement) {
// Check that we can actually derive Hashable for this type.
@@ -483,7 +467,7 @@ ValueDecl *DerivedConformance::deriveHashable(TypeChecker &tc,
// Build the necessary decl.
if (requirement->getName().str() == "hashValue") {
if (auto theEnum = dyn_cast<EnumDecl>(type))
return deriveHashable_enum_hashValue(tc, parentDecl, theEnum);
return deriveHashable_enum_hashValue(tc, theEnum);
else
llvm_unreachable("todo");
}

View File

@@ -61,7 +61,6 @@ static void deriveBodyErrorType_enum_domain(AbstractFunctionDecl *domainDecl) {
}
static ValueDecl *deriveErrorType_enum_domain(TypeChecker &tc,
Decl *parentDecl,
EnumDecl *enumDecl) {
// enum SomeEnum {
// @derived
@@ -76,24 +75,24 @@ static ValueDecl *deriveErrorType_enum_domain(TypeChecker &tc,
ASTContext &C = tc.Context;
auto stringTy = C.getStringDecl()->getDeclaredType();
Type enumType = cast<DeclContext>(parentDecl)->getDeclaredTypeInContext();
Type enumType = enumDecl->getDeclaredTypeInContext();
// Define the getter.
auto getterDecl = declareDerivedPropertyGetter(tc, parentDecl, enumDecl,
enumType, stringTy, stringTy);
auto getterDecl = declareDerivedPropertyGetter(tc, enumDecl, enumType,
stringTy, stringTy);
getterDecl->setBodySynthesizer(&deriveBodyErrorType_enum_domain);
// Define the property.
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl)
= declareDerivedReadOnlyProperty(tc, parentDecl, enumDecl, C.Id__domain,
stringTy, stringTy, getterDecl);
= declareDerivedReadOnlyProperty(tc, enumDecl, C.Id__domain,
stringTy, stringTy,
getterDecl);
auto dc = cast<IterableDeclContext>(parentDecl);
dc->addMember(getterDecl);
dc->addMember(propDecl);
dc->addMember(pbDecl);
enumDecl->addMember(getterDecl);
enumDecl->addMember(propDecl);
enumDecl->addMember(pbDecl);
return propDecl;
}
@@ -114,11 +113,9 @@ static void deriveBodyErrorType_enum_code(AbstractFunctionDecl *codeDecl) {
//
// TODO: Some convenient way to override the code if that's desired.
auto parentDC = codeDecl->getDeclContext();
ASTContext &C = parentDC->getASTContext();
auto enumDecl = parentDC->isEnumOrEnumExtensionContext();
Type enumType = parentDC->getDeclaredTypeInContext();
ASTContext &C = codeDecl->getASTContext();
auto enumDecl = cast<EnumDecl>(codeDecl->getDeclContext());
Type enumType = enumDecl->getDeclaredTypeInContext();
SmallVector<CaseStmt*, 4> cases;
SmallString<11> strBuf;
@@ -179,7 +176,6 @@ static void deriveBodyErrorType_enum_code(AbstractFunctionDecl *codeDecl) {
}
static ValueDecl *deriveErrorType_enum_code(TypeChecker &tc,
Decl *parentDecl,
EnumDecl *enumDecl) {
// enum SomeEnum {
// case A,B,C,D
@@ -198,32 +194,29 @@ static ValueDecl *deriveErrorType_enum_code(TypeChecker &tc,
ASTContext &C = tc.Context;
auto intTy = C.getIntDecl()->getDeclaredType();
Type enumType = cast<DeclContext>(parentDecl)->getDeclaredTypeInContext();
Type enumType = enumDecl->getDeclaredTypeInContext();
// Define the getter.
auto getterDecl = declareDerivedPropertyGetter(tc, parentDecl, enumDecl,
enumType, intTy, intTy);
auto getterDecl = declareDerivedPropertyGetter(tc, enumDecl, enumType,
intTy, intTy);
getterDecl->setBodySynthesizer(&deriveBodyErrorType_enum_code);
// Define the property.
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl)
= declareDerivedReadOnlyProperty(tc, parentDecl, enumDecl, C.Id__code,
= declareDerivedReadOnlyProperty(tc, enumDecl, C.Id__code,
intTy, intTy,
getterDecl);
auto dc = cast<IterableDeclContext>(parentDecl);
dc->addMember(getterDecl);
dc->addMember(propDecl);
dc->addMember(pbDecl);
enumDecl->addMember(getterDecl);
enumDecl->addMember(propDecl);
enumDecl->addMember(pbDecl);
return propDecl;
}
ValueDecl *DerivedConformance::deriveErrorType(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement) {
if (!canDeriveConformance(type))
@@ -232,9 +225,9 @@ ValueDecl *DerivedConformance::deriveErrorType(TypeChecker &tc,
auto enumType = cast<EnumDecl>(type);
if (requirement->getName() == tc.Context.Id__domain)
return deriveErrorType_enum_domain(tc, parentDecl, enumType);
return deriveErrorType_enum_domain(tc, enumType);
else if (requirement->getName() == tc.Context.Id__code)
return deriveErrorType_enum_code(tc, parentDecl, enumType);
return deriveErrorType_enum_code(tc, enumType);
tc.diagnose(requirement->getLoc(),
diag::broken_errortype_requirement);
@@ -266,7 +259,6 @@ static void deriveBodyBridgedNSError_enum_NSErrorDomain(
}
static ValueDecl *deriveBridgedNSError_enum_NSErrorDomain(TypeChecker &tc,
Decl *parentDecl,
EnumDecl *enumDecl) {
// enum SomeEnum {
// @derived
@@ -284,8 +276,8 @@ static ValueDecl *deriveBridgedNSError_enum_NSErrorDomain(TypeChecker &tc,
Type enumType = enumDecl->getDeclaredTypeInContext();
// Define the getter.
auto getterDecl = declareDerivedPropertyGetter(tc, parentDecl, enumDecl,
enumType, stringTy, stringTy,
auto getterDecl = declareDerivedPropertyGetter(tc, enumDecl, enumType,
stringTy, stringTy,
/*isStatic=*/true);
getterDecl->setBodySynthesizer(&deriveBodyBridgedNSError_enum_NSErrorDomain);
@@ -293,21 +285,17 @@ static ValueDecl *deriveBridgedNSError_enum_NSErrorDomain(TypeChecker &tc,
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl)
= declareDerivedReadOnlyProperty(tc, parentDecl, enumDecl,
C.Id__NSErrorDomain,
= declareDerivedReadOnlyProperty(tc, enumDecl, C.Id__NSErrorDomain,
stringTy, stringTy,
getterDecl, /*isStatic=*/true);
auto dc = cast<IterableDeclContext>(parentDecl);
dc->addMember(getterDecl);
dc->addMember(propDecl);
dc->addMember(pbDecl);
enumDecl->addMember(getterDecl);
enumDecl->addMember(propDecl);
enumDecl->addMember(pbDecl);
return propDecl;
}
ValueDecl *DerivedConformance::deriveBridgedNSError(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement) {
if (!canDeriveConformance(type))
@@ -316,9 +304,10 @@ ValueDecl *DerivedConformance::deriveBridgedNSError(TypeChecker &tc,
auto enumType = cast<EnumDecl>(type);
if (requirement->getName() == tc.Context.Id__NSErrorDomain)
return deriveBridgedNSError_enum_NSErrorDomain(tc, parentDecl, enumType);
return deriveBridgedNSError_enum_NSErrorDomain(tc, enumType);
tc.diagnose(requirement->getLoc(),
diag::broken_errortype_requirement);
return nullptr;
}

View File

@@ -52,15 +52,13 @@ static LiteralExpr *cloneRawLiteralExpr(ASTContext &C, LiteralExpr *expr) {
return clone;
}
static Type deriveRawRepresentable_Raw(TypeChecker &tc, Decl *parentDecl,
EnumDecl *enumDecl) {
static Type deriveRawRepresentable_Raw(TypeChecker &tc, EnumDecl *enumDecl) {
// enum SomeEnum : SomeType {
// @derived
// typealias Raw = SomeType
// }
auto rawInterfaceType = enumDecl->getRawType();
return ArchetypeBuilder::mapTypeIntoContext(cast<DeclContext>(parentDecl),
rawInterfaceType);
return ArchetypeBuilder::mapTypeIntoContext(enumDecl, rawInterfaceType);
}
static void deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl) {
@@ -76,11 +74,7 @@ static void deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl) {
// }
// }
// }
auto parentDC = toRawDecl->getDeclContext();
ASTContext &C = parentDC->getASTContext();
auto enumDecl = parentDC->isEnumOrEnumExtensionContext();
auto enumDecl = cast<EnumDecl>(toRawDecl->getDeclContext());
Type rawTy = enumDecl->getRawType();
assert(rawTy);
@@ -91,7 +85,8 @@ static void deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl) {
}
}
Type enumType = parentDC->getDeclaredTypeInContext();
ASTContext &C = enumDecl->getASTContext();
Type enumType = enumDecl->getDeclaredTypeInContext();
SmallVector<CaseStmt*, 4> cases;
for (auto elt : enumDecl->getAllElements()) {
@@ -124,19 +119,16 @@ static void deriveBodyRawRepresentable_raw(AbstractFunctionDecl *toRawDecl) {
}
static VarDecl *deriveRawRepresentable_raw(TypeChecker &tc,
Decl *parentDecl,
EnumDecl *enumDecl) {
ASTContext &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
auto rawInterfaceType = enumDecl->getRawType();
auto rawType = ArchetypeBuilder::mapTypeIntoContext(parentDC,
auto rawType = ArchetypeBuilder::mapTypeIntoContext(enumDecl,
rawInterfaceType);
Type enumType = parentDC->getDeclaredTypeInContext();
Type enumType = enumDecl->getDeclaredTypeInContext();
// Define the getter.
auto getterDecl = declareDerivedPropertyGetter(tc, parentDecl, enumDecl,
enumType,
auto getterDecl = declareDerivedPropertyGetter(tc, enumDecl, enumType,
rawInterfaceType,
rawType);
getterDecl->setBodySynthesizer(&deriveBodyRawRepresentable_raw);
@@ -145,16 +137,13 @@ static VarDecl *deriveRawRepresentable_raw(TypeChecker &tc,
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl)
= declareDerivedReadOnlyProperty(tc, parentDecl, enumDecl,
C.Id_rawValue, rawType,
rawInterfaceType,
= declareDerivedReadOnlyProperty(tc, enumDecl, C.Id_rawValue,
rawType, rawInterfaceType,
getterDecl);
auto dc = cast<IterableDeclContext>(parentDecl);
dc->addMember(getterDecl);
dc->addMember(propDecl);
dc->addMember(pbDecl);
enumDecl->addMember(getterDecl);
enumDecl->addMember(propDecl);
enumDecl->addMember(pbDecl);
return propDecl;
}
@@ -175,11 +164,7 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl) {
// }
// }
auto parentDC = initDecl->getDeclContext();
ASTContext &C = parentDC->getASTContext();
auto nominalTypeDecl = parentDC->isNominalTypeOrNominalTypeExtensionContext();
auto enumDecl = cast<EnumDecl>(nominalTypeDecl);
auto enumDecl = cast<EnumDecl>(initDecl->getDeclContext());
Type rawTy = enumDecl->getRawType();
assert(rawTy);
@@ -192,7 +177,8 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl) {
}
}
Type enumType = parentDC->getDeclaredTypeInContext();
ASTContext &C = enumDecl->getASTContext();
Type enumType = enumDecl->getDeclaredTypeInContext();
auto selfDecl = cast<ConstructorDecl>(initDecl)->getImplicitSelfDecl();
@@ -249,13 +235,11 @@ deriveBodyRawRepresentable_init(AbstractFunctionDecl *initDecl) {
}
static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
Decl *parentDecl,
EnumDecl *enumDecl) {
ASTContext &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
auto rawInterfaceType = enumDecl->getRawType();
auto rawType = ArchetypeBuilder::mapTypeIntoContext(parentDC,
auto rawType = ArchetypeBuilder::mapTypeIntoContext(enumDecl,
rawInterfaceType);
// Make sure that the raw type is Equatable. We need it to ensure that we have
@@ -271,14 +255,14 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
return nullptr;
}
Type enumType = parentDC->getDeclaredTypeInContext();
Type enumType = enumDecl->getDeclaredTypeInContext();
VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/false,
SourceLoc(),
Identifier(),
SourceLoc(),
C.Id_self,
enumType,
parentDC);
enumDecl);
selfDecl->setImplicit();
Pattern *selfParam = new (C) NamedPattern(selfDecl, /*implicit*/ true);
selfParam->setType(enumType);
@@ -293,7 +277,7 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
SourceLoc(),
C.Id_rawValue,
rawType,
parentDC);
enumDecl);
rawDecl->setImplicit();
Pattern *rawParam = new (C) NamedPattern(rawDecl, /*implicit*/ true);
rawParam->setType(rawType);
@@ -314,7 +298,7 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
rawParam,
nullptr,
SourceLoc(),
parentDC);
enumDecl);
initDecl->setImplicit();
initDecl->setBodySynthesizer(&deriveBodyRawRepresentable_init);
@@ -345,7 +329,7 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
// Compute the interface type of the initializer.
Type retInterfaceType
= OptionalType::get(parentDC->getDeclaredInterfaceType());
= OptionalType::get(enumDecl->getDeclaredInterfaceType());
Type interfaceType = FunctionType::get(interfaceArgType, retInterfaceType);
Type selfInterfaceType = initDecl->computeInterfaceSelfType(/*init*/ false);
Type selfInitializerInterfaceType
@@ -353,7 +337,7 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
Type allocIfaceType;
Type initIfaceType;
if (auto sig = parentDC->getGenericSignatureOfContext()) {
if (auto sig = enumDecl->getGenericSignatureOfContext()) {
allocIfaceType = GenericFunctionType::get(sig, selfInterfaceType,
interfaceType,
FunctionType::ExtInfo());
@@ -371,12 +355,11 @@ static ConstructorDecl *deriveRawRepresentable_init(TypeChecker &tc,
if (enumDecl->hasClangNode())
tc.implicitlyDefinedFunctions.push_back(initDecl);
cast<IterableDeclContext>(parentDecl)->addMember(initDecl);
enumDecl->addMember(initDecl);
return initDecl;
}
ValueDecl *DerivedConformance::deriveRawRepresentable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement) {
// Check preconditions. These should already have been diagnosed by
@@ -402,10 +385,10 @@ ValueDecl *DerivedConformance::deriveRawRepresentable(TypeChecker &tc,
tc.validateDecl(elt);
if (requirement->getName() == tc.Context.Id_rawValue)
return deriveRawRepresentable_raw(tc, parentDecl, enumDecl);
return deriveRawRepresentable_raw(tc, enumDecl);
if (requirement->getName() == tc.Context.Id_init)
return deriveRawRepresentable_init(tc, parentDecl, enumDecl);
return deriveRawRepresentable_init(tc, enumDecl);
tc.diagnose(requirement->getLoc(),
diag::broken_raw_representable_requirement);
@@ -413,7 +396,6 @@ ValueDecl *DerivedConformance::deriveRawRepresentable(TypeChecker &tc,
}
Type DerivedConformance::deriveRawRepresentable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
AssociatedTypeDecl *assocType) {
// Check preconditions. These should already have been diagnosed by
@@ -439,7 +421,7 @@ Type DerivedConformance::deriveRawRepresentable(TypeChecker &tc,
tc.validateDecl(elt);
if (assocType->getName() == tc.Context.Id_RawValue) {
return deriveRawRepresentable_Raw(tc, parentDecl, enumDecl);
return deriveRawRepresentable_Raw(tc, enumDecl);
}
tc.diagnose(assocType->getLoc(),

View File

@@ -53,7 +53,6 @@ DerivedConformance::createSelfDeclRef(AbstractFunctionDecl *fn) {
}
FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *typeDecl,
Type contextType,
Type propertyInterfaceType,
@@ -65,15 +64,13 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
if (isStatic)
selfType = MetatypeType::get(selfType);
auto parentDC = cast<DeclContext>(parentDecl);
VarDecl *selfDecl = new (C) ParamDecl(/*IsLet*/true,
SourceLoc(),
Identifier(),
SourceLoc(),
C.Id_self,
selfType,
parentDC);
typeDecl);
selfDecl->setImplicit();
Pattern *selfParam = new (C) NamedPattern(selfDecl, /*implicit*/ true);
selfParam->setType(selfType);
@@ -88,7 +85,7 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
FuncDecl::create(C, SourceLoc(), StaticSpellingKind::None, SourceLoc(),
DeclName(), SourceLoc(), SourceLoc(), nullptr, Type(),
params, TypeLoc::withoutLoc(propertyContextType),
parentDC);
typeDecl);
getterDecl->setImplicit();
getterDecl->setStatic(isStatic);
@@ -108,7 +105,7 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
Type interfaceType = FunctionType::get(TupleType::getEmpty(C),
propertyInterfaceType);
Type selfInterfaceType = getterDecl->computeInterfaceSelfType(false);
if (auto sig = parentDC->getGenericSignatureOfContext())
if (auto sig = typeDecl->getGenericSignatureOfContext())
interfaceType = GenericFunctionType::get(sig, selfInterfaceType,
interfaceType,
FunctionType::ExtInfo());
@@ -125,7 +122,6 @@ FuncDecl *DerivedConformance::declareDerivedPropertyGetter(TypeChecker &tc,
std::pair<VarDecl *, PatternBindingDecl *>
DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *typeDecl,
Identifier name,
Type propertyInterfaceType,
@@ -133,13 +129,12 @@ DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc,
FuncDecl *getterDecl,
bool isStatic) {
auto &C = tc.Context;
auto parentDC = cast<DeclContext>(parentDecl);
VarDecl *propDecl = new (C) VarDecl(isStatic,
/*let*/ false,
SourceLoc(), name,
propertyContextType,
parentDC);
typeDecl);
propDecl->setImplicit();
propDecl->makeComputed(SourceLoc(), getterDecl, nullptr, nullptr,
SourceLoc());
@@ -155,7 +150,7 @@ DerivedConformance::declareDerivedReadOnlyProperty(TypeChecker &tc,
auto pbDecl = PatternBindingDecl::create(C, SourceLoc(),
StaticSpellingKind::None,
SourceLoc(), propPat, nullptr,
parentDC);
typeDecl);
pbDecl->setImplicit();
return {propDecl, pbDecl};

View File

@@ -35,7 +35,6 @@ namespace DerivedConformance {
///
/// \returns the derived member, which will also be added to the type.
ValueDecl *deriveRawRepresentable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement);
@@ -44,7 +43,6 @@ ValueDecl *deriveRawRepresentable(TypeChecker &tc,
///
/// \returns the derived member, which will also be added to the type.
Type deriveRawRepresentable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
AssociatedTypeDecl *assocType);
@@ -56,7 +54,6 @@ Type deriveRawRepresentable(TypeChecker &tc,
///
/// \returns the derived member, which will also be added to the type.
ValueDecl *deriveEquatable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement);
@@ -68,7 +65,6 @@ ValueDecl *deriveEquatable(TypeChecker &tc,
///
/// \returns the derived member, which will also be added to the type.
ValueDecl *deriveHashable(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement);
@@ -79,7 +75,6 @@ ValueDecl *deriveHashable(TypeChecker &tc,
///
/// \returns the derived member, which will also be added to the type.
ValueDecl *deriveErrorType(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement);
@@ -87,7 +82,6 @@ ValueDecl *deriveErrorType(TypeChecker &tc,
///
/// \returns the derived member, which will also be added to the type.
ValueDecl *deriveBridgedNSError(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *type,
ValueDecl *requirement);
@@ -109,7 +103,6 @@ inline SomeDecl *insertOperatorDecl(ASTContext &C,
/// Declare a getter for a derived property.
FuncDecl *declareDerivedPropertyGetter(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *typeDecl,
Type contextType,
Type propertyInterfaceType,
@@ -119,7 +112,6 @@ FuncDecl *declareDerivedPropertyGetter(TypeChecker &tc,
/// Declare a read-only property with an existing getter.
std::pair<VarDecl *, PatternBindingDecl *>
declareDerivedReadOnlyProperty(TypeChecker &tc,
Decl *parentDecl,
NominalTypeDecl *typeDecl,
Identifier name,
Type propertyInterfaceType,

View File

@@ -5338,13 +5338,6 @@ public:
validateAttributes(TC, ED);
}
// Check conformances before visiting members, since we might
// synthesize bodies for derived conformances
if (!IsFirstPass) {
computeDefaultAccessibility(TC, ED);
checkExplicitConformance(ED, ED->getExtendedType());
}
if (!ED->isInvalid()) {
for (Decl *Member : ED->getMembers())
visit(Member);
@@ -5352,6 +5345,10 @@ public:
visit(Global);
}
if (!IsFirstPass) {
computeDefaultAccessibility(TC, ED);
checkExplicitConformance(ED, ED->getExtendedType());
}
TC.checkDeclAttributes(ED);
}

View File

@@ -2380,7 +2380,7 @@ ResolveWitnessResult ConformanceChecker::resolveWitnessViaDerivation(
}
// Attempt to derive the witness.
auto derived = TC.deriveProtocolRequirement(DC, derivingTypeDecl, requirement);
auto derived = TC.deriveProtocolRequirement(derivingTypeDecl, requirement);
if (!derived)
return ResolveWitnessResult::ExplicitFailed;
@@ -3090,7 +3090,7 @@ void ConformanceChecker::resolveTypeWitnesses() {
return Type();
// Try to derive the type witness.
Type derivedType = TC.deriveTypeWitness(DC, derivingTypeDecl, assocType);
Type derivedType = TC.deriveTypeWitness(derivingTypeDecl, assocType);
if (!derivedType)
return Type();
@@ -3875,8 +3875,7 @@ void TypeChecker::resolveWitness(const NormalProtocolConformance *conformance,
checker.resolveSingleWitness(requirement);
}
ValueDecl *TypeChecker::deriveProtocolRequirement(DeclContext *DC,
NominalTypeDecl *TypeDecl,
ValueDecl *TypeChecker::deriveProtocolRequirement(NominalTypeDecl *TypeDecl,
ValueDecl *Requirement) {
auto *protocol = cast<ProtocolDecl>(Requirement->getDeclContext());
@@ -3885,24 +3884,22 @@ ValueDecl *TypeChecker::deriveProtocolRequirement(DeclContext *DC,
if (!knownKind)
return nullptr;
auto Decl = DC->getInnermostDeclarationDeclContext();
switch (*knownKind) {
case KnownProtocolKind::RawRepresentable:
return DerivedConformance::deriveRawRepresentable(*this, Decl,
return DerivedConformance::deriveRawRepresentable(*this,
TypeDecl, Requirement);
case KnownProtocolKind::Equatable:
return DerivedConformance::deriveEquatable(*this, Decl, TypeDecl, Requirement);
return DerivedConformance::deriveEquatable(*this, TypeDecl, Requirement);
case KnownProtocolKind::Hashable:
return DerivedConformance::deriveHashable(*this, Decl, TypeDecl, Requirement);
return DerivedConformance::deriveHashable(*this, TypeDecl, Requirement);
case KnownProtocolKind::ErrorType:
return DerivedConformance::deriveErrorType(*this, Decl, TypeDecl, Requirement);
return DerivedConformance::deriveErrorType(*this, TypeDecl, Requirement);
case KnownProtocolKind::_BridgedNSError:
return DerivedConformance::deriveBridgedNSError(*this, Decl, TypeDecl,
return DerivedConformance::deriveBridgedNSError(*this, TypeDecl,
Requirement);
default:
@@ -3910,22 +3907,19 @@ ValueDecl *TypeChecker::deriveProtocolRequirement(DeclContext *DC,
}
}
Type TypeChecker::deriveTypeWitness(DeclContext *DC,
NominalTypeDecl *TypeDecl,
AssociatedTypeDecl *AssocType) {
auto *protocol = cast<ProtocolDecl>(AssocType->getDeclContext());
Type TypeChecker::deriveTypeWitness(NominalTypeDecl *nominal,
AssociatedTypeDecl *assocType) {
auto *protocol = cast<ProtocolDecl>(assocType->getDeclContext());
auto knownKind = protocol->getKnownProtocolKind();
if (!knownKind)
return nullptr;
auto Decl = DC->getInnermostDeclarationDeclContext();
switch (*knownKind) {
case KnownProtocolKind::RawRepresentable:
return DerivedConformance::deriveRawRepresentable(*this, Decl,
TypeDecl, AssocType);
return DerivedConformance::deriveRawRepresentable(*this, nominal,
assocType);
default:
return nullptr;

View File

@@ -1253,23 +1253,19 @@ public:
/// Derive an implicit declaration to satisfy a requirement of a derived
/// protocol conformance.
///
/// \param DC The declaration context where the conformance was
/// defined, either the type itself or an extension
/// \param TypeDecl The type for which the requirement is being derived.
/// \param Requirement The protocol requirement.
///
/// \returns nullptr if the derivation failed, or the derived declaration
/// if it succeeded. If successful, the derived declaration is added
/// to TypeDecl's body.
ValueDecl *deriveProtocolRequirement(DeclContext *DC,
NominalTypeDecl *TypeDecl,
ValueDecl *deriveProtocolRequirement(NominalTypeDecl *TypeDecl,
ValueDecl *Requirement);
/// Derive an implicit type witness for the given associated type in
/// the conformance of the given nominal type to some known
/// protocol.
Type deriveTypeWitness(DeclContext *DC,
NominalTypeDecl *nominal,
Type deriveTypeWitness(NominalTypeDecl *nominal,
AssociatedTypeDecl *assocType);
/// \brief Given a set of archetype substitutions, verify and record all of

View File

@@ -3500,8 +3500,8 @@ static void addOperatorsAndTopLevel(Serializer &S, Range members,
bool isDerivedTopLevel,
bool isLocal = false) {
for (const Decl *member : members) {
if (auto memberValue = dyn_cast<ValueDecl>(member)) {
if (!memberValue->hasName())
auto memberValue = dyn_cast<ValueDecl>(member);
if (!memberValue)
continue;
if (isDerivedTopLevel) {
@@ -3518,14 +3518,13 @@ static void addOperatorsAndTopLevel(Serializer &S, Range members,
S.addDeclRef(memberValue)
});
}
}
// Recurse into nested declarations.
if (auto iterable = dyn_cast<IterableDeclContext>(member)) {
addOperatorsAndTopLevel(S, iterable->getMembers(),
// Recurse into nested types.
if (auto nominal = dyn_cast<NominalTypeDecl>(member)) {
addOperatorsAndTopLevel(S, nominal->getMembers(),
operatorMethodDecls, topLevelDecls, objcMethods,
false);
addOperatorsAndTopLevel(S, iterable->getDerivedGlobalDecls(),
addOperatorsAndTopLevel(S, nominal->getDerivedGlobalDecls(),
operatorMethodDecls, topLevelDecls, objcMethods,
true);
}
@@ -3539,7 +3538,7 @@ static void addOperatorsAndTopLevel(Serializer &S, Range members,
objcMethods[func->getObjCSelector()].push_back(
std::make_tuple(owningTypeID,
func->isObjCInstanceMethod(),
S.addDeclRef(func)));
S.addDeclRef(memberValue)));
}
}
}
@@ -3566,30 +3565,36 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
for (auto D : fileDecls) {
if (isa<ImportDecl>(D))
continue;
if (auto VD = dyn_cast<ValueDecl>(D)) {
else if (auto VD = dyn_cast<ValueDecl>(D)) {
if (!VD->hasName())
continue;
topLevelDecls[VD->getName()]
.push_back({ getKindForTable(D), addDeclRef(D) });
// Add operator methods from nominal types.
if (auto nominal = dyn_cast<NominalTypeDecl>(VD)) {
addOperatorsAndTopLevel(*this, nominal->getMembers(),
operatorMethodDecls, topLevelDecls,
objcMethods, false);
addOperatorsAndTopLevel(*this, nominal->getDerivedGlobalDecls(),
operatorMethodDecls, topLevelDecls,
objcMethods, true);
}
} else if (auto ED = dyn_cast<ExtensionDecl>(D)) {
Type extendedTy = ED->getExtendedType();
const NominalTypeDecl *extendedNominal = extendedTy->getAnyNominal();
extensionDecls[extendedNominal->getName()]
.push_back({ getKindForTable(extendedNominal), addDeclRef(D) });
// Add operator methods from extensions.
addOperatorsAndTopLevel(*this, ED->getMembers(),
operatorMethodDecls, topLevelDecls, objcMethods,
false);
} else if (auto OD = dyn_cast<OperatorDecl>(D)) {
operatorDecls[OD->getName()]
.push_back({ getStableFixity(OD->getKind()), addDeclRef(D) });
}
if (auto IDC = dyn_cast<IterableDeclContext>(D)) {
addOperatorsAndTopLevel(*this, IDC->getMembers(),
operatorMethodDecls, topLevelDecls,
objcMethods, false);
addOperatorsAndTopLevel(*this, IDC->getDerivedGlobalDecls(),
operatorMethodDecls, topLevelDecls,
objcMethods, true);
}
}
SmallVector<TypeDecl *, 16> localTypeDecls;
@@ -3609,11 +3614,11 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
addDeclRef(TD), TD->getLocalDiscriminator()
});
if (auto IDC = dyn_cast<IterableDeclContext>(TD)) {
addOperatorsAndTopLevel(*this, IDC->getMembers(),
if (auto nominal = dyn_cast<NominalTypeDecl>(TD)) {
addOperatorsAndTopLevel(*this, nominal->getMembers(),
operatorMethodDecls, topLevelDecls,
objcMethods, false, /*isLocal=*/true);
addOperatorsAndTopLevel(*this, IDC->getDerivedGlobalDecls(),
addOperatorsAndTopLevel(*this, nominal->getDerivedGlobalDecls(),
operatorMethodDecls, topLevelDecls,
objcMethods, true, /*isLocal=*/true);
}

View File

@@ -1,15 +0,0 @@
public enum TrafficLight {
case Red
case Yellow
case Green
}
public enum Term<T, U> {
case Value(U)
case Function(T, U)
}
public enum Phantom<T> : Int {
case Up
case Down
}

View File

@@ -1,10 +1,5 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: %target-swift-frontend -emit-module -module-name def_enum -o %t %S/Inputs/def_enum.swift
// RUN: %target-swift-frontend -I %t -O -primary-file %s -emit-ir | FileCheck -check-prefix=CHECK -check-prefix=CHECK-NORMAL %s
// RUN: %target-swift-frontend -I %t -O -primary-file %s -enable-testing -emit-ir | FileCheck -check-prefix=CHECK -check-prefix=CHECK-TESTABLE %s
import def_enum
// RUN: %target-swift-frontend -O -primary-file %s -emit-ir | FileCheck -check-prefix=CHECK -check-prefix=CHECK-NORMAL %s
// RUN: %target-swift-frontend -O -primary-file %s -enable-testing -emit-ir | FileCheck -check-prefix=CHECK -check-prefix=CHECK-TESTABLE %s
// Check if the hashValue and == for an enum (without payload) are generated and
// check if that functions are compiled in an optimal way.
@@ -29,23 +24,3 @@ enum E {
// CHECK-TESTABLE-LABEL:define i1 @_TZF12enum_derivedoi2eeFTOS_1ES0__Sb(i2, i2)
// CHECK: %2 = icmp eq i2 %0, %1
// CHECK: ret i1 %2
// Derived conformances from extensions
// The actual enums are in Inputs/def_enum.swift
extension def_enum.TrafficLight : ErrorType {}
// CHECK-LABEL: define { i8*, i64, i64 } @_TFE12enum_derivedO8def_enum12TrafficLightg7_domainSS(i2) #0
// CHECK-LABEL: define i64 @_TFE12enum_derivedO8def_enum12TrafficLightg5_codeSi(i2)
extension def_enum.Term : ErrorType {}
// CHECK-NORMAL-LABEL: define hidden i64 @_TFO12enum_derived7Phantomg8rawValueSi(i1, %swift.type* nocapture readnone %T) #1
// CHECK-TESTABLE-LABEL: define i64 @_TFO12enum_derived7Phantomg8rawValueSi(i1, %swift.type* nocapture readnone %T) #1
enum Phantom<T> : Int {
case Up
case Down
}
extension Phantom : RawRepresentable {}

View File

@@ -34,7 +34,7 @@ enum CustomHashable {
var hashValue: Int { return 0 }
}
func ==(x: CustomHashable, y: CustomHashable) -> Bool { // expected-note{{non-matching type}}
func ==(x: CustomHashable, y: CustomHashable) -> Bool {
return true
}
@@ -49,7 +49,7 @@ enum InvalidCustomHashable {
var hashValue: String { return "" } // expected-note{{previously declared here}}
}
func ==(x: InvalidCustomHashable, y: InvalidCustomHashable) -> String { // expected-note{{non-matching type}}
func ==(x: InvalidCustomHashable, y: InvalidCustomHashable) -> String {
return ""
}
if InvalidCustomHashable.A == .B { }
@@ -100,27 +100,3 @@ private enum Bar<T> {
}
}
}
// Equatable extension -- rdar://20981254
enum Instrument {
case Piano
case Violin
case Guitar
}
extension Instrument : Equatable {}
// Explicit conformance should work too
public enum Medicine {
case Antibiotic
case Antihistamine
}
extension Medicine : Equatable {}
public func ==(lhs: Medicine, rhs: Medicine) -> Bool { // expected-note{{non-matching type}}
return true
}
// No explicit conformance and cannot be derived
extension Complex : Hashable {} // expected-error 2 {{does not conform}}

View File

@@ -31,9 +31,3 @@ public enum Lazy<T> : Computable {
// }
}
}
public enum Breakfast<Champions> : Int {
case Eggs
case Bacon
case Coffee
}

View File

@@ -1,3 +0,0 @@
extension Breakfast : RawRepresentable {}
extension Breakfast : ErrorType {}

View File

@@ -1,6 +1,6 @@
// RUN: rm -rf %t
// RUN: mkdir %t
// RUN: %target-swift-frontend -emit-module -module-name def_enum -o %t %S/Inputs/def_enum.swift %S/Inputs/def_enum_derived.swift
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/def_enum.swift
// RUN: llvm-bcanalyzer %t/def_enum.swiftmodule | FileCheck %s
// RUN: %target-swift-frontend -parse -I %t %s -o /dev/null
// RUN: %target-swift-frontend -emit-sil -I %t %s -o /dev/null
@@ -30,9 +30,3 @@ var comp : Computable = lazy
comp.compute()
lazy.compute()
struct Tea {}
let meal = Breakfast<Basic>.Bacon
let n = meal.rawValue
do { throw meal } catch {}