mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
SILGen: Fix key paths that reference internal private(set) decls from other files.
The setter needs to be given hidden linkage so that other files can still form key paths to it.
This commit is contained in:
@@ -314,8 +314,19 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
|
|||||||
neverPublic = true;
|
neverPublic = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto effectiveAccess = d->getEffectiveAccess();
|
||||||
|
|
||||||
|
// Private setter implementations for an internal storage declaration should
|
||||||
|
// be internal as well, so that a dynamically-writable
|
||||||
|
// keypath can be formed from other files.
|
||||||
|
if (auto accessor = dyn_cast<AccessorDecl>(d)) {
|
||||||
|
if (accessor->isSetter()
|
||||||
|
&& accessor->getStorage()->getEffectiveAccess() == AccessLevel::Internal)
|
||||||
|
effectiveAccess = AccessLevel::Internal;
|
||||||
|
}
|
||||||
|
|
||||||
switch (d->getEffectiveAccess()) {
|
switch (effectiveAccess) {
|
||||||
case AccessLevel::Private:
|
case AccessLevel::Private:
|
||||||
case AccessLevel::FilePrivate:
|
case AccessLevel::FilePrivate:
|
||||||
return maybeAddExternal(SILLinkage::Private);
|
return maybeAddExternal(SILLinkage::Private);
|
||||||
|
|||||||
11
test/SILGen/Inputs/keypaths_multi_file_b.swift
Normal file
11
test/SILGen/Inputs/keypaths_multi_file_b.swift
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
struct A {
|
||||||
|
private(set) var x: Int {
|
||||||
|
get { return 0 }
|
||||||
|
set {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private(set) subscript(x: Int) -> Int {
|
||||||
|
get { return x }
|
||||||
|
set {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,7 +105,7 @@ internal struct PrivateSettersForReadOnlyInternal : PublicReadOnlyOperations {
|
|||||||
// CHECK-DAG: sil hidden{{( \[.+\])*}} @$S22accessibility_warnings33PrivateSettersForReadOnlyInternalV4sizeSivg
|
// CHECK-DAG: sil hidden{{( \[.+\])*}} @$S22accessibility_warnings33PrivateSettersForReadOnlyInternalV4sizeSivg
|
||||||
public private(set) var size = 0
|
public private(set) var size = 0
|
||||||
// CHECK-DAG: sil hidden @$S22accessibility_warnings33PrivateSettersForReadOnlyInternalVyS2icig
|
// CHECK-DAG: sil hidden @$S22accessibility_warnings33PrivateSettersForReadOnlyInternalVyS2icig
|
||||||
// CHECK-DAG: sil private @$S22accessibility_warnings33PrivateSettersForReadOnlyInternalVyS2icis
|
// CHECK-DAG: sil hidden @$S22accessibility_warnings33PrivateSettersForReadOnlyInternalVyS2icis
|
||||||
internal private(set) subscript (_: Int) -> Int { // no-warning
|
internal private(set) subscript (_: Int) -> Int { // no-warning
|
||||||
get { return 42 }
|
get { return 42 }
|
||||||
set {}
|
set {}
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ struct Foo {
|
|||||||
private(set) subscript(withPrivateSet x: Void) -> Void {
|
private(set) subscript(withPrivateSet x: Void) -> Void {
|
||||||
// CHECK-DAG: sil hidden @$S9accessors3FooV14withPrivateSetyyt_tcig : $@convention(method) (Foo) -> () {
|
// CHECK-DAG: sil hidden @$S9accessors3FooV14withPrivateSetyyt_tcig : $@convention(method) (Foo) -> () {
|
||||||
get {}
|
get {}
|
||||||
// CHECK-DAG: sil private @$S9accessors3FooV14withPrivateSetyyt_tcis : $@convention(method) (@inout Foo) -> () {
|
// CHECK-DAG: sil hidden @$S9accessors3FooV14withPrivateSetyyt_tcis : $@convention(method) (@inout Foo) -> () {
|
||||||
set {}
|
set {}
|
||||||
}
|
}
|
||||||
subscript(withNestedClass x: Void) -> Void {
|
subscript(withNestedClass x: Void) -> Void {
|
||||||
@@ -229,7 +229,7 @@ struct Foo {
|
|||||||
private(set) var variableWithPrivateSet: Void {
|
private(set) var variableWithPrivateSet: Void {
|
||||||
// CHECK-DAG: sil hidden @$S9accessors3FooV22variableWithPrivateSetytvg : $@convention(method) (Foo) -> () {
|
// CHECK-DAG: sil hidden @$S9accessors3FooV22variableWithPrivateSetytvg : $@convention(method) (Foo) -> () {
|
||||||
get {}
|
get {}
|
||||||
// CHECK-DAG: sil private @$S9accessors3FooV22variableWithPrivateSetytvs : $@convention(method) (@inout Foo) -> () {
|
// CHECK-DAG: sil hidden @$S9accessors3FooV22variableWithPrivateSetytvs : $@convention(method) (@inout Foo) -> () {
|
||||||
set {}
|
set {}
|
||||||
}
|
}
|
||||||
var propertyWithNestedClass: Void {
|
var propertyWithNestedClass: Void {
|
||||||
|
|||||||
20
test/SILGen/keypaths_multi_file.swift
Normal file
20
test/SILGen/keypaths_multi_file.swift
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// RUN: %target-swift-emit-silgen -module-name keypaths -primary-file %s %S/Inputs/keypaths_multi_file_b.swift | %FileCheck %s
|
||||||
|
// RUN: %target-swift-emit-silgen -module-name keypaths %s -primary-file %S/Inputs/keypaths_multi_file_b.swift | %FileCheck --check-prefix=DEFINITION %s
|
||||||
|
|
||||||
|
func foo(x: Int) -> KeyPath<A, Int> {
|
||||||
|
switch x {
|
||||||
|
case 0:
|
||||||
|
return \A.x
|
||||||
|
default:
|
||||||
|
return \A.[0]
|
||||||
|
}
|
||||||
|
return \A.x
|
||||||
|
}
|
||||||
|
|
||||||
|
// A.x setter
|
||||||
|
// CHECK-LABEL: sil hidden_external @$S8keypaths1AV1xSivs
|
||||||
|
// DEFINITION-LABEL: sil hidden @$S8keypaths1AV1xSivs
|
||||||
|
|
||||||
|
// A.subscript setter
|
||||||
|
// CHECK-LABEL: sil hidden_external @$S8keypaths1AVyS2icis
|
||||||
|
// DEFINITION-LABEL: sil hidden @$S8keypaths1AVyS2icis
|
||||||
19
test/stdlib/Inputs/KeyPathMultiFile_b.swift
Normal file
19
test/stdlib/Inputs/KeyPathMultiFile_b.swift
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
struct A {
|
||||||
|
private(set) var x: Int {
|
||||||
|
get { return 0 }
|
||||||
|
set {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private(set) subscript(x: Int) -> Int {
|
||||||
|
get { return 0 }
|
||||||
|
set {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func A_x_keypath() -> WritableKeyPath<A, Int> {
|
||||||
|
return \A.x
|
||||||
|
}
|
||||||
|
|
||||||
|
func A_subscript_0_keypath() -> WritableKeyPath<A, Int> {
|
||||||
|
return \A.[0]
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// RUN: %empty-directory(%t)
|
// RUN: %empty-directory(%t)
|
||||||
// RUN: %target-build-swift %s -Xfrontend -enable-sil-ownership -Xfrontend -g -o %t/a.out
|
// RUN: %target-build-swift %s -o %t/a.out
|
||||||
// RUN: %target-run %t/a.out
|
// RUN: %target-run %t/a.out
|
||||||
// REQUIRES: executable_test
|
// REQUIRES: executable_test
|
||||||
|
|
||||||
|
|||||||
15
test/stdlib/KeyPathMultiFile.swift
Normal file
15
test/stdlib/KeyPathMultiFile.swift
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// RUN: %empty-directory(%t)
|
||||||
|
// RUN: cp %s %t/main.swift
|
||||||
|
// RUN: %target-build-swift -o %t/a.out %t/main.swift %S/Inputs/KeyPathMultiFile_b.swift
|
||||||
|
// RUN: %target-run %t/a.out
|
||||||
|
|
||||||
|
import StdlibUnittest
|
||||||
|
|
||||||
|
var keyPathMultiFile = TestSuite("key paths across multiple files")
|
||||||
|
|
||||||
|
keyPathMultiFile.test("identity across multiple files") {
|
||||||
|
expectEqual(A_x_keypath(), \A.x)
|
||||||
|
expectEqual(A_subscript_0_keypath(), \A.[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
runAllTests()
|
||||||
Reference in New Issue
Block a user