[Diagnostics] Don't suggest unwrap with default value if type is not materializable

This commit is contained in:
Pavel Yaskevich
2019-03-08 01:07:30 -08:00
parent 39dd6306c6
commit 3940cebebf
2 changed files with 55 additions and 0 deletions

View File

@@ -549,8 +549,59 @@ bool MemberAccessOnOptionalBaseFailure::diagnoseAsError() {
resultIsOptional, SourceRange());
}
Optional<AnyFunctionType::Param>
MissingOptionalUnwrapFailure::getOperatorParameterFor(Expr *expr) const {
auto *parentExpr = findParentExpr(expr);
if (!parentExpr)
return None;
auto getArgIdx = [](TupleExpr *tuple, Expr *argExpr) -> unsigned {
for (unsigned i = 0, n = tuple->getNumElements(); i != n; ++i) {
if (tuple->getElement(i) == argExpr)
return i;
}
llvm_unreachable("argument is not in enclosing tuple?!");
};
auto *tupleExpr = dyn_cast<TupleExpr>(parentExpr);
if (!(tupleExpr && tupleExpr->isImplicit()))
return None;
parentExpr = findParentExpr(tupleExpr);
if (!(parentExpr && isa<ApplyExpr>(parentExpr)))
return None;
auto &cs = getConstraintSystem();
auto *fnExpr = cast<ApplyExpr>(parentExpr)->getFn();
if (auto overload =
getOverloadChoiceIfAvailable(cs.getConstraintLocator(fnExpr))) {
if (auto *decl = overload->choice.getDecl()) {
if (!decl->isOperator())
return None;
auto *fnType = overload->openedType->castTo<FunctionType>();
return fnType->getParams()[getArgIdx(tupleExpr, expr)];
}
}
return None;
}
void MissingOptionalUnwrapFailure::offerDefaultValueUnwrapFixIt(
DeclContext *DC, Expr *expr) const {
auto *anchor = getAnchor();
// If anchor is an explicit address-of, or expression which produces
// an l-value (e.g. first argument of `+=` operator), let's not
// suggest default value here because that would produce r-value type.
if (isa<InOutExpr>(anchor))
return;
if (auto param = getOperatorParameterFor(anchor)) {
if (param->isInOut())
return;
}
auto diag = emitDiagnostic(expr->getLoc(), diag::unwrap_with_default_value);
auto &TC = getTypeChecker();