Skip to content

Commit 44531db

Browse files
authored
Merge pull request #15856 from rudkx/sr7098
Swap two conditions to get dynamically looked-up optional requirement…
2 parents fe965a7 + c2b1d03 commit 44531db

File tree

2 files changed

+38
-27
lines changed

2 files changed

+38
-27
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,31 +1675,6 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
16751675
choice.getFunctionRefKind(), locator);
16761676
}
16771677

1678-
if (!isRequirementOrWitness(locator) &&
1679-
choice.getDecl()->getAttrs().hasAttribute<OptionalAttr>() &&
1680-
!isa<SubscriptDecl>(choice.getDecl())) {
1681-
// For a non-subscript declaration that is an optional
1682-
// requirement in a protocol, strip off the lvalue-ness (FIXME:
1683-
// one cannot assign to such declarations for now) and make a
1684-
// reference to that declaration be optional.
1685-
//
1686-
// Subscript declarations are handled within
1687-
// getTypeOfMemberReference(); their result types are optional.
1688-
1689-
// Deal with values declared as implicitly unwrapped, or
1690-
// functions with return types that are implicitly unwrapped.
1691-
if (choice.isImplicitlyUnwrappedValueOrReturnValue()) {
1692-
// Build the disjunction to attempt binding both T? and T (or
1693-
// function returning T? and function returning T).
1694-
Type ty = createTypeVariable(locator);
1695-
buildDisjunctionForImplicitlyUnwrappedOptional(ty, refType,
1696-
locator);
1697-
addConstraint(ConstraintKind::Bind, boundType,
1698-
OptionalType::get(ty->getRValueType()), locator);
1699-
bindConstraintCreated = true;
1700-
}
1701-
refType = OptionalType::get(refType->getRValueType());
1702-
}
17031678
// For a non-subscript declaration found via dynamic lookup, strip
17041679
// off the lvalue-ness (FIXME: as a temporary hack. We eventually
17051680
// want this to work) and make a reference to that declaration be
@@ -1708,7 +1683,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
17081683
// Subscript declarations are handled within
17091684
// getTypeOfMemberReference(); their result types are unchecked
17101685
// optional.
1711-
else if (isDynamicResult) {
1686+
if (isDynamicResult) {
17121687
if (isa<SubscriptDecl>(choice.getDecl())) {
17131688
// We always expect function type for subscripts.
17141689
auto fnTy = refType->castTo<AnyFunctionType>();
@@ -1773,8 +1748,31 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
17731748
}
17741749

17751750
bindConstraintCreated = true;
1776-
}
1751+
} else if (!isRequirementOrWitness(locator) &&
1752+
choice.getDecl()->getAttrs().hasAttribute<OptionalAttr>() &&
1753+
!isa<SubscriptDecl>(choice.getDecl())) {
1754+
// For a non-subscript declaration that is an optional
1755+
// requirement in a protocol, strip off the lvalue-ness (FIXME:
1756+
// one cannot assign to such declarations for now) and make a
1757+
// reference to that declaration be optional.
1758+
//
1759+
// Subscript declarations are handled within
1760+
// getTypeOfMemberReference(); their result types are optional.
1761+
1762+
// Deal with values declared as implicitly unwrapped, or
1763+
// functions with return types that are implicitly unwrapped.
1764+
if (choice.isImplicitlyUnwrappedValueOrReturnValue()) {
1765+
// Build the disjunction to attempt binding both T? and T (or
1766+
// function returning T? and function returning T).
1767+
Type ty = createTypeVariable(locator);
1768+
buildDisjunctionForImplicitlyUnwrappedOptional(ty, refType, locator);
1769+
addConstraint(ConstraintKind::Bind, boundType,
1770+
OptionalType::get(ty->getRValueType()), locator);
1771+
bindConstraintCreated = true;
1772+
}
17771773

1774+
refType = OptionalType::get(refType->getRValueType());
1775+
}
17781776
// If the declaration is unavailable, note that in the score.
17791777
if (choice.getDecl()->getAttrs().isUnavailable(getASTContext())) {
17801778
increaseScore(SK_Unavailable);

test/Constraints/sr7098.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s
2+
// REQUIRES: objc_interop
3+
4+
import Foundation
5+
6+
class C : NSObject, NSWobbling {
7+
func wobble() {}
8+
func returnMyself() -> Self { return self }
9+
}
10+
11+
func testDynamicOptionalRequirement(_ a: AnyObject) {
12+
a.optionalRequirement?()
13+
}

0 commit comments

Comments
 (0)