Skip to content

Commit 5dbced9

Browse files
committed
[Diagnostics] Allow failure diagnostic implementation to extend getAnchor
Some of the diagnostics have special rules about anchor location, let's make `getAnchor` virtual and allow sub-class to override default implementation.
1 parent 1036302 commit 5dbced9

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -864,12 +864,17 @@ bool NoEscapeFuncToTypeConversionFailure::diagnoseParameterUse() const {
864864
return true;
865865
}
866866

867-
bool MissingForcedDowncastFailure::diagnoseAsError() {
868-
auto *expr = getAnchor();
867+
Expr *MissingForcedDowncastFailure::getAnchor() const {
868+
auto *expr = FailureDiagnostic::getAnchor();
869+
869870
if (auto *assignExpr = dyn_cast<AssignExpr>(expr))
870-
expr = assignExpr->getSrc();
871+
return assignExpr->getSrc();
871872

872-
auto *coerceExpr = cast<CoerceExpr>(expr);
873+
return expr;
874+
}
875+
876+
bool MissingForcedDowncastFailure::diagnoseAsError() {
877+
auto *coerceExpr = cast<CoerceExpr>(getAnchor());
873878

874879
auto fromType = getFromType();
875880
auto toType = getToType();
@@ -897,13 +902,21 @@ bool MissingAddressOfFailure::diagnoseAsError() {
897902
return true;
898903
}
899904

905+
Expr *MissingExplicitConversionFailure::getAnchor() const {
906+
auto *anchor = FailureDiagnostic::getAnchor();
907+
908+
if (auto *assign = dyn_cast<AssignExpr>(anchor))
909+
return assign->getSrc();
910+
911+
if (auto *paren = dyn_cast<ParenExpr>(anchor))
912+
return paren->getSubExpr();
913+
914+
return anchor;
915+
}
916+
900917
bool MissingExplicitConversionFailure::diagnoseAsError() {
901918
auto *DC = getDC();
902919
auto *anchor = getAnchor();
903-
if (auto *assign = dyn_cast<AssignExpr>(anchor))
904-
anchor = assign->getSrc();
905-
if (auto *paren = dyn_cast<ParenExpr>(anchor))
906-
anchor = paren->getSubExpr();
907920

908921
auto fromType = getFromType();
909922
auto toType = getToType();
@@ -915,9 +928,9 @@ bool MissingExplicitConversionFailure::diagnoseAsError() {
915928
if (!useAs && !TypeChecker::checkedCastMaySucceed(fromType, toType, DC))
916929
return false;
917930

918-
auto *expr = findParentExpr(getAnchor());
931+
auto *expr = findParentExpr(anchor);
919932
if (!expr)
920-
expr = getAnchor();
933+
expr = anchor;
921934

922935
// If we're performing pattern matching,
923936
// "as" means something completely different...
@@ -3027,13 +3040,17 @@ bool NonOptionalUnwrapFailure::diagnoseAsError() {
30273040
return true;
30283041
}
30293042

3043+
Expr *MissingCallFailure::getAnchor() const {
3044+
auto *anchor = FailureDiagnostic::getAnchor();
3045+
if (auto *FVE = dyn_cast<ForceValueExpr>(anchor))
3046+
return FVE->getSubExpr();
3047+
return anchor;
3048+
}
3049+
30303050
bool MissingCallFailure::diagnoseAsError() {
30313051
auto *baseExpr = getAnchor();
30323052
SourceLoc insertLoc = baseExpr->getEndLoc();
30333053

3034-
if (auto *FVE = dyn_cast<ForceValueExpr>(baseExpr))
3035-
baseExpr = FVE->getSubExpr();
3036-
30373054
// Calls are not yet supported by key path, but it
30383055
// is useful to record this fix to diagnose chaining
30393056
// where one of the key path components is a method
@@ -3811,6 +3828,13 @@ bool ImplicitInitOnNonConstMetatypeFailure::diagnoseAsError() {
38113828
return true;
38123829
}
38133830

3831+
Expr *MissingArgumentsFailure::getAnchor() const {
3832+
auto *anchor = FailureDiagnostic::getAnchor();
3833+
if (auto *captureList = dyn_cast<CaptureListExpr>(anchor))
3834+
return captureList->getClosureBody();
3835+
return anchor;
3836+
}
3837+
38143838
bool MissingArgumentsFailure::diagnoseAsError() {
38153839
auto *locator = getLocator();
38163840

@@ -3827,8 +3851,6 @@ bool MissingArgumentsFailure::diagnoseAsError() {
38273851
return false;
38283852

38293853
auto *anchor = getAnchor();
3830-
if (auto *captureList = dyn_cast<CaptureListExpr>(anchor))
3831-
anchor = captureList->getClosureBody();
38323854

38333855
if (auto *closure = dyn_cast<ClosureExpr>(anchor))
38343856
return diagnoseClosure(closure);

lib/Sema/CSDiagnostics.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class FailureDiagnostic {
8181

8282
Expr *getRawAnchor() const { return RawAnchor; }
8383

84-
Expr *getAnchor() const { return Anchor; }
84+
virtual Expr *getAnchor() const { return Anchor; }
8585

8686
ConstraintLocator *getLocator() const { return Locator; }
8787

@@ -779,6 +779,8 @@ class MissingExplicitConversionFailure final : public ContextualFailure {
779779
Type toType, ConstraintLocator *locator)
780780
: ContextualFailure(solution, fromType, toType, locator) {}
781781

782+
Expr *getAnchor() const override;
783+
782784
bool diagnoseAsError() override;
783785

784786
private:
@@ -936,6 +938,8 @@ class MissingCallFailure final : public FailureDiagnostic {
936938
MissingCallFailure(const Solution &solution, ConstraintLocator *locator)
937939
: FailureDiagnostic(solution, locator) {}
938940

941+
Expr *getAnchor() const override;
942+
939943
bool diagnoseAsError() override;
940944
};
941945

@@ -1214,6 +1218,8 @@ class MissingArgumentsFailure final : public FailureDiagnostic {
12141218
assert(!SynthesizedArgs.empty() && "No missing arguments?!");
12151219
}
12161220

1221+
Expr *getAnchor() const override;
1222+
12171223
bool diagnoseAsError() override;
12181224

12191225
bool diagnoseAsNote() override;
@@ -1830,6 +1836,8 @@ class MissingForcedDowncastFailure final : public ContextualFailure {
18301836
Type toType, ConstraintLocator *locator)
18311837
: ContextualFailure(solution, fromType, toType, locator) {}
18321838

1839+
Expr *getAnchor() const override;
1840+
18331841
bool diagnoseAsError() override;
18341842
};
18351843

test/Constraints/fixes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class T {
111111
// <rdar://problem/17741575>
112112
let l = self.m2!.prop1
113113
// expected-error@-1 {{cannot force unwrap value of non-optional type '() -> U?'}} {{22-23=}}
114-
// expected-error@-2 {{method 'm2' was used as a property; add () to call it}} {{23-23=()}}
114+
// expected-error@-2 {{method 'm2' was used as a property; add () to call it}} {{22-22=()}}
115115
}
116116

117117
func m2() -> U! {

0 commit comments

Comments
 (0)