[Diagnostics] Add a fix-it for optional to raw representable type conversion

Situations where there is a contextual RawRepresentable type is
used incorrectly would produce `<Type>(rawValue: )` fix-it only
in cases where neither or both sides of the expression are optional.
Let's fix that by adding a fix-it for optional to contextual raw
value type conversion.

Resolves: rdar://problem/32431736
This commit is contained in:
Pavel Yaskevich
2017-05-30 18:50:10 -07:00
parent fd693b4ecc
commit c94fe94d5d
10 changed files with 62 additions and 34 deletions

View File

@@ -7216,17 +7216,6 @@ static bool exprNeedsParensAfterAddingAs(TypeChecker &TC, DeclContext *DC,
return exprNeedsParensOutsideFollowingOperator(TC, DC, expr, rootExpr, asPG);
}
static bool exprNeedsParensInsidePostfixOperator(TypeChecker &TC,
DeclContext *DC,
Expr *expr) {
// Prefix and infix operators will bind outside of a postfix operator.
// Postfix operators will get token-merged with a new postfix operator.
return (isa<PrefixUnaryExpr>(expr) ||
isa<PostfixUnaryExpr>(expr) ||
isa<OptionalEvaluationExpr>(expr) ||
expr->isInfixOperator());
}
namespace {
class ExprWalker : public ASTWalker {
ExprRewriter &Rewriter;
@@ -7424,14 +7413,11 @@ bool ConstraintSystem::applySolutionFix(Expr *expr,
} else {
auto diag = TC.diagnose(affected->getLoc(),
diag::missing_unwrap_optional, type);
bool parensNeeded =
exprNeedsParensInsidePostfixOperator(TC, DC, affected);
if (parensNeeded) {
if (affected->canAppendPostfixExpression(true)) {
diag.fixItInsertAfter(affected->getEndLoc(), "!");
} else {
diag.fixItInsert(affected->getStartLoc(), "(")
.fixItInsertAfter(affected->getEndLoc(), ")!");
} else {
diag.fixItInsertAfter(affected->getEndLoc(), "!");
}
}
return true;