Skip to content

Commit cca7ab0

Browse files
authored
Merge pull request #17414 from huonw/redefinition-swift-4-compat-4.2
[4.2] Swift 4 compatibility hack for redeclaration of properties in generic type and extension
2 parents 8199e8d + 4741777 commit cca7ab0

File tree

7 files changed

+54
-9
lines changed

7 files changed

+54
-9
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ ERROR(reserved_member_name,none,
622622

623623
ERROR(invalid_redecl,none,"invalid redeclaration of %0", (DeclName))
624624
WARNING(invalid_redecl_swift5_warning,none,
625-
"redeclaration of %0 is deprecated and will be illegal in Swift 5",
625+
"redeclaration of %0 is deprecated and will be an error in Swift 5",
626626
(DeclName))
627627

628628
NOTE(invalid_redecl_prev,none,

lib/AST/Decl.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,30 @@ bool swift::conflicting(ASTContext &ctx,
17681768
}
17691769

17701770
// Otherwise, the declarations conflict if the overload types are the same.
1771-
return sig1Type == sig2Type;
1771+
if (sig1Type != sig2Type)
1772+
return false;
1773+
1774+
// The Swift 5 overload types are the same, but similar to the above, prior to
1775+
// Swift 5, a variable not in an extension of a generic type got a null
1776+
// overload type instead of a function type as it does now, so we really
1777+
// follow that behaviour and warn if there's going to be a conflict in future.
1778+
if (!ctx.isSwiftVersionAtLeast(5)) {
1779+
auto swift4Sig1Type = sig1.IsVariable && !sig1.InExtensionOfGenericType
1780+
? CanType()
1781+
: sig1Type;
1782+
auto swift4Sig2Type = sig1.IsVariable && !sig2.InExtensionOfGenericType
1783+
? CanType()
1784+
: sig1Type;
1785+
if (swift4Sig1Type != swift4Sig2Type) {
1786+
// Old was different to the new behaviour!
1787+
if (wouldConflictInSwift5)
1788+
*wouldConflictInSwift5 = true;
1789+
1790+
return false;
1791+
}
1792+
}
1793+
1794+
return true;
17721795
}
17731796

17741797
static Type mapSignatureFunctionType(ASTContext &ctx, Type type,

lib/Sema/TypeCheckDecl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,6 +1063,17 @@ static void checkRedeclaration(TypeChecker &tc, ValueDecl *current) {
10631063
continue;
10641064
}
10651065

1066+
// If both are VarDecls, and both have exactly the same type, then
1067+
// matching the Swift 4 behaviour (i.e. just emitting the future-compat
1068+
// warning) will result in SILGen crashes due to both properties mangling
1069+
// the same, so it's better to just follow the Swift 5 behaviour and emit
1070+
// the actual error.
1071+
if (wouldBeSwift5Redeclaration && isa<VarDecl>(current) &&
1072+
isa<VarDecl>(other) &&
1073+
current->getInterfaceType()->isEqual(other->getInterfaceType())) {
1074+
wouldBeSwift5Redeclaration = false;
1075+
}
1076+
10661077
// If this isn't a redeclaration in the current version of Swift, but
10671078
// would be in Swift 5 mode, emit a warning instead of an error.
10681079
if (wouldBeSwift5Redeclaration) {

test/IDE/complete_value_expr.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,15 +1656,15 @@ func testDeDuped(_ x: dedupS) {
16561656
}
16571657
func testDeDuped2(_ x: dedupP) {
16581658
x#^PROTOCOL_EXT_DEDUP_2^#
1659-
// PROTOCOL_EXT_DEDUP_2: Begin completions, 3 items
1659+
// PROTOCOL_EXT_DEDUP_2: Begin completions, 4 items
16601660
// PROTOCOL_EXT_DEDUP_2: Decl[InstanceMethod]/CurrNominal: .foo()[#dedupP.T#]; name=foo()
16611661
// PROTOCOL_EXT_DEDUP_2: Decl[InstanceVar]/CurrNominal: .bar[#dedupP.T#]; name=bar
16621662
// PROTOCOL_EXT_DEDUP_2: Decl[Subscript]/CurrNominal: [{#Self.T#}][#Self.T#]; name=[Self.T]
16631663
// PROTOCOL_EXT_DEDUP_2: End completions
16641664
}
16651665
func testDeDuped3<T : dedupP where T.T == Int>(_ x: T) {
16661666
x#^PROTOCOL_EXT_DEDUP_3^#
1667-
// PROTOCOL_EXT_DEDUP_3: Begin completions, 3 items
1667+
// PROTOCOL_EXT_DEDUP_3: Begin completions, 4 items
16681668
// PROTOCOL_EXT_DEDUP_3: Decl[InstanceMethod]/Super: .foo()[#Int#]; name=foo()
16691669
// PROTOCOL_EXT_DEDUP_3: Decl[InstanceVar]/Super: .bar[#Int#]; name=bar
16701670
// PROTOCOL_EXT_DEDUP_3: Decl[Subscript]/Super: [{#Self.T#}][#Self.T#]; name=[Self.T]

test/decl/overload.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ struct SR7249<T> {
448448
}
449449

450450
extension SR7249 {
451-
var x: Int { fatalError() } // expected-error{{invalid redeclaration of 'x'}}
452-
var y: T { fatalError() } // expected-error{{invalid redeclaration of 'y'}}
451+
var x: Int { fatalError() } // expected-warning{{redeclaration of 'x' is deprecated and will be an error in Swift 5}}
452+
var y: T { fatalError() } // expected-warning{{redeclaration of 'y' is deprecated and will be an error in Swift 5}}
453453
var z: Int { fatalError() } // expected-error{{invalid redeclaration of 'z'}}
454454
}
455455

test/decl/overload_swift4.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ extension SR7251 {
99
// expected-note@-1 {{previously declared here}}
1010
// expected-note@-2 {{previously declared here}}
1111

12-
struct i {} // expected-warning {{redeclaration of 'i' is deprecated and will be illegal in Swift 5}}
13-
typealias i = Int // expected-warning {{redeclaration of 'i' is deprecated and will be illegal in Swift 5}}
12+
struct i {} // expected-warning {{redeclaration of 'i' is deprecated and will be an error in Swift 5}}
13+
typealias i = Int // expected-warning {{redeclaration of 'i' is deprecated and will be an error in Swift 5}}
1414

15-
static var j: Int { return 0 } // expected-warning {{redeclaration of 'j' is deprecated and will be illegal in Swift 5}}
15+
static var j: Int { return 0 } // expected-warning {{redeclaration of 'j' is deprecated and will be an error in Swift 5}}
1616

1717
struct k {} // expected-error{{invalid redeclaration of 'k'}}
1818
}

test/decl/overload_swift5.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,14 @@ extension SR7251 {
1111
struct k {} // expected-error{{invalid redeclaration of 'k'}}
1212
}
1313

14+
struct SR7249<T> {
15+
var x: T { fatalError() } // expected-note {{previously declared}}
16+
var y: Int // expected-note {{previously declared}}
17+
var z: Int // expected-note {{previously declared}}
18+
}
19+
20+
extension SR7249 {
21+
var x: Int { fatalError() } // expected-error{{invalid redeclaration of 'x'}}
22+
var y: T { fatalError() } // expected-error{{invalid redeclaration of 'y'}}
23+
var z: Int { fatalError() } // expected-error{{invalid redeclaration of 'z'}}
24+
}

0 commit comments

Comments
 (0)