[Move-only-types] Break cycle with OpaqueReadOwnershipRequest and @objc selector

The interface-type computation in OpaqueReadOwnershipRequest is causing
a cycle with `@objc` names for the getter/setter of a property. Break
the cycle by relying on the fact that `@objc` names can only be
directly on the getter/setter, not on some other accessor, so we can
go through `getAccessor` for both cases.

I am not convinced that we won't have additional issues related to the
interface-type computation in OpaqueReadOwnershipRequest, but I
couldn't see any obvious ones in the code base either.

Fixes rdar://106575164.
This commit is contained in:
Doug Gregor
2023-03-10 13:03:48 -08:00
parent b412c6c884
commit b829e86027
3 changed files with 39 additions and 2 deletions

View File

@@ -6309,7 +6309,7 @@ getNameFromObjcAttribute(const ObjCAttr *attr, DeclName preferredName) {
ObjCSelector
AbstractStorageDecl::getObjCGetterSelector(Identifier preferredName) const {
// If the getter has an @objc attribute with a name, use that.
if (auto getter = getOpaqueAccessor(AccessorKind::Get)) {
if (auto getter = getAccessor(AccessorKind::Get)) {
if (auto name = getNameFromObjcAttribute(getter->getAttrs().
getAttribute<ObjCAttr>(), preferredName))
return *name;
@@ -6339,7 +6339,7 @@ AbstractStorageDecl::getObjCGetterSelector(Identifier preferredName) const {
ObjCSelector
AbstractStorageDecl::getObjCSetterSelector(Identifier preferredName) const {
// If the setter has an @objc attribute with a name, use that.
auto setter = getOpaqueAccessor(AccessorKind::Set);
auto setter = getAccessor(AccessorKind::Set);
auto objcAttr = setter ? setter->getAttrs().getAttribute<ObjCAttr>()
: nullptr;
if (auto name = getNameFromObjcAttribute(objcAttr, DeclName(preferredName))) {

View File

@@ -0,0 +1,16 @@
#import <Foundation/NSObject.h>
#import <Foundation/NSUUID.h>
__attribute__((objc_subclassing_restricted))
__attribute__((swift_name("TricksyClass")))
__attribute__((external_source_symbol(language="Swift", defined_in="MyModule", generated_declaration)))
@interface CPTricksyClass : NSObject
@end
@protocol P
@property(readonly) NSUUID *uuid;
@end
@interface CPTricksyClass() <P>
@end

View File

@@ -0,0 +1,21 @@
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5 -import-objc-header %S/Inputs/move_only_types_cycle.h
// REQUIRES: objc_interop
// REQUIRES: OS=macosx
// This test triggered a cyclic dependency between @objc getter selector
// checking and some checking for move-only types, which is both horrifying and
// exciting at the same time.
import Foundation
@objc(CPTricksyClass)
public class TricksyClass: NSObject {
public enum Color {
case red
}
var id = UUID()
}
extension TricksyClass.Color {
}