Skip to content

Commit 502f2ec

Browse files
authored
Merge pull request #31763 from hamishknight/a-blast-from-the-past-5.3
2 parents 067700d + f842202 commit 502f2ec

File tree

6 files changed

+57
-14
lines changed

6 files changed

+57
-14
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/ConstraintSystem.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,9 +216,19 @@ getDynamicResultSignature(ValueDecl *decl) {
216216
}
217217

218218
if (auto asd = dyn_cast<AbstractStorageDecl>(decl)) {
219+
auto ty = asd->getInterfaceType();
220+
221+
// Strip off a generic signature if we have one. This matches the logic
222+
// for methods, and ensures that we don't take a protocol's generic
223+
// signature into account for a subscript requirement.
224+
if (auto *genericFn = ty->getAs<GenericFunctionType>()) {
225+
ty = FunctionType::get(genericFn->getParams(), genericFn->getResult(),
226+
genericFn->getExtInfo());
227+
}
228+
219229
// Handle properties and subscripts, anchored by the getter's selector.
220230
return std::make_tuple(asd->isStatic(), asd->getObjCGetterSelector(),
221-
asd->getInterfaceType()->getCanonicalType());
231+
ty->getCanonicalType());
222232
}
223233

224234
llvm_unreachable("Not a valid @objc member");

lib/Sema/MiscDiagnostics.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
137137
if (auto *SE = dyn_cast<SubscriptExpr>(E))
138138
CallArgs.insert(SE->getIndex());
139139

140+
if (auto *DSE = dyn_cast<DynamicSubscriptExpr>(E))
141+
CallArgs.insert(DSE->getIndex());
142+
140143
if (auto *KPE = dyn_cast<KeyPathExpr>(E)) {
141144
for (auto Comp : KPE->getComponents()) {
142145
if (auto *Arg = Comp.getIndexExpr())

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/Constraints/dynamic_lookup.swift

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,11 @@ func dynamicInitCrash(ao: AnyObject.Type) {
354354
func unambiguousMethodParam(_ x: Int)
355355

356356
subscript(ambiguousSubscript _: Int) -> String { get } // expected-note {{found this candidate}}
357-
subscript(unambiguousSubscript _: String) -> Int { get } // expected-note {{found this candidate}}
357+
subscript(unambiguousSubscript _: String) -> Int { get }
358+
359+
subscript(differentSelectors _: Int) -> Int { // expected-note {{found this candidate}}
360+
@objc(differentSelector1:) get
361+
}
358362
}
359363

360364
class C1 {
@@ -368,7 +372,15 @@ class C1 {
368372
@objc func unambiguousMethodParam(_ x: Int) {}
369373

370374
@objc subscript(ambiguousSubscript _: Int) -> Int { return 0 } // expected-note {{found this candidate}}
371-
@objc subscript(unambiguousSubscript _: String) -> Int { return 0 } // expected-note {{found this candidate}}
375+
@objc subscript(unambiguousSubscript _: String) -> Int { return 0 }
376+
377+
@objc subscript(differentSelectors _: Int) -> Int { // expected-note {{found this candidate}}
378+
@objc(differentSelector2:) get { return 0 }
379+
}
380+
}
381+
382+
class C2 {
383+
@objc subscript(singleCandidate _: Int) -> Int { return 0 }
372384
}
373385

374386
func testAnyObjectAmbiguity(_ x: AnyObject) {
@@ -384,10 +396,19 @@ func testAnyObjectAmbiguity(_ x: AnyObject) {
384396
_ = x.ambiguousMethodParam // expected-error {{ambiguous use of 'ambiguousMethodParam'}}
385397
_ = x.unambiguousMethodParam
386398

399+
// SR-12799: Don't emit a "single-element" tuple error.
400+
_ = x[singleCandidate: 0]
401+
387402
_ = x[ambiguousSubscript: 0] // expected-error {{ambiguous use of 'subscript(ambiguousSubscript:)'}}
403+
_ = x[ambiguousSubscript: 0] as Int
404+
_ = x[ambiguousSubscript: 0] as String
405+
406+
// SR-8611: Make sure we can coalesce subscripts with the same types and
407+
// selectors through AnyObject lookup.
408+
_ = x[unambiguousSubscript: ""]
388409

389-
// FIX-ME(SR-8611): This is currently ambiguous but shouldn't be.
390-
_ = x[unambiguousSubscript: ""] // expected-error {{ambiguous use of 'subscript(unambiguousSubscript:)'}}
410+
// But not if they have different selectors.
411+
_ = x[differentSelectors: 0] // expected-error {{ambiguous use of 'subscript(differentSelectors:)}}
391412
}
392413

393414
// SR-11648

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)