mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Diagnostics] Don't suggest unwrap with default value if type is not materializable
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user