Skip to content

Commit 362047f

Browse files
authored
Merge pull request #29679 from slavapestov/fix-enum-error-case-alias
ClangImporter: Fix importEnumCaseAlias() when the original is itself an alias
2 parents 1ed846d + b903382 commit 362047f

File tree

5 files changed

+58
-13
lines changed

5 files changed

+58
-13
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5823,23 +5823,38 @@ Decl *SwiftDeclConverter::importEnumCaseAlias(
58235823
if (!importIntoDC)
58245824
importIntoDC = importedEnum;
58255825

5826-
// Construct the original constant. Enum constants without payloads look
5827-
// like simple values, but actually have type 'MyEnum.Type -> MyEnum'.
5828-
auto constantRef =
5829-
new (Impl.SwiftContext) DeclRefExpr(original, DeclNameLoc(),
5830-
/*implicit*/ true);
5831-
constantRef->setType(original->getInterfaceType());
5832-
58335826
Type importedEnumTy = importedEnum->getDeclaredInterfaceType();
5834-
58355827
auto typeRef = TypeExpr::createImplicit(importedEnumTy, Impl.SwiftContext);
5836-
auto instantiate = new (Impl.SwiftContext)
5837-
DotSyntaxCallExpr(constantRef, SourceLoc(), typeRef);
5838-
instantiate->setType(importedEnumTy);
5839-
instantiate->setThrows(false);
5828+
5829+
Expr *result = nullptr;
5830+
if (auto *enumElt = dyn_cast<EnumElementDecl>(original)) {
5831+
assert(!enumElt->hasAssociatedValues());
5832+
5833+
// Construct the original constant. Enum constants without payloads look
5834+
// like simple values, but actually have type 'MyEnum.Type -> MyEnum'.
5835+
auto constantRef =
5836+
new (Impl.SwiftContext) DeclRefExpr(enumElt, DeclNameLoc(),
5837+
/*implicit*/ true);
5838+
constantRef->setType(enumElt->getInterfaceType());
5839+
5840+
auto instantiate = new (Impl.SwiftContext)
5841+
DotSyntaxCallExpr(constantRef, SourceLoc(), typeRef);
5842+
instantiate->setType(importedEnumTy);
5843+
instantiate->setThrows(false);
5844+
5845+
result = instantiate;
5846+
} else {
5847+
assert(isa<VarDecl>(original));
5848+
5849+
result =
5850+
new (Impl.SwiftContext) MemberRefExpr(typeRef, SourceLoc(),
5851+
original, DeclNameLoc(),
5852+
/*implicit*/ true);
5853+
result->setType(original->getInterfaceType());
5854+
}
58405855

58415856
Decl *CD = Impl.createConstant(name, importIntoDC, importedEnumTy,
5842-
instantiate, ConstantConvertKind::None,
5857+
result, ConstantConvertKind::None,
58435858
/*isStatic*/ true, alias);
58445859
Impl.importAttributes(alias, CD);
58455860
return CD;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
Name: AliasCaseErrorEnum
3+
Tags:
4+
- Name: AliasError
5+
NSErrorDomain: AliasErrorDomain
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@import Foundation;
2+
3+
#define kAliasErrorDomain "com.acme.AliasErrorDomain"
4+
5+
extern NSString *const __nonnull AliasErrorDomain;
6+
7+
typedef NS_ENUM(NSInteger, AliasError) {
8+
AliasErrorRealName = 1,
9+
AliasErrorFakeName = 1,
10+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module AliasCaseErrorEnum {
2+
umbrella header "AliasCaseErrorEnum.h"
3+
export *
4+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-sil %s -enable-objc-interop -I %S/Inputs/custom-modules/AliasCaseErrorEnum
2+
3+
// REQUIRES: objc_interop
4+
5+
import AliasCaseErrorEnum
6+
7+
// Make sure that we can reference aliases defined in the wrapper type
8+
// which themselves point at aliases inside the nested 'Code' type.
9+
10+
_ = AliasError.realName
11+
_ = AliasError.fakeName

0 commit comments

Comments
 (0)