IRGen: Fix incorrect conformance check

Fixes rdar://126637139, rdar://126779977.
This commit is contained in:
Slava Pestov
2024-05-06 14:29:17 -04:00
parent db7580f842
commit 5d7e502299
3 changed files with 79 additions and 7 deletions

View File

@@ -523,7 +523,7 @@ const TypeInfo *TypeConverter::convertTupleType(TupleType *tuple) {
auto *bitwiseCopyableProtocol =
IGM.getSwiftModule()->getASTContext().getProtocol(
KnownProtocolKind::BitwiseCopyable);
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->lookupConformance(
if (bitwiseCopyableProtocol && IGM.getSwiftModule()->checkConformance(
tuple, bitwiseCopyableProtocol)) {
return BitwiseCopyableTypeInfo::create(IGM.OpaqueTy, IsABIAccessible);
}

View File

@@ -0,0 +1,37 @@
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
sil_stage canonical
import Builtin
import Swift
import SwiftShims
// CHECK-LABEL: define{{.*}} swiftcc void @func1
// CHECK: [[METADATA_PAIR:%.*]] = phi %swift.metadata_response
// CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[METADATA_PAIR]], 0
// CHECK: [[VWT_PTR:%.*]] = getelementptr inbounds ptr, ptr [[METADATA]], {{i32|i64}} -1
// CHECK: [[VWT:%.*]] = load ptr, ptr [[VWT_PTR]]
// CHECK: [[DESTROY_PTR:%.*]] = getelementptr inbounds ptr, ptr [[VWT]], i32 1
// CHECK: [[DESTROY:%.*]] = load ptr, ptr [[DESTROY_PTR]]
// CHECK: call void [[DESTROY]]({{.*}})
// CHECK: ret void
sil @func1 : $@convention(thin) <each V> (@in (repeat each V)) -> () {
bb0(%0 : $*(repeat each V)):
destroy_addr %0 : $*(repeat each V)
%ret = tuple ()
return %ret : $()
}
// CHECK-LABEL: define{{.*}} swiftcc void @func2
// CHECK-NOT: call void %
// CHECK: ret void
sil @func2 : $@convention(thin) <each V where repeat each V : BitwiseCopyable> (@in (repeat each V)) -> () {
bb0(%0 : $*(repeat each V)):
destroy_addr %0 : $*(repeat each V)
%ret = tuple ()
return %ret : $()
}

View File

@@ -5,13 +5,13 @@
import StdlibUnittest
var types = TestSuite("VariadicGenericCaptures")
var captures = TestSuite("VariadicGenericCaptures")
func hasMetadataPack<each T>(_: repeat each T) -> () -> Any.Type {
return { return (repeat each T).self }
}
types.test("Metadata") {
captures.test("Metadata") {
expectEqual(Void.self, hasMetadataPack()())
expectEqual((Int, String, Bool).self, hasMetadataPack(1, "hi", false)())
}
@@ -20,7 +20,7 @@ func hasWitnessTablePack<each T: Sequence>(_: repeat each T) -> () -> Any.Type {
return { return (repeat (each T).Element).self }
}
types.test("WitnessTable") {
captures.test("WitnessTable") {
expectEqual(Void.self, hasWitnessTablePack()())
expectEqual((Int, String, Bool).self, hasWitnessTablePack([1], ["hi"], [false])())
}
@@ -29,7 +29,7 @@ func hasWitnessTablePack2<each T: Sequence>(_: repeat each T) -> () -> Any.Type
return { return (repeat (each T).Element.Element).self }
}
types.test("WitnessTable2") {
captures.test("WitnessTable2") {
expectEqual(Void.self, hasWitnessTablePack2()())
expectEqual((Int, String, Bool).self, hasWitnessTablePack2([[1]], [["hi"]], [[false]])())
}
@@ -43,7 +43,7 @@ func lifetimeTest2() -> () -> Any.Type {
return hasMetadataPack(3, 1.0)
}
types.test("Lifetime") {
captures.test("Lifetime") {
let fn1 = lifetimeTest1()
let fn2 = lifetimeTest2()
expectEqual((String, Set<Int>).self, fn1())
@@ -71,7 +71,7 @@ func testNonEscapingCapture<each T: Hashable>(_ t: repeat each T) -> [AnyHashabl
}
}
types.test("CapturedValue") {
captures.test("CapturedValue") {
let fn1 = testEscapingCapture(1, "hi")
let fn2 = testEscapingCapture(5.0, false)
@@ -82,4 +82,39 @@ types.test("CapturedValue") {
expectEqual([true, 7], testNonEscapingCapture(true, 7))
}
captures.test("Leaks") {
func callee<T>(_: T) {}
func takesEscapingClosure(_ fn: @escaping () -> ()) {
fn()
fn()
fn()
}
func takesNonEscapingClosure(_ fn: () -> ()) {
fn()
fn()
fn()
}
func formPackCaptures<each V>(_ v: repeat each V) {
takesEscapingClosure { repeat callee(each v) }
takesNonEscapingClosure { repeat callee(each v) }
{ repeat callee(each v) }()
}
struct S {
init<each V>(_ v: repeat each V) {
takesEscapingClosure { repeat callee(each v) }
takesNonEscapingClosure { repeat callee(each v) }
{ repeat callee(each v) }()
}
}
for _ in 0..<10 {
formPackCaptures(LifetimeTracked(0), LifetimeTracked(0), LifetimeTracked(0))
callee(S(LifetimeTracked(1), LifetimeTracked(1), LifetimeTracked(1)))
}
}
runAllTests()