@@ -2659,6 +2659,9 @@ static void inferObjCName(TypeChecker &tc, ValueDecl *decl) {
2659
2659
if (isa<DestructorDecl>(decl))
2660
2660
return ;
2661
2661
2662
+ auto attr = decl->getAttrs ().getAttribute <ObjCAttr>();
2663
+ assert (attr && " should only be called on decls already marked @objc" );
2664
+
2662
2665
// If this declaration overrides an @objc declaration, use its name.
2663
2666
if (auto overridden = decl->getOverriddenDecl ()) {
2664
2667
if (overridden->isObjC ()) {
@@ -2667,17 +2670,6 @@ static void inferObjCName(TypeChecker &tc, ValueDecl *decl) {
2667
2670
// Determine the selector of the overridden method.
2668
2671
ObjCSelector overriddenSelector = overriddenFunc->getObjCSelector ();
2669
2672
2670
- // Dig out the @objc attribute on the method, if it exists.
2671
- auto attr = decl->getAttrs ().getAttribute <ObjCAttr>();
2672
- if (!attr) {
2673
- // There was no @objc attribute; add one with the
2674
- // appropriate name.
2675
- decl->getAttrs ().add (ObjCAttr::create (tc.Context ,
2676
- overriddenSelector,
2677
- true ));
2678
- return ;
2679
- }
2680
-
2681
2673
// Determine whether there is a name conflict.
2682
2674
bool shouldFixName = !attr->hasName ();
2683
2675
if (attr->hasName () && *attr->getName () != overriddenSelector) {
@@ -2711,18 +2703,6 @@ static void inferObjCName(TypeChecker &tc, ValueDecl *decl) {
2711
2703
Identifier overriddenName = overriddenProp->getObjCPropertyName ();
2712
2704
ObjCSelector overriddenNameAsSel (tc.Context , 0 , overriddenName);
2713
2705
2714
- // Dig out the @objc attribute, if specified.
2715
- auto attr = decl->getAttrs ().getAttribute <ObjCAttr>();
2716
- if (!attr) {
2717
- // There was no @objc attribute; add one with the
2718
- // appropriate name.
2719
- decl->getAttrs ().add (
2720
- ObjCAttr::createNullary (tc.Context ,
2721
- overriddenName,
2722
- /* isNameImplicit=*/ true ));
2723
- return ;
2724
- }
2725
-
2726
2706
// Determine whether there is a name conflict.
2727
2707
bool shouldFixName = !attr->hasName ();
2728
2708
if (attr->hasName () && *attr->getName () != overriddenNameAsSel) {
@@ -2751,11 +2731,9 @@ static void inferObjCName(TypeChecker &tc, ValueDecl *decl) {
2751
2731
}
2752
2732
}
2753
2733
2754
- // Dig out the @objc attribute. If it already has a name, do
2755
- // nothing; the protocol conformance checker will handle any
2756
- // mismatches.
2757
- auto attr = decl->getAttrs ().getAttribute <ObjCAttr>();
2758
- if (attr && attr->hasName ()) return ;
2734
+ // If the decl already has a name, do nothing; the protocol conformance
2735
+ // checker will handle any mismatches.
2736
+ if (attr->hasName ()) return ;
2759
2737
2760
2738
// When no override determined the Objective-C name, look for
2761
2739
// requirements for which this declaration is a witness.
@@ -2799,13 +2777,8 @@ static void inferObjCName(TypeChecker &tc, ValueDecl *decl) {
2799
2777
2800
2778
// If we have a name, install it via an @objc attribute.
2801
2779
if (requirementObjCName) {
2802
- if (attr)
2803
- const_cast <ObjCAttr *>(attr)->setName (*requirementObjCName,
2804
- /* implicit=*/ true );
2805
- else
2806
- decl->getAttrs ().add (
2807
- ObjCAttr::create (tc.Context , *requirementObjCName,
2808
- /* implicitName=*/ true ));
2780
+ const_cast <ObjCAttr *>(attr)->setName (*requirementObjCName,
2781
+ /* implicit=*/ true );
2809
2782
}
2810
2783
}
2811
2784
@@ -3943,6 +3916,16 @@ static void validateAbstractStorageDecl(TypeChecker &TC,
3943
3916
storage->setIsGetterMutating (computeIsGetterMutating (TC, storage));
3944
3917
storage->setIsSetterMutating (computeIsSetterMutating (TC, storage));
3945
3918
3919
+ // We can't delay validation of getters and setters on @objc properties,
3920
+ // because if they never get validated at all then conformance checkers
3921
+ // will complain about selector mismatches.
3922
+ if (storage->isObjC ()) {
3923
+ if (auto *getter = storage->getGetter ())
3924
+ TC.validateDecl (getter);
3925
+ if (auto *setter = storage->getSetter ())
3926
+ TC.validateDecl (setter);
3927
+ }
3928
+
3946
3929
// Create a materializeForSet function if necessary. This needs to
3947
3930
// happen immediately so that subclass materializeForSet functions
3948
3931
// will be properly marked as overriding it.
0 commit comments