Skip to content

Commit 0114f86

Browse files
authored
Merge pull request #10894 from DougGregor/objc-accessors-sr-5025
2 parents 6e3eeb6 + ff7bfa8 commit 0114f86

File tree

4 files changed

+57
-13
lines changed

4 files changed

+57
-13
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3296,6 +3296,8 @@ ERROR(objc_invalid_on_func_curried,none,
32963296
"cannot be represented in Objective-C", (unsigned))
32973297
ERROR(objc_observing_accessor, none,
32983298
"observing accessors are not allowed to be marked @objc", ())
3299+
ERROR(objc_addressor, none,
3300+
"addressors are not allowed to be marked @objc", ())
32993301
ERROR(objc_invalid_on_func_variadic,none,
33003302
"method cannot be %" OBJC_ATTR_SELECT "0 because it has a variadic "
33013303
"parameter", (unsigned))

lib/Sema/CSSimplify.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,13 @@ static void enumerateOptionalConversionRestrictions(
13751375
}
13761376
}
13771377

1378+
/// Determine whether we can bind the given type variable to the given
1379+
/// fixed type.
1380+
static bool isBindable(TypeVariableType *typeVar, Type type) {
1381+
return !ConstraintSystem::typeVarOccursInType(typeVar, type) &&
1382+
!type->is<DependentMemberType>();
1383+
}
1384+
13781385
ConstraintSystem::SolutionKind
13791386
ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
13801387
TypeMatchOptions flags,
@@ -1480,8 +1487,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
14801487
// Simplify the right-hand type and perform the "occurs" check.
14811488
typeVar1 = getRepresentative(typeVar1);
14821489
type2 = simplifyType(type2, flags);
1483-
if (typeVarOccursInType(typeVar1, type2) ||
1484-
type2->is<DependentMemberType>())
1490+
if (!isBindable(typeVar1, type2))
14851491
return formUnsolvedResult();
14861492

14871493
// Equal constraints allow mixed LValue/RValue bindings, but
@@ -1531,8 +1537,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
15311537
// Simplify the left-hand type and perform the "occurs" check.
15321538
typeVar2 = getRepresentative(typeVar2);
15331539
type1 = simplifyType(type1, flags);
1534-
if (typeVarOccursInType(typeVar2, type1) ||
1535-
type1->is<DependentMemberType>())
1540+
if (!isBindable(typeVar2, type1))
15361541
return formUnsolvedResult();
15371542

15381543
// Equal constraints allow mixed LValue/RValue bindings, but
@@ -1564,8 +1569,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
15641569
// Simplify the left-hand type and perform the "occurs" check.
15651570
typeVar2 = getRepresentative(typeVar2);
15661571
type1 = simplifyType(type1, flags);
1567-
if (typeVarOccursInType(typeVar2, type1) ||
1568-
type1->is<DependentMemberType>())
1572+
if (!isBindable(typeVar2, type1))
15691573
return formUnsolvedResult();
15701574

15711575
if (auto *iot = type1->getAs<InOutType>()) {
@@ -1578,8 +1582,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
15781582
// Simplify the right-hand type and perform the "occurs" check.
15791583
typeVar1 = getRepresentative(typeVar1);
15801584
type2 = simplifyType(type2, flags);
1581-
if (typeVarOccursInType(typeVar1, type2) ||
1582-
type2->is<DependentMemberType>())
1585+
if (!isBindable(typeVar1, type2))
15831586
return formUnsolvedResult();
15841587

15851588
if (auto *lvt = type2->getAs<LValueType>()) {

lib/Sema/TypeCheckType.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,17 +3515,36 @@ bool TypeChecker::isRepresentableInObjC(
35153515
return false;
35163516
}
35173517

3518-
// willSet/didSet implementations are never exposed to objc, they are
3519-
// always directly dispatched from the synthesized setter.
3520-
if (FD->isObservingAccessor()) {
3518+
switch (FD->getAccessorKind()) {
3519+
case AccessorKind::NotAccessor:
3520+
llvm_unreachable("already checking for accessor-ness");
3521+
3522+
case AccessorKind::IsDidSet:
3523+
case AccessorKind::IsWillSet:
3524+
// willSet/didSet implementations are never exposed to objc, they are
3525+
// always directly dispatched from the synthesized setter.
35213526
if (Diagnose) {
35223527
diagnose(AFD->getLoc(), diag::objc_observing_accessor);
35233528
describeObjCReason(*this, AFD, Reason);
35243529
}
35253530
return false;
3531+
3532+
case AccessorKind::IsGetter:
3533+
case AccessorKind::IsSetter:
3534+
return true;
3535+
3536+
case AccessorKind::IsMaterializeForSet:
3537+
// materializeForSet is synthesized, so never complain about it
3538+
return false;
3539+
3540+
case AccessorKind::IsAddressor:
3541+
case AccessorKind::IsMutableAddressor:
3542+
if (Diagnose) {
3543+
diagnose(AFD->getLoc(), diag::objc_addressor);
3544+
describeObjCReason(*this, AFD, Reason);
3545+
}
3546+
return false;
35263547
}
3527-
assert(FD->isGetterOrSetter() && "missing diags for other accessors");
3528-
return true;
35293548
}
35303549

35313550
unsigned ExpectedParamPatterns = 1;

test/attr/attr_objc.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,3 +2262,23 @@ extension SubclassInfersFromProtocol2 {
22622262
@objc class NeverReturningMethod {
22632263
@objc func doesNotReturn() -> Never {}
22642264
}
2265+
2266+
// SR-5025
2267+
class User: NSObject {
2268+
}
2269+
2270+
@objc extension User {
2271+
var name: String {
2272+
get {
2273+
return "No name"
2274+
}
2275+
set {
2276+
// Nothing
2277+
}
2278+
}
2279+
2280+
var other: String {
2281+
unsafeAddress { // expected-error{{addressors are not allowed to be marked @objc}}
2282+
}
2283+
}
2284+
}

0 commit comments

Comments
 (0)