Skip to content

Commit 842d26e

Browse files
authored
Merge pull request swiftlang#68703 from eeckstein/devirt-witness-methods
Devirtualizer: be less restrictive when checking for correct types to enable witness method devirtualization
2 parents 57aacdf + 79b79c7 commit 842d26e

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
@@ -1210,6 +1210,17 @@ static bool canDevirtualizeWitnessMethod(ApplySite applySite, bool isMandatory)
12101210
if (!interfaceTy->hasTypeParameter())
12111211
return true;
12121212

1213+
auto subs = getWitnessMethodSubstitutions(f->getModule(), applySite,
1214+
f, wmi->getConformance());
1215+
CanSILFunctionType substCalleTy = f->getLoweredFunctionType()->substGenericArgs(
1216+
f->getModule(), subs,
1217+
applySite.getFunction()->getTypeExpansionContext());
1218+
CanSILFunctionType applySubstCalleeTy = applySite.getSubstCalleeType();
1219+
1220+
// If the function types match, there is no problem.
1221+
if (substCalleTy == applySubstCalleeTy)
1222+
return true;
1223+
12131224
auto selfGP = wmi->getLookupProtocol()->getSelfInterfaceType();
12141225
auto isSelfRootedTypeParameter = [selfGP](Type T) -> bool {
12151226
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)