Skip to content

Commit b38d11d

Browse files
committed
[Diagnostics] Add a distinct diagnostic for use of raw representable instead of its raw value
Diagnose an attempt to pass raw representable type where its raw value is expected instead. ```swift enum E : Int { case one = 1 } let _: Int = E.one ``` `E.one` has to use `.rawValue` to match `Int` expected by pattern binding.
1 parent 761657f commit b38d11d

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6423,3 +6423,32 @@ bool MissingRawRepresentativeInitFailure::diagnoseAsNote() {
64236423

64246424
return false;
64256425
}
6426+
6427+
void UseOfRawRepresentableInsteadOfItsRawValueFailure::fixIt(
6428+
InFlightDiagnostic &diagnostic) const {
6429+
auto *E = getAsExpr(getAnchor());
6430+
if (!E)
6431+
return;
6432+
6433+
std::string fix;
6434+
6435+
auto range = E->getSourceRange();
6436+
if (!E->canAppendPostfixExpression()) {
6437+
diagnostic.fixItInsert(range.Start, "(");
6438+
fix += ")";
6439+
}
6440+
6441+
// If raw representable is an optional we need to map its raw value out
6442+
// out first and then, if destination is not optional, allow to specify
6443+
// default value.
6444+
if (RawReprType->getOptionalObjectType()) {
6445+
fix += ".map { $0.rawValue } ";
6446+
6447+
if (!ValueType->getOptionalObjectType())
6448+
fix += "?? <#default value#>";
6449+
} else {
6450+
fix += ".rawValue";
6451+
}
6452+
6453+
diagnostic.fixItInsertAfter(range.End, fix);
6454+
}

lib/Sema/CSDiagnostics.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,35 @@ class MissingRawRepresentativeInitFailure final
21572157
void fixIt(InFlightDiagnostic &diagnostic) const override;
21582158
};
21592159

2160+
/// Diagnose an attempt to pass raw representable type where its raw value
2161+
/// is expected instead.
2162+
///
2163+
/// ```swift
2164+
/// enum E : Int {
2165+
/// case one = 1
2166+
/// }
2167+
///
2168+
/// let _: Int = E.one
2169+
/// ```
2170+
///
2171+
/// `E.one` has to use `.rawValue` to match `Int` expected by pattern binding.
2172+
class UseOfRawRepresentableInsteadOfItsRawValueFailure final
2173+
: public AbstractRawRepresentableFailure {
2174+
public:
2175+
UseOfRawRepresentableInsteadOfItsRawValueFailure(const Solution &solution,
2176+
Type rawReprType,
2177+
Type valueType,
2178+
ConstraintLocator *locator)
2179+
: AbstractRawRepresentableFailure(solution, rawReprType, valueType,
2180+
locator) {}
2181+
2182+
Type getFromType() const override { return RawReprType; }
2183+
Type getToType() const override { return ValueType; }
2184+
2185+
private:
2186+
void fixIt(InFlightDiagnostic &diagnostic) const override;
2187+
};
2188+
21602189
} // end namespace constraints
21612190
} // end namespace swift
21622191

0 commit comments

Comments
 (0)