[Compiler] add 'value' label for NSNumber to prevent roundabout error message.

This commit is contained in:
jiaren wang
2021-09-11 21:44:17 +08:00
parent d8780d33e9
commit 391c6e07ad
3 changed files with 58 additions and 25 deletions

View File

@@ -1182,8 +1182,8 @@ bool MissingExplicitConversionFailure::diagnoseAsError() {
}
}
bool needsParensInside = exprNeedsParensBeforeAddingAs(anchor);
bool needsParensOutside = exprNeedsParensAfterAddingAs(anchor);
bool needsParensInside = exprNeedsParensBeforeAddingAs(anchor, DC);
bool needsParensOutside = exprNeedsParensAfterAddingAs(anchor, DC);
llvm::SmallString<2> insertBefore;
llvm::SmallString<32> insertAfter;
@@ -2940,6 +2940,30 @@ bool ContextualFailure::tryIntegerCastFixIts(
}
}
// bridge to prevent roundabout error message
// See rdar://problem/82828226
if (TypeChecker::isObjCBridgedTo(fromType, toType, getDC())) {
auto *ac = castToExpr(getAnchor());
bool needsParensInside = exprNeedsParensBeforeAddingAs(ac, getDC());
bool needsParensOutside = exprNeedsParensAfterAddingAs(ac, getDC());
llvm::SmallString<2> insertBefore;
llvm::SmallString<32> insertAfter;
if (needsParensOutside) {
insertBefore += "(";
}
if (needsParensInside) {
insertBefore += "(";
insertAfter += ")";
}
insertAfter += " as ";
insertAfter += toType->getWithoutParens()->getString();
if (needsParensOutside)
insertAfter += ")";
diagnostic.fixItInsert(exprRange.Start, insertBefore);
diagnostic.fixItInsertAfter(exprRange.End, insertAfter);
return true;
}
// Add a wrapping integer cast.
std::string convWrapBefore = toType.getString();
convWrapBefore += "(";

View File

@@ -701,6 +701,29 @@ protected:
static Optional<Diag<Type, Type>>
getDiagnosticFor(ContextualTypePurpose context, Type contextualType);
protected:
bool exprNeedsParensBeforeAddingAs(const Expr *expr, DeclContext *DC) const {
auto asPG = TypeChecker::lookupPrecedenceGroup(
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc())
.getSingle();
if (!asPG)
return true;
return exprNeedsParensInsideFollowingOperator(DC, const_cast<Expr *>(expr),
asPG);
}
bool exprNeedsParensAfterAddingAs(const Expr *expr, DeclContext *DC) const {
auto asPG = TypeChecker::lookupPrecedenceGroup(
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc())
.getSingle();
if (!asPG)
return true;
return exprNeedsParensOutsideFollowingOperator(
DC, const_cast<Expr *>(expr), asPG,
[&](auto *E) { return findParentExpr(E); });
}
};
/// Diagnose errors related to using an array literal where a
@@ -891,29 +914,6 @@ public:
ASTNode getAnchor() const override;
bool diagnoseAsError() override;
private:
bool exprNeedsParensBeforeAddingAs(const Expr *expr) {
auto *DC = getDC();
auto asPG = TypeChecker::lookupPrecedenceGroup(
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc()).getSingle();
if (!asPG)
return true;
return exprNeedsParensInsideFollowingOperator(DC, const_cast<Expr *>(expr),
asPG);
}
bool exprNeedsParensAfterAddingAs(const Expr *expr) {
auto *DC = getDC();
auto asPG = TypeChecker::lookupPrecedenceGroup(
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc()).getSingle();
if (!asPG)
return true;
return exprNeedsParensOutsideFollowingOperator(
DC, const_cast<Expr *>(expr), asPG,
[&](auto *E) { return findParentExpr(E); });
}
};
/// Diagnose failures related to passing value of some type

View File

@@ -0,0 +1,9 @@
// RUN: %target-typecheck-verify-swift
// REQUIRES: objc_interop
import Foundation
let int: Int = 0
func a(_ a: NSNumber) {}
a(int)// expected-error {{cannot convert value of type 'Int' to expected argument type 'NSNumber'}} {{6-6= as NSNumber}}