Skip to content

Commit 25d8029

Browse files
authored
Merge pull request #60439 from jckarter/canonicalize-builtin-conformances-5.7
[5.7] Canonicalize the conforming type of BuiltinConformances.
2 parents 50204e0 + d707d42 commit 25d8029

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
@@ -1608,8 +1608,22 @@ bool ProtocolConformance::isCanonical() const {
16081608

16091609
switch (getKind()) {
16101610
case ProtocolConformanceKind::Self:
1611-
case ProtocolConformanceKind::Normal:
1611+
case ProtocolConformanceKind::Normal: {
1612+
return true;
1613+
}
16121614
case ProtocolConformanceKind::Builtin: {
1615+
// Check that the generic signature of the conformance is canonical.
1616+
auto builtinConformance = cast<BuiltinProtocolConformance>(this);
1617+
if (builtinConformance->getGenericSignature()
1618+
&& !builtinConformance->getGenericSignature()->isCanonical()) {
1619+
return false;
1620+
}
1621+
// Check that the satisfied conditional requirements are canonical.
1622+
for (auto &requirement : builtinConformance->getConditionalRequirements()) {
1623+
if (!requirement.isCanonical()) {
1624+
return false;
1625+
}
1626+
}
16131627
return true;
16141628
}
16151629
case ProtocolConformanceKind::Inherited: {
@@ -1638,11 +1652,25 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
16381652

16391653
switch (getKind()) {
16401654
case ProtocolConformanceKind::Self:
1641-
case ProtocolConformanceKind::Normal:
1642-
case ProtocolConformanceKind::Builtin: {
1655+
case ProtocolConformanceKind::Normal: {
16431656
// Root conformances are always canonical by construction.
16441657
return this;
16451658
}
1659+
case ProtocolConformanceKind::Builtin: {
1660+
// Canonicalize the subject type of the builtin conformance.
1661+
auto &Ctx = getType()->getASTContext();
1662+
auto builtinConformance = cast<BuiltinProtocolConformance>(this);
1663+
SmallVector<Requirement, 4> canonicalRequirements;
1664+
for (auto &reqt : builtinConformance->getConditionalRequirements()) {
1665+
canonicalRequirements.push_back(reqt.getCanonical());
1666+
}
1667+
return Ctx.getBuiltinConformance(
1668+
builtinConformance->getType()->getCanonicalType(),
1669+
builtinConformance->getProtocol(),
1670+
builtinConformance->getGenericSignature().getCanonicalSignature(),
1671+
canonicalRequirements,
1672+
builtinConformance->getBuiltinConformanceKind());
1673+
}
16461674

16471675
case ProtocolConformanceKind::Inherited: {
16481676
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)