Skip to content

Commit bd7d212

Browse files
authored
Merge pull request swiftlang#39261 from JiarenWang/wjr
[Compiler] add 'value' label for `NSNumber` to prevent roundabout err…
2 parents 16c1eb3 + 391c6e0 commit bd7d212

File tree

3 files changed

+58
-25
lines changed

3 files changed

+58
-25
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,8 +1166,8 @@ bool MissingExplicitConversionFailure::diagnoseAsError() {
11661166
}
11671167
}
11681168

1169-
bool needsParensInside = exprNeedsParensBeforeAddingAs(anchor);
1170-
bool needsParensOutside = exprNeedsParensAfterAddingAs(anchor);
1169+
bool needsParensInside = exprNeedsParensBeforeAddingAs(anchor, DC);
1170+
bool needsParensOutside = exprNeedsParensAfterAddingAs(anchor, DC);
11711171

11721172
llvm::SmallString<2> insertBefore;
11731173
llvm::SmallString<32> insertAfter;
@@ -2872,6 +2872,30 @@ bool ContextualFailure::tryIntegerCastFixIts(
28722872
}
28732873
}
28742874

2875+
// bridge to prevent roundabout error message
2876+
// See rdar://problem/82828226
2877+
if (TypeChecker::isObjCBridgedTo(fromType, toType, getDC())) {
2878+
auto *ac = castToExpr(getAnchor());
2879+
bool needsParensInside = exprNeedsParensBeforeAddingAs(ac, getDC());
2880+
bool needsParensOutside = exprNeedsParensAfterAddingAs(ac, getDC());
2881+
llvm::SmallString<2> insertBefore;
2882+
llvm::SmallString<32> insertAfter;
2883+
if (needsParensOutside) {
2884+
insertBefore += "(";
2885+
}
2886+
if (needsParensInside) {
2887+
insertBefore += "(";
2888+
insertAfter += ")";
2889+
}
2890+
insertAfter += " as ";
2891+
insertAfter += toType->getWithoutParens()->getString();
2892+
if (needsParensOutside)
2893+
insertAfter += ")";
2894+
diagnostic.fixItInsert(exprRange.Start, insertBefore);
2895+
diagnostic.fixItInsertAfter(exprRange.End, insertAfter);
2896+
return true;
2897+
}
2898+
28752899
// Add a wrapping integer cast.
28762900
std::string convWrapBefore = toType.getString();
28772901
convWrapBefore += "(";

lib/Sema/CSDiagnostics.h

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,29 @@ class ContextualFailure : public FailureDiagnostic {
697697

698698
static Optional<Diag<Type, Type>>
699699
getDiagnosticFor(ContextualTypePurpose context, Type contextualType);
700+
701+
protected:
702+
bool exprNeedsParensBeforeAddingAs(const Expr *expr, DeclContext *DC) const {
703+
auto asPG = TypeChecker::lookupPrecedenceGroup(
704+
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc())
705+
.getSingle();
706+
if (!asPG)
707+
return true;
708+
return exprNeedsParensInsideFollowingOperator(DC, const_cast<Expr *>(expr),
709+
asPG);
710+
}
711+
712+
bool exprNeedsParensAfterAddingAs(const Expr *expr, DeclContext *DC) const {
713+
auto asPG = TypeChecker::lookupPrecedenceGroup(
714+
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc())
715+
.getSingle();
716+
if (!asPG)
717+
return true;
718+
719+
return exprNeedsParensOutsideFollowingOperator(
720+
DC, const_cast<Expr *>(expr), asPG,
721+
[&](auto *E) { return findParentExpr(E); });
722+
}
700723
};
701724

702725
/// Diagnose errors related to using an array literal where a
@@ -887,29 +910,6 @@ class MissingExplicitConversionFailure final : public ContextualFailure {
887910
ASTNode getAnchor() const override;
888911

889912
bool diagnoseAsError() override;
890-
891-
private:
892-
bool exprNeedsParensBeforeAddingAs(const Expr *expr) {
893-
auto *DC = getDC();
894-
auto asPG = TypeChecker::lookupPrecedenceGroup(
895-
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc()).getSingle();
896-
if (!asPG)
897-
return true;
898-
return exprNeedsParensInsideFollowingOperator(DC, const_cast<Expr *>(expr),
899-
asPG);
900-
}
901-
902-
bool exprNeedsParensAfterAddingAs(const Expr *expr) {
903-
auto *DC = getDC();
904-
auto asPG = TypeChecker::lookupPrecedenceGroup(
905-
DC, DC->getASTContext().Id_CastingPrecedence, SourceLoc()).getSingle();
906-
if (!asPG)
907-
return true;
908-
909-
return exprNeedsParensOutsideFollowingOperator(
910-
DC, const_cast<Expr *>(expr), asPG,
911-
[&](auto *E) { return findParentExpr(E); });
912-
}
913913
};
914914

915915
/// Diagnose failures related to passing value of some type

test/Constraints/rdar82828226.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
7+
let int: Int = 0
8+
func a(_ a: NSNumber) {}
9+
a(int)// expected-error {{cannot convert value of type 'Int' to expected argument type 'NSNumber'}} {{6-6= as NSNumber}}

0 commit comments

Comments
 (0)