mirror of
https://github.com/apple/swift.git
synced 2026-10-12 14:50:47 +02:00
Although a `@usableFromInline` variable cannot be named directly by a client, its value can still reach a client binary: an `@inlinable` function may fold the variable into an integer generic argument, and that folded value is then serialized into the function body that the client inlines.
e.g.
```swift
@usableFromInline let x = 8, y = 8, z = 8
@usableFromInline func bar(_ zs: [z of Int]) {}
@inlinable public func foo() {
let xs: [x of Int] = [1, 2, 3, 4, 5, 6, 7, 8]
let ys: [y of Int] = xs
bar(ys)
}
```
A subsequent change to the folded value would leave already-compiled clients inconsistent with the evolved module, so the variable's value is, in effect, part of the ABI.
51 lines
2.7 KiB
Swift
51 lines
2.7 KiB
Swift
// Literal expressions may not reference `let` bindings that are part of the
|
|
// module's ABI surface: publicly visible bindings, or `@usableFromInline` ones.
|
|
// REQUIRES: swift_feature_LiteralExpressions
|
|
// RUN: %target-swift-frontend -typecheck %s -verify \
|
|
// RUN: -package-name myPkg \
|
|
// RUN: -disable-availability-checking \
|
|
// RUN: -enable-experimental-feature LiteralExpressions
|
|
|
|
public let publicPageSize = 4096
|
|
package let packagePageSize = 4096
|
|
internal let internalPageSize = 4096
|
|
@usableFromInline internal let usableFromInlinePageSize = 4096
|
|
fileprivate let filePrivatePageSize = 4096
|
|
private let privatePageSize = 4096
|
|
|
|
// =============================================================================
|
|
// @section initializer position: public and package bindings are rejected.
|
|
// `open` is not exercised here because it cannot apply to a top-level `let`;
|
|
// the diagnostic's `%select` branch for `open` is preserved for completeness.
|
|
// =============================================================================
|
|
|
|
@section("mysection") let a = 2 * publicPageSize
|
|
// expected-error@-1 {{reference to a public 'let' binding is not permitted in a literal expression}}
|
|
|
|
@section("mysection") let b = 2 * packagePageSize
|
|
// expected-error@-1 {{reference to a package 'let' binding is not permitted in a literal expression}}
|
|
|
|
@section("mysection") let bUFI = 2 * usableFromInlinePageSize
|
|
// expected-error@-1 {{reference to a '@usableFromInline' 'let' binding is not permitted in a literal expression}}
|
|
|
|
// Internal, fileprivate, and private bindings are allowed.
|
|
@section("mysection") let c = 2 * internalPageSize
|
|
@section("mysection") let d = 2 * filePrivatePageSize
|
|
@section("mysection") let e = 2 * privatePageSize
|
|
|
|
// =============================================================================
|
|
// Integer generic argument position: same restriction applies.
|
|
// =============================================================================
|
|
|
|
let f: InlineArray<(2 * publicPageSize), UInt8> = .init(repeating: 0)
|
|
// expected-error@-1 {{reference to a public 'let' binding is not permitted in a literal expression}}
|
|
// expected-error@-2 {{generic value must be an integer literal expression}}
|
|
|
|
let g: InlineArray<(2 * packagePageSize), UInt8> = .init(repeating: 0)
|
|
// expected-error@-1 {{reference to a package 'let' binding is not permitted in a literal expression}}
|
|
// expected-error@-2 {{generic value must be an integer literal expression}}
|
|
|
|
let gUFI: InlineArray<(2 * usableFromInlinePageSize), UInt8> = .init(repeating: 0)
|
|
// expected-error@-1 {{reference to a '@usableFromInline' 'let' binding is not permitted in a literal expression}}
|
|
// expected-error@-2 {{generic value must be an integer literal expression}}
|