Skip to content

Commit 4908123

Browse files
committed
[Sema] Reject an @objc generic subscript
Previously we could allow such a declaration to be marked @objc, despite being incompatible. This caused crashes later down the pipeline as the subscript's accessors were correctly checked for generic params and were not marked @objc. Resolves SR-12801.
1 parent 5ab5c60 commit 4908123

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4239,8 +4239,8 @@ ERROR(objc_invalid_on_subscript,none,
42394239
ERROR(objc_invalid_on_static_subscript,none,
42404240
"%0 cannot be %" OBJC_ATTR_SELECT "1", (DescriptiveDeclKind, unsigned))
42414241
ERROR(objc_invalid_with_generic_params,none,
4242-
"method cannot be %" OBJC_ATTR_SELECT "0 because it has generic "
4243-
"parameters", (unsigned))
4242+
"%0 cannot be %" OBJC_ATTR_SELECT "1 because it has generic parameters",
4243+
(DescriptiveDeclKind, unsigned))
42444244
ERROR(objc_convention_invalid,none,
42454245
"%0 is not representable in Objective-C, so it cannot be used"
42464246
" with '@convention(%1)'", (Type, StringRef))

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,17 @@ static bool isParamListRepresentableInObjC(const AbstractFunctionDecl *AFD,
304304

305305
/// Check whether the given declaration contains its own generic parameters,
306306
/// and therefore is not representable in Objective-C.
307-
static bool checkObjCWithGenericParams(const AbstractFunctionDecl *AFD,
308-
ObjCReason Reason) {
309-
bool Diagnose = shouldDiagnoseObjCReason(Reason, AFD->getASTContext());
307+
static bool checkObjCWithGenericParams(const ValueDecl *VD, ObjCReason Reason) {
308+
bool Diagnose = shouldDiagnoseObjCReason(Reason, VD->getASTContext());
310309

311-
if (AFD->getGenericParams()) {
310+
auto *GC = VD->getAsGenericContext();
311+
assert(GC);
312+
if (GC->getGenericParams()) {
312313
// Diagnose this problem, if asked to.
313314
if (Diagnose) {
314-
AFD->diagnose(diag::objc_invalid_with_generic_params,
315-
getObjCDiagnosticAttrKind(Reason));
316-
describeObjCReason(AFD, Reason);
315+
VD->diagnose(diag::objc_invalid_with_generic_params,
316+
VD->getDescriptiveKind(), getObjCDiagnosticAttrKind(Reason));
317+
describeObjCReason(VD, Reason);
317318
}
318319

319320
return true;
@@ -855,6 +856,8 @@ bool swift::isRepresentableInObjC(const SubscriptDecl *SD, ObjCReason Reason) {
855856

856857
if (checkObjCInForeignClassContext(SD, Reason))
857858
return false;
859+
if (checkObjCWithGenericParams(SD, Reason))
860+
return false;
858861

859862
// ObjC doesn't support class subscripts.
860863
if (!SD->isInstanceMember()) {

test/attr/attr_objc.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2375,3 +2375,9 @@ class SR_9035_C {}
23752375
func throwingMethod2() throws -> Unmanaged<SR_9035_C> // expected-error {{method cannot be a member of an @objc protocol because its result type cannot be represented in Objective-C}}
23762376
// expected-note@-1 {{inferring '@objc' because the declaration is a member of an '@objc' protocol}}
23772377
}
2378+
2379+
// SR-12801: Make sure we reject an @objc generic subscript.
2380+
class SR12801 {
2381+
@objc subscript<T>(foo : [T]) -> Int { return 0 }
2382+
// expected-error@-1 {{subscript cannot be marked @objc because it has generic parameters}}
2383+
}

0 commit comments

Comments
 (0)