Skip to content

Commit 04cfdbf

Browse files
committed
[Serialization] Deal with ErrorTypes in specialized conformances
This can represent a conformance that can never actually be used, such as an inherited conditional conformance where the subclass has provided a concrete generic parameter. (See the test case.) We probably shouldn't be forming these conformances at all, but for now this lets us build without errors. https://bugs.swift.org/browse/SR-7337
1 parent 4039db5 commit 04cfdbf

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

lib/Serialization/Deserialization.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,8 @@ ModuleFile::maybeReadSubstitution(llvm::BitstreamCursor &cursor,
678678
numConformances);
679679

680680
auto replacementTy = getType(replacementID);
681+
if (!replacementTy)
682+
replacementTy = ErrorType::get(getContext());
681683
if (genericEnv) {
682684
replacementTy = genericEnv->mapTypeIntoContext(replacementTy);
683685
}

lib/Serialization/Serialization.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1646,7 +1646,8 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
16461646
abbrCode,
16471647
addTypeRef(type),
16481648
substitutions.size());
1649-
writeSubstitutions(substitutions, abbrCodes, genericEnv);
1649+
writeSubstitutions(substitutions, abbrCodes, genericEnv,
1650+
/*ignoreReplacementErrors*/true);
16501651

16511652
writeConformance(conf->getGenericConformance(), abbrCodes, genericEnv);
16521653
break;
@@ -1691,7 +1692,8 @@ Serializer::writeConformances(ArrayRef<ProtocolConformance*> conformances,
16911692
void
16921693
Serializer::writeSubstitutions(SubstitutionList substitutions,
16931694
const std::array<unsigned, 256> &abbrCodes,
1694-
GenericEnvironment *genericEnv) {
1695+
GenericEnvironment *genericEnv,
1696+
bool ignoreReplacementErrors) {
16951697
using namespace decls_block;
16961698
auto abbrCode = abbrCodes[BoundGenericSubstitutionLayout::Code];
16971699

@@ -1700,6 +1702,8 @@ Serializer::writeSubstitutions(SubstitutionList substitutions,
17001702
if (genericEnv && replacementType->hasArchetype()) {
17011703
replacementType = replacementType->mapTypeOutOfContext();
17021704
}
1705+
if (replacementType->hasError() && ignoreReplacementErrors)
1706+
replacementType = Type();
17031707

17041708
BoundGenericSubstitutionLayout::emitRecord(
17051709
Out, ScratchRecord, abbrCode,

lib/Serialization/Serialization.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,8 @@ class Serializer {
495495
/// being written.
496496
void writeSubstitutions(SubstitutionList substitutions,
497497
const std::array<unsigned, 256> &abbrCodes,
498-
GenericEnvironment *genericEnv = nullptr);
498+
GenericEnvironment *genericEnv = nullptr,
499+
bool ignoreReplacementErrors = false);
499500

500501
/// Write a normal protocol conformance.
501502
void writeNormalConformance(const NormalProtocolConformance *conformance);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -emit-module -o %t/Lib.swiftmodule %s -DLIB
3+
// RUN: %target-build-swift -emit-module -o %t/main.swiftmodule -I %t %s
4+
5+
#if LIB
6+
7+
protocol Proto {}
8+
9+
open class Base<T> {}
10+
public struct ArbitraryStruct {}
11+
12+
extension Base: Proto where T: Proto {}
13+
14+
#else // LIB
15+
16+
import Lib
17+
18+
final class ConcreteSub: Base<ArbitraryStruct> {}
19+
20+
#endif // LIB

0 commit comments

Comments
 (0)