Files
swift-mirror/test/ClangImporter/objc_redeclared_properties_incompatible.swift
Robert Widmann 1f59f10f44 Unwind the Bogus Delayed Categories Hack
Delayed categories only existed to keep
ClangImporter/objc_redeclared_properties passing.  But this test
appears to exhibit incorrect behavior as written.

The clang importer implements limited behavior for overwriting
variable declarations. If that overwrite occurs somewhere else in the
class hierarchy, the declaration is rewritten as a Swift override.  The
remaining case is categories, which enable all sorts of awful
redeclaration behaviors.  When a bridging header declares a category
that tries to stomp the API surface of another category, we need to
import that category first, and we would import that category first - by
accident.  Re-entrancy does have its upsides.

In order to keep the tests passing post re-entrant lookup, we stubbed in a hack that delayed
categories in the bridging header so they were installed last, which
meant the variable merging logic would mostly decline to import those
properties.  But the rest of the world expects the opposite: Bridging
header contents are more sacred than the rest of the SDK and must be
installed *first* in order for a number of nightmarish header hacks to
go through.

Unwind the old, incorrect emergent behavior and re-establish the
correct behavior as the way the world ought to work.

Resolves rdar://58493356, rdar://58493357, rdar://58493362, rdar://58493370
2020-01-14 21:42:52 -08:00

109 lines
5.8 KiB
Swift

// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -typecheck -F %S/Inputs/frameworks %s 2>&1 | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PUBLIC %s
// RUN: echo '#import <PrivatelyReadwrite/Private.h>' > %t.h
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -F %S/Inputs/frameworks -enable-objc-interop -import-objc-header %t.h %s 2>&1 | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PRIVATE %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -emit-pch -F %S/Inputs/frameworks -o %t.pch %t.h
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -F %S/Inputs/frameworks -enable-objc-interop -import-objc-header %t.pch %s 2>&1 | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PRIVATE %s
// RUN: not %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -F %S/Inputs/frameworks -enable-objc-interop -import-objc-header %t.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck -check-prefix=CHECK -check-prefix=CHECK-PRIVATE %s
import PrivatelyReadwrite
// In the original bug, it made a difference whether the type was instantiated;
// it resulted in members being imported in a different order.
func testWithInitializer() {
let obj = PropertiesInit()
let _: Int = obj.nullabilityChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
let _: Int = obj.missingGenerics
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'GenericClass<Base>' to specified type 'Int'
let _: Int = obj.typeChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
obj.readwriteChange = Base() // CHECK-PRIVATE-NOT: [[@LINE]]:{{.+}}: error
// CHECK-PUBLIC: [[@LINE-1]]:7: error: cannot assign to property: 'readwriteChange' is a get-only property
}
func testWithoutInitializer(obj: PropertiesNoInit) {
let _: Int = obj.nullabilityChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
let _: Int = obj.missingGenerics
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'GenericClass<Base>' to specified type 'Int'
let _: Int = obj.typeChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
obj.readwriteChange = Base() // CHECK-PRIVATE-NOT: [[@LINE]]:{{.+}}: error
// CHECK-PUBLIC: [[@LINE-1]]:7: error: cannot assign to property: 'readwriteChange' is a get-only property
}
func testGenericWithInitializer() {
let obj = PropertiesInitGeneric<Base>()
let _: Int = obj.nullabilityChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
let _: Int = obj.missingGenerics
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'GenericClass<Base>' to specified type 'Int'
let _: Int = obj.typeChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
obj.readwriteChange = Base() // CHECK-PRIVATE-NOT: [[@LINE]]:{{.+}}: error
// CHECK-PUBLIC: [[@LINE-1]]:7: error: cannot assign to property: 'readwriteChange' is a get-only property
}
func testGenericWithoutInitializer(obj: PropertiesNoInitGeneric<Base>) {
let _: Int = obj.nullabilityChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
let _: Int = obj.missingGenerics
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'GenericClass<Base>' to specified type 'Int'
let _: Int = obj.typeChange
// CHECK: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
obj.readwriteChange = Base() // CHECK-PRIVATE-NOT: [[@LINE]]:{{.+}}: error
// CHECK-PUBLIC: [[@LINE-1]]:7: error: cannot assign to property: 'readwriteChange' is a get-only property
}
func testCategoryWithInitializer() {
let obj = PropertiesInitCategory()
let _: Int = obj.nullabilityChange
// CHECK-PUBLIC: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
// CHECK-PRIVATE: [[@LINE-2]]:20: error: cannot convert value of type 'Base?' to specified type 'Int'
let _: Int = obj.missingGenerics
// CHECK-PUBLIC: [[@LINE-1]]:20: error: cannot convert value of type 'GenericClass<Base>' to specified type 'Int'
// CHECK-PRIVATE: [[@LINE-2]]:20: error: cannot convert value of type 'GenericClass<AnyObject>' to specified type 'Int'
let _: Int = obj.typeChange
// CHECK-PUBLIC: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
// CHECK-PRIVATE: [[@LINE-2]]:20: error: cannot convert value of type 'PrivateSubclass' to specified type 'Int'
obj.readwriteChange = Base() // CHECK-PRIVATE-NOT: [[@LINE]]:{{.+}}: error
// CHECK-PUBLIC: [[@LINE-1]]:7: error: cannot assign to property: 'readwriteChange' is a get-only property
}
func testCategoryWithoutInitializer(obj: PropertiesNoInitCategory) {
let _: Int = obj.nullabilityChange
// CHECK-PUBLIC: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
// CHECK-PRIVATE: [[@LINE-2]]:20: error: cannot convert value of type 'Base?' to specified type 'Int'
let _: Int = obj.missingGenerics
// CHECK-PUBLIC: [[@LINE-1]]:20: error: cannot convert value of type 'GenericClass<Base>' to specified type 'Int'
// CHECK-PRIVATE: [[@LINE-2]]:20: error: cannot convert value of type 'GenericClass<AnyObject>' to specified type 'Int'
let _: Int = obj.typeChange
// CHECK-PUBLIC: [[@LINE-1]]:20: error: cannot convert value of type 'Base' to specified type 'Int'
// CHECK-PRIVATE: [[@LINE-2]]:20: error: cannot convert value of type 'PrivateSubclass' to specified type 'Int'
obj.readwriteChange = Base() // CHECK-PRIVATE-NOT: [[@LINE]]:{{.+}}: error
// CHECK-PUBLIC: [[@LINE-1]]:7: error: cannot assign to property: 'readwriteChange' is a get-only property
}