Files
swift-mirror/test/SILOptimizer/opaque_values_Onone_stdlib.swift
Kavon Farvardin 091d63a5c8 revise how the Copyable constraint is added
The _Copyable constraint was implemented as a marker protocol.
That protocol is part of the KnownProtocol's in the compiler.
When `ASTContext::getProtocol(KnownProtocolKind kind)` tries
to find the ProtocolDecl for Copyable, it will look in the
stdlib module (i.e., Swift module), which is where I initially
planned to put it.

That created problems initially when some regression tests
use `-parse-stdlib` failed to do that protocol lookup, which is
essential for adding the constraint (given the current implementation).

That led to believe we need to pull Copyable out of the stdlib, but that's
wrong. In fact, when building the Swift module itself, we do `-parse-stdlib`
but we also include `-module-name Swift`. This causes the _Copyable protocol
defined in the Stdlib to be correctly discovered while building the stdlib
itself (see the test case in this commit). So, the only downside of
having the Copyable protocol in the Stdlib is that `-parse-stdlib` tests
in the compiler can't use move-only types correctly, as they'll be
allowed in generic contexts. No real program would build like this.

Until I have time to do a further refactoring, this is an acceptable trade-off.

fixes rdar://104898230
2023-03-04 11:42:09 -08:00

141 lines
5.5 KiB
Swift

// RUN: %target-swift-frontend -enable-experimental-move-only -parse-stdlib -module-name Swift -enable-sil-opaque-values -parse-as-library -emit-sil -Onone %s | %FileCheck %s
// Like opaque_values_Onone.swift but for code that needs to be compiled with
// -parse-stdlib.
protocol Error {}
enum Never : Error{}
precedencegroup AssignmentPrecedence { assignment: true }
precedencegroup CastingPrecedence {}
public protocol _ObjectiveCBridgeable {}
@_marker public protocol _Copyable {}
public protocol _ExpressibleByBuiltinBooleanLiteral {
init(_builtinBooleanLiteral value: Builtin.Int1)
}
struct Bool : _ExpressibleByBuiltinBooleanLiteral {
var _value: Builtin.Int1
@_silgen_name("Bool_init_noargs")
init()
init(_ v: Builtin.Int1) { self._value = v }
init(_ value: Bool) { self = value }
init(_builtinBooleanLiteral value: Builtin.Int1) {
self._value = value
}
}
@_silgen_name("typeof")
@_semantics("typechecker.type(of:)")
public func type<T, Metatype>(of value: T) -> Metatype
class X {}
func consume(_ x : __owned X) {}
func foo(@_noImplicitCopy _ x: __owned X) {
consume(_copy(x))
consume(x)
}
// CHECK-LABEL: sil [transparent] [_semantics "lifetimemanagement.copy"] @_copy : {{.*}} {
// CHECK: {{bb[0-9]+}}([[OUT_ADDR:%[^,]+]] : $*T, [[IN_ADDR:%[^,]+]] : $*T):
// CHECK: [[TMP_ADDR:%[^,]+]] = alloc_stack $T
// CHECK: copy_addr [[IN_ADDR]] to [init] [[TMP_ADDR]] : $*T
// CHECK: builtin "copy"<T>([[OUT_ADDR]] : $*T, [[TMP_ADDR]] : $*T) : $()
// CHECK: dealloc_stack [[TMP_ADDR]] : $*T
// CHECK: return {{%[^,]+}} : $()
// CHECK-LABEL: } // end sil function '_copy'
@_transparent
@_semantics("lifetimemanagement.copy")
@_silgen_name("_copy")
public func _copy<T>(_ value: T) -> T {
#if $BuiltinCopy
Builtin.copy(value)
#else
value
#endif
}
// CHECK-LABEL: sil hidden @getRawPointer : {{.*}} {
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
// CHECK: [[PTR:%[^,]+]] = address_to_pointer [stack_protection] [[ADDR]]
// CHECK: return [[PTR]]
// CHECK-LABEL: } // end sil function 'getRawPointer'
@_silgen_name("getRawPointer")
func getRawPointer<T>(to value: T) -> Builtin.RawPointer {
return Builtin.addressOfBorrow(value)
}
// CHECK-LABEL: sil hidden @getUnprotectedRawPointer : {{.*}} {
// CHECK: {{bb[0-9]+}}([[ADDR:%[^,]+]] : $*T):
// CHECK: [[PTR:%[^,]+]] = address_to_pointer [[ADDR]]
// CHECK: return [[PTR]]
// CHECK-LABEL: } // end sil function 'getUnprotectedRawPointer'
@_silgen_name("getUnprotectedRawPointer")
func getUnprotectedRawPointer<T>(to value: T) -> Builtin.RawPointer {
return Builtin.unprotectedAddressOfBorrow(value)
}
// CHECK-LABEL: sil hidden @getBridgeObject : {{.*}} {
// CHECK: [[OBJECT_ADDR:%[^,]+]] = unchecked_addr_cast {{%[^,]+}} : $*T to $*Builtin.BridgeObject
// CHECK: [[OBJECT:%[^,]+]] = load [[OBJECT_ADDR]]
// CHECK: return [[OBJECT]]
// CHECK-LABEL: } // end sil function 'getBridgeObject'
@_silgen_name("getBridgeObject")
func toObject<T>(_ object: inout T) -> Builtin.BridgeObject {
Builtin.reinterpretCast(object)
}
// CHECK-LABEL: sil hidden @getAnotherType : {{.*}} {
// CHECK: {{bb[0-9]+}}([[RETADDR:%[^,]+]] : $*U, {{%[^,]+}} : $*T, {{%[^,]+}} : $@thick U.Type):
// CHECK: [[OTHER_TY_ADDR:%[^,]+]] = unchecked_addr_cast {{%[^,]+}} : $*T to $*U
// CHECK: copy_addr [[OTHER_TY_ADDR]] to [init] [[RETADDR]] : $*U
// CHECK-LABEL: } // end sil function 'getAnotherType'
@_silgen_name("getAnotherType")
func getAnotherType<T, U>(_ object: inout T, to ty: U.Type) -> U {
Builtin.reinterpretCast(object)
}
@_silgen_name("isOfTypeOfAnyObjectType")
func isOfTypeOfAnyObjectType(fromAny any: Any) -> Bool {
type(of: any) is Builtin.AnyObject.Type
}
@available(SwiftStdlib 5.1, *)
struct UnsafeContinuation<T, E: Error> {
@usableFromInline internal var context: Builtin.RawUnsafeContinuation
// CHECK-LABEL: sil {{.*}}@unsafeContinuationResumeNoThrow : {{.*}} {
// CHECK: {{bb[0-9]+}}([[VALUE:%[^,]+]] : $*T, [[CONTINUATION:%[^,]+]] : $UnsafeContinuation<T, Never>):
// CHECK: [[STACK:%[^,]+]] = alloc_stack $T
// CHECK: [[CONTEXT:%[^,]+]] = struct_extract [[CONTINUATION]]
// CHECK: copy_addr [[VALUE]] to [init] [[STACK]]
// CHECK: builtin "resumeNonThrowingContinuationReturning"<T>([[CONTEXT]] : $Builtin.RawUnsafeContinuation, [[STACK]] : $*T)
// CHECK: destroy_addr [[VALUE]]
// CHECK-LABEL: } // end sil function 'unsafeContinuationResumeNoThrow'
@_silgen_name("unsafeContinuationResumeNoThrow")
@_alwaysEmitIntoClient
public func resume(returning value: __owned T) where E == Never {
#if compiler(>=5.5) && $BuiltinContinuation
Builtin.resumeNonThrowingContinuationReturning(context, value)
#endif
}
// CHECK-LABEL: sil {{.*}}@unsafeContinuationResumeThrow : {{.*}} {
// CHECK: {{bb[0-9]+}}([[VALUE:%[^,]+]] : $*T, [[CONTINUATION:%[^,]+]] : $UnsafeContinuation<T, E>):
// CHECK: [[STACK:%[^,]+]] = alloc_stack $T
// CHECK: [[CONTEXT:%[^,]+]] = struct_extract [[CONTINUATION]]
// CHECK: copy_addr [[VALUE]] to [init] [[STACK]]
// CHECK: builtin "resumeThrowingContinuationReturning"<T>([[CONTEXT]] : $Builtin.RawUnsafeContinuation, [[STACK]] : $*T)
// CHECK: destroy_addr [[VALUE]]
// CHECK-LABEL: } // end sil function 'unsafeContinuationResumeThrow'
@_silgen_name("unsafeContinuationResumeThrow")
@_alwaysEmitIntoClient
public func resume(returning value: __owned T) {
#if compiler(>=5.5) && $BuiltinContinuation
Builtin.resumeThrowingContinuationReturning(context, value)
#endif
}
}