Skip to content

Commit 3849407

Browse files
authored
Merge pull request swiftlang#84545 from xedin/rdar-160816474
[SIL] Allow init accessor declarations in constrained extensions
2 parents 927bdb2 + f4f99ba commit 3849407

File tree

3 files changed

+88
-9
lines changed

3 files changed

+88
-9
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,8 +2955,10 @@ static CanSILFunctionType getSILFunctionTypeForInitAccessor(
29552955

29562956
// Make a new 'self' parameter.
29572957
if (!declContext->isLocalContext()) {
2958-
auto selfInterfaceType =
2959-
MetatypeType::get(declContext->getSelfInterfaceType());
2958+
auto selfInterfaceType = MetatypeType::get(
2959+
(genericSig)
2960+
? declContext->getSelfInterfaceType()->getReducedType(genericSig)
2961+
: declContext->getSelfTypeInContext());
29602962
AbstractionPattern origSelfType(genericSig,
29612963
selfInterfaceType->getCanonicalType());
29622964
auto loweredSelfType = TC.getLoweredType(

lib/SILGen/SILGenFunction.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,11 +1931,6 @@ void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue,
19311931

19321932
auto initTy = initFRef->getType().castTo<SILFunctionType>();
19331933

1934-
// If there are substitutions we need to emit partial apply to
1935-
// apply substitutions to the init accessor reference type.
1936-
initTy = initTy->substGenericArgs(SGM.M, substitutions,
1937-
getTypeExpansionContext());
1938-
19391934
// Emit partial apply with self metatype argument to produce a substituted
19401935
// init accessor reference.
19411936
auto selfTy = selfValue.getType().getASTType();
@@ -1949,8 +1944,9 @@ void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue,
19491944
selfMetatype = B.createMetatype(loc, getLoweredType(metatypeTy));
19501945
}
19511946

1952-
auto expectedSelfTy = initAccessor->getDeclContext()->getSelfInterfaceType()
1953-
.subst(substitutions);
1947+
auto expectedSelfTy =
1948+
initAccessor->getDeclContext()->getSelfInterfaceType().subst(
1949+
substitutions);
19541950

19551951
// This should only happen in the invalid case where we attempt to initialize
19561952
// superclass storage from a subclass initializer. However, we shouldn't
@@ -1960,6 +1956,14 @@ void SILGenFunction::emitAssignOrInit(SILLocation loc, ManagedValue selfValue,
19601956
selfMetatype = B.createUpcast(loc, selfMetatype,
19611957
getLoweredType(MetatypeType::get(expectedSelfTy)));
19621958
}
1959+
1960+
if (auto invocationSig = initTy->getInvocationGenericSignature()) {
1961+
if (invocationSig->areAllParamsConcrete())
1962+
substitutions = SubstitutionMap();
1963+
} else {
1964+
substitutions = SubstitutionMap();
1965+
}
1966+
19631967
PartialApplyInst *initPAI =
19641968
B.createPartialApply(loc, initFRef, substitutions, selfMetatype,
19651969
ParameterConvention::Direct_Guaranteed,
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: %target-swift-frontend -Xllvm -sil-print-types -Xllvm -sil-print-after=definite-init -emit-sil -module-name assign_or_init_lowering %s -o /dev/null 2>&1 | %FileCheck %s
2+
3+
struct S1<T> {
4+
}
5+
6+
extension S1 where T == Int {
7+
class Test {
8+
var test1: Int {
9+
init(initialValue) { }
10+
set {}
11+
get { 0 }
12+
}
13+
14+
var test2: T {
15+
init(initialValue) { }
16+
set {}
17+
get { 0 }
18+
}
19+
20+
// CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering2S1VAASiRszlE4TestCAEySi_Gycfc : $@convention(method) (@owned S1<Int>.Test) -> @owned S1<Int>.Test
21+
//
22+
// CHECK: [[TEST1_INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering2S1VAASiRszlE4TestC5test1Sivi : $@convention(thin) (Int, @thick S1<Int>.Test.Type) -> ()
23+
// CHECK-NEXT: [[SELF:%.*]] = value_metatype $@thick S1<Int>.Test.Type, {{.*}} : $S1<Int>.Test
24+
// CHECK-NEXT: [[TEST1_INIT_REF_WITH_SELF_APPLIED:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[TEST1_INIT_REF]]([[SELF]]) : $@convention(thin) (Int, @thick S1<Int>.Test.Type) -> ()
25+
// CHECK: assign_or_init [init] #S1.Test.test1, self {{.*}} : $S1<Int>.Test, value {{.*}} : $Int, init [[TEST1_INIT_REF_WITH_SELF_APPLIED]] : $@noescape @callee_guaranteed (Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int) -> ()
26+
//
27+
// CHECK: [[TEST2_INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering2S1VAASiRszlE4TestC5test2Sivi : $@convention(thin) (Int, @thick S1<Int>.Test.Type) -> ()
28+
// CHECK-NEXT: [[SELF:%.*]] = value_metatype $@thick S1<Int>.Test.Type, {{.*}} : $S1<Int>.Test
29+
// CHECK-NEXT: [[TEST2_INIT_REF_WITH_SELF_APPLIED:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[TEST2_INIT_REF]]([[SELF]]) : $@convention(thin) (Int, @thick S1<Int>.Test.Type) -> ()
30+
// CHECK: assign_or_init [init] #S1.Test.test2, self {{.*}} : $S1<Int>.Test, value {{.*}} : $Int, init [[TEST2_INIT_REF_WITH_SELF_APPLIED]] : $@noescape @callee_guaranteed (Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int) -> ()
31+
// CHECK: } // end sil function '$s23assign_or_init_lowering2S1VAASiRszlE4TestCAEySi_Gycfc'
32+
init() {
33+
test1 = 0
34+
test2 = 1
35+
}
36+
}
37+
}
38+
39+
struct S2<T, U> {
40+
}
41+
42+
extension S2 where T == Int {
43+
class Test {
44+
var test1: T {
45+
init(initialValue) { }
46+
set {}
47+
get { 0 }
48+
}
49+
50+
var test2: U {
51+
init(initialValue) { }
52+
set {}
53+
get { fatalError() }
54+
}
55+
56+
// CHECK-LABEL: sil hidden [ossa] @$s23assign_or_init_lowering2S2VAASiRszrlE4TestC1uAEySiq__Gq__tcfc : $@convention(method) <T, U where T == Int> (@in U, @owned S2<Int, U>.Test) -> @owned S2<Int, U>.Test {
57+
//
58+
// CHECK: [[TEST1_INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering2S2VAASiRszrlE4TestC5test1Sivi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == Int> (Int, @thick S2<Int, τ_0_1>.Test.Type) -> ()
59+
// CHECK-NEXT: [[SELF:%.*]] = value_metatype $@thick S2<Int, U>.Test.Type, {{.*}} : $S2<Int, U>.Test
60+
// CHECK-NEXT: [[TEST1_INIT_REF_WITH_SELF_APPLIED:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[TEST1_INIT_REF]]<Int, U>([[SELF]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == Int> (Int, @thick S2<Int, τ_0_1>.Test.Type) -> ()
61+
// CHECK: assign_or_init [init] #S2.Test.test1, self {{.*}} : $S2<Int, U>.Test, value {{.*}} : $Int, init [[TEST1_INIT_REF_WITH_SELF_APPLIED]] : $@noescape @callee_guaranteed (Int) -> (), set {{.*}} : $@noescape @callee_guaranteed (Int) -> ()
62+
//
63+
// CHECK: [[TEST2_INIT_REF:%.*]] = function_ref @$s23assign_or_init_lowering2S2VAASiRszrlE4TestC5test2q_vi : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == Int> (@in τ_0_1, @thick S2<Int, τ_0_1>.Test.Type) -> ()
64+
// CHECK-NEXT: [[SELF:%.*]] = value_metatype $@thick S2<Int, U>.Test.Type, {{.*}} : $S2<Int, U>.Test
65+
// CHECK-NEXT: [[TEST2_INIT_REF_WITH_SELF_APPLIED:%.*]] = partial_apply [callee_guaranteed] [on_stack] [[TEST2_INIT_REF]]<Int, U>([[SELF]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 == Int> (@in τ_0_1, @thick S2<Int, τ_0_1>.Test.Type) -> ()
66+
// CHECK: assign_or_init [init] #S2.Test.test2, self {{.*}} : $S2<Int, U>.Test, value {{.*}} : $*U, init [[TEST2_INIT_REF_WITH_SELF_APPLIED]] : $@noescape @callee_guaranteed (@in U) -> (), set {{.*}} : $@noescape @callee_guaranteed (@in U) -> ()
67+
// CHECK: } // end sil function '$s23assign_or_init_lowering2S2VAASiRszrlE4TestC1uAEySiq__Gq__tcfc'
68+
init(u: U) {
69+
test1 = 0
70+
test2 = u
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)