mirror of
https://github.com/apple/swift.git
synced 2025-12-25 12:15:36 +01:00
* [Swiftify] Emit Mutable[Raw]Span when possible Previously wrappers would use UnsafeMutable[Raw]Pointer for mutable pointers, and Span for non-const std::span, to prevent the compiler from complaining that MutableSpan didn't exist. Now that MutableSpan has landed we can finally emit MutableSpan without causing compilation errors. While we had (disabled) support for MutableSpan syntax already, some unexpected semantic errors required additional changes: - Mutable[Raw]Span parameters need to be inout (for mutation) - inout ~Escapable paramters need explicit lifetime annotations - MutableSpan cannot be directly bitcast to std::span, because it is ~Copyable, so they need unwrapping to UnsafeMutableBufferPointer rdar://147883022 * [Swiftify] Wrap if-expressions in Immediately Called Closures When parameters in swiftified wrapper functions are nullable, we use separate branches for the nil and nonnil cases, because `withUnsafeBufferPointer` (and similar) cannot be called on nil. If-expressions have some limitations on where they are allowed in the grammar, and cannot be passed as arguments to a function. As such, when the return value is also swiftified, we get an error when trying to pass the if-expression to the UnsafeBufferPointer/Span constructor. While it isn't pretty, the best way forward seems to be by wrapping the if-expressions in Immediately Called Closures. The closures have the side-effect of acting as a barrier for 'unsafe': unsafe keywords outside the closure do not "reach" unsafe expressions inside the closure. We therefore have to emit "unsafe" where unsafe expressions are used, rather than just when returning. rdar://148153063
74 lines
4.8 KiB
Swift
74 lines
4.8 KiB
Swift
// RUN: %empty-directory(%t)
|
|
// RUN: %target-swift-ide-test -plugin-path %swift-plugin-dir -I %S/Inputs -enable-experimental-feature SafeInteropWrappers -print-module -module-to-print=StdSpan -source-filename=x -enable-experimental-cxx-interop -Xcc -std=c++20 -module-cache-path %t > %t/interface.swift
|
|
// RUN: %FileCheck %s < %t/interface.swift
|
|
|
|
// REQUIRES: swift_feature_SafeInteropWrappers
|
|
|
|
// FIXME swift-ci linux tests do not support std::span
|
|
// UNSUPPORTED: OS=linux-gnu
|
|
|
|
#if !BRIDGING_HEADER
|
|
import StdSpan
|
|
#endif
|
|
import CxxStdlib
|
|
|
|
// CHECK: struct DependsOnSelf {
|
|
// CHECK: @lifetime(borrow self)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public borrowing func get() -> Span<CInt>
|
|
// CHECK-NEXT: borrowing func get() -> ConstSpanOfInt
|
|
|
|
// CHECK: mutating func set(_ x: borrowing std.{{.*}}vector<CInt, std.{{.*}}allocator<CInt>>)
|
|
// CHECK: func funcWithSafeWrapper(_ s: ConstSpanOfInt)
|
|
// CHECK-NEXT: func funcWithSafeWrapper2(_ s: ConstSpanOfInt) -> ConstSpanOfInt
|
|
// CHECK-NEXT: func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> ConstSpanOfInt
|
|
// CHECK: struct X {
|
|
// CHECK-NEXT: init()
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public mutating func methodWithSafeWrapper(_ s: Span<CInt>)
|
|
// CHECK-NEXT: mutating func methodWithSafeWrapper(_ s: ConstSpanOfInt)
|
|
// CHECK-NEXT: }
|
|
// CHECK: struct SpanWithoutTypeAlias {
|
|
// CHECK-NEXT: init()
|
|
// CHECK-NEXT: @lifetime(borrow self)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func bar() -> Span<CInt>
|
|
// CHECK-NEXT: mutating func bar() -> std.{{.*}}span<__cxxConst<CInt>, _C{{.*}}_{{.*}}>
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public mutating func foo(_ s: Span<CInt>)
|
|
// CHECK-NEXT: mutating func foo(_ s: std.{{.*}}span<__cxxConst<CInt>, _C{{.*}}_{{.*}}>)
|
|
// CHECK-NEXT: }
|
|
|
|
// CHECK: @lifetime(s: copy s)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func FuncWithMutableSafeWrapper(_ s: inout MutableSpan<CInt>)
|
|
// CHECK-NEXT: @lifetime(copy s)
|
|
// CHECK-NEXT: @lifetime(s: copy s)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func FuncWithMutableSafeWrapper2(_ s: inout MutableSpan<CInt>) -> MutableSpan<CInt>
|
|
// CHECK-NEXT: @lifetime(borrow v)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func FuncWithMutableSafeWrapper3(_ v: inout VecOfInt) -> MutableSpan<CInt>
|
|
// CHECK-NEXT: @lifetime(copy p)
|
|
// CHECK-NEXT: @lifetime(p: copy p)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper1(_ p: inout MutableSpan<Int32>) -> MutableSpan<CInt>
|
|
// CHECK-NEXT: @lifetime(borrow v)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper2(_ v: inout VecOfInt, _ len: Int32) -> MutableSpan<Int32>
|
|
// CHECK-NEXT: @lifetime(s: copy s)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper3(_ s: inout MutableSpan<CInt>, _ p: UnsafeMutableBufferPointer<Int32>)
|
|
// CHECK-NEXT: @lifetime(s: copy s)
|
|
// CHECK-NEXT: @lifetime(p: copy p)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper4(_ s: inout MutableSpan<CInt>, _ p: inout MutableSpan<Int32>)
|
|
// CHECK-NEXT: @lifetime(p: copy p)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper5(_ s: SpanOfInt, _ p: inout MutableSpan<Int32>)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper6(_ s: SpanOfInt, _ p: UnsafeMutableBufferPointer<Int32>)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper7(_ p: UnsafeMutableBufferPointer<Int32>) -> SpanOfInt
|
|
|
|
// CHECK: @_alwaysEmitIntoClient public func funcWithSafeWrapper(_ s: Span<CInt>)
|
|
// CHECK-NEXT: @lifetime(copy s)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: Span<CInt>) -> Span<CInt>
|
|
// CHECK-NEXT: @lifetime(borrow v)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> Span<CInt>
|
|
// CHECK-NEXT: @lifetime(copy p)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper1(_ p: Span<Int32>) -> Span<CInt>
|
|
// CHECK-NEXT: @lifetime(borrow v)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper2(_ v: borrowing VecOfInt, _ len: Int32) -> Span<Int32>
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper3(_ s: Span<CInt>, _ p: UnsafeMutableBufferPointer<Int32>)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper4(_ s: Span<CInt>, _ p: Span<Int32>)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper5(_ s: ConstSpanOfInt, _ p: Span<Int32>)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper6(_ s: ConstSpanOfInt, _ p: UnsafeMutableBufferPointer<Int32>)
|
|
// CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper7(_ p: UnsafeBufferPointer<Int32>) -> ConstSpanOfInt
|