[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.
This commit is contained in:
Pavel Yaskevich
2020-05-27 17:03:58 -07:00
parent 9d322fef28
commit d6bf31cb97
2 changed files with 55 additions and 0 deletions

View File

@@ -6389,3 +6389,31 @@ bool UnableToInferKeyPathRootFailure::diagnoseAsError() {
.fixItInsertAfter(keyPathExpr->getStartLoc(), "<#Root#>");
return true;
}
bool MissingRawRepresentativeInitFailure::diagnoseAsError() {
auto *locator = getLocator();
Optional<Diag<Type, Type>> message;
if (locator->isForContextualType()) {
message = diag::cannot_convert_initializer_value;
} else if (locator->isForAssignment()) {
message = diag::cannot_convert_assign;
} else if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
message = diag::cannot_convert_argument_value;
}
if (!message)
return false;
auto diagnostic = emitDiagnostic(*message, ValueType, RawReprType);
if (auto *E = getAsExpr(getAnchor())) {
auto range = E->getSourceRange();
diagnostic
.fixItInsert(range.Start, RawReprType->getString() + "(rawValue: ")
.fixItInsertAfter(range.End, ") ?? <#default value#>");
}
return true;
}