Skip to content

Commit a1bf54a

Browse files
[CSDiagnostics] Extract diagnostic for CoerceExpr to function
1 parent 6093baf commit a1bf54a

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1854,21 +1854,8 @@ bool ContextualFailure::diagnoseAsError() {
18541854
return true;
18551855
}
18561856

1857-
if (auto *coerceExpr = dyn_cast<CoerceExpr>(anchor)) {
1858-
auto fromType = getFromType();
1859-
auto toType = getType(coerceExpr->getCastTypeLoc());
1860-
auto diagnostic =
1861-
getDiagnosticFor(CTP_CoerceOperand,
1862-
/*forProtocol=*/toType->isAnyExistentialType());
1863-
1864-
auto diag =
1865-
emitDiagnostic(anchor->getLoc(), *diagnostic, fromType, toType);
1866-
diag.highlight(anchor->getSourceRange());
1867-
1868-
(void)tryFixIts(diag);
1869-
1857+
if (diagnoseConversionInCoercion())
18701858
return true;
1871-
}
18721859

18731860
return false;
18741861
}
@@ -2236,6 +2223,28 @@ bool ContextualFailure::diagnoseMissingFunctionCall() const {
22362223
return true;
22372224
}
22382225

2226+
bool ContextualFailure::diagnoseConversionInCoercion() const {
2227+
auto *anchor = getAnchor();
2228+
2229+
if (auto *coerceExpr = dyn_cast<CoerceExpr>(anchor)) {
2230+
auto fromType = getFromType();
2231+
auto toType = getType(coerceExpr->getCastTypeLoc());
2232+
auto diagnostic =
2233+
getDiagnosticFor(CTP_CoerceOperand,
2234+
/*forProtocol=*/toType->isAnyExistentialType());
2235+
2236+
auto diag =
2237+
emitDiagnostic(anchor->getLoc(), *diagnostic, fromType, toType);
2238+
diag.highlight(anchor->getSourceRange());
2239+
2240+
(void)tryFixIts(diag);
2241+
2242+
return true;
2243+
}
2244+
2245+
return false;
2246+
}
2247+
22392248
bool ContextualFailure::diagnoseConversionToBool() const {
22402249
auto toType = getToType();
22412250
if (!toType->isBool())
@@ -2581,6 +2590,10 @@ bool ContextualFailure::trySequenceSubsequenceFixIts(
25812590
if (getFromType()->isEqual(Substring)) {
25822591
if (getToType()->isEqual(String)) {
25832592
auto *anchor = getAnchor()->getSemanticsProvidingExpr();
2593+
if (auto *CE = dyn_cast<CoerceExpr>(anchor)) {
2594+
anchor = CE->getSubExpr();
2595+
}
2596+
25842597
auto range = anchor->getSourceRange();
25852598
diagnostic.fixItInsert(range.Start, "String(");
25862599
diagnostic.fixItInsertAfter(range.End, ")");

lib/Sema/CSDiagnostics.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,9 @@ class ContextualFailure : public FailureDiagnostic {
554554

555555
/// If we're trying to convert something to `nil`.
556556
bool diagnoseConversionToNil() const;
557+
558+
/// Diagnose failed conversion in a `CoerceExpr`.
559+
bool diagnoseConversionInCoercion() const;
557560

558561
// If we're trying to convert something of type "() -> T" to T,
559562
// then we probably meant to call the value.

test/Parse/recovery.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,11 @@ class WrongInheritanceClause6(Int {}
619619
class WrongInheritanceClause7<T>(Int where T:AnyObject {}
620620

621621
// <rdar://problem/18502220> [swift-crashes 078] parser crash on invalid cast in sequence expr
622-
Base=1 as Base=1 // expected-error {{cannot convert value of type 'Int' to type 'Base' in coercion}}
623-
624-
622+
Base=1 as Base=1 // expected-error{{cannot convert value of type 'Int' to type 'Base' in coercion}}
623+
// expected-error@-1 {{cannot assign to immutable expression of type 'Base.Type'}}
624+
// expected-error@-2 {{left side of mutating operator has immutable type 'Base'}}
625+
// expected-error@-3 {{cannot assign value of type '()' to type 'Base.Type'}}
626+
// expected-error@-4 {{cannot assign value of type 'Int' to type 'Base'}}
625627

626628
// <rdar://problem/18634543> Parser hangs at swift::Parser::parseType
627629
public enum TestA {

0 commit comments

Comments
 (0)