Skip to content

Commit f8465fa

Browse files
authored
Merge pull request #3448 from ahoppen/SR-1827-fixit
SR-1827: Wrong fixits when matching `Selector?`
2 parents e61fc66 + c8ec2c0 commit f8465fa

File tree

4 files changed

+42
-6
lines changed

4 files changed

+42
-6
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4558,10 +4558,16 @@ bool FailureDiagnosis::visitApplyExpr(ApplyExpr *callExpr) {
45584558

45594559
if (callExpr->isImplicit() && overloadName == "~=") {
45604560
// This binop was synthesized when typechecking an expression pattern.
4561-
diagnose(lhsExpr->getLoc(),
4562-
diag::cannot_match_expr_pattern_with_value, lhsType, rhsType)
4563-
.highlight(lhsExpr->getSourceRange())
4564-
.highlight(rhsExpr->getSourceRange());
4561+
auto diag = diagnose(lhsExpr->getLoc(),
4562+
diag::cannot_match_expr_pattern_with_value,
4563+
lhsType, rhsType);
4564+
diag.highlight(lhsExpr->getSourceRange());
4565+
diag.highlight(rhsExpr->getSourceRange());
4566+
if (auto optUnwrappedType = rhsType->getOptionalObjectType()) {
4567+
if (lhsType->isEqual(optUnwrappedType)) {
4568+
diag.fixItInsert(lhsExpr->getEndLoc(), "?");
4569+
}
4570+
}
45654571
return true;
45664572
}
45674573

@@ -5943,7 +5949,7 @@ bool ConstraintSystem::salvage(SmallVectorImpl<Solution> &viable, Expr *expr) {
59435949

59445950
if (getExpressionTooComplex()) {
59455951
TC.diagnose(expr->getLoc(), diag::expression_too_complex).
5946-
highlight(expr->getSourceRange());
5952+
highlight(expr->getSourceRange());
59475953
return true;
59485954
}
59495955

lib/Sema/CSSimplify.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2009,7 +2009,20 @@ ConstraintSystem::matchTypes(Type type1, Type type2, TypeMatchKind kind,
20092009
// If we have an optional type, try to force-unwrap it.
20102010
// FIXME: Should we also try '?'?
20112011
if (objectType1->getOptionalObjectType()) {
2012-
conversionsOrFixes.push_back(FixKind::ForceOptional);
2012+
bool forceUnwrapPossible = true;
2013+
if (auto declRefExpr =
2014+
dyn_cast_or_null<DeclRefExpr>(locator.trySimplifyToExpr())) {
2015+
if (declRefExpr->getDecl()->isImplicit()) {
2016+
// The expression that provides the first type is implicit and never
2017+
// spelled out in source code, e.g. $match in an expression pattern.
2018+
// Thus we cannot force unwrap the first type
2019+
forceUnwrapPossible = false;
2020+
}
2021+
}
2022+
2023+
if (forceUnwrapPossible) {
2024+
conversionsOrFixes.push_back(FixKind::ForceOptional);
2025+
}
20132026
}
20142027

20152028
// If we have a value of type AnyObject that we're trying to convert to

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,6 +2155,8 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
21552155
Context.getIdentifier("$match"),
21562156
rhsType,
21572157
DC);
2158+
2159+
matchVar->setImplicit();
21582160
EP->setMatchVar(matchVar);
21592161
matchVar->setHasNonPatternBindingInit();
21602162

test/expr/unary/selector/selector.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,18 @@ switch optionalSel {
120120
case #selector(C1.method1)?:
121121
break
122122
}
123+
124+
@objc class SR1827 {
125+
func bar() {}
126+
}
127+
128+
switch optionalSel {
129+
case #selector(SR1827.bar): // expected-error{{expression pattern of type 'Selector' cannot match values of type 'Selector?'}} {{26-26=?}}
130+
break
131+
case #selector(SR1827.bar)!: // expected-error{{cannot force unwrap value of non-optional type 'Selector'}}
132+
break
133+
case #selector(SR1827.bar)?:
134+
break
135+
default:
136+
break
137+
}

0 commit comments

Comments
 (0)