Skip to content

Commit d866ebf

Browse files
authored
Merge pull request #11744 from gspiers/bugfix/SR-479-ownership-in-protocols
[SE implementation] Ownership keyword removal in protocols
2 parents a1fbf9d + c5d6e17 commit d866ebf

File tree

7 files changed

+69
-3
lines changed

7 files changed

+69
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3120,6 +3120,13 @@ ERROR(invalid_weak_ownership_not_optional,none,
31203120
"'weak' variable should have optional type %0", (Type))
31213121
ERROR(invalid_weak_let,none,
31223122
"'weak' must be a mutable variable, because it may change at runtime", ())
3123+
ERROR(ownership_invalid_in_protocols,none,
3124+
"'%select{strong|weak|unowned|unowned}0' cannot be applied to a property declaration in a protocol",
3125+
(/*Ownership*/unsigned))
3126+
WARNING(ownership_invalid_in_protocols_compat_warning,none,
3127+
"'%select{strong|weak|unowned|unowned}0' should not be applied to a property declaration "
3128+
"in a protocol and will be disallowed in future versions",
3129+
(/*Ownership*/unsigned))
31233130

31243131
// required
31253132
ERROR(required_initializer_nonclass,none,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,10 @@ void TypeChecker::checkTypeModifyingDeclAttributes(VarDecl *var) {
20062006
}
20072007

20082008
void TypeChecker::checkOwnershipAttr(VarDecl *var, OwnershipAttr *attr) {
2009+
// Don't check ownership attribute if the declaration is already marked invalid.
2010+
if (var->isInvalid())
2011+
return;
2012+
20092013
Type type = var->getType();
20102014
Type interfaceType = var->getInterfaceType();
20112015

@@ -2053,6 +2057,20 @@ void TypeChecker::checkOwnershipAttr(VarDecl *var, OwnershipAttr *attr) {
20532057

20542058
diagnose(var->getStartLoc(), D, (unsigned) ownershipKind, underlyingType);
20552059
attr->setInvalid();
2060+
} else if (dyn_cast<ProtocolDecl>(var->getDeclContext())) {
2061+
// Ownership does not make sense in protocols.
2062+
if (Context.isSwiftVersionAtLeast(5))
2063+
diagnose(attr->getLocation(),
2064+
diag::ownership_invalid_in_protocols,
2065+
(unsigned) ownershipKind)
2066+
.fixItRemove(attr->getRange());
2067+
else
2068+
diagnose(attr->getLocation(),
2069+
diag::ownership_invalid_in_protocols_compat_warning,
2070+
(unsigned) ownershipKind)
2071+
.fixItRemove(attr->getRange());
2072+
2073+
attr->setInvalid();
20562074
}
20572075

20582076
if (attr->isInvalid())
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 4
2+
// Generate a swift 4 compatible warning if ownership is specified in a protocol
3+
4+
class SomeClass {}
5+
6+
protocol P {
7+
weak var foo: SomeClass? { get set } // expected-warning {{'weak' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
8+
unowned var foo2: SomeClass { get set } // expected-warning {{'unowned' should not be applied to a property declaration in a protocol and will be disallowed in future versions}}
9+
weak var foo3: Int? { get set } // expected-error {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}}
10+
unowned var foo4: Int { get set } // expected-error {{'unowned' may only be applied to class and class-bound protocol types, not 'Int'}}
11+
}
12+

test/SILGen/Inputs/weak_other.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ extension Router {
1111
}
1212

1313
public protocol Environment : class {
14-
unowned var router: Router { get }
14+
var router: Router { get }
1515
}
1616

1717
open class UI {

test/SILGen/properties.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ struct ObservingPropertiesWithOwnershipTypesInferred {
850850

851851
// <rdar://problem/16554876> property accessor synthesization of weak variables doesn't work
852852
protocol WeakPropertyProtocol {
853-
weak var maybePresent : Ref? { get set }
853+
var maybePresent : Ref? { get set }
854854
}
855855

856856
struct WeakPropertyStruct : WeakPropertyProtocol {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
2+
3+
class SomeClass {}
4+
5+
protocol P {
6+
weak var foo: SomeClass? { get set } // expected-error {{'weak' cannot be applied to a property declaration in a protocol}}
7+
unowned var foo2: SomeClass { get set } // expected-error {{'unowned' cannot be applied to a property declaration in a protocol}}
8+
weak var foo3: Int? { get set } // expected-error {{'weak' may only be applied to class and class-bound protocol types, not 'Int'}}
9+
unowned var foo4: Int { get set } // expected-error {{'unowned' may only be applied to class and class-bound protocol types, not 'Int'}}
10+
var foo9: SomeClass? { get }
11+
}
12+
13+
extension P {
14+
weak var foo5: SomeClass? // expected-error {{extensions must not contain stored properties}}
15+
unowned var foo6: SomeClass // expected-error {{extensions must not contain stored properties}}
16+
17+
weak var foo7: SomeClass? { // Okay
18+
return SomeClass()
19+
}
20+
21+
unowned var foo8: SomeClass { // Okay
22+
return SomeClass()
23+
}
24+
25+
weak var foo9: SomeClass? { // Okay
26+
return nil
27+
}
28+
}
29+

test/stdlib/WeakMirror.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ mirrors.test("struct/StructHasNativeWeakReference") {
103103
import Foundation
104104

105105
@objc protocol ObjCClassExistential : class {
106-
weak var weakProperty: AnyObject? { get set }
106+
var weakProperty: AnyObject? { get set }
107107
var x: Int { get }
108108
}
109109

0 commit comments

Comments
 (0)