Skip to content

Commit 57fac03

Browse files
committed
[Mangler] Handle ElementArchetypeType for decls
Element archetypes can occur when mangling the USR for local variables for e.g SourceKit cursor info, as well as for regular compilation for things like lazy variables. This patch adds some basic mangling logic to handle mangling the type for a decl, which is sufficient to fix things like cursor info. More work is needed to support lazy variables though (now it crashes in SILGen). This patch doesn't handle mangling standalone element archetypes for e.g `printTypeUSR`, we'll either need to fixup each of the clients there, or we'll need to rethink how we form local archetypes to correctly handle that. rdar://143077965
1 parent 95dca81 commit 57fac03

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4038,6 +4038,18 @@ CanType ASTMangler::getDeclTypeForMangling(
40384038
ty = ty->stripConcurrency(/*recurse=*/true, /*dropGlobalActor=*/true);
40394039
}
40404040

4041+
// Map any local archetypes out of context.
4042+
if (ty->hasLocalArchetype()) {
4043+
CaptureInfo captureInfo;
4044+
auto *innerDC = decl->getInnermostDeclContext();
4045+
if (auto fn = AnyFunctionRef::fromDeclContext(innerDC))
4046+
captureInfo = fn->getCaptureInfo();
4047+
4048+
ty = mapLocalArchetypesOutOfContext(
4049+
ty, innerDC->getGenericSignatureOfContext(),
4050+
captureInfo.getGenericEnvironments());
4051+
}
4052+
40414053
auto canTy = ty->getCanonicalType();
40424054

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

lib/AST/LocalArchetypeRequirementCollector.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,29 @@ Type MapLocalArchetypesOutOfContext::getInterfaceType(
183183
++depth;
184184
}
185185

186+
// If the environment we have is not for a capture, this must be a generic
187+
// environment local to the parent function. For element archetypes, the depth
188+
// we have is relative to the parent signature, so we can compute the correct
189+
// depth by offsetting it by the number of parent captured environments.
190+
if (genericEnv->getKind() == GenericEnvironment::Kind::OpenedElement) {
191+
ASSERT(rootParam->getDepth() >= baseGenericSig.getNextDepth());
192+
return GenericTypeParamType::getType(
193+
rootParam->getDepth() + capturedEnvs.size(), rootParam->getIndex(),
194+
rootParam->getASTContext());
195+
}
196+
197+
// For opened archetypes, we have no way of computing the correct depth.
186198
llvm::errs() << "Fell off the end:\n";
187199
interfaceTy->dump(llvm::errs());
188200
abort();
189201
}
190202

191203
Type MapLocalArchetypesOutOfContext::operator()(SubstitutableType *type) const {
192-
auto *archetypeTy = cast<ArchetypeType>(type);
204+
// Local archetypes can appear in interface types alongside generic param
205+
// types, ignore them here.
206+
auto *archetypeTy = dyn_cast<ArchetypeType>(type);
207+
if (!archetypeTy)
208+
return type;
193209

194210
// Primary archetypes just map out of context.
195211
if (isa<PrimaryArchetypeType>(archetypeTy) ||
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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_qd0__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+
}
34+
}
35+
36+
func baz<each T, each U, each V>(
37+
ts: repeat each T, us: repeat each U, urs: repeat (each U).R, vs: repeat each V
38+
) where repeat each U: P, (repeat (each U, each V)): Any {
39+
for t in repeat each ts {
40+
func localFn() {
41+
for y in repeat each us {
42+
func genericLocalFn<A>(_ a: A) {
43+
for (u, ur, v) in repeat (each us, each urs, each vs) {
44+
let k = (a, t, y, u, ur, v)
45+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):17 %s -- %s | %FileCheck %s --check-prefix=TUPLE1
46+
// 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
47+
// -> (A1, A2, A3, A4, A4.main.P.R, B4)
48+
49+
_ = {
50+
let k = (a, t, y, u, ur, v)
51+
// RUN: %sourcekitd-test -req=cursor -pos=%(line-1):19 %s -- %s | %FileCheck %s --check-prefix=TUPLE2
52+
// 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
53+
// -> (A1, A2, A3, A4, A4.main.P.R, B4)
54+
}
55+
}
56+
}
57+
}
58+
}
59+
}
60+
}

0 commit comments

Comments
 (0)