Skip to content

Commit a1b008c

Browse files
committed
SILCloner: Fix logic error when cloning without a substitution map
If we have no substitution map, we still substitute types appearing in the original function, because we need to remap any local archetypes, which are always cloned. However, the conformance lookup callback used for this substitution was wrong. We should only do mapTypeOutOfContext() if we're going to callSubstitutionMap::lookupConformance(), otherwise we form a new abstract conformance with an interface type, and not a primary archetype as expected.
1 parent beb2b58 commit a1b008c

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

include/swift/SIL/SILCloner.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ struct SubstitutionMapWithLocalArchetypes {
8686
if (origType->is<LocalArchetypeType>())
8787
return swift::lookupConformance(origType.subst(IFS), proto);
8888

89-
if (origType->is<PrimaryArchetypeType>() ||
90-
origType->is<PackArchetypeType>())
91-
origType = origType->mapTypeOutOfContext();
92-
9389
if (SubsMap) {
90+
if (origType->is<PrimaryArchetypeType>() ||
91+
origType->is<PackArchetypeType>()) {
92+
origType = origType->mapTypeOutOfContext();
93+
}
94+
9495
return SubsMap->lookupConformance(
9596
origType->getCanonicalType(), proto);
9697
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// RUN: %target-sil-opt %s -mandatory-allocbox-to-stack
2+
3+
// This tickled a bug in the SILCloner that was caught by the verifier.
4+
5+
sil_stage raw
6+
7+
import Builtin
8+
import Swift
9+
import SwiftShims
10+
11+
protocol P {
12+
associatedtype A
13+
}
14+
15+
protocol Q: AnyObject {
16+
}
17+
18+
struct S: P {
19+
typealias A = Int
20+
}
21+
22+
sil [ossa] @testit : $@convention(thin) (Int, @guaranteed any Q, @in_guaranteed Int, @in_guaranteed S) -> () {
23+
bb0(%0 : $Int, %3 : @guaranteed $any Q, %4 : $*Int, %5 : $*S):
24+
%6 = alloc_box ${ var Int }, var, name "duration"
25+
%7 = begin_borrow [var_decl] %6
26+
%8 = project_box %7, 0
27+
store %0 to [trivial] %8
28+
%66 = function_ref @closure : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.A, τ_0_1 : P> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1, @guaranteed { var Int }, @guaranteed any Q) -> ()
29+
%67 = apply %66<Int, S>(%4, %5, %7, %3) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == τ_0_1.A, τ_0_1 : P> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1, @guaranteed { var Int }, @guaranteed any Q) -> ()
30+
end_borrow %7
31+
destroy_value %6
32+
%75 = tuple ()
33+
return %75
34+
}
35+
36+
sil private [ossa] @closure : $@convention(thin) <T, V where T == V.A, V : P> (@in_guaranteed T, @in_guaranteed V, @guaranteed { var Int }, @guaranteed any Q) -> () {
37+
bb0(%0 : $*T, %1 : $*V, %2 : @closureCapture @guaranteed ${ var Int }, %3 : @closureCapture @guaranteed $any Q):
38+
%13 = open_existential_ref %3 to $@opened("891BD9C8-56A2-11F0-A4DF-0EA13E3AABAF", any Q) Self
39+
%17 = apply undef<@opened("891BD9C8-56A2-11F0-A4DF-0EA13E3AABAF", any Q) Self, V>(%0, %1) : $@convention(thin) <τ_0_0><τ_1_0 where τ_1_0 : P> (@in_guaranteed τ_1_0.A, @in_guaranteed τ_1_0) -> ()
40+
%20 = tuple ()
41+
return %20
42+
}
43+
44+

0 commit comments

Comments
 (0)