Skip to content

Commit 44139d6

Browse files
committed
Canonicalize the conforming type of BuiltinConformances.
It turns out they aren't always canonical by construction (and they don't really need to be), so we should canonicalize the type and requirements when we canonical a conformance ref. Fixes rdar://94877954.
1 parent 0464fd3 commit 44139d6

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

lib/AST/ProtocolConformance.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,11 +1638,25 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
16381638

16391639
switch (getKind()) {
16401640
case ProtocolConformanceKind::Self:
1641-
case ProtocolConformanceKind::Normal:
1642-
case ProtocolConformanceKind::Builtin: {
1641+
case ProtocolConformanceKind::Normal: {
16431642
// Root conformances are always canonical by construction.
16441643
return this;
16451644
}
1645+
case ProtocolConformanceKind::Builtin: {
1646+
// Canonicalize the subject type of the builtin conformance.
1647+
auto &Ctx = getType()->getASTContext();
1648+
auto builtinConformance = cast<BuiltinProtocolConformance>(this);
1649+
SmallVector<Requirement, 4> canonicalRequirements;
1650+
for (auto &reqt : builtinConformance->getConditionalRequirements()) {
1651+
canonicalRequirements.push_back(reqt.getCanonical());
1652+
}
1653+
return Ctx.getBuiltinConformance(
1654+
builtinConformance->getType()->getCanonicalType(builtinConformance->getGenericSignature()),
1655+
builtinConformance->getProtocol(),
1656+
builtinConformance->getGenericSignature().getCanonicalSignature(),
1657+
canonicalRequirements,
1658+
builtinConformance->getBuiltinConformanceKind());
1659+
}
16461660

16471661
case ProtocolConformanceKind::Inherited: {
16481662
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)