Skip to content

Commit af699c3

Browse files
committed
Fix canSerialize logic
1 parent 4ff5a4a commit af699c3

File tree

3 files changed

+78
-7
lines changed

3 files changed

+78
-7
lines changed

lib/SILOptimizer/IPO/CrossModuleOptimization.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,8 @@ class InstructionVisitor : public SILCloner<InstructionVisitor> {
203203
for (Type replType : Subs.getReplacementTypes()) {
204204
switch (mode) {
205205
case VisitMode::DetectSerializableInst:
206-
CMS.canSerializeType(replType->getCanonicalType());
206+
if (!CMS.canSerializeType(replType->getCanonicalType()))
207+
isInstSerializable = false;
207208
break;
208209
case VisitMode::SerializeInst:
209210
/// Ensure that all replacement types of \p Subs are usable from serialized
@@ -667,16 +668,17 @@ bool CrossModuleOptimization::canSerializeType(CanType type) {
667668
if (iter != canTypesChecked.end())
668669
return iter->getSecond();
669670

670-
bool success = type.findIf(
671+
bool success = !type.findIf(
671672
[this](Type rawSubType) {
672673
CanType subType = rawSubType->getCanonicalType();
673674
if (auto nominal = subType->getNominalOrBoundGenericNominal()) {
674-
return canSerializeDecl(nominal);
675+
return !canSerializeDecl(nominal);
675676
}
676-
// If reached here, the type is a Builtin type or similar,
677-
// e.g. Builtin.Int64, Builtin.Word, Builtin.NativeObject, etc.
678-
return true;
679-
});
677+
// Types that might not have nominal include Builtin types (e.g. Builtin.Int64),
678+
// generic parameter types (e.g. T as in Foo<T>), SIL function result types
679+
// (e.g. @convention(method) (Int, @thin Hasher.Type) -> Hasher), etc.
680+
return false;
681+
});
680682

681683
canTypesChecked[type] = success;
682684
return success;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: split-file %s %t
3+
4+
// RUN: %target-swift-frontend -emit-module -wmo -enable-default-cmo -parse-as-library %t/Lib.swift -emit-module-path=%t/Lib.swiftmodule -module-name=Lib -enable-testing -I%t
5+
// RUN: %target-sil-opt %t/Lib.swiftmodule -sil-verify-all -o %t/Lib.sil
6+
// RUN: %FileCheck %s < %t/Lib.sil
7+
8+
/// Deserializing Lib module should not cause an assert fail.
9+
// RUN: %target-swift-frontend -emit-sil -sil-verify-all -wmo %t/Client.swift -I%t
10+
11+
// REQUIRES: swift_in_compiler
12+
// REQUIRES: asserts
13+
14+
//--- Client.swift
15+
@testable import Lib
16+
17+
//--- Lib.swift
18+
import Foundation
19+
20+
public class PubKlass {
21+
var field = InternalStruct()
22+
23+
// CHECK-NOT: sil [serialized] [ossa] @$s3Lib8PubKlassC3run4fromQrAA0B6StructV_tF : $@convention(method) (PubStruct, @guaranteed PubKlass) -> @out @_opaqueReturnTypeOf("$s3Lib8PubKlassC3run4fromQrAA0B6StructV_tF", 0) __ {
24+
// CHECK-NOT: function_ref @$s3Lib14InternalStructV3run4fromQrAA03PubC0V_tF : $@convention(method) (PubStruct, @guaranteed InternalStruct) -> @out LazyMapSequence<IteratorSequence<EntityIterator<PubStruct>>, InternalStruct.Klass>
25+
// CHECK: sil [canonical] @$s3Lib8PubKlassC3run4fromQrAA0B6StructV_tF : $@convention(method) (PubStruct, @guaranteed PubKlass) -> @out @_opaqueReturnTypeOf("$s3Lib8PubKlassC3run4fromQrAA0B6StructV_tF", 0) __
26+
func run(from arg: PubStruct) -> some Sequence<InternalStruct.Klass> {
27+
field.run(from: arg)
28+
}
29+
}
30+
31+
public struct PubStruct: Hashable { }
32+
33+
struct InternalStruct: Hashable {
34+
class Klass: Hashable {
35+
let data: PubStruct
36+
init(_ arg: PubStruct) {
37+
self.data = arg
38+
}
39+
func hash(into hasher: inout Hasher) {
40+
hasher.combine(data)
41+
}
42+
static func == (lhs: Klass, rhs: Klass) -> Bool {
43+
return lhs.data == rhs.data
44+
}
45+
}
46+
47+
var entities: [PubStruct: Klass] = [:]
48+
49+
func run(from arg: PubStruct) -> some Sequence<Klass> {
50+
IteratorSequence(EntityIterator(from: arg))
51+
.lazy.map { entities[$0]! }
52+
}
53+
}
54+
55+
56+
private struct EntityIterator<T: Hashable>: IteratorProtocol {
57+
private var list: [T]
58+
init(from start: T) {
59+
self.list = [start]
60+
}
61+
private mutating func pop() -> T? {
62+
return nil
63+
}
64+
mutating func next() -> T? {
65+
return nil
66+
}
67+
}
68+
69+

0 commit comments

Comments
 (0)