mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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:
@@ -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))) {
|
||||
|
||||
16
test/ClangImporter/Inputs/move_only_types_cycle.h
Normal file
16
test/ClangImporter/Inputs/move_only_types_cycle.h
Normal 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
|
||||
21
test/ClangImporter/move_only_types_cycle.swift
Normal file
21
test/ClangImporter/move_only_types_cycle.swift
Normal 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 {
|
||||
}
|
||||
Reference in New Issue
Block a user