missing diagnostics for switch statements that switch on a value whose type is a type parameter
nishanths opened this issue · 3 comments
It is unclear to me at this point what effect the upcoming go1.18 type parameter change will have on this analyzer. We may need to define the analyzer's behavior when type parameters are involved. The analzyer implementation may also need to be updated to handle type parameters.
now that 1.18 is out, does anyone know if this still works?
It continues to work if the switch statement doesn't switch on a type-parameterized type.
However, if the switch statements switches on a type-parameterized type, exhaustive fails to detect missing cases. For example, for the switch statement in the function foo
below, I think it should have reported missing B
. In bar
, I think it should have reported missing B
and C
.
package typeparam
type M int
const (
A M = iota
B
)
type N uint
const (
C N = iota
D
)
func foo[T M](v T) {
switch v {
case T(A):
}
}
func bar[T M | N](v T) {
switch v {
case T(A):
case T(D):
}
}
One of the issues that should be addressed is that exhaustive doesn't check these switch statement because of an early-out return in switch.go
.
Lines 94 to 99 in c85349a
(The type is *types.TypeParam
, not *types.Named
, for the example above.)
Work-in-progress definition of the analyzer's behavior for type parameters.
Initial version
# Type parameters
A switch statement that switches on a value whose type is a type
parameter is checked for exhaustiveness iff each term of the type
constraint is an enum type. The following switch statement will be
checked, assuming M, N, and O are enum types. To satisfy exhaustiveness,
all enum members for each of M, N, and O must be listed in the switch
statement's cases.
func bar[T M | I](v T) {
switch v {
}
}
type I interface {
N | O
}
Update 1
# Type parameters
A switch statement that switches on a value whose type is a type parameter is
checked for exhaustiveness iff each type element in the type constraint is
an enum type and shares the same underlying basic kind. For example, the
following switch statement will be checked, assuming M, N, and O are enum
types with the same underlying basic kind. To satisfy exhaustiveness, all enum
members for each of the types M, N, and O must be listed in the switch
statement's cases.
func bar[T M | I](v T) {
switch v {
}
}
type I interface{ N | J }
type J interface{ O }