Skip to content

Commit 5fee07b

Browse files
[CSDiagnostics] Adapt diagnostics to handle new CoercionOperand elt
1 parent a93eff1 commit 5fee07b

File tree

3 files changed

+76
-36
lines changed

3 files changed

+76
-36
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,8 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
786786
//
787787
// `value` has to get implicitly wrapped into 2 optionals
788788
// before pointer types could be compared.
789-
auto path = getLocator()->getPath();
789+
auto locator = getLocator();
790+
auto path = locator->getPath();
790791
unsigned toDrop = 0;
791792
for (const auto &elt : llvm::reverse(path)) {
792793
if (!elt.is<LocatorPathElt::OptionalPayload>())
@@ -802,7 +803,7 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
802803
if (path.empty()) {
803804
if (isExpr<AssignExpr>(anchor)) {
804805
diagnostic = getDiagnosticFor(CTP_AssignSource);
805-
} else if (isExpr<CoerceExpr>(anchor)) {
806+
} else if (locator->isForCoercion()) {
806807
diagnostic = getDiagnosticFor(CTP_CoerceOperand);
807808
} else {
808809
return false;
@@ -887,6 +888,11 @@ bool GenericArgumentsMismatchFailure::diagnoseAsError() {
887888
break;
888889
}
889890

891+
case ConstraintLocator::CoercionOperand: {
892+
diagnostic = getDiagnosticFor(CTP_CoerceOperand);
893+
break;
894+
}
895+
890896
default:
891897
break;
892898
}
@@ -1222,17 +1228,18 @@ ASTNode InvalidCoercionFailure::getAnchor() const {
12221228
bool InvalidCoercionFailure::diagnoseAsError() {
12231229
auto fromType = getFromType();
12241230
auto toType = getToType();
1231+
auto *CE = getAsExpr<CoerceExpr>(getRawAnchor());
12251232

12261233
emitDiagnostic(diag::cannot_coerce_to_type, fromType, toType);
12271234

12281235
if (UseConditionalCast) {
12291236
emitDiagnostic(diag::missing_optional_downcast)
1230-
.highlight(getSourceRange())
1231-
.fixItReplace(getLoc(), "as?");
1237+
.highlight(CE->getSourceRange())
1238+
.fixItReplace(CE->getAsLoc(), "as?");
12321239
} else {
12331240
emitDiagnostic(diag::missing_forced_downcast)
1234-
.highlight(getSourceRange())
1235-
.fixItReplace(getLoc(), "as!");
1241+
.highlight(CE->getSourceRange())
1242+
.fixItReplace(CE->getAsLoc(), "as!");
12361243
}
12371244

12381245
return true;
@@ -2487,7 +2494,7 @@ bool ContextualFailure::diagnoseAsError() {
24872494
diagnostic = diag::cannot_convert_condition_value;
24882495
break;
24892496
}
2490-
2497+
case ConstraintLocator::CoercionOperand:
24912498
case ConstraintLocator::InstanceType: {
24922499
if (diagnoseCoercionToUnrelatedType())
24932500
return true;
@@ -2655,7 +2662,7 @@ bool ContextualFailure::diagnoseAsError() {
26552662
}
26562663

26572664
bool ContextualFailure::diagnoseAsNote() {
2658-
auto *locator = getLocator();
2665+
auto *locator = getAmbiguityLocator();
26592666

26602667
auto overload = getCalleeOverloadChoiceIfAvailable(locator);
26612668
if (!(overload && overload->choice.isDecl()))
@@ -2809,7 +2816,7 @@ bool ContextualFailure::diagnoseConversionToNil() const {
28092816
emitDiagnostic(diag::unresolved_nil_literal);
28102817
return true;
28112818
}
2812-
} else if (isa<CoerceExpr>(parentExpr)) {
2819+
} else if (locator->isForCoercion()) {
28132820
// `nil` is passed as a left-hand side of the coercion
28142821
// operator e.g. `nil as Foo`
28152822
CTP = CTP_CoerceOperand;
@@ -2891,23 +2898,23 @@ bool ContextualFailure::diagnoseExtraneousAssociatedValues() const {
28912898
}
28922899

28932900
bool ContextualFailure::diagnoseCoercionToUnrelatedType() const {
2894-
auto anchor = getAnchor();
2901+
auto anchor = getRawAnchor();
2902+
auto *coerceExpr = getAsExpr<CoerceExpr>(anchor);
2903+
if (!coerceExpr) {
2904+
return false;
2905+
}
28952906

2896-
if (auto *coerceExpr = getAsExpr<CoerceExpr>(anchor)) {
2897-
const auto fromType = getType(coerceExpr->getSubExpr());
2898-
const auto toType = getType(coerceExpr->getCastTypeRepr());
2907+
const auto fromType = getType(coerceExpr->getSubExpr());
2908+
const auto toType = getType(coerceExpr->getCastTypeRepr());
28992909

2900-
auto diagnostic = getDiagnosticFor(CTP_CoerceOperand, toType);
2910+
auto diagnostic = getDiagnosticFor(CTP_CoerceOperand, toType);
29012911

2902-
auto diag = emitDiagnostic(*diagnostic, fromType, toType);
2903-
diag.highlight(getSourceRange());
2912+
auto diag = emitDiagnostic(*diagnostic, fromType, toType);
2913+
diag.highlight(getSourceRange());
29042914

2905-
(void)tryFixIts(diag);
2906-
2907-
return true;
2908-
}
2915+
(void)tryFixIts(diag);
29092916

2910-
return false;
2917+
return true;
29112918
}
29122919

29132920
bool ContextualFailure::diagnoseConversionToBool() const {
@@ -3178,9 +3185,6 @@ bool ContextualFailure::trySequenceSubsequenceFixIts(
31783185
if (getFromType()->isSubstring()) {
31793186
if (getToType()->isString()) {
31803187
auto *anchor = castToExpr(getAnchor())->getSemanticsProvidingExpr();
3181-
if (auto *CE = dyn_cast<CoerceExpr>(anchor)) {
3182-
anchor = CE->getSubExpr();
3183-
}
31843188

31853189
if (auto *call = dyn_cast<CallExpr>(anchor)) {
31863190
auto *fnExpr = call->getFn();
@@ -4927,7 +4931,7 @@ bool MissingArgumentsFailure::diagnoseAsError() {
49274931
}
49284932

49294933
bool MissingArgumentsFailure::diagnoseAsNote() {
4930-
auto *locator = getLocator();
4934+
auto *locator = getAmbiguityLocator();
49314935
if (auto overload = getCalleeOverloadChoiceIfAvailable(locator)) {
49324936
auto *fn = resolveType(overload->adjustedOpenedType)->getAs<AnyFunctionType>();
49334937
auto loc = overload->choice.getDecl()->getLoc();
@@ -5729,7 +5733,7 @@ bool ExtraneousArgumentsFailure::diagnoseAsError() {
57295733
}
57305734

57315735
bool ExtraneousArgumentsFailure::diagnoseAsNote() {
5732-
auto overload = getCalleeOverloadChoiceIfAvailable(getLocator());
5736+
auto overload = getCalleeOverloadChoiceIfAvailable(getAmbiguityLocator());
57335737
if (!(overload && overload->choice.isDecl()))
57345738
return false;
57355739

@@ -5741,7 +5745,7 @@ bool ExtraneousArgumentsFailure::diagnoseAsNote() {
57415745
(numArgs == 1));
57425746
} else {
57435747
emitDiagnosticAt(decl, diag::candidate_with_extraneous_args,
5744-
decl->getInterfaceType(), numArgs, ContextualType,
5748+
overload->adjustedOpenedType, numArgs, ContextualType,
57455749
ContextualType->getNumParams());
57465750
}
57475751
return true;
@@ -8758,12 +8762,7 @@ GlobalActorFunctionMismatchFailure::getDiagnosticMessage() const {
87588762
auto path = locator->getPath();
87598763

87608764
if (path.empty()) {
8761-
auto anchor = getAnchor();
8762-
if (isExpr<CoerceExpr>(anchor)) {
8763-
return diag::cannot_convert_global_actor_coercion;
8764-
} else {
8765-
return diag::cannot_convert_global_actor;
8766-
}
8765+
return diag::cannot_convert_global_actor;
87678766
}
87688767

87698768
auto last = path.back();
@@ -8781,6 +8780,9 @@ GlobalActorFunctionMismatchFailure::getDiagnosticMessage() const {
87818780
case ConstraintLocator::TernaryBranch: {
87828781
return diag::ternary_expr_cases_global_actor_mismatch;
87838782
}
8783+
case ConstraintLocator::CoercionOperand: {
8784+
return diag::cannot_convert_global_actor_coercion;
8785+
}
87848786
default:
87858787
break;
87868788
}

lib/Sema/CSDiagnostics.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ class FailureDiagnostic {
9090

9191
ConstraintLocator *getLocator() const { return Locator; }
9292

93+
ConstraintLocator *getAmbiguityLocator() const {
94+
auto &cs = getConstraintSystem();
95+
return cs.getConstraintLocatorForAmbiguity(Locator);
96+
}
97+
9398
Type getType(ASTNode node, bool wantRValue = true) const;
9499

95100
/// Get type associated with a given ASTNode without resolving it,

test/Constraints/overload.swift

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,40 @@ func rdar97396399() {
287287
}
288288

289289
// https://github.com/apple/swift/issues/63834
290-
func f63834(int: Int, string: String) {} // expected-note{{found candidate with type '(Int, String) -> ()'}}
291-
func f63834(int: Int, string: Bool) {} // expected-note{{found candidate with type '(Int, Bool) -> ()'}}
290+
func f63834(int: Int, string: String) {} // expected-note 3{{found candidate with type '(Int, String) -> ()'}}
291+
func f63834(int: Int, string: Bool) {} // expected-note 3{{found candidate with type '(Int, Bool) -> ()'}}
292+
293+
func f63834_1(int: Int, string: Bool) {} // expected-note{{candidate '(Int, Bool) -> ()' has 2 parameters, but context '(Int) -> Void' has 1}}
294+
func f63834_1(int: Int, string: String) {} // expected-note{{candidate '(Int, String) -> ()' has 2 parameters, but context '(Int) -> Void' has 1}}
295+
296+
// FIXME: We can mention candidate type.
297+
func f63834_2(int: Int, string: Bool) {} // expected-note {{found this candidate}}
298+
func f63834_2(int: Int, string: String) {} // expected-note {{found this candidate}}
299+
300+
// One function argument mismatch
301+
let _ = f63834(int:string:) as (Int, Int) -> Void // expected-error{{no exact matches in reference to global function 'f63834'}}
302+
// Contextual mismatch
303+
let _ = f63834(int:string:) as Int // expected-error{{no exact matches in reference to global function 'f63834'}}
304+
let _ = (f63834(int:string:)) as Int // expected-error{{no exact matches in reference to global function 'f63834'}}
305+
306+
// Missing function argument
307+
let _ = f63834_1(int:string:) as (Int) -> Void // expected-error{{no exact matches in reference to global function 'f63834_1'}}
308+
// None of the function argument types matches
309+
let _ = f63834_2(int:string:) as (Double, Double) -> Void // expected-error{{no exact matches in reference to global function 'f63834_2'}}
310+
let _ = { i, j in } as (Int) -> Void // expected-error{{contextual closure type '(Int) -> Void' expects 1 argument, but 2 were used in closure body}}
311+
312+
struct A63834 {
313+
static func fn(int: Int, string: String) {} // expected-note{{candidate '(Int, String) -> ()' has 2 parameters, but context '(Int) -> Void' has 1}}
314+
static func fn(int: Int, string: Bool) {} // expected-note{{candidate '(Int, Bool) -> ()' has 2 parameters, but context '(Int) -> Void' has 1}}
315+
316+
static func fn1(int: Int, string: String) {} // expected-note{{found candidate with type '(Int, String) -> ()'}}
317+
static func fn1(int: Int, string: Bool) {} // expected-note{{found candidate with type '(Int, Bool) -> ()'}}
318+
}
319+
let _ = A63834.fn1(int:string:) as Int // expected-error {{no exact matches in reference to static method 'fn1'}}
320+
let _ = A63834.fn(int:string:) as (Int) -> Void // expected-error{{no exact matches in reference to static method 'fn'}}
321+
322+
typealias Magic<T> = T
323+
func f63834_D(_ x: Int = 0) {}
324+
func f63834_D(_ x: String) {}
292325

293-
let a = f63834(int:string:) as (Int, Int) -> Void // expected-error{{no exact matches in reference to global function 'f63834'}}
326+
(f63834_D as Magic)() // expected-error{{missing argument for parameter #1 in call}}

0 commit comments

Comments
 (0)