Skip to content

Commit cddec31

Browse files
authored
Merge pull request #25099 from theblixguy/fix/SR-10084
[5.1] [Typechecker] Allow static functions to overload enum cases
2 parents c01e5cd + f26e326 commit cddec31

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed

include/swift/AST/Decl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,15 @@ struct OverloadSignature {
220220
/// Whether this is a function.
221221
unsigned IsFunction : 1;
222222

223+
/// Whether this is a enum element.
224+
unsigned IsEnumElement : 1;
225+
226+
/// Whether this is a nominal type.
227+
unsigned IsNominal : 1;
228+
229+
/// Whether this is a type alias.
230+
unsigned IsTypeAlias : 1;
231+
223232
/// Whether this signature is part of a protocol extension.
224233
unsigned InProtocolExtension : 1;
225234

lib/AST/Decl.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,32 @@ bool swift::conflicting(ASTContext &ctx,
21652165
if (!conflicting(sig1, sig2, skipProtocolExtensionCheck))
21662166
return false;
21672167

2168+
// Functions and enum elements do not conflict with each other if their types
2169+
// are different.
2170+
if (((sig1.IsFunction && sig2.IsEnumElement) ||
2171+
(sig1.IsEnumElement && sig2.IsFunction)) &&
2172+
sig1Type != sig2Type) {
2173+
return false;
2174+
}
2175+
2176+
// Nominal types and enum elements always conflict with each other.
2177+
if ((sig1.IsNominal && sig2.IsEnumElement) ||
2178+
(sig1.IsEnumElement && sig2.IsNominal)) {
2179+
return true;
2180+
}
2181+
2182+
// Typealiases and enum elements always conflict with each other.
2183+
if ((sig1.IsTypeAlias && sig2.IsEnumElement) ||
2184+
(sig1.IsEnumElement && sig2.IsTypeAlias)) {
2185+
return true;
2186+
}
2187+
2188+
// Enum elements always conflict with each other. At this point, they
2189+
// have the same base name but different types.
2190+
if (sig1.IsEnumElement && sig2.IsEnumElement) {
2191+
return true;
2192+
}
2193+
21682194
// Functions always conflict with non-functions with the same signature.
21692195
// In practice, this only applies for zero argument functions.
21702196
if (sig1.IsFunction != sig2.IsFunction)
@@ -2336,6 +2362,9 @@ OverloadSignature ValueDecl::getOverloadSignature() const {
23362362
signature.IsInstanceMember = isInstanceMember();
23372363
signature.IsVariable = isa<VarDecl>(this);
23382364
signature.IsFunction = isa<AbstractFunctionDecl>(this);
2365+
signature.IsEnumElement = isa<EnumElementDecl>(this);
2366+
signature.IsNominal = isa<NominalTypeDecl>(this);
2367+
signature.IsTypeAlias = isa<TypeAliasDecl>(this);
23392368
signature.HasOpaqueReturnType =
23402369
!signature.IsVariable && (bool)getOpaqueResultTypeDecl();
23412370

@@ -2388,6 +2417,13 @@ CanType ValueDecl::getOverloadSignatureType() const {
23882417
->getCanonicalType();
23892418
}
23902419

2420+
if (isa<EnumElementDecl>(this)) {
2421+
auto mappedType = mapSignatureFunctionType(
2422+
getASTContext(), getInterfaceType(), /*topLevelFunction=*/false,
2423+
/*isMethod=*/false, /*isInitializer=*/false, /*curryLevels=*/0);
2424+
return mappedType->getCanonicalType();
2425+
}
2426+
23912427
// Note: If you add more cases to this function, you should update the
23922428
// implementation of the swift::conflicting overload that deals with
23932429
// overload types, in order to account for cases where the overload types

test/decl/overload.swift

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,5 +486,122 @@ extension SR7250 where T : P3 {
486486
subscript(i: Int) -> String { return "" }
487487
}
488488

489+
// SR-10084
489490

491+
struct SR_10084_S {
492+
let name: String
493+
}
494+
495+
enum SR_10084_E {
496+
case foo(SR_10084_S) // expected-note {{'foo' previously declared here}}
497+
498+
static func foo(_ name: String) -> SR_10084_E { // Okay
499+
return .foo(SR_10084_S(name: name))
500+
}
501+
502+
func foo(_ name: Bool) -> SR_10084_E { // Okay
503+
return .foo(SR_10084_S(name: "Test"))
504+
}
505+
506+
static func foo(_ value: SR_10084_S) -> SR_10084_E { // expected-error {{invalid redeclaration of 'foo'}}
507+
return .foo(value)
508+
}
509+
}
510+
511+
enum SR_10084_E_1 {
512+
static func foo(_ name: String) -> SR_10084_E_1 { // Okay
513+
return .foo(SR_10084_S(name: name))
514+
}
515+
516+
static func foo(_ value: SR_10084_S) -> SR_10084_E_1 { // expected-note {{'foo' previously declared here}}
517+
return .foo(value)
518+
}
519+
520+
case foo(SR_10084_S) // expected-error {{invalid redeclaration of 'foo'}}
521+
}
522+
523+
enum SR_10084_E_2 {
524+
case fn(() -> Void) // expected-note {{'fn' previously declared here}}
525+
526+
static func fn(_ x: @escaping () -> Void) -> SR_10084_E_2 { // expected-error {{invalid redeclaration of 'fn'}}
527+
fatalError()
528+
}
529+
530+
static func fn(_ x: @escaping () -> Int) -> SR_10084_E_2 { // Okay
531+
fatalError()
532+
}
533+
534+
static func fn(_ x: @escaping () -> Bool) -> SR_10084_E_2 { // Okay
535+
fatalError()
536+
}
537+
}
538+
539+
enum SR_10084_E_3 {
540+
protocol A {} //expected-error {{protocol 'A' cannot be nested inside another declaration}} // expected-note {{'A' previously declared here}}
541+
case A // expected-error {{invalid redeclaration of 'A'}}
542+
}
543+
544+
enum SR_10084_E_4 {
545+
class B {} // expected-note {{'B' previously declared here}}
546+
case B // expected-error {{invalid redeclaration of 'B'}}
547+
}
548+
549+
enum SR_10084_E_5 {
550+
struct C {} // expected-note {{'C' previously declared here}}
551+
case C // expected-error {{invalid redeclaration of 'C'}}
552+
}
553+
554+
enum SR_10084_E_6 {
555+
case D // expected-note {{'D' previously declared here}}
556+
protocol D {} //expected-error {{protocol 'D' cannot be nested inside another declaration}} // expected-error {{invalid redeclaration of 'D'}}
557+
}
558+
559+
enum SR_10084_E_7 {
560+
case E // expected-note {{'E' previously declared here}}
561+
class E {} // expected-error {{invalid redeclaration of 'E'}}
562+
}
563+
564+
enum SR_10084_E_8 {
565+
case F // expected-note {{'F' previously declared here}}
566+
struct F {} // expected-error {{invalid redeclaration of 'F'}}
567+
}
568+
569+
enum SR_10084_E_9 {
570+
case A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}}
571+
static let A: SR_10084_E_9 = .A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}} // expected-error {{ambiguous use of 'A'}}
572+
}
573+
574+
enum SR_10084_E_10 {
575+
static let A: SR_10084_E_10 = .A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}} // expected-error {{ambiguous use of 'A'}}
576+
case A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}}
577+
}
578+
579+
enum SR_10084_E_11 {
580+
case A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}}
581+
static var A: SR_10084_E_11 = .A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}} // expected-error {{ambiguous use of 'A'}}
582+
}
583+
584+
enum SR_10084_E_12 {
585+
static var A: SR_10084_E_12 = .A // expected-note {{found this candidate}} // expected-note {{'A' previously declared here}} // expected-error {{ambiguous use of 'A'}}
586+
case A // expected-note {{found this candidate}} // expected-error {{invalid redeclaration of 'A'}}
587+
}
588+
589+
enum SR_10084_E_13 {
590+
case X // expected-note {{'X' previously declared here}}
591+
struct X<T> {} // expected-error {{invalid redeclaration of 'X'}}
592+
}
593+
594+
enum SR_10084_E_14 {
595+
struct X<T> {} // expected-note {{'X' previously declared here}}
596+
case X // expected-error {{invalid redeclaration of 'X'}}
597+
}
598+
599+
enum SR_10084_E_15 {
600+
case Y // expected-note {{'Y' previously declared here}}
601+
typealias Y = Int // expected-error {{invalid redeclaration of 'Y'}}
602+
}
490603

604+
enum SR_10084_E_16 {
605+
typealias Z = Int // expected-note {{'Z' previously declared here}}
606+
case Z // expected-error {{invalid redeclaration of 'Z'}}
607+
}

0 commit comments

Comments
 (0)