Skip to content

Commit 6095dc9

Browse files
authored
Merge pull request #14754 from rudkx/rdar37241550
[ConstraintSystem] Do not attempt to force references of unapplied fu…
2 parents d23fc27 + b9cd303 commit 6095dc9

File tree

4 files changed

+85
-56
lines changed

4 files changed

+85
-56
lines changed

lib/Sema/CSApply.cpp

Lines changed: 54 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -544,10 +544,11 @@ namespace {
544544

545545
public:
546546
/// \brief Build a reference to the given declaration.
547-
Expr *buildDeclRef(ValueDecl *decl, DeclNameLoc loc, Type openedType,
547+
Expr *buildDeclRef(OverloadChoice choice, DeclNameLoc loc, Type openedType,
548548
ConstraintLocatorBuilder locator, bool implicit,
549549
FunctionRefKind functionRefKind,
550550
AccessSemantics semantics) {
551+
auto *decl = choice.getDecl();
551552
// Determine the declaration selected for this overloaded reference.
552553
auto &ctx = cs.getASTContext();
553554

@@ -612,7 +613,7 @@ namespace {
612613
if (auto fnConv = dyn_cast<FunctionConversionExpr>(refExpr))
613614
refExpr = fnConv->getSubExpr();
614615

615-
return forceUnwrapIfExpected(refExpr, decl, locator);
616+
return forceUnwrapIfExpected(refExpr, choice, locator);
616617
}
617618
}
618619
}
@@ -623,7 +624,7 @@ namespace {
623624
TypeExpr::createImplicitHack(loc.getBaseNameLoc(), baseTy, ctx);
624625
cs.cacheExprTypes(base);
625626

626-
return buildMemberRef(base, openedType, SourceLoc(), decl, loc,
627+
return buildMemberRef(base, openedType, SourceLoc(), choice, loc,
627628
openedFnType->getResult(), locator, locator,
628629
implicit, functionRefKind, semantics,
629630
/*isDynamic=*/false);
@@ -659,7 +660,7 @@ namespace {
659660
loc, implicit, semantics, type);
660661
cs.cacheType(declRefExpr);
661662
declRefExpr->setFunctionRefKind(functionRefKind);
662-
return forceUnwrapIfExpected(declRefExpr, decl, locator);
663+
return forceUnwrapIfExpected(declRefExpr, choice, locator);
663664
}
664665

665666
/// Describes an opened existential that has not yet been closed.
@@ -899,11 +900,12 @@ namespace {
899900

900901
/// \brief Build a new member reference with the given base and member.
901902
Expr *buildMemberRef(Expr *base, Type openedFullType, SourceLoc dotLoc,
902-
ValueDecl *member, DeclNameLoc memberLoc,
903+
OverloadChoice choice, DeclNameLoc memberLoc,
903904
Type openedType, ConstraintLocatorBuilder locator,
904905
ConstraintLocatorBuilder memberLocator, bool Implicit,
905906
FunctionRefKind functionRefKind,
906907
AccessSemantics semantics, bool isDynamic) {
908+
ValueDecl *member = choice.getDecl();
907909
auto &tc = cs.getTypeChecker();
908910
auto &context = tc.Context;
909911

@@ -949,7 +951,7 @@ namespace {
949951
ref->setFunctionRefKind(functionRefKind);
950952
auto *DSBI = cs.cacheType(new (context) DotSyntaxBaseIgnoredExpr(
951953
base, dotLoc, ref, cs.getType(ref)));
952-
return forceUnwrapIfExpected(DSBI, member, memberLocator);
954+
return forceUnwrapIfExpected(DSBI, choice, memberLocator);
953955
}
954956

955957
// The formal type of the 'self' value for the member's declaration.
@@ -1088,8 +1090,9 @@ namespace {
10881090
// We also need to handle the implicitly unwrap of the result
10891091
// of the called function if that's the type checking solution
10901092
// we ended up with.
1091-
return forceUnwrapIfExpected(ref, member, memberLocator,
1092-
member->getAttrs().hasAttribute<OptionalAttr>());
1093+
return forceUnwrapIfExpected(
1094+
ref, choice, memberLocator,
1095+
member->getAttrs().hasAttribute<OptionalAttr>());
10931096
}
10941097

10951098
// For types and properties, build member references.
@@ -1115,7 +1118,7 @@ namespace {
11151118
cs.setType(memberRefExpr, simplifyType(openedType));
11161119
Expr *result = memberRefExpr;
11171120
closeExistential(result, locator);
1118-
return forceUnwrapIfExpected(result, member, memberLocator);
1121+
return forceUnwrapIfExpected(result, choice, memberLocator);
11191122
}
11201123

11211124
// Handle all other references.
@@ -1135,7 +1138,7 @@ namespace {
11351138
ApplyExpr *apply;
11361139
if (isa<ConstructorDecl>(member)) {
11371140
// FIXME: Provide type annotation.
1138-
ref = forceUnwrapIfExpected(ref, member, memberLocator);
1141+
ref = forceUnwrapIfExpected(ref, choice, memberLocator);
11391142
apply = new (context) ConstructorRefCallExpr(ref, base);
11401143
} else if (!baseIsInstance && member->isInstanceMember()) {
11411144
// Reference to an unbound instance method.
@@ -1144,11 +1147,11 @@ namespace {
11441147
cs.getType(ref));
11451148
cs.cacheType(result);
11461149
closeExistential(result, locator, /*force=*/openedExistential);
1147-
return forceUnwrapIfExpected(result, member, memberLocator);
1150+
return forceUnwrapIfExpected(result, choice, memberLocator);
11481151
} else {
11491152
assert((!baseIsInstance || member->isInstanceMember()) &&
11501153
"can't call a static method on an instance");
1151-
ref = forceUnwrapIfExpected(ref, member, memberLocator);
1154+
ref = forceUnwrapIfExpected(ref, choice, memberLocator);
11521155
apply = new (context) DotSyntaxCallExpr(ref, dotLoc, base);
11531156
if (Implicit) {
11541157
apply->setImplicit();
@@ -1449,10 +1452,10 @@ namespace {
14491452
if (selected->choice.getKind() ==
14501453
OverloadChoiceKind::DynamicMemberLookup)
14511454
locatorKind = ConstraintLocator::Member;
1452-
1453-
newSubscript = forceUnwrapIfExpected(
1454-
newSubscript, selected->choice.getDecl(),
1455-
locator.withPathElement(locatorKind));
1455+
1456+
newSubscript =
1457+
forceUnwrapIfExpected(newSubscript, selected->choice,
1458+
locator.withPathElement(locatorKind));
14561459
}
14571460

14581461
return newSubscript;
@@ -2471,8 +2474,9 @@ namespace {
24712474
}
24722475
}
24732476

2474-
bool shouldForceUnwrapResult(Decl *decl, ConstraintLocatorBuilder locator) {
2475-
if (!decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
2477+
bool shouldForceUnwrapResult(OverloadChoice choice,
2478+
ConstraintLocatorBuilder locator) {
2479+
if (!choice.isImplicitlyUnwrappedValueOrReturnValue())
24762480
return false;
24772481

24782482
auto *choiceLocator = cs.getConstraintLocator(locator.withPathElement(
@@ -2481,10 +2485,10 @@ namespace {
24812485
return solution.getDisjunctionChoice(choiceLocator);
24822486
}
24832487

2484-
Expr *forceUnwrapIfExpected(Expr *expr, Decl *decl,
2488+
Expr *forceUnwrapIfExpected(Expr *expr, OverloadChoice choice,
24852489
ConstraintLocatorBuilder locator,
2486-
bool forForcedOptional =false) {
2487-
if (!shouldForceUnwrapResult(decl, locator))
2490+
bool forForcedOptional = false) {
2491+
if (!shouldForceUnwrapResult(choice, locator))
24882492
return expr;
24892493

24902494
// Force the expression if required for the solution.
@@ -2503,12 +2507,9 @@ namespace {
25032507
cs.setType(expr, varDecl->getType());
25042508
return expr;
25052509
}
2506-
2507-
auto choice = selected->choice;
2508-
auto decl = choice.getDecl();
25092510

2510-
return buildDeclRef(decl, expr->getNameLoc(), selected->openedFullType,
2511-
locator, expr->isImplicit(),
2511+
return buildDeclRef(selected->choice, expr->getNameLoc(),
2512+
selected->openedFullType, locator, expr->isImplicit(),
25122513
expr->getFunctionRefKind(),
25132514
expr->getAccessSemantics());
25142515
}
@@ -2539,9 +2540,8 @@ namespace {
25392540
auto locator = cs.getConstraintLocator(expr);
25402541
auto selected = getOverloadChoice(locator);
25412542
auto choice = selected.choice;
2542-
auto decl = choice.getDecl();
25432543

2544-
return buildDeclRef(decl, expr->getNameLoc(), selected.openedFullType,
2544+
return buildDeclRef(choice, expr->getNameLoc(), selected.openedFullType,
25452545
locator, expr->isImplicit(),
25462546
choice.getFunctionRefKind(),
25472547
AccessSemantics::Ordinary);
@@ -2566,7 +2566,7 @@ namespace {
25662566
= selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
25672567
return buildMemberRef(
25682568
expr->getBase(), selected.openedFullType, expr->getDotLoc(),
2569-
selected.choice.getDecl(), expr->getNameLoc(), selected.openedType,
2569+
selected.choice, expr->getNameLoc(), selected.openedType,
25702570
cs.getConstraintLocator(expr), memberLocator, expr->isImplicit(),
25712571
selected.choice.getFunctionRefKind(), expr->getAccessSemantics(),
25722572
isDynamic);
@@ -2594,7 +2594,6 @@ namespace {
25942594
auto memberLocator = cs.getConstraintLocator(
25952595
expr, ConstraintLocator::UnresolvedMember);
25962596
auto selected = getOverloadChoice(memberLocator);
2597-
auto member = selected.choice.getDecl();
25982597

25992598
// If the member came by optional unwrapping, then unwrap the base type.
26002599
if (selected.choice.getKind()
@@ -2614,7 +2613,7 @@ namespace {
26142613
bool isDynamic
26152614
= selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
26162615
auto result = buildMemberRef(
2617-
base, selected.openedFullType, expr->getDotLoc(), member,
2616+
base, selected.openedFullType, expr->getDotLoc(), selected.choice,
26182617
expr->getNameLoc(), selected.openedType,
26192618
cs.getConstraintLocator(expr), memberLocator, expr->isImplicit(),
26202619
selected.choice.getFunctionRefKind(), AccessSemantics::Ordinary,
@@ -2651,9 +2650,10 @@ namespace {
26512650
Expr *applyCtorRefExpr(Expr *expr, Expr *base, SourceLoc dotLoc,
26522651
DeclNameLoc nameLoc, bool implicit,
26532652
ConstraintLocator *ctorLocator,
2654-
ConstructorDecl *ctor,
2655-
FunctionRefKind functionRefKind,
2656-
Type openedType) {
2653+
OverloadChoice choice,
2654+
FunctionRefKind functionRefKind, Type openedType) {
2655+
2656+
auto *ctor = cast<ConstructorDecl>(choice.getDecl());
26572657

26582658
// If the member is a constructor, verify that it can be legally
26592659
// referenced from this base.
@@ -2665,7 +2665,7 @@ namespace {
26652665
// constructor.
26662666
if (cs.getType(base)->is<AnyMetatypeType>()) {
26672667
return buildMemberRef(
2668-
base, openedType, dotLoc, ctor, nameLoc, cs.getType(expr),
2668+
base, openedType, dotLoc, choice, nameLoc, cs.getType(expr),
26692669
ConstraintLocatorBuilder(cs.getConstraintLocator(expr)),
26702670
ctorLocator, implicit, functionRefKind, AccessSemantics::Ordinary,
26712671
/*isDynamic=*/false);
@@ -2731,10 +2731,9 @@ namespace {
27312731
ConstraintLocator::ConstructorMember);
27322732
if (auto selected = getOverloadChoiceIfAvailable(ctorLocator)) {
27332733
auto choice = selected->choice;
2734-
auto *ctor = cast<ConstructorDecl>(choice.getDecl());
2735-
return applyCtorRefExpr(expr, base, dotLoc, nameLoc, implicit,
2736-
ctorLocator, ctor, choice.getFunctionRefKind(),
2737-
selected->openedFullType);
2734+
return applyCtorRefExpr(
2735+
expr, base, dotLoc, nameLoc, implicit, ctorLocator, choice,
2736+
choice.getFunctionRefKind(), selected->openedFullType);
27382737
}
27392738

27402739
// Determine the declaration selected for this overloaded reference.
@@ -2783,11 +2782,11 @@ namespace {
27832782
case OverloadChoiceKind::DeclViaDynamic: {
27842783
bool isDynamic
27852784
= selected.choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
2786-
return buildMemberRef(
2787-
base, selected.openedFullType, dotLoc, selected.choice.getDecl(),
2788-
nameLoc, selected.openedType, cs.getConstraintLocator(expr),
2789-
memberLocator, implicit, selected.choice.getFunctionRefKind(),
2790-
AccessSemantics::Ordinary, isDynamic);
2785+
return buildMemberRef(base, selected.openedFullType, dotLoc,
2786+
selected.choice, nameLoc, selected.openedType,
2787+
cs.getConstraintLocator(expr), memberLocator,
2788+
implicit, selected.choice.getFunctionRefKind(),
2789+
AccessSemantics::Ordinary, isDynamic);
27912790
}
27922791

27932792
case OverloadChoiceKind::TupleIndex: {
@@ -4370,7 +4369,7 @@ namespace {
43704369
baseTy = component.getComponentType();
43714370
resolvedComponents.push_back(component);
43724371

4373-
if (shouldForceUnwrapResult(property, locator)) {
4372+
if (shouldForceUnwrapResult(foundDecl->choice, locator)) {
43744373
auto objectTy = getObjectType(baseTy);
43754374
auto loc = origComponent.getLoc();
43764375
component = KeyPathExpr::Component::forOptionalForce(objectTy, loc);
@@ -4451,7 +4450,7 @@ namespace {
44514450
baseTy = component.getComponentType();
44524451
resolvedComponents.push_back(component);
44534452

4454-
if (shouldForceUnwrapResult(subscript, locator)) {
4453+
if (shouldForceUnwrapResult(foundDecl->choice, locator)) {
44554454
auto objectTy = getObjectType(baseTy);
44564455
auto loc = origComponent.getLoc();
44574456
component = KeyPathExpr::Component::forOptionalForce(objectTy, loc);
@@ -7469,17 +7468,16 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
74697468

74707469
// We have the constructor.
74717470
auto choice = selected->choice;
7472-
auto decl = choice.getDecl();
74737471

74747472
// Consider the constructor decl reference expr 'implicit', but the
74757473
// constructor call expr itself has the apply's 'implicitness'.
74767474
bool isDynamic = choice.getKind() == OverloadChoiceKind::DeclViaDynamic;
7477-
Expr *declRef =
7478-
buildMemberRef(fn, selected->openedFullType,
7479-
/*dotLoc=*/SourceLoc(), decl, DeclNameLoc(fn->getEndLoc()),
7480-
selected->openedType, locator, ctorLocator,
7481-
/*Implicit=*/true, choice.getFunctionRefKind(),
7482-
AccessSemantics::Ordinary, isDynamic);
7475+
Expr *declRef = buildMemberRef(fn, selected->openedFullType,
7476+
/*dotLoc=*/SourceLoc(), choice,
7477+
DeclNameLoc(fn->getEndLoc()),
7478+
selected->openedType, locator, ctorLocator,
7479+
/*Implicit=*/true, choice.getFunctionRefKind(),
7480+
AccessSemantics::Ordinary, isDynamic);
74837481
if (!declRef)
74847482
return nullptr;
74857483
declRef->setImplicit(apply->isImplicit());
@@ -8173,8 +8171,10 @@ Expr *TypeChecker::callWitness(Expr *base, DeclContext *dc,
81738171
ExprRewriter rewriter(cs, solution,
81748172
/*suppressDiagnostics=*/false);
81758173

8174+
auto choice =
8175+
OverloadChoice(openedFullType, witness, FunctionRefKind::SingleApply);
81768176
auto memberRef = rewriter.buildMemberRef(
8177-
base, openedFullType, base->getStartLoc(), witness,
8177+
base, openedFullType, base->getStartLoc(), choice,
81788178
DeclNameLoc(base->getEndLoc()), openedType, dotLocator, dotLocator,
81798179
/*Implicit=*/true, FunctionRefKind::SingleApply,
81808180
AccessSemantics::Ordinary,

lib/Sema/ConstraintSystem.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,23 @@ DeclName OverloadChoice::getName() const {
19571957
}
19581958

19591959
bool OverloadChoice::isImplicitlyUnwrappedValueOrReturnValue() const {
1960-
return isDecl() &&
1961-
getDecl()->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>();
1960+
if (!isDecl())
1961+
return false;
1962+
1963+
auto *decl = getDecl();
1964+
if (!decl->getAttrs().hasAttribute<ImplicitlyUnwrappedOptionalAttr>())
1965+
return false;
1966+
1967+
auto itfType = decl->getInterfaceType();
1968+
if (!itfType->getAs<AnyFunctionType>())
1969+
return true;
1970+
1971+
switch (getFunctionRefKind()) {
1972+
case FunctionRefKind::Unapplied:
1973+
case FunctionRefKind::Compound:
1974+
return false;
1975+
case FunctionRefKind::SingleApply:
1976+
case FunctionRefKind::DoubleApply:
1977+
return true;
1978+
}
19621979
}

lib/Sema/OverloadChoice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ class OverloadChoice {
190190
result.BaseAndDeclKind.setPointer(base);
191191
result.DeclOrKind = value;
192192
result.DynamicNameAndFRK.setPointer(name);
193+
result.DynamicNameAndFRK.setInt(FunctionRefKind::SingleApply);
193194
return result;
194195
}
195196

test/Constraints/iuo.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,14 @@ func cast<T : P>(_ t: T) {
167167
let _: (Bool) -> T? = id(T.iuoResultStatic as (Bool) -> T?)
168168
let _: T! = id(T.iuoResultStatic(true))
169169
}
170+
171+
class rdar37241550 {
172+
public init(blah: Float) { fatalError() }
173+
public convenience init() { fatalError() }
174+
public convenience init!(with void: ()) { fatalError() }
175+
176+
static func f(_ fn: () -> rdar37241550) {}
177+
static func test() {
178+
f(rdar37241550.init) // no error, the failable init is not applicable
179+
}
180+
}

0 commit comments

Comments
 (0)