Skip to content

Commit d6bf31c

Browse files
committed
[Diagnostics] Add a distinct diagnostic for missing raw representable init
Diagnose an attempt to initialize raw representable type or convert to it a value of some other type that matches its `RawValue` type. ```swift enum E : Int { case a, b, c } let _: E = 0 ``` `0` has to be wrapped into `E(rawValue: 0)` and either defaulted via `??` or force unwrapped to constitute a valid binding.
1 parent 9d322fe commit d6bf31c

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6389,3 +6389,31 @@ bool UnableToInferKeyPathRootFailure::diagnoseAsError() {
63896389
.fixItInsertAfter(keyPathExpr->getStartLoc(), "<#Root#>");
63906390
return true;
63916391
}
6392+
6393+
bool MissingRawRepresentativeInitFailure::diagnoseAsError() {
6394+
auto *locator = getLocator();
6395+
6396+
Optional<Diag<Type, Type>> message;
6397+
6398+
if (locator->isForContextualType()) {
6399+
message = diag::cannot_convert_initializer_value;
6400+
} else if (locator->isForAssignment()) {
6401+
message = diag::cannot_convert_assign;
6402+
} else if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
6403+
message = diag::cannot_convert_argument_value;
6404+
}
6405+
6406+
if (!message)
6407+
return false;
6408+
6409+
auto diagnostic = emitDiagnostic(*message, ValueType, RawReprType);
6410+
6411+
if (auto *E = getAsExpr(getAnchor())) {
6412+
auto range = E->getSourceRange();
6413+
diagnostic
6414+
.fixItInsert(range.Start, RawReprType->getString() + "(rawValue: ")
6415+
.fixItInsertAfter(range.End, ") ?? <#default value#>");
6416+
}
6417+
6418+
return true;
6419+
}

lib/Sema/CSDiagnostics.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,33 @@ class UnableToInferKeyPathRootFailure final : public FailureDiagnostic {
21022102
bool diagnoseAsError() override;
21032103
};
21042104

2105+
/// Diagnose an attempt to initialize raw representable type or convert to it
2106+
/// a value of some other type that matches its `RawValue` type.
2107+
///
2108+
/// ```swift
2109+
/// enum E : Int {
2110+
/// case a, b, c
2111+
/// }
2112+
///
2113+
/// let _: E = 0
2114+
/// ```
2115+
///
2116+
/// `0` has to be wrapped into `E(rawValue: 0)` and either defaulted via `??` or
2117+
/// force unwrapped to constitute a valid binding.
2118+
class MissingRawRepresentativeInitFailure final : public FailureDiagnostic {
2119+
Type RawReprType;
2120+
Type ValueType;
2121+
2122+
public:
2123+
MissingRawRepresentativeInitFailure(const Solution &solution,
2124+
Type rawReprType, Type valueType,
2125+
ConstraintLocator *locator)
2126+
: FailureDiagnostic(solution, locator), RawReprType(rawReprType),
2127+
ValueType(valueType) {}
2128+
2129+
bool diagnoseAsError() override;
2130+
};
2131+
21052132
} // end namespace constraints
21062133
} // end namespace swift
21072134

0 commit comments

Comments
 (0)