[Sema] Don't suggest fixits that try to force unwrap implicit $match

Check if a variable is actually spelled out in code before suggesting a
fixit that adds a force unwrap to it

This fixes SR-1827
This commit is contained in:
Alex Hoppen
2016-07-11 15:06:32 +02:00
parent f96083c840
commit fc4216e94b
4 changed files with 32 additions and 2 deletions

View File

@@ -5943,7 +5943,7 @@ bool ConstraintSystem::salvage(SmallVectorImpl<Solution> &viable, Expr *expr) {
if (getExpressionTooComplex()) { if (getExpressionTooComplex()) {
TC.diagnose(expr->getLoc(), diag::expression_too_complex). TC.diagnose(expr->getLoc(), diag::expression_too_complex).
highlight(expr->getSourceRange()); highlight(expr->getSourceRange());
return true; return true;
} }

View File

@@ -2009,7 +2009,20 @@ commit_to_conversions:
// If we have an optional type, try to force-unwrap it. // If we have an optional type, try to force-unwrap it.
// FIXME: Should we also try '?'? // FIXME: Should we also try '?'?
if (objectType1->getOptionalObjectType()) { if (objectType1->getOptionalObjectType()) {
conversionsOrFixes.push_back(FixKind::ForceOptional); bool forceUnwrapPossible = true;
if (auto declRefExpr =
dyn_cast_or_null<DeclRefExpr>(locator.trySimplifyToExpr())) {
if (declRefExpr->getDecl()->isImplicit()) {
// The expression that provides the first type is implicit and never
// spelled out in source code, e.g. $match in an expression pattern.
// Thus we cannot force unwrap the first type
forceUnwrapPossible = false;
}
}
if (forceUnwrapPossible) {
conversionsOrFixes.push_back(FixKind::ForceOptional);
}
} }
// If we have a value of type AnyObject that we're trying to convert to // If we have a value of type AnyObject that we're trying to convert to

View File

@@ -2150,6 +2150,8 @@ bool TypeChecker::typeCheckExprPattern(ExprPattern *EP, DeclContext *DC,
Context.getIdentifier("$match"), Context.getIdentifier("$match"),
rhsType, rhsType,
DC); DC);
matchVar->setImplicit();
EP->setMatchVar(matchVar); EP->setMatchVar(matchVar);
matchVar->setHasNonPatternBindingInit(); matchVar->setHasNonPatternBindingInit();

View File

@@ -120,3 +120,18 @@ switch optionalSel {
case #selector(C1.method1)?: case #selector(C1.method1)?:
break break
} }
@objc class SR1827 {
func bar() {}
}
switch optionalSel {
case #selector(SR1827.bar): // expected-error{{expression pattern of type 'Selector' cannot match values of type 'Selector?'}}
break
case #selector(SR1827.bar)!: // expected-error{{cannot force unwrap value of non-optional type 'Selector'}}
break
case #selector(SR1827.bar)?:
break
default:
break
}