Skip to content

Commit a04a557

Browse files
committed
SILGen: Substitute generics for partial super_method instructions
These need to be provided to partial_apply instructions.
1 parent ab29adf commit a04a557

File tree

4 files changed

+260
-75
lines changed

4 files changed

+260
-75
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3498,20 +3498,21 @@ namespace {
34983498

34993499
// Special case for superclass method calls.
35003500
if (isPartiallyAppliedSuperMethod(uncurryLevel)) {
3501-
auto constant = callee.getMethodName();
3502-
auto loc = uncurriedLoc.getValue();
3503-
auto subs = callee.getSubstitutions();
35043501
assert(uncurriedArgs.size() == 1 &&
35053502
"Can only partially apply the self parameater of a super method call");
35063503

3504+
auto constant = callee.getMethodName();
3505+
auto loc = uncurriedLoc.getValue();
3506+
auto subs = callee.getSubstitutions();
35073507
auto upcastedSelf = uncurriedArgs.back();
35083508
auto self = cast<UpcastInst>(upcastedSelf.getValue())->getOperand();
35093509
auto constantInfo = gen.getConstantInfo(callee.getMethodName());
3510+
auto functionTy = constantInfo.getSILType();
35103511
SILValue superMethodVal = gen.B.createSuperMethod(
35113512
loc,
35123513
self,
35133514
constant,
3514-
constantInfo.getSILType(),
3515+
functionTy,
35153516
/*volatile*/
35163517
constant.isForeign);
35173518

@@ -3520,11 +3521,17 @@ namespace {
35203521
1,
35213522
gen.B.getModule(),
35223523
subs);
3523-
3524+
3525+
auto &module = gen.getFunction().getModule();
3526+
3527+
auto partialApplyTy = functionTy;
3528+
if (constantInfo.SILFnType->isPolymorphic() && !subs.empty())
3529+
partialApplyTy = partialApplyTy.substGenericArgs(module, subs);
3530+
35243531
SILValue partialApply = gen.B.createPartialApply(
35253532
loc,
35263533
superMethodVal,
3527-
constantInfo.getSILType(),
3534+
partialApplyTy,
35283535
subs,
35293536
{ upcastedSelf.forward(gen) },
35303537
closureTy);
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
public func doFoo(f: () -> ()) {
2+
f()
3+
}
4+
5+
public class OutsideParent {
6+
public init() {
7+
print("OutsideParent.init()")
8+
}
9+
10+
public func method() {
11+
print("OutsideParent.method()")
12+
}
13+
14+
public class func classMethod() {
15+
print("OutsideParent.classMethod()")
16+
}
17+
}
18+
19+
public class OutsideChild : OutsideParent {
20+
public override func method() {
21+
print("OutsideChild.method()")
22+
super.method()
23+
}
24+
25+
public override class func classMethod() {
26+
print("OutsideChild.classMethod()")
27+
super.classMethod()
28+
}
29+
}
30+
31+
public class GenericOutsideParent<A> {
32+
let a: A
33+
public init(a: A) {
34+
self.a = a
35+
print("OutsideParent.init()")
36+
}
37+
38+
public func method() {
39+
print("OutsideParent.method()")
40+
}
41+
42+
public class func classMethod() {
43+
print("OutsideParent.classMethod()")
44+
}
45+
}
46+
47+
public class GenericOutsideChild<A> : GenericOutsideParent<A> {
48+
public override init(a: A) {
49+
print("OutsideGenericChild.init(a: A)")
50+
super.init(a: a)
51+
}
52+
53+
public override func method() {
54+
print("OutsideChild.method()")
55+
super.method()
56+
}
57+
58+
public override class func classMethod() {
59+
print("OutsideChild.classMethod()")
60+
super.classMethod()
61+
}
62+
}
63+
64+
public class ConcreteOutsideChild : GenericOutsideParent<String> {
65+
public override init(a: String) {
66+
print("ConcreteOutsideChild.init(s: String)")
67+
super.init(a: a)
68+
}
69+
70+
public override func method() {
71+
print("OutsideChild.method()")
72+
super.method()
73+
}
74+
75+
public override class func classMethod() {
76+
print("OutsideChild.classMethod()")
77+
super.classMethod()
78+
}
79+
}

test/Inputs/partial_apply_super.swift

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import OutsideClasses
2+
3+
public class Parent {
4+
public init() {}
5+
public func method() {}
6+
public class func classMethod() {}
7+
}
8+
9+
public class GenericParent<A> {
10+
let a: A
11+
public init(a: A) {
12+
self.a = a
13+
}
14+
public func method() {}
15+
public class func classMethod() {}
16+
}
17+
18+
class Child : Parent {
19+
override func method() {
20+
doFoo(super.method)
21+
}
22+
23+
override class func classMethod() {
24+
doFoo(super.classMethod)
25+
}
26+
}
27+
28+
class GenericChild<A> : GenericParent<A> {
29+
override init(a: A) {
30+
super.init(a: a)
31+
}
32+
33+
override func method() {
34+
doFoo(super.method)
35+
}
36+
37+
override class func classMethod() {
38+
doFoo(super.classMethod)
39+
}
40+
}
41+
42+
class GrandchildToOutside : OutsideChild {
43+
override func method() {
44+
doFoo(super.method)
45+
}
46+
47+
override class func classMethod() {
48+
doFoo(super.classMethod)
49+
}
50+
}
51+
52+
let c = {
53+
class Child : Parent {
54+
override func method() {
55+
doFoo(super.method)
56+
}
57+
58+
override class func classMethod() {
59+
doFoo(super.classMethod)
60+
}
61+
}
62+
63+
class GrandchildToOutside : OutsideChild {
64+
override func method() {
65+
doFoo(super.method)
66+
}
67+
68+
override class func classMethod() {
69+
doFoo(super.classMethod)
70+
}
71+
}
72+
}
73+
74+
class GenericGrandchildToOutside<A> : GenericOutsideChild<A> {
75+
override func method() {
76+
doFoo(super.method)
77+
}
78+
79+
override class func classMethod() {
80+
doFoo(super.classMethod)
81+
}
82+
}
83+
84+
let cHasGenerics = {
85+
class GenericChild<A> : GenericParent<A> {
86+
override init(a: A) {
87+
super.init(a: a)
88+
}
89+
90+
override func method() {
91+
doFoo(super.method)
92+
}
93+
94+
override class func classMethod() {
95+
doFoo(super.classMethod)
96+
}
97+
}
98+
99+
class GenericGrandchildToOutside<A> : GenericOutsideChild<A> {
100+
override func method() {
101+
doFoo(super.method)
102+
}
103+
104+
override class func classMethod() {
105+
doFoo(super.classMethod)
106+
}
107+
}
108+
}

test/SILGen/partial_apply_super.swift

Lines changed: 60 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,68 @@
1-
// RUN: %target-swift-frontend -use-native-super-method -emit-silgen %s | FileCheck %s
1+
// RUN: rm -rf %t
2+
// RUN: mkdir %t
3+
// RUN: %target-swift-frontend -emit-module -module-name OutsideClasses -o %t %S/../Inputs/outside_classes_before.swift
4+
// RUN: %target-swift-frontend -use-native-super-method -emit-silgen -I %t %S/../Inputs/partial_apply_super.swift | FileCheck %s --check-prefix=SILGEN
25

3-
func doFoo(f: () -> ()) {
4-
f()
5-
}
6+
// Child.method
7+
// SILGEN-LABEL: sil hidden @_TFC19partial_apply_super5Child6methodfT_T_
8+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_
9+
// SILGEN: [[CASTED_SELF:%[0-9]+]] = upcast {{%[0-9]+}} : $Child to $Parent
10+
// SILGEN: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $Child, #Parent.method!1
11+
// SILGEN: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]])
12+
// SILGEN: apply [[DOFOO]]([[PARTIAL_APPLY]])
613

7-
class Base {
8-
func method() { }
9-
func bar()() { }
10-
class func classMethod() {}
11-
}
14+
// Child.classMethod
15+
// SILGEN-LABEL: sil hidden @_TZFC19partial_apply_super5Child11classMethodfT_T_ : $@convention(thin) (@thick Child.Type) -> () {
16+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () // user: %6
17+
// SILGEN-NEXT: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $@thick Child.Type to $@thick Parent.Type // user: %5
18+
// SILGEN-NEXT: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $@thick Child.Type, #Parent.classMethod!1 : Parent.Type -> () -> () , $@convention(thin) (@thick Parent.Type) -> ()
19+
// SILGEN-NEXT: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> ()
20+
// SILGEN-NEXT: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
1221

13-
class Derived : Base {
14-
// CHECK-LABEL: sil hidden @_TFC19partial_apply_super7Derived6methodfT_T_
15-
// CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_
16-
// CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $Derived to $Base
17-
// CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $Derived, #Base.method!1
18-
// CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]])
19-
// CHECK: apply [[DOFOO]]([[PARTIAL_APPLY]])
20-
override func method() {
21-
doFoo(super.method)
22-
}
22+
// GenericChild.method
23+
// SILGEN-LABEL: sil hidden @_TFC19partial_apply_super12GenericChild6methodfT_T_ : $@convention(method) <A> (@guaranteed GenericChild<A>) -> ()
24+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
25+
// SILGEN: [[CASTED_SELF:%[0-9]+]] = upcast {{%[0-9]+}} : $GenericChild<A> to $GenericParent<A>
26+
// SILGEN: [[SUPER_METHOD:%[0-9]+]] = super_method {{%[0-9]+}} : $GenericChild<A>, #GenericParent.method!1 : <A> GenericParent<A> -> () -> () , $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> ()
27+
// SILGEN: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]<A>([[CASTED_SELF]]) : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> ()
28+
// SILGEN: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
2329

24-
// CHECK-LABEL: sil hidden @_TZFC19partial_apply_super7Derived11classMethodfT_T_
25-
// CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_
26-
// CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $@thick Derived.Type to $@thick Base.Type
27-
// CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $@thick Derived.Type, #Base.classMethod!1
28-
// CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply %4(%3) : $@convention(thin) (@thick Base.Type) -> ()
29-
override class func classMethod() {
30-
doFoo(super.classMethod)
31-
}
30+
// GenericChild.classMethod
31+
// SILGEN-LABEL: sil hidden @_TZFC19partial_apply_super12GenericChild11classMethodfT_T_ : $@convention(thin) <A> (@thick GenericChild<A>.Type) -> ()
32+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
33+
// SILGEN: [[CASTED_SELF:%[0-9]+]] = upcast {{%[0-9]+}} : $@thick GenericChild<A>.Type to $@thick GenericParent<A>.Type
34+
// SILGEN: [[SUPER_METHOD:%[0-9]+]] = super_method {{%[0-9]}} : $@thick GenericChild<A>.Type, #GenericParent.classMethod!1 : <A> GenericParent<A>.Type -> () -> () , $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> ()
35+
// SILGEN: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]<A>([[CASTED_SELF]]) : $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> ()
36+
// SILGEN: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
3237

33-
// CHECK-LABEL: sil hidden @_TFC19partial_apply_super7Derived10getMethodsfT_TFT_T_FT_T__
34-
// CHECK: function_ref @_TFC19partial_apply_super7Derived6method
35-
// CHECK: super_method %0 : $Derived, #Base.method!1 : Base -> () -> ()
36-
func getMethods() -> (() -> (), () -> ()) {
37-
return (self.method, super.method)
38-
}
38+
// closure.Child.method
39+
// SILGEN-LABEL: sil shared @_TFCF19partial_apply_superU_FT_T_L_5Child6methodfT_T_ : $@convention(method) (@guaranteed Child) -> ()
40+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () // user: %7
41+
// SILGEN: [[CASTED_SELF:%[0-9]+]] = upcast {{%[0-9]+}} : $Child to $Parent
42+
// SILGEN: [[SUPER_METHOD:%[0-9]+]] = super_method {{%[0-9]+}} : $Child, #Parent.method!1 : Parent -> () -> () , $@convention(method) (@guaranteed Parent) -> ()
43+
// SILGEN: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(method) (@guaranteed Parent) -> ()
44+
// SILGEN: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
3945

40-
// CHECK-LABEL: sil shared @_TFC19partial_apply_super7Derived6methodFT_T_
41-
// CHECK: class_method %0 : $Derived, #Derived.method!1
46+
// closure.Child.classMethod
47+
// SILGEN-LABEL: sil shared @_TZFCF19partial_apply_superU_FT_T_L_5Child11classMethodfT_T_ : $@convention(thin) (@thick Child.Type) -> () {
48+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> () // user: %6
49+
// SILGEN: [[CASTED_SELF:%[0-9]+]] = upcast {{%[0-9]+}} : $@thick Child.Type to $@thick Parent.Type // user: %5
50+
// SILGEN: [[SUPER_METHOD:%[0-9]+]] = super_method {{%[0-9]+}} : $@thick Child.Type, #Parent.classMethod!1 : Parent.Type -> () -> () , $@convention(thin) (@thick Parent.Type) -> () // user: %5
51+
// SILGEN: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]]) : $@convention(thin) (@thick Parent.Type) -> () // user: %6
52+
// SILGEN: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
4253

43-
// CHECK-LABEL: sil hidden @_TFC19partial_apply_super7Derived6getBar
44-
// CHECK: function_ref @_TFC19partial_apply_super4Base3barFT_FT_T_
45-
func getBar() -> (() -> () -> ()) {
46-
return self.bar
47-
}
48-
}
54+
// closure.GenericChild.method
55+
// SILGEN-LABEL: sil shared @_TFCF19partial_apply_superU0_FT_T_L_12GenericChild6methodfT_T_ : $@convention(method) <A> (@guaranteed GenericChild<A>) -> ()
56+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
57+
// SILGEN: [[CASTED_SELF:%[0-9]+]] = upcast {{%[0-9]+}} : $GenericChild<A> to $GenericParent<A>
58+
// SILGEN: [[SUPER_METHOD:%[0-9]+]] = super_method {{%[0-9]+}} : $GenericChild<A>, #GenericParent.method!1 : <A> GenericParent<A> -> () -> () , $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> ()
59+
// SILGEN: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]<A>([[CASTED_SELF]]) : $@convention(method) <τ_0_0> (@guaranteed GenericParent<τ_0_0>) -> ()
60+
// SILGEN: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
4961

50-
// Test partial application of super with local types
51-
let c = {
52-
class Base {
53-
func method() {}
54-
class func classMethod() {}
55-
}
56-
class Derived : Base {
57-
// CHECK-LABEL: sil shared @_TFCF19partial_apply_superU_FT_T_L_7Derived6methodfT_T_
58-
// CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_
59-
// CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $Derived to $Base
60-
// CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $Derived, #<anonymous function>Base.method!1
61-
// CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]([[CASTED_SELF]])
62-
// CHECK: apply [[DOFOO]]([[PARTIAL_APPLY]])
63-
override func method() {
64-
doFoo(super.method)
65-
}
66-
67-
// CHECK-LABEL: sil shared @_TZFCF19partial_apply_superU_FT_T_L_7Derived11classMethodfT_T_
68-
// CHECK: [[DOFOO:%[0-9]+]] = function_ref @_TF19partial_apply_super5doFooFFT_T_T_
69-
// CHECK: [[CASTED_SELF:%[0-9]+]] = upcast %0 : $@thick Derived.Type to $@thick Base.Type
70-
// CHECK: [[SUPER_METHOD:%[0-9]+]] = super_method %0 : $@thick Derived.Type, #<anonymous function>Base.classMethod!1
71-
// CHECK: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply %4(%3) : $@convention(thin) (@thick Base.Type) -> ()
72-
// CHECK: apply [[DOFOO]]([[PARTIAL_APPLY]])
73-
override class func classMethod() {
74-
doFoo(super.classMethod)
75-
}
76-
}
77-
}
62+
// closure.GenericChild.classMethod
63+
// SILGEN-LABEL: sil shared @_TZFCF19partial_apply_superU0_FT_T_L_12GenericChild11classMethodfT_T_ : $@convention(thin) <A> (@thick GenericChild<A>.Type) -> ()
64+
// SILGEN: [[DOFOO:%[0-9]+]] = function_ref @_TF14OutsideClasses5doFooFFT_T_T_ : $@convention(thin) (@owned @callee_owned () -> ()) -> ()
65+
// SILGEN: [[CASTED_SELF:%[0-9]+]] = upcast {{%[0-9]+}} : $@thick GenericChild<A>.Type to $@thick GenericParent<A>.Type
66+
// SILGEN: [[SUPER_METHOD:%[0-9]+]] = super_method {{%[0-9]+}} : $@thick GenericChild<A>.Type, #GenericParent.classMethod!1 : <A> GenericParent<A>.Type -> () -> () , $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> ()
67+
// SILGEN: [[PARTIAL_APPLY:%[0-9]+]] = partial_apply [[SUPER_METHOD]]<A>([[CASTED_SELF]]) : $@convention(thin) <τ_0_0> (@thick GenericParent<τ_0_0>.Type) -> ()
68+
// SILGEN: apply [[DOFOO]]([[PARTIAL_APPLY]]) : $@convention(thin) (@owned @callee_owned () -> ()) -> ()

0 commit comments

Comments
 (0)