Skip to content

Commit 21500ab

Browse files
committed
AST: Never query the map with non-root archetypes in QueryTypeSubstitutionMapOrIdentity
This makes `SILCloner::getASTTypeInClonedContext` and `getTypeInClonedContext`, which use `QueryTypeSubstitutionMapOrIdentity`, work for nested opened archetypes and consequently fixes inlining of instructions involving these archetypes.
1 parent 63d0130 commit 21500ab

File tree

3 files changed

+45
-9
lines changed

3 files changed

+45
-9
lines changed

lib/AST/Type.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@ Type QueryTypeSubstitutionMap::operator()(SubstitutableType *type) const {
6565

6666
Type
6767
QueryTypeSubstitutionMapOrIdentity::operator()(SubstitutableType *type) const {
68+
// FIXME: Type::subst should not be pass in non-root archetypes.
69+
// Consider only root archetypes.
70+
if (auto *archetype = dyn_cast<ArchetypeType>(type)) {
71+
if (!archetype->isRoot())
72+
return Type();
73+
}
74+
6875
auto key = type->getCanonicalType()->castTo<SubstitutableType>();
6976
auto known = substitutions.find(key);
7077
if (known != substitutions.end() && known->second)

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,18 +2582,16 @@ CanSILFunctionType swift::buildSILFunctionThunkType(
25822582
}
25832583

25842584
auto substTypeHelper = [&](SubstitutableType *type) -> Type {
2585+
// FIXME: Type::subst should not pass in non-root archetypes.
2586+
// Consider only root archetypes.
2587+
if (auto *archetype = dyn_cast<ArchetypeType>(type)) {
2588+
if (!archetype->isRoot())
2589+
return Type();
2590+
}
2591+
25852592
if (CanType(type) == openedExistential)
25862593
return newArchetype;
25872594

2588-
// If a nested archetype is rooted on our opened existential, fail:
2589-
// Type::subst attempts to substitute the parent of a nested archetype
2590-
// only if it fails to find a replacement for the nested one.
2591-
if (auto *opened = dyn_cast<OpenedArchetypeType>(type)) {
2592-
if (openedExistential->isEqual(opened->getRoot())) {
2593-
return nullptr;
2594-
}
2595-
}
2596-
25972595
return Type(type).subst(contextSubs);
25982596
};
25992597
auto substConformanceHelper =
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %target-swift-frontend -emit-sil -O -primary-file %s | %FileCheck %s
2+
3+
// FIXME: Ideally, this should be a sil-opt test, but TypeRepr cannot model
4+
// types like '(@opened("...") P).Assoc' as of now.
5+
6+
protocol P {
7+
associatedtype Assoc: P
8+
9+
func f() -> Self.Assoc
10+
}
11+
12+
// CHECK-LABEL: sil hidden [always_inline] @$s35mandatory_inlining_open_existential6callee1pAA1P_pAaD_p_tF
13+
// CHECK: [[OPENED:%[0-9]+]] = open_existential_addr immutable_access {{%[0-9]+}} : $*P to $*[[OPENED_TY:@opened\("[-A-F0-9]+"\) P]]
14+
// CHECK: [[WITNESS:%[0-9]+]] = witness_method $[[OPENED_TY]], #P.f : <Self where Self : P> (Self) -> () -> Self.Assoc
15+
// CHECK: [[RESULT:%[0-9]+]] = init_existential_addr {{%[0-9]+}} : $*P, $([[OPENED_TY]]).Assoc
16+
// CHECK: apply [[WITNESS]]<[[OPENED_TY]]>([[RESULT]], [[OPENED]])
17+
// CHECK: }
18+
@inline(__always)
19+
func callee(p: any P) -> any P {
20+
return p.f()
21+
}
22+
23+
// CHECK-LABEL: sil hidden @$s35mandatory_inlining_open_existential6caller1pAA1P_pAaD_p_tF
24+
// CHECK: [[OPENED:%[0-9]+]] = open_existential_addr immutable_access {{%[0-9]+}} : $*P to $*[[OPENED_TY:@opened\("[-A-F0-9]+"\) P]]
25+
// CHECK: [[WITNESS:%[0-9]+]] = witness_method $[[OPENED_TY]], #P.f : <Self where Self : P> (Self) -> () -> Self.Assoc
26+
// CHECK: [[RESULT:%[0-9]+]] = init_existential_addr {{%[0-9]+}} : $*P, $([[OPENED_TY]]).Assoc
27+
// CHECK: apply [[WITNESS]]<[[OPENED_TY]]>([[RESULT]], [[OPENED]])
28+
// CHECK: }
29+
func caller(p: any P) -> any P {
30+
return callee(p: p)
31+
}

0 commit comments

Comments
 (0)