|
15 | 15 | //===----------------------------------------------------------------------===//
|
16 | 16 |
|
17 | 17 | #include "TypeChecker.h"
|
| 18 | +#include "swift/AST/ConformanceLookup.h" |
18 | 19 | #include "swift/AST/ExistentialLayout.h"
|
19 | 20 | #include "swift/AST/GenericSignature.h"
|
20 | 21 | #include "swift/Basic/OptionSet.h"
|
@@ -554,6 +555,30 @@ static void determineBestChoicesInContext(
|
554 | 555 | }
|
555 | 556 | }
|
556 | 557 |
|
| 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 | + |
557 | 582 | if (options.contains(MatchFlag::ExactOnly))
|
558 | 583 | return areEqual(candidateType, paramType) ? 1 : 0;
|
559 | 584 |
|
|
0 commit comments