mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Compiler] add 'value' label for NSNumber to prevent roundabout error message.
This commit is contained in:
@@ -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 += "(";
|
||||
|
||||
@@ -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
|
||||
|
||||
9
test/Constraints/rdar82828226.swift
Normal file
9
test/Constraints/rdar82828226.swift
Normal 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}}
|
||||
Reference in New Issue
Block a user