Skip to content

Commit 0f1cce3

Browse files
committed
[Diagnostics] Assign missing member eagerly when there is no context
Without contextual information it won't be possible to bind a missing member to a concrete type later, so let's bind them eagerly and propagate placeholders outward. Resolves: rdar://152021264 Resolves: #81770 (cherry picked from commit 10186d6)
1 parent 148e2d1 commit 0f1cce3

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3484,6 +3484,15 @@ class ConstraintSystem {
34843484
return nullptr;
34853485
}
34863486

3487+
Expr *getSemanticsProvidingParentExpr(Expr *expr) {
3488+
while (auto *parent = getParentExpr(expr)) {
3489+
if (parent->getSemanticsProvidingExpr() == parent)
3490+
return parent;
3491+
expr = parent;
3492+
}
3493+
return nullptr;
3494+
}
3495+
34873496
/// Retrieve the depth of the given expression.
34883497
std::optional<unsigned> getExprDepth(Expr *expr) {
34893498
if (auto result = getExprDepthAndParent(expr))

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11438,6 +11438,14 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
1143811438
// `key path` constraint can't be retired until all components
1143911439
// are simplified.
1144011440
addTypeVariableConstraintsToWorkList(memberTypeVar);
11441+
} else if (locator->getAnchor().is<Expr *>() &&
11442+
!getSemanticsProvidingParentExpr(
11443+
getAsExpr(locator->getAnchor()))) {
11444+
// If there are no contextual expressions that could provide
11445+
// a type for the member type variable, let's default it to
11446+
// a placeholder eagerly so it could be propagated to the
11447+
// pattern if necessary.
11448+
recordTypeVariablesAsHoles(memberTypeVar);
1144111449
} else if (locator->isLastElement<LocatorPathElt::PatternMatch>()) {
1144211450
// Let's handle member patterns specifically because they use
1144311451
// equality instead of argument application constraint, so allowing

test/Constraints/closures.swift

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,6 @@ overloaded { print("hi"); print("bye") } // multiple expression closure without
803803
// expected-error@-1 {{ambiguous use of 'overloaded'}}
804804

805805
func not_overloaded(_ handler: () -> Int) {}
806-
// expected-note@-1 {{'not_overloaded' declared here}}
807806

808807
not_overloaded { } // empty body
809808
// expected-error@-1 {{cannot convert value of type '()' to closure result type 'Int'}}
@@ -1347,3 +1346,23 @@ do {
13471346
let _ = V(value: { [Int]() }) // expected-error {{add () to forward '@autoclosure' parameter}} {{31-31=()}}
13481347
let _ = V(other: { [Int]() }) // expected-error {{cannot convert value of type '[Int]' to closure result type 'String'}}
13491348
}
1349+
1350+
// https://github.com/swiftlang/swift/issues/81770
1351+
do {
1352+
func test(_: Int) {}
1353+
func test(_: Int = 42, _: (Int) -> Void) {}
1354+
1355+
test {
1356+
if let _ = $0.missing { // expected-error {{value of type 'Int' has no member 'missing'}}
1357+
}
1358+
}
1359+
1360+
test {
1361+
if let _ = (($0.missing)) { // expected-error {{value of type 'Int' has no member 'missing'}}
1362+
}
1363+
}
1364+
1365+
test { // expected-error {{invalid conversion from throwing function of type '(Int) throws -> Void' to non-throwing function type '(Int) -> Void'}}
1366+
try $0.missing // expected-error {{value of type 'Int' has no member 'missing'}}
1367+
}
1368+
}

0 commit comments

Comments
 (0)