Skip to content

Commit b3e9330

Browse files
authored
Merge pull request #38236 from xedin/rdar-65667992-5.5
[5.5][ConstraintSystem] Bind missing member in pattern match to a hole early
2 parents 4cd2bb6 + 8fec8c0 commit b3e9330

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4878,14 +4878,24 @@ bool ConstraintSystem::repairFailures(
48784878
}
48794879

48804880
case ConstraintLocator::PatternMatch: {
4881+
auto *pattern = elt.castTo<LocatorPathElt::PatternMatch>().getPattern();
4882+
bool isMemberMatch =
4883+
lhs->is<FunctionType>() && isa<EnumElementPattern>(pattern);
4884+
4885+
// If member reference couldn't be resolved, let's allow pattern
4886+
// to have holes.
4887+
if (rhs->isPlaceholder() && isMemberMatch) {
4888+
markAnyTypeVarsAsPotentialHoles(lhs);
4889+
return true;
4890+
}
4891+
48814892
// If either type is a placeholder, consider this fixed.
48824893
if (lhs->isPlaceholder() || rhs->isPlaceholder())
48834894
return true;
48844895

4885-
// If the left-hand side is a function type and the pattern is an enum
4886-
// element pattern, call it a contextual mismatch.
4887-
auto pattern = elt.castTo<LocatorPathElt::PatternMatch>().getPattern();
4888-
if (lhs->is<FunctionType>() && isa<EnumElementPattern>(pattern)) {
4896+
// If member reference didn't match expected pattern,
4897+
// let's consider that a contextual mismatch.
4898+
if (isMemberMatch) {
48894899
markAnyTypeVarsAsPotentialHoles(lhs);
48904900
markAnyTypeVarsAsPotentialHoles(rhs);
48914901

@@ -8189,6 +8199,13 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
81898199
// `key path` constraint can't be retired until all components
81908200
// are simplified.
81918201
addTypeVariableConstraintsToWorkList(memberTypeVar);
8202+
} else if (locator->isLastElement<LocatorPathElt::PatternMatch>()) {
8203+
// Let's handle member patterns specifically because they use
8204+
// equality instead of argument application constraint, so allowing
8205+
// them to bind member could mean missing valid hole positions in
8206+
// the pattern.
8207+
assignFixedType(memberTypeVar,
8208+
PlaceholderType::get(getASTContext(), memberTypeVar));
81928209
} else {
81938210
recordPotentialHole(memberTypeVar);
81948211
}

test/Constraints/result_builder_diags.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,3 +737,32 @@ struct TuplifiedStructWithInvalidClosure {
737737
}
738738
}
739739
}
740+
741+
// rdar://65667992 - invalid case in enum causes fallback diagnostic
742+
func test_rdar65667992() {
743+
@resultBuilder
744+
struct Builder {
745+
static func buildBlock<T>(_ t: T) -> T { t }
746+
static func buildEither<T>(first: T) -> T { first }
747+
static func buildEither<T>(second: T) -> T { second }
748+
}
749+
750+
struct S {}
751+
752+
enum E {
753+
case set(v: Int, choices: [Int])
754+
case notSet(choices: [Int])
755+
}
756+
757+
struct MyView {
758+
var entry: E
759+
760+
@Builder var body: S {
761+
switch entry { // expected-error {{type 'E' has no member 'unset'}}
762+
case .set(_, _): S()
763+
case .unset(_): S()
764+
default: S()
765+
}
766+
}
767+
}
768+
}

0 commit comments

Comments
 (0)