Skip to content

Commit a24121a

Browse files
authored
Merge pull request #13417 from DougGregor/override-objc-diag
2 parents 68a4545 + cabdf84 commit a24121a

File tree

13 files changed

+92
-42
lines changed

13 files changed

+92
-42
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,10 +1795,13 @@ NOTE(overridden_near_match_here,none,
17951795
"potential overridden %0 %1 here",
17961796
(DescriptiveDeclKind, DeclName))
17971797
ERROR(override_decl_extension,none,
1798-
"overriding declarations %select{in extensions|from extensions}0 "
1799-
"is not supported", (bool))
1798+
"overriding %select{|non-@objc }0declarations "
1799+
"%select{in extensions|from extensions}0 is not supported", (bool, bool))
18001800
NOTE(overridden_here,none,
18011801
"overridden declaration is here", ())
1802+
NOTE(overridden_here_can_be_objc,none,
1803+
"add '@objc' to make this declaration overridable", ())
1804+
18021805
ERROR(override_objc_type_mismatch_method,none,
18031806
"overriding method with selector %0 has incompatible type %1",
18041807
(ObjCSelector, Type))

include/swift/AST/RequirementEnvironment.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- RequirementEnvironment.h - Swift Language Type ASTs ----*- C++ -*-===//
1+
//===--- RequirementEnvironment.h - Requirement Environments ----*- C++ -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//

lib/AST/RequirementEnvironment.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===--- RequirementEnvironment.cpp - ASTContext Implementation -----------===//
1+
//===--- RequirementEnvironment.cpp - Requirement Environments ------------===//
22
//
33
// This source file is part of the Swift.org open source project
44
//

lib/Sema/TypeCheckDecl.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6687,9 +6687,18 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
66876687
if ((base->getDeclContext()->isExtensionContext() ||
66886688
override->getDeclContext()->isExtensionContext()) &&
66896689
!base->isObjC() && !isKnownObjC) {
6690-
TC.diagnose(override, diag::override_decl_extension,
6691-
!override->getDeclContext()->isExtensionContext());
6692-
TC.diagnose(base, diag::overridden_here);
6690+
bool baseCanBeObjC = TC.canBeRepresentedInObjC(base);
6691+
TC.diagnose(override, diag::override_decl_extension, baseCanBeObjC,
6692+
!base->getDeclContext()->isExtensionContext());
6693+
if (baseCanBeObjC) {
6694+
SourceLoc insertionLoc =
6695+
override->getAttributeInsertionLoc(/*forModifier=*/false);
6696+
TC.diagnose(base, diag::overridden_here_can_be_objc)
6697+
.fixItInsert(insertionLoc, "@objc ");
6698+
} else {
6699+
TC.diagnose(base, diag::overridden_here);
6700+
}
6701+
66936702
return true;
66946703
}
66956704

lib/Sema/TypeCheckType.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3945,6 +3945,26 @@ bool TypeChecker::isRepresentableInObjC(const SubscriptDecl *SD,
39453945
return Result;
39463946
}
39473947

3948+
bool TypeChecker::canBeRepresentedInObjC(const ValueDecl *decl) {
3949+
if (!Context.LangOpts.EnableObjCInterop)
3950+
return false;
3951+
3952+
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
3953+
Optional<ForeignErrorConvention> errorConvention;
3954+
return isRepresentableInObjC(func, ObjCReason::MemberOfObjCMembersClass,
3955+
errorConvention);
3956+
}
3957+
3958+
if (auto var = dyn_cast<VarDecl>(decl))
3959+
return isRepresentableInObjC(var, ObjCReason::MemberOfObjCMembersClass);
3960+
3961+
if (auto subscript = dyn_cast<SubscriptDecl>(decl))
3962+
return isRepresentableInObjC(subscript,
3963+
ObjCReason::MemberOfObjCMembersClass);
3964+
3965+
return false;
3966+
}
3967+
39483968
void TypeChecker::diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
39493969
Type T,
39503970
SourceRange TypeRange) {

lib/Sema/TypeChecker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,6 +2265,8 @@ class TypeChecker final : public LazyResolver {
22652265
bool isRepresentableInObjC(const VarDecl *VD, ObjCReason Reason);
22662266
bool isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason);
22672267

2268+
bool canBeRepresentedInObjC(const ValueDecl *decl);
2269+
22682270
void diagnoseTypeNotRepresentableInObjC(const DeclContext *DC,
22692271
Type T, SourceRange TypeRange);
22702272

test/Compatibility/attr_override.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class A {
6767
set { }
6868
}
6969

70-
func overriddenInExtension() {} // expected-note {{overridden declaration is here}}
70+
func overriddenInExtension() {} // expected-note {{overri}}
7171
}
7272

7373
class B : A {
@@ -140,7 +140,7 @@ class B : A {
140140
}
141141

142142
extension B {
143-
override func overriddenInExtension() {} // expected-error{{overriding declarations in extensions is not supported}}
143+
override func overriddenInExtension() {} // expected-error{{overri}}
144144
}
145145

146146
struct S {

test/attr/attr_objc_override.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -swift-version 4
22
//
33
// REQUIRES: objc_interop
44

@@ -8,16 +8,32 @@ class MixedKeywordsAndAttributes { // expected-note{{in declaration of 'MixedKey
88
}
99

1010
@objc class ObjCClass {}
11+
struct SwiftStruct { }
1112

1213
class A {
1314
@objc subscript (a: ObjCClass) -> ObjCClass { // expected-note{{overridden declaration here has type '(ObjCClass) -> ObjCClass'}}
1415
get { return ObjCClass() }
1516
}
17+
18+
func bar() { } // expected-note{{add '@objc' to make this declaration overridable}}{{3-3=@objc }}
19+
}
20+
21+
extension A {
22+
func foo() { } // expected-note{{add '@objc' to make this declaration overridable}}{{3-3=@objc }}
23+
func wibble(_: SwiftStruct) { } // expected-note{{overridden declaration is here}}
1624
}
1725

1826
class B : A {
1927
// Objective-C
2028
@objc subscript (a: ObjCClass) -> AnyObject { // expected-error{{overriding keyed subscript with incompatible type '(ObjCClass) -> AnyObject'}}
2129
get { return self }
2230
}
31+
32+
override func foo() { } // expected-error{{overriding non-@objc declarations from extensions is not supported}}
33+
34+
override func wibble(_: SwiftStruct) { } // expected-error{{overriding declarations in extensions is not supported}}
35+
}
36+
37+
extension B {
38+
override func bar() { } // expected-error{{overriding non-@objc declarations from extensions is not supported}}
2339
}

test/attr/attr_override.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class A {
6767
set { }
6868
}
6969

70-
func overriddenInExtension() {} // expected-note {{overridden declaration is here}}
70+
func overriddenInExtension() {} // expected-note {{overr}}
7171
}
7272

7373
class B : A {
@@ -140,7 +140,7 @@ class B : A {
140140
}
141141

142142
extension B {
143-
override func overriddenInExtension() {} // expected-error{{overriding declarations in extensions is not supported}}
143+
override func overriddenInExtension() {} // expected-error{{overr}}
144144
}
145145

146146
struct S {

test/decl/class/classes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class B : A {
66
func g() -> (B, B) { return (B(), B()) } // expected-error {{declaration 'g()' cannot override more than one superclass declaration}}
77
override func h() -> (A, B) { return (B(), B()) } // expected-note {{'h()' previously overridden here}}
88
override func h() -> (B, A) { return (B(), B()) } // expected-error {{'h()' has already been overridden}}
9-
func i() {} // expected-error {{overriding declarations from extensions is not supported}}
9+
func i() {} // expected-error {{overri}}
1010
override func j() -> Int { return 0 }
1111
func j() -> Float { return 0.0 }
1212
func k() -> Float { return 0.0 }
@@ -39,7 +39,7 @@ class A {
3939
}
4040
}
4141
extension A {
42-
func i() {} // expected-note{{overridden declaration is here}}
42+
func i() {} // expected-note{{overri}}
4343
}
4444
func f() {
4545
let x = B()

test/decl/func/static_func.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,30 +61,30 @@ extension E {
6161
}
6262

6363
class C {
64-
static func f1() {} // expected-note 3{{overridden declaration is here}}
64+
static func f1() {} // expected-note 3{{overri}}
6565
class func f2() {}
6666
class func f3() {}
67-
class func f4() {} // expected-note {{overridden declaration is here}}
68-
class func f5() {} // expected-note {{overridden declaration is here}}
67+
class func f4() {} // expected-note {{overri}}
68+
class func f5() {} // expected-note {{overri}}
6969
static final func f6() {} // expected-error {{static declarations are already final}} {{10-16=}}
70-
final class func f7() {} // expected-note 3{{overridden declaration is here}}
70+
final class func f7() {} // expected-note 3{{overri}}
7171
}
7272

7373
extension C {
7474
static func ef1() {}
75-
class func ef2() {} // expected-note {{overridden declaration is here}}
76-
class func ef3() {} // expected-note {{overridden declaration is here}}
77-
class func ef4() {} // expected-note {{overridden declaration is here}}
78-
class func ef5() {} // expected-note {{overridden declaration is here}}
75+
class func ef2() {} // expected-note {{overri}}
76+
class func ef3() {} // expected-note {{overri}}
77+
class func ef4() {} // expected-note {{overri}}
78+
class func ef5() {} // expected-note {{overri}}
7979
}
8080

8181
class C_Derived : C {
8282
override static func f1() {} // expected-error {{cannot override static method}}
8383
override class func f2() {}
8484
class override func f3() {}
8585

86-
override class func ef2() {} // expected-error {{overriding declarations from extensions is not supported}}
87-
class override func ef3() {} // expected-error {{overriding declarations from extensions is not supported}}
86+
override class func ef2() {} // expected-error {{not supported}}
87+
class override func ef3() {} // expected-error {{not supported}}
8888
override static func f7() {} // expected-error {{static method overrides a 'final' class method}}
8989
}
9090

@@ -98,11 +98,11 @@ class C_Derived3 : C {
9898
}
9999

100100
extension C_Derived {
101-
override class func f4() {} // expected-error {{overriding declarations in extensions is not supported}}
102-
class override func f5() {} // expected-error {{overriding declarations in extensions is not supported}}
101+
override class func f4() {} // expected-error {{not supported}}
102+
class override func f5() {} // expected-error {{not supported}}
103103

104-
override class func ef4() {} // expected-error {{overriding declarations in extensions is not supported}}
105-
class override func ef5() {} // expected-error {{overriding declarations in extensions is not supported}}
104+
override class func ef4() {} // expected-error {{not supported}}
105+
class override func ef5() {} // expected-error {{not supported}}
106106
}
107107

108108
protocol P {

test/decl/inherit/override.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
@objc class ObjCClassB : ObjCClassA {}
55

66
class A {
7-
func f1() { } // expected-note{{overridden declaration is here}}
8-
func f2() -> A { } // expected-note{{overridden declaration is here}}
7+
func f1() { } // expected-note{{overri}}
8+
func f2() -> A { } // expected-note{{overri}}
99

10-
@objc func f3() { } // expected-note{{overridden declaration is here}}
11-
@objc func f4() -> ObjCClassA { } // expected-note{{overridden declaration is here}}
12-
@objc var v1: Int { return 0 } // expected-note{{overridden declaration is here}}
13-
@objc var v2: Int { return 0 } // expected-note{{overridden declaration is here}}
14-
@objc var v3: Int = 0 // expected-note{{overridden declaration is here}}
10+
@objc func f3() { } // expected-note{{overri}}
11+
@objc func f4() -> ObjCClassA { } // expected-note{{overri}}
12+
@objc var v1: Int { return 0 } // expected-note{{overri}}
13+
@objc var v2: Int { return 0 } // expected-note{{overri}}
14+
@objc var v3: Int = 0 // expected-note{{overri}}
1515

1616
dynamic func f3D() { } // expected-error{{'dynamic' instance method 'f3D()' must also be '@objc'}}{{3-3=@objc }}
1717
dynamic func f4D() -> ObjCClassA { } // expected-error{{'dynamic' instance method 'f4D()' must also be '@objc'}}{{3-3=@objc }}
1818
}
1919

2020
extension A {
21-
func f5() { } // expected-note{{overridden declaration is here}}
22-
func f6() -> A { } // expected-note{{overridden declaration is here}}
21+
func f5() { } // expected-note{{overri}}
22+
func f6() -> A { } // expected-note{{overri}}
2323

2424
@objc func f7() { }
2525
@objc func f8() -> ObjCClassA { }
@@ -28,8 +28,8 @@ extension A {
2828
class B : A { }
2929

3030
extension B {
31-
func f1() { } // expected-error{{overriding declarations in extensions is not supported}}
32-
func f2() -> B { } // expected-error{{overriding declarations in extensions is not supported}}
31+
func f1() { } // expected-error{{overri}}
32+
func f2() -> B { } // expected-error{{overri}}
3333

3434
override func f3() { } // expected-error{{cannot override a non-dynamic class declaration from an extension}}
3535
override func f4() -> ObjCClassB { } // expected-error{{cannot override a non-dynamic class declaration from an extension}}
@@ -46,7 +46,7 @@ extension B {
4646
override func f3D() { }
4747
override func f4D() -> ObjCClassB { }
4848

49-
func f5() { } // expected-error{{overriding declarations in extensions is not supported}}
49+
func f5() { } // expected-error{{overridi}}
5050
func f6() -> A { } // expected-error{{overriding declarations in extensions is not supported}}
5151

5252
@objc override func f7() { }

test/decl/var/properties.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ class OwnershipBadSub : OwnershipBase {
11211121

11221122
// <rdar://problem/17391625> Swift Compiler Crashes when Declaring a Variable and didSet in an Extension
11231123
class rdar17391625 {
1124-
var prop = 42 // expected-note {{overridden declaration is here}}
1124+
var prop = 42 // expected-note {{overri}}
11251125
}
11261126

11271127
extension rdar17391625 {
@@ -1137,7 +1137,7 @@ class rdar17391625derived : rdar17391625 {
11371137

11381138
extension rdar17391625derived {
11391139
// Not a stored property, computed because it is an override.
1140-
override var prop: Int { // expected-error {{overriding declarations in extensions is not supported}}
1140+
override var prop: Int { // expected-error {{overri}}
11411141
didSet {
11421142
}
11431143
}

0 commit comments

Comments
 (0)