Skip to content

Commit 2690560

Browse files
authored
Merge pull request #16023 from xedin/rdar-36497404
[Serialization] Refactor normal conformance serialization
2 parents 773cd93 + 07b9170 commit 2690560

File tree

7 files changed

+82
-43
lines changed

7 files changed

+82
-43
lines changed

include/swift/AST/Witness.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,6 @@ class Witness {
150150
/// Determines whether there is a witness at all.
151151
explicit operator bool() const { return !storage.isNull(); }
152152

153-
/// Determine whether this witness requires any substitutions.
154-
bool requiresSubstitution() const { return storage.is<StoredWitness *>(); }
155-
156153
/// Retrieve the substitutions required to use this witness from the
157154
/// synthetic environment.
158155
///
@@ -164,15 +161,17 @@ class Witness {
164161

165162
/// Retrieve the synthetic generic environment.
166163
GenericEnvironment *getSyntheticEnvironment() const {
167-
assert(requiresSubstitution() && "No substitutions required for witness");
168-
return storage.get<StoredWitness *>()->syntheticEnvironment;
164+
if (auto *storedWitness = storage.dyn_cast<StoredWitness *>())
165+
return storedWitness->syntheticEnvironment;
166+
return nullptr;
169167
}
170168

171169
/// Retrieve the substitution map that maps the interface types of the
172170
/// requirement to the interface types of the synthetic environment.
173171
SubstitutionList getRequirementToSyntheticSubs() const {
174-
assert(requiresSubstitution() && "No substitutions required for witness");
175-
return storage.get<StoredWitness *>()->reqToSyntheticEnvSubs;
172+
if (auto *storedWitness = storage.dyn_cast<StoredWitness *>())
173+
return storedWitness->reqToSyntheticEnvSubs;
174+
return {};
176175
}
177176

178177
LLVM_ATTRIBUTE_DEPRECATED(

include/swift/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const uint16_t VERSION_MAJOR = 0;
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
5757
/// Don't worry about adhering to the 80-column limit for this line.
58-
const uint16_t VERSION_MINOR = 408; // Last change: begin_access [nontracking]
58+
const uint16_t VERSION_MINOR = 409; // Last change: standalone requirement subs
5959

6060
using DeclIDField = BCFixed<31>;
6161

lib/AST/ASTVerifier.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2522,13 +2522,18 @@ class Verifier : public ASTWalker {
25222522
// Check the witness substitutions.
25232523
const auto &witness = normal->getWitness(req, nullptr);
25242524

2525-
if (witness.requiresSubstitution()) {
2526-
GenericEnv.push_back({witness.getSyntheticEnvironment()});
2527-
for (const auto &sub : witness.getSubstitutions()) {
2528-
verifyChecked(sub.getReplacement());
2529-
}
2525+
if (auto *genericEnv = witness.getSyntheticEnvironment())
2526+
GenericEnv.push_back({genericEnv});
2527+
2528+
for (const auto &sub : witness.getRequirementToSyntheticSubs())
2529+
verifyChecked(sub.getReplacement());
2530+
2531+
for (const auto &sub : witness.getSubstitutions())
2532+
verifyChecked(sub.getReplacement());
2533+
2534+
if (auto *genericEnv = witness.getSyntheticEnvironment()) {
25302535
assert(GenericEnv.back().storage.dyn_cast<GenericEnvironment *>()
2531-
== witness.getSyntheticEnvironment());
2536+
== genericEnv);
25322537
GenericEnv.pop_back();
25332538
}
25342539

lib/AST/ProtocolConformance.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,13 @@ using namespace swift;
4141
Witness::Witness(ValueDecl *decl, SubstitutionList substitutions,
4242
GenericEnvironment *syntheticEnv,
4343
SubstitutionList reqToSynthesizedEnvSubs) {
44-
auto &ctx = decl->getASTContext();
44+
if (!syntheticEnv && substitutions.empty() &&
45+
reqToSynthesizedEnvSubs.empty()) {
46+
storage = decl;
47+
return;
48+
}
4549

50+
auto &ctx = decl->getASTContext();
4651
auto declRef = ConcreteDeclRef(ctx, decl, substitutions);
4752
auto storedMem = ctx.Allocate(sizeof(StoredWitness), alignof(StoredWitness));
4853
auto stored = new (storedMem)

lib/Serialization/Deserialization.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5309,13 +5309,13 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
53095309
if (auto syntheticSig = getGenericSignature(*rawIDIter++)) {
53105310
// Create the synthetic environment.
53115311
syntheticEnv = syntheticSig->createGenericEnvironment();
5312+
}
53125313

5313-
// Requirement -> synthetic substitutions.
5314-
if (unsigned numReqSubstitutions = *rawIDIter++) {
5315-
while (numReqSubstitutions--) {
5316-
auto sub = maybeReadSubstitution(DeclTypeCursor, nullptr);
5317-
reqToSyntheticSubs.push_back(*sub);
5318-
}
5314+
// Requirement -> synthetic substitutions.
5315+
if (unsigned numReqSubstitutions = *rawIDIter++) {
5316+
while (numReqSubstitutions--) {
5317+
auto sub = maybeReadSubstitution(DeclTypeCursor, nullptr);
5318+
reqToSyntheticSubs.push_back(*sub);
53195319
}
53205320
}
53215321

@@ -5334,13 +5334,6 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
53345334
continue;
53355335
}
53365336

5337-
// Handle simple witnesses.
5338-
if (witnessSubstitutions.empty() && !syntheticSig && !syntheticEnv &&
5339-
reqToSyntheticSubs.empty()) {
5340-
trySetWitness(Witness(witness));
5341-
continue;
5342-
}
5343-
53445337
// Set the witness.
53455338
trySetWitness(Witness(witness, witnessSubstitutions,
53465339
syntheticEnv, reqToSyntheticSubs));

lib/Serialization/Serialization.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1530,19 +1530,17 @@ void Serializer::writeNormalConformance(
15301530
// If there is no witness, we're done.
15311531
if (!witness.getDecl()) return;
15321532

1533-
if (auto genericEnv = witness.requiresSubstitution()
1534-
? witness.getSyntheticEnvironment()
1535-
: nullptr) {
1533+
if (auto *genericEnv = witness.getSyntheticEnvironment()) {
15361534
// Generic signature.
15371535
auto *genericSig = genericEnv->getGenericSignature();
15381536
data.push_back(addGenericSignatureRef(genericSig));
1539-
1540-
auto reqToSyntheticSubs = witness.getRequirementToSyntheticSubs();
1541-
data.push_back(reqToSyntheticSubs.size());
15421537
} else {
15431538
data.push_back(/*null generic signature*/0);
15441539
}
15451540

1541+
auto reqToSyntheticSubs = witness.getRequirementToSyntheticSubs();
1542+
1543+
data.push_back(reqToSyntheticSubs.size());
15461544
data.push_back(witness.getSubstitutions().size());
15471545
});
15481546

@@ -1568,19 +1566,14 @@ void Serializer::writeNormalConformance(
15681566
// Bail out early for simple witnesses.
15691567
if (!witness.getDecl()) return;
15701568

1571-
if (witness.requiresSubstitution()) {
1572-
// Write requirement-to-synthetic substitutions.
1573-
writeSubstitutions(witness.getRequirementToSyntheticSubs(),
1574-
DeclTypeAbbrCodes,
1575-
nullptr);
1576-
}
1569+
// Write requirement-to-synthetic substitutions.
1570+
writeSubstitutions(witness.getRequirementToSyntheticSubs(),
1571+
DeclTypeAbbrCodes, nullptr);
15771572

15781573
// Write the witness substitutions.
15791574
writeSubstitutions(witness.getSubstitutions(),
15801575
DeclTypeAbbrCodes,
1581-
witness.requiresSubstitution()
1582-
? witness.getSyntheticEnvironment()
1583-
: nullptr);
1576+
witness.getSyntheticEnvironment());
15841577
});
15851578
}
15861579

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %target-build-swift -emit-module -o %t %s
2+
3+
public protocol P1 {}
4+
public protocol P2 {}
5+
6+
public protocol P3 {
7+
static func a()
8+
9+
func b()
10+
func b<I: P1>(_: (I) -> Void)
11+
12+
static func c<I: P1>(_: I)
13+
static func d()
14+
static func d<I: P1>(_: ([(I, I)]) -> Void)
15+
static func d<I: P1>(_: ([I: I]) -> Void)
16+
static func d<Q: P1>(_: Q)
17+
18+
static func e<Q: P1, I: P2>(_: Q, _: (I) -> Void)
19+
static func f<Q: P1, I: P2>(_: Q, _: (I) -> Void)
20+
21+
func g<I: P1>(_: I)
22+
}
23+
24+
public extension P3 {
25+
static func a() {}
26+
27+
func b() {}
28+
func b<I: P1>(_: (I) -> Void) {}
29+
30+
static func c<I: P1>(_: I) {}
31+
32+
static func d() {}
33+
static func d<I: P1>(_: ([(I, I)]) -> Void) {}
34+
static func d<I: P1>(_: ([I: I]) -> Void) {}
35+
static func d<Q: P1>(_: Q) {}
36+
37+
static func e<Q: P1, I: P2>(_: Q, _: (I) -> Void) {}
38+
static func f<Q: P1, I: P2>(_: Q, _: (I) -> Void) {}
39+
40+
func g<I: P1>(_: I) {}
41+
}
42+
43+
struct S: P3 {
44+
}

0 commit comments

Comments
 (0)