Skip to content

Commit 994848f

Browse files
committed
[Mangler] Handle local archetypes in getDeclTypeForMangling
Element archetypes can occur here when mangling the USR for local variables for e.g SourceKit cursor info, as well as for regular compilation for things like lazy variables. Update `getDeclTypeForMangling` to map local archetypes out of context, using both the captured generic environments and the archetypes present in the type. More work is needed to support lazy variable though (now it crashes in SILGen). This patch doesn't handle mangling standalone element archetypes for e.g `printTypeUSR`, ideally we'd fix the clients there to not pass local archetypes. rdar://143077965
1 parent c6d1060 commit 994848f

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)