Skip to content

Commit b52d154

Browse files
authored
Merge pull request #78855 from hamishknight/elemental
[Mangler] Handle local archetypes in `getDeclTypeForMangling`
2 parents ed9eef2 + 994848f commit b52d154

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4016,6 +4016,43 @@ static bool isMethodDecl(const Decl *decl) {
40164016
&& decl->getDeclContext()->isTypeContext();
40174017
}
40184018

4019+
/// Map any local archetypes in a decl's interface type out of context, such
4020+
/// that the resulting type is suitable for mangling.
4021+
///
4022+
/// Note this does not guarantee that different archetypes produce different
4023+
/// interface types across decls, but it is guaranteed within a single decl
4024+
/// type. This is okay though since local decls are assigned discriminators.
4025+
static Type mapLocalArchetypesOutOfContextForDecl(const ValueDecl *decl,
4026+
Type ty) {
4027+
if (!ty->hasLocalArchetype())
4028+
return ty;
4029+
4030+
ASSERT(decl->getDeclContext()->isLocalContext());
4031+
4032+
CaptureInfo captureInfo;
4033+
auto *innerDC = decl->getInnermostDeclContext();
4034+
auto genericSig = innerDC->getGenericSignatureOfContext();
4035+
if (auto fn = AnyFunctionRef::fromDeclContext(innerDC))
4036+
captureInfo = fn->getCaptureInfo();
4037+
4038+
// Record any captured generic environments we have.
4039+
llvm::SmallSetVector<GenericEnvironment *, 4> capturedEnvs;
4040+
for (auto *genericEnv : captureInfo.getGenericEnvironments())
4041+
capturedEnvs.insert(genericEnv);
4042+
4043+
// We may still have archetypes local to the current context, e.g for
4044+
// decls in local for loops over pack expansions. In this case, collect
4045+
// any remaining generic environments from the type.
4046+
ty.visit([&](Type t) {
4047+
if (auto *archetypeTy = t->getAs<LocalArchetypeType>()) {
4048+
capturedEnvs.insert(archetypeTy->getGenericEnvironment());
4049+
}
4050+
});
4051+
4052+
return swift::mapLocalArchetypesOutOfContext(ty, genericSig,
4053+
capturedEnvs.getArrayRef());
4054+
}
4055+
40194056
CanType ASTMangler::getDeclTypeForMangling(
40204057
const ValueDecl *decl,
40214058
GenericSignature &genericSig,
@@ -4048,6 +4085,9 @@ CanType ASTMangler::getDeclTypeForMangling(
40484085
ty = ty->stripConcurrency(/*recurse=*/true, /*dropGlobalActor=*/true);
40494086
}
40504087

4088+
// Map any local archetypes out of context.
4089+
ty = mapLocalArchetypesOutOfContextForDecl(decl, ty);
4090+
40514091
auto canTy = ty->getCanonicalType();
40524092

40534093
if (auto gft = dyn_cast<GenericFunctionType>(canTy)) {

lib/AST/LocalArchetypeRequirementCollector.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ Type MapLocalArchetypesOutOfContext::getInterfaceType(
189189
}
190190

191191
Type MapLocalArchetypesOutOfContext::operator()(SubstitutableType *type) const {
192-
auto *archetypeTy = cast<ArchetypeType>(type);
192+
// Local archetypes can appear in interface types alongside generic param
193+
// types, ignore them here.
194+
auto *archetypeTy = dyn_cast<ArchetypeType>(type);
195+
if (!archetypeTy)
196+
return type;
193197

194198
// Primary archetypes just map out of context.
195199
if (isa<PrimaryArchetypeType>(archetypeTy) ||
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// https://github.com/swiftlang/swift/issues/78690
2+
// rdar://143077965
3+
4+
protocol P {
5+
associatedtype R
6+
}
7+
8+
func foo<each T>(_ xs: repeat each T) {
9+
for x in repeat each xs {
10+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):7 %s -- %s | %FileCheck %s --check-prefix=BASIC
11+
// BASIC: s:4main3fooyyxxQpRvzlF1xL_qd__vp
12+
for x2 in repeat each xs {
13+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):9 %s -- %s | %FileCheck %s --check-prefix=NESTED
14+
// NESTED: s:4main3fooyyxxQpRvzlF2x2L_qd__vp
15+
}
16+
}
17+
}
18+
19+
func bar<each T, each U>(xs: repeat each T, ys: repeat each U) {
20+
for x1 in repeat each xs {
21+
for y1 in repeat each ys {
22+
func localFn() {
23+
for x2 in repeat each xs {
24+
for y2 in repeat each ys {
25+
let k = (x1, y1, x2, y2)
26+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):17 %s -- %s | %FileCheck %s --check-prefix=DOUBLENESTED
27+
// DOUBLENESTED: s:4main3bar2xs2ysyxxQp_q_q_QptRvzRv_r0_lF7localFnL_yyRvzRv_r0_lF1kL_qd___qd0__qd1__qd2__tvp
28+
// -> (A1, A2, A3, A4)
29+
}
30+
}
31+
}
32+
_ = {
33+
for x2 in repeat each xs {
34+
for y2 in repeat each ys {
35+
let k = (x1, y1, x2, y2)
36+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):17 %s -- %s | %FileCheck %s --check-prefix=DOUBLENESTED-CLOSURE
37+
// DOUBLENESTED-CLOSURE: s:4main3bar2xs2ysyxxQp_q_q_QptRvzRv_r0_lFyycfU_1kL_qd___qd0__qd1__qd2__tvp
38+
// -> (A1, A2, A3, A4)
39+
}
40+
}
41+
}
42+
}
43+
}
44+
}
45+
46+
func baz<each T, each U, each V>(
47+
ts: repeat each T, us: repeat each U, urs: repeat (each U).R, vs: repeat each V
48+
) where repeat each U: P, (repeat (each U, each V)): Any {
49+
for t in repeat each ts {
50+
func localFn() {
51+
for y in repeat each us {
52+
func genericLocalFn<A>(_ a: A) {
53+
for (u, ur, v) in repeat (each us, each urs, each vs) {
54+
let k = (a, t, y, u, ur, v)
55+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):17 %s -- %s | %FileCheck %s --check-prefix=TUPLE1
56+
// TUPLE1: s:4main3baz2ts2us3urs2vsyxxQp_q_q_Qp1RQy_q_Qpq0_q_QptRvzRv_Rv0_AA1PR_q0_Rh_r1_lF7localFnL_yyRvzRv_Rv0_AaIR_q0_Rh_r1_lF012genericLocalH0L_yyqd__RvzRv_Rv0_AaIR_q0_Rh_r1__lF1kL_qd___qd0__qd1__qd2__AgaIPQyd2__qd2_0_tvp
57+
// -> (A1, A2, A3, A4, A4.main.P.R, B4)
58+
59+
_ = {
60+
let k = (a, t, y, u, ur, v)
61+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):19 %s -- %s | %FileCheck %s --check-prefix=TUPLE2
62+
// TUPLE2: s:4main3baz2ts2us3urs2vsyxxQp_q_q_Qp1RQy_q_Qpq0_q_QptRvzRv_Rv0_AA1PR_q0_Rh_r1_lF7localFnL_yyRvzRv_Rv0_AaIR_q0_Rh_r1_lF012genericLocalH0L_yyqd__RvzRv_Rv0_AaIR_q0_Rh_r1__lFyycfU_1kL_qd___qd0__qd1__qd2__AgaIPQyd2__qd2_0_tvp
63+
// -> (A1, A2, A3, A4, A4.main.P.R, B4)
64+
}
65+
}
66+
}
67+
}
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)