Skip to content

Commit 6a29a89

Browse files
authored
Merge pull request swiftlang#70200 from eeckstein/devirt-witness-methods-5.10
[5.10] Devirtualizer: be less restrictive when checking for correct types to enable witness method devirtualization
2 parents 80b6ce1 + fd50411 commit 6a29a89

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

lib/SILOptimizer/Utils/Devirtualize.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,17 @@ static bool canDevirtualizeWitnessMethod(ApplySite applySite, bool isMandatory)
12011201
if (!interfaceTy->hasTypeParameter())
12021202
return true;
12031203

1204+
auto subs = getWitnessMethodSubstitutions(f->getModule(), applySite,
1205+
f, wmi->getConformance());
1206+
CanSILFunctionType substCalleTy = f->getLoweredFunctionType()->substGenericArgs(
1207+
f->getModule(), subs,
1208+
applySite.getFunction()->getTypeExpansionContext());
1209+
CanSILFunctionType applySubstCalleeTy = applySite.getSubstCalleeType();
1210+
1211+
// If the function types match, there is no problem.
1212+
if (substCalleTy == applySubstCalleeTy)
1213+
return true;
1214+
12041215
auto selfGP = wmi->getLookupProtocol()->getSelfInterfaceType();
12051216
auto isSelfRootedTypeParameter = [selfGP](Type T) -> bool {
12061217
if (!T->hasTypeParameter())

test/SILOptimizer/devirt_protocol_method_invocations.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,33 @@ public func testNoDevirt() {
344344
p.assoc3 { _ in }
345345
p.assoc4 { _ in }
346346
}
347+
348+
protocol MyProtocol {
349+
associatedtype Element
350+
var array: [Element] { get }
351+
var foo: Bool { get }
352+
}
353+
354+
extension Array {
355+
var isThisACoolArray: Bool {
356+
return true
357+
}
358+
}
359+
360+
extension MyProtocol {
361+
var foo: Bool { array.isThisACoolArray }
362+
}
363+
364+
public struct MyStruct {
365+
var array: [Int] = []
366+
}
367+
368+
extension MyStruct: MyProtocol {}
369+
370+
// CHECK-LABEL: sil @$s34devirt_protocol_method_invocations15testArrayReturn1xSbAA8MyStructVz_tF :
371+
// CHECK-NOT: witness_method
372+
// CHECK: } // end sil function '$s34devirt_protocol_method_invocations15testArrayReturn1xSbAA8MyStructVz_tF'
373+
public func testArrayReturn(x: inout MyStruct) -> Bool {
374+
return x.foo
375+
}
376+

0 commit comments

Comments
 (0)