Skip to content

Commit 96a1ab7

Browse files
authored
Merge pull request #9800 from jrose-apple/null-does-not-mean-absent
[Serialization] Fix incorrect counting of value witnesses
2 parents 70578b8 + f128803 commit 96a1ab7

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

lib/AST/ASTDumper.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,6 +2743,35 @@ void ProtocolConformance::dump(llvm::raw_ostream &out, unsigned indent) const {
27432743

27442744
printCommon("normal");
27452745
// Maybe print information about the conforming context?
2746+
if (normal->isLazilyResolved()) {
2747+
out << " lazy";
2748+
} else {
2749+
forEachTypeWitness(nullptr, [&](const AssociatedTypeDecl *req,
2750+
Type ty, const TypeDecl *) -> bool {
2751+
out << '\n';
2752+
out.indent(indent + 2);
2753+
PrintWithColorRAII(out, ParenthesisColor) << '(';
2754+
out << "assoc_type req=" << req->getName() << " type=";
2755+
PrintWithColorRAII(out, TypeColor) << ty;
2756+
PrintWithColorRAII(out, ParenthesisColor) << ')';
2757+
return false;
2758+
});
2759+
normal->forEachValueWitness(nullptr, [&](const ValueDecl *req,
2760+
Witness witness) {
2761+
out << '\n';
2762+
out.indent(indent + 2);
2763+
PrintWithColorRAII(out, ParenthesisColor) << '(';
2764+
out << "value req=" << req->getFullName() << " witness=";
2765+
if (!witness) {
2766+
out << "(none)";
2767+
} else if (witness.getDecl() == req) {
2768+
out << "(dynamic)";
2769+
} else {
2770+
witness.getDecl()->dumpRef(out);
2771+
}
2772+
PrintWithColorRAII(out, ParenthesisColor) << ')';
2773+
});
2774+
}
27462775

27472776
for (auto conformance : normal->getSignatureConformances()) {
27482777
out << '\n';

lib/Serialization/Serialization.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,7 @@ void Serializer::writeNormalConformance(
12961296

12971297
conformance->forEachValueWitness(nullptr,
12981298
[&](ValueDecl *req, Witness witness) {
1299+
++numValueWitnesses;
12991300
data.push_back(addDeclRef(req));
13001301
data.push_back(addDeclRef(witness.getDecl()));
13011302
assert(witness.getDecl() || req->getAttrs().hasAttribute<OptionalAttr>()
@@ -1319,11 +1320,10 @@ void Serializer::writeNormalConformance(
13191320

13201321
// Requirements come at the end.
13211322
} else {
1322-
data.push_back(0);
1323+
data.push_back(/*number of generic parameters*/0);
13231324
}
13241325

13251326
data.push_back(witness.getSubstitutions().size());
1326-
++numValueWitnesses;
13271327
});
13281328

13291329
conformance->forEachTypeWitness(/*resolver=*/nullptr,

test/Serialization/cross_module_optional_protocol_reqt.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,28 @@
22
// RUN: %target-swift-frontend -module-name cross_module_optional_protocol_reqt -c -emit-module-path %t/cross_module_optional_protocol_reqt~partial.swiftmodule -primary-file %s %S/Inputs/cross_module_optional_protocol_reqt_2.swift -import-objc-header %S/Inputs/cross_module_optional_protocol_reqt.h -o /dev/null
33
// RUN: %target-swift-frontend -module-name cross_module_optional_protocol_reqt -c -emit-module-path %t/cross_module_optional_protocol_reqt_2~partial.swiftmodule %s -primary-file %S/Inputs/cross_module_optional_protocol_reqt_2.swift -import-objc-header %S/Inputs/cross_module_optional_protocol_reqt.h -o /dev/null
44
// RUN: %target-swift-frontend -module-name cross_module_optional_protocol_reqt -emit-module -emit-module-path %t/cross_module_optional_protocol_reqt.swiftmodule %t/cross_module_optional_protocol_reqt~partial.swiftmodule %t/cross_module_optional_protocol_reqt_2~partial.swiftmodule -import-objc-header %S/Inputs/cross_module_optional_protocol_reqt.h
5+
// RUN: %target-swift-frontend -I %t -typecheck %s -DTEST -module-name main
56
// REQUIRES: objc_interop
67

8+
#if TEST
9+
10+
import cross_module_optional_protocol_reqt
11+
12+
func test(_ foo: Foo) {
13+
// At one point this forced deserialization of the conformance to ObjCProto,
14+
// which was corrupted by the presence of the optional requirement with no
15+
// witness.
16+
foo.nonoptionalMethod()
17+
foo.nonoptionalMethod2()
18+
}
19+
20+
#else // TEST
21+
722
public protocol SwiftProto: ObjCProto {}
823

924
public class Foo: ObjCFoo, SwiftProto {
1025
public func nonoptionalMethod() {}
1126
public func nonoptionalMethod2() {}
1227
}
28+
29+
#endif // TEST

0 commit comments

Comments
 (0)