Skip to content

Commit b29d6cc

Browse files
authored
Merge pull request #60402 from jckarter/canonicalize-builtin-conformances
Canonicalize the conforming type of BuiltinConformances.
2 parents a5dbf98 + 4f0643c commit b29d6cc

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

lib/AST/ProtocolConformance.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,8 +1570,22 @@ bool ProtocolConformance::isCanonical() const {
15701570

15711571
switch (getKind()) {
15721572
case ProtocolConformanceKind::Self:
1573-
case ProtocolConformanceKind::Normal:
1573+
case ProtocolConformanceKind::Normal: {
1574+
return true;
1575+
}
15741576
case ProtocolConformanceKind::Builtin: {
1577+
// Check that the generic signature of the conformance is canonical.
1578+
auto builtinConformance = cast<BuiltinProtocolConformance>(this);
1579+
if (builtinConformance->getGenericSignature()
1580+
&& !builtinConformance->getGenericSignature()->isCanonical()) {
1581+
return false;
1582+
}
1583+
// Check that the satisfied conditional requirements are canonical.
1584+
for (auto &requirement : builtinConformance->getConditionalRequirements()) {
1585+
if (!requirement.isCanonical()) {
1586+
return false;
1587+
}
1588+
}
15751589
return true;
15761590
}
15771591
case ProtocolConformanceKind::Inherited: {
@@ -1600,11 +1614,25 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
16001614

16011615
switch (getKind()) {
16021616
case ProtocolConformanceKind::Self:
1603-
case ProtocolConformanceKind::Normal:
1604-
case ProtocolConformanceKind::Builtin: {
1617+
case ProtocolConformanceKind::Normal: {
16051618
// Root conformances are always canonical by construction.
16061619
return this;
16071620
}
1621+
case ProtocolConformanceKind::Builtin: {
1622+
// Canonicalize the subject type of the builtin conformance.
1623+
auto &Ctx = getType()->getASTContext();
1624+
auto builtinConformance = cast<BuiltinProtocolConformance>(this);
1625+
SmallVector<Requirement, 4> canonicalRequirements;
1626+
for (auto &reqt : builtinConformance->getConditionalRequirements()) {
1627+
canonicalRequirements.push_back(reqt.getCanonical());
1628+
}
1629+
return Ctx.getBuiltinConformance(
1630+
builtinConformance->getType()->getCanonicalType(),
1631+
builtinConformance->getProtocol(),
1632+
builtinConformance->getGenericSignature().getCanonicalSignature(),
1633+
canonicalRequirements,
1634+
builtinConformance->getBuiltinConformanceKind());
1635+
}
16081636

16091637
case ProtocolConformanceKind::Inherited: {
16101638
auto &Ctx = getType()->getASTContext();
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-emit-silgen -disable-availability-checking -verify %s
2+
3+
// rdar://94877954
4+
5+
// `dynamic` prevents SILGen from lowering away
6+
// the opaque return type of `foo`
7+
dynamic func foo<T: Sendable>(f: () -> T) -> some Sendable {
8+
if #available(macOS 11.0, *) {
9+
return f()
10+
} else {
11+
return ()
12+
}
13+
}
14+
15+
func bar() {
16+
let x: Void = ()
17+
let y: () = ()
18+
var a = foo { x }
19+
a = foo { y }
20+
_ = a
21+
}

0 commit comments

Comments
 (0)