Skip to content

Commit e9c97a7

Browse files
committed
---
yaml --- r: 343399 b: refs/heads/master-rebranch c: fdbc219 h: refs/heads/master i: 343397: 7d6d0d1 343395: 88845b0 343391: 6c9f0c5
1 parent 8ef5497 commit e9c97a7

File tree

9 files changed

+89
-20
lines changed

9 files changed

+89
-20
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-02-a: ddd2b2976aa9bfde5f20fe37f6bd2
14551455
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-03-a: 171cc166f2abeb5ca2a4003700a8a78a108bd300
14561456
refs/heads/benlangmuir-patch-1: baaebaf39d52f3bf36710d4fe40cf212e996b212
14571457
refs/heads/i-do-redeclare: 8c4e6d5de5c1e3f0a2cedccf319df713ea22c48e
1458-
refs/heads/master-rebranch: abbf052780ae4190eeb866842698fcf5241f2ef6
1458+
refs/heads/master-rebranch: fdbc21911b37651a70f64fbff462acd7abc3ca83
14591459
refs/heads/rdar-53901732: 9bd06af3284e18a109cdbf9aa59d833b24eeca7b
14601460
refs/heads/revert-26776-subst-always-returns-a-type: 1b8e18fdd391903a348970a4c848995d4cdd789c
14611461
refs/heads/tensorflow-merge: 8b854f62f80d4476cb383d43c4aac2001dde3cec

branches/master-rebranch/lib/Sema/CSApply.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2272,6 +2272,17 @@ namespace {
22722272
auto *choiceLocator = cs.getConstraintLocator(locator.withPathElement(
22732273
ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice));
22742274

2275+
// We won't have a disjunction choice if we have an IUO function call
2276+
// wrapped in parens (i.e. '(s.foo)()'), because we only create a
2277+
// single constraint to bind to an optional type. So, we can just return
2278+
// false here as there's no need to force unwrap.
2279+
if (!solution.DisjunctionChoices.count(choiceLocator)) {
2280+
auto type = choice.getDecl()->getInterfaceType();
2281+
assert((type && type->is<AnyFunctionType>()) &&
2282+
"expected a function type");
2283+
return false;
2284+
}
2285+
22752286
return solution.getDisjunctionChoice(choiceLocator);
22762287
}
22772288

branches/master-rebranch/lib/Sema/CSDiag.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ bool FailureDiagnosis::diagnoseGeneralOverloadFailure(Constraint *constraint) {
820820
// Get the referenced expression from the failed constraint.
821821
auto anchor = expr;
822822
if (auto locator = bindOverload->getLocator()) {
823-
anchor = simplifyLocatorToAnchor(CS, locator);
823+
anchor = simplifyLocatorToAnchor(locator);
824824
if (!anchor)
825825
return false;
826826
}
@@ -1002,7 +1002,7 @@ bool FailureDiagnosis::diagnoseGeneralConversionFailure(Constraint *constraint){
10021002
bool resolvedAnchorToExpr = false;
10031003

10041004
if (auto locator = constraint->getLocator()) {
1005-
anchor = simplifyLocatorToAnchor(CS, locator);
1005+
anchor = simplifyLocatorToAnchor(locator);
10061006
if (anchor)
10071007
resolvedAnchorToExpr = true;
10081008
else
@@ -5390,7 +5390,7 @@ bool FailureDiagnosis::visitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
53905390
Constraint *memberConstraint = nullptr;
53915391
auto checkConstraint = [&](Constraint *C) {
53925392
if (C->getKind() == ConstraintKind::UnresolvedValueMember &&
5393-
simplifyLocatorToAnchor(CS, C->getLocator()) == E)
5393+
simplifyLocatorToAnchor(C->getLocator()) == E)
53945394
memberConstraint = C;
53955395
};
53965396

branches/master-rebranch/lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
212212
auto *argLocator = cs.getConstraintLocator(
213213
anchor, argPath, ConstraintLocator::getSummaryFlagsForPath(argPath));
214214

215-
auto *argExpr = simplifyLocatorToAnchor(cs, argLocator);
215+
auto *argExpr = simplifyLocatorToAnchor(argLocator);
216216

217217
// If we were unable to simplify down to the argument expression, we don't
218218
// know what this is.

branches/master-rebranch/lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,7 +2161,7 @@ static ConstraintFix *fixPropertyWrapperFailure(
21612161
baseExpr = SE->getBase();
21622162
else if (auto *MRE = dyn_cast<MemberRefExpr>(anchor))
21632163
baseExpr = MRE->getBase();
2164-
else if (auto *anchor = simplifyLocatorToAnchor(cs, locator))
2164+
else if (auto *anchor = simplifyLocatorToAnchor(locator))
21652165
baseExpr = anchor;
21662166
}
21672167

@@ -2300,9 +2300,7 @@ bool ConstraintSystem::repairFailures(
23002300
// default values, let's see whether error is related to missing
23012301
// explicit call.
23022302
if (fnType->getNumParams() > 0) {
2303-
auto *anchor =
2304-
simplifyLocatorToAnchor(*this, getConstraintLocator(locator));
2305-
2303+
auto *anchor = simplifyLocatorToAnchor(getConstraintLocator(locator));
23062304
if (!anchor)
23072305
return false;
23082306

branches/master-rebranch/lib/Sema/ConstraintSystem.cpp

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,9 +2190,34 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
21902190
openedFullType,
21912191
refType};
21922192

2193+
// If we have something like '(s.foo)()', where 's.foo()' returns an IUO,
2194+
// then we need to only create a single constraint that binds the
2195+
// type to an optional.
2196+
auto isIUOCallWrappedInParens = [&]() {
2197+
auto decl = choice.getDecl();
2198+
auto type = decl ? decl->getInterfaceType() : nullptr;
2199+
if (!type || !type->is<AnyFunctionType>())
2200+
return false;
2201+
2202+
auto expr = locator->getAnchor();
2203+
if (!expr)
2204+
return false;
2205+
2206+
if (isa<CallExpr>(expr)) {
2207+
return false;
2208+
}
2209+
2210+
auto parentExpr = getParentExpr(expr);
2211+
if (parentExpr && isa<ParenExpr>(parentExpr))
2212+
return true;
2213+
2214+
return false;
2215+
};
2216+
21932217
// In some cases we already created the appropriate bind constraints.
21942218
if (!bindConstraintCreated) {
2195-
if (choice.isImplicitlyUnwrappedValueOrReturnValue()) {
2219+
if (choice.isImplicitlyUnwrappedValueOrReturnValue() &&
2220+
!isIUOCallWrappedInParens()) {
21962221
// Build the disjunction to attempt binding both T? and T (or
21972222
// function returning T? and function returning T).
21982223
buildDisjunctionForImplicitlyUnwrappedOptional(boundType, refType,
@@ -2600,7 +2625,7 @@ bool ConstraintSystem::diagnoseAmbiguity(Expr *expr,
26002625

26012626
// If we can't resolve the locator to an anchor expression with no path,
26022627
// we can't diagnose this well.
2603-
auto *anchor = simplifyLocatorToAnchor(*this, overload.locator);
2628+
auto *anchor = simplifyLocatorToAnchor(overload.locator);
26042629
if (!anchor)
26052630
continue;
26062631
auto it = indexMap.find(anchor);
@@ -2641,7 +2666,7 @@ bool ConstraintSystem::diagnoseAmbiguity(Expr *expr,
26412666
if (bestOverload) {
26422667
auto &overload = diff.overloads[*bestOverload];
26432668
auto name = getOverloadChoiceName(overload.choices);
2644-
auto anchor = simplifyLocatorToAnchor(*this, overload.locator);
2669+
auto anchor = simplifyLocatorToAnchor(overload.locator);
26452670

26462671
// Emit the ambiguity diagnostic.
26472672
auto &tc = getTypeChecker();
@@ -2693,17 +2718,21 @@ bool ConstraintSystem::diagnoseAmbiguity(Expr *expr,
26932718
return false;
26942719
}
26952720

2696-
Expr *constraints::simplifyLocatorToAnchor(ConstraintSystem &cs,
2697-
ConstraintLocator *locator) {
2698-
if (!locator || !locator->getAnchor())
2721+
Expr *constraints::simplifyLocatorToAnchor(ConstraintLocator *locator) {
2722+
if (!locator)
26992723
return nullptr;
27002724

2701-
SourceRange range;
2702-
locator = simplifyLocator(cs, locator, range);
2703-
if (!locator->getAnchor() || !locator->getPath().empty())
2725+
auto *anchor = locator->getAnchor();
2726+
if (!anchor)
27042727
return nullptr;
27052728

2706-
return locator->getAnchor();
2729+
SourceRange range;
2730+
auto path = locator->getPath();
2731+
simplifyLocator(anchor, path, range);
2732+
2733+
// We only want the new anchor if all the path elements have been simplified
2734+
// away.
2735+
return path.empty() ? anchor : nullptr;
27072736
}
27082737

27092738
Expr *constraints::getArgumentExpr(Expr *expr, unsigned index) {

branches/master-rebranch/lib/Sema/ConstraintSystem.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3950,7 +3950,7 @@ void simplifyLocator(Expr *&anchor,
39503950
///
39513951
/// \returns the anchor expression if it fully describes the locator, or
39523952
/// null otherwise.
3953-
Expr *simplifyLocatorToAnchor(ConstraintSystem &cs, ConstraintLocator *locator);
3953+
Expr *simplifyLocatorToAnchor(ConstraintLocator *locator);
39543954

39553955
/// Retrieve argument at specified index from given expression.
39563956
/// The expression could be "application", "subscript" or "member" call.

branches/master-rebranch/test/Constraints/iuo.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,26 @@ var y: Int = 2
223223

224224
let r = sr6988(x: x, y: y)
225225
let _: Int = r
226+
227+
// SR-10492
228+
229+
struct SR_10492_S {
230+
func foo() -> Int! { return 0 }
231+
}
232+
233+
let sr_10492_s = SR_10492_S()
234+
let sr_10492_int1: Int = (sr_10492_s.foo)() // expected-error {{value of optional type 'Int?' must be unwrapped to a value of type 'Int'}}
235+
// expected-note@-1 {{coalesce}}{{44-44= ?? <#default value#>}}
236+
// expected-note@-2 {{force-unwrap}}{{44-44=!}}
237+
let sr_10492_int2: Int? = (sr_10492_s.foo)() // Okay
238+
239+
240+
class SR_10492_C1 {
241+
init!() {}
242+
}
243+
244+
class SR_10492_C2 {
245+
init(_ foo: SR_10492_C1) {}
246+
}
247+
248+
let bar = SR_10492_C2(SR_10492_C1()) // Okay
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: not %target-swift-frontend -emit-silgen %s
2+
3+
struct S {
4+
func foo() -> Int! { return 0 }
5+
}
6+
7+
let s = S()
8+
let x: Int = (s.foo)()

0 commit comments

Comments
 (0)