Skip to content

Commit 77caa71

Browse files
committed
[CSOptimizer] Extend candidate/parameter matching to support array literals
Match `[...]` to Array<...> and/or `ExpressibleByArrayLiteral` conforming types. This is very helpful for expressions like: `[...] + [...]`.
1 parent 0737542 commit 77caa71

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
//===----------------------------------------------------------------------===//
1616

1717
#include "TypeChecker.h"
18+
#include "swift/AST/ConformanceLookup.h"
1819
#include "swift/AST/ExistentialLayout.h"
1920
#include "swift/AST/GenericSignature.h"
2021
#include "swift/Basic/OptionSet.h"
@@ -554,6 +555,30 @@ static void determineBestChoicesInContext(
554555
}
555556
}
556557

558+
// Match `[...]` to Array<...> and/or `ExpressibleByArrayLiteral`
559+
// conforming types.
560+
if (options.contains(MatchFlag::OnParam) &&
561+
options.contains(MatchFlag::Literal) &&
562+
isUnboundArrayType(candidateType)) {
563+
// If an exact match is requested favor only `[...]` to `Array<...>`
564+
// since everything else is going to increase to score.
565+
if (options.contains(MatchFlag::ExactOnly))
566+
return paramType->isArrayType() ? 1 : 0;
567+
568+
Type type = paramType->lookThroughAllOptionalTypes();
569+
// Otherwise, check if the other side conforms to
570+
// `ExpressibleByArrayLiteral` protocol (in some way).
571+
if (auto *nominal = type->getAnyNominal()) {
572+
auto &ctx = cs.getASTContext();
573+
SmallVector<ProtocolConformance *> conformances;
574+
575+
nominal->lookupConformance(
576+
ctx.getProtocol(KnownProtocolKind::ExpressibleByArrayLiteral),
577+
conformances);
578+
return conformances.empty() ? 0 : 0.3;
579+
}
580+
}
581+
557582
if (options.contains(MatchFlag::ExactOnly))
558583
return areEqual(candidateType, paramType) ? 1 : 0;
559584

validation-test/Sema/type_checker_perf/fast/array_count_property_vs_method.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=5
1+
// RUN: %target-typecheck-verify-swift -solver-scope-threshold=11000
22
// REQUIRES: tools-release,no_asan
33

44
func f(n: Int, a: [Int]) {

0 commit comments

Comments
 (0)