Motivated by this bug report and corresponding PR, I was thinking a bit about how to improve developer feedback for what's going on in this scenario:
func deadNilCoalesce<T>(_ value: T?, fallback: T) {
let _ = (value ?? fallback).flatMap { $0 }
`- warning: left side of nil coalescing operator '??' has non-optional type 'T?', so the right side is never used
}
Obviously the wording "...has non-optional type 'T?'" is self-contradictory, hence the bug report. But, the diagnostic is still "right" that the RHS of the ?? operator is dead. The reason is that the LHS gets injected into an optional (as the .some case of a T??), so it can't be nil. Without getting into why the typechecker ends up with this particular solution, I was wondering how we might improve developer feedback in this situation.
The current diagnostic wording mentions only types and not values. This generally makes sense in the cases where the LHS type actually is not optional:
let x: Int
let _ = x ?? 42
// warning: left side of nil coalescing operator '??' has non-optional type 'Int', so the right side is never used
But, IIUC, even in this case the reality is that the LHS value is implicitly wrapped in an optional. Indeed, the left side of the ?? must be optional, since that's how the operator is defined, and its entire purpose is to provide a fallback value for a nil optional.
I can imagine rewording this diagnostic so that it no longer hides the fact that there's an implicit optional injection occurring, which would generalize to the case in the bug report:
let _ = (value ?? fallback).flatMap { $0 }
`- warning: left side of nil coalescing operator '??' is implicitly wrapped in an optional, so the right side is never used
And if we wanted to elaborate more on the types involved or whatever, we could add a note:
let _ = (value ?? fallback).flatMap { $0 }
| `- warning: left side of nil coalescing operator '??' is implicitly wrapped in an optional, so the right side is never used
` note: value of type 'T?' is implicitly wrapped in an optional here, producing 'T??'
But I'm wondering if explicitly discussing the optional injection/wrapping is actually helpful or desirable since it's sort of an implementation detail.
So, overall, looking for feedback from people about how this diagnostic could be improved. What sort of wording would you expect to see here? Should the implicit optional wrapping mechanism be unconditionally mentioned or should we special-case the double-optional scenario with some different feedback? What is the mental model we want to foster with this diagnostic?