Skip to content

Commit 67d8cb8

Browse files
committed
[CSBindings] Copy-initialize transitive protocols for equivalence class
Since equivalence class shares protocols, let's copy-initialize transitive requirement sets because move would result in slots with null pointers if equivalence class is bigger than just one member. Resolves: rdar://74723323
1 parent 16d3f78 commit 67d8cb8

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -253,11 +253,11 @@ void PotentialBindings::inferTransitiveProtocolRequirements(
253253
const SmallPtrSetImpl<Constraint *> &transitive) {
254254
auto &destination = protocols[dstVar];
255255

256-
for (auto *protocol : direct)
257-
destination.insert(protocol);
256+
if (direct.size() > 0)
257+
destination.insert(direct.begin(), direct.end());
258258

259-
for (auto *protocol : transitive)
260-
destination.insert(protocol);
259+
if (transitive.size() > 0)
260+
destination.insert(transitive.begin(), transitive.end());
261261
};
262262

263263
addToWorkList(nullptr, TypeVar);
@@ -289,7 +289,7 @@ void PotentialBindings::inferTransitiveProtocolRequirements(
289289
addToWorkList(currentVar, entry.first);
290290

291291
// If current type variable is part of an equivalence
292-
// class, make it a "representative" and let's it infer
292+
// class, make it a "representative" and let it infer
293293
// supertypes and direct protocol requirements from
294294
// other members.
295295
for (const auto &entry : bindings.EquivalentTo) {
@@ -325,7 +325,7 @@ void PotentialBindings::inferTransitiveProtocolRequirements(
325325
propagateProtocolsTo(parent, bindings.Protocols, protocols[currentVar]);
326326
}
327327

328-
auto inferredProtocols = std::move(protocols[currentVar]);
328+
auto &inferredProtocols = protocols[currentVar];
329329

330330
llvm::SmallPtrSet<Constraint *, 4> protocolsForEquivalence;
331331

@@ -348,13 +348,15 @@ void PotentialBindings::inferTransitiveProtocolRequirements(
348348
auto eqBindings = inferredBindings.find(equivalence.first);
349349
if (eqBindings != inferredBindings.end()) {
350350
auto &bindings = eqBindings->getSecond();
351-
bindings.TransitiveProtocols.emplace(protocolsForEquivalence);
351+
bindings.TransitiveProtocols.emplace(protocolsForEquivalence.begin(),
352+
protocolsForEquivalence.end());
352353
}
353354
}
354355

355356
// Update the bindings associated with current type variable,
356357
// to avoid repeating this inference process.
357-
bindings.TransitiveProtocols.emplace(std::move(inferredProtocols));
358+
bindings.TransitiveProtocols.emplace(inferredProtocols.begin(),
359+
inferredProtocols.end());
358360
} while (!workList.empty());
359361
}
360362

0 commit comments

Comments
 (0)