This bug is shared between go/types and types2 and therefore between the compiler and gopls.

% cat x.go
package p

import "fmt"

func f() {
    x := 1
    for e := range x.Method() {
        switch m := e.(type) {
        case int:
            fmt.Printf("%d\n", m)
        }
    }
}
% go build x.go
# command-line-arguments
./x.go:3:8: "fmt" imported and not used   <<< WRONG
./x.go:7:19: x.Method undefined (type int has no field or method Method)
% gopls check x.go
Log: Loading packages...
Info: Finished loading packages.
Log: Running...
Info: completed
/tmp/x.go: found packages p (x.go) and main (y.go) in /tmp
/tmp/x.go:3:8-13: "fmt" imported and not used   <<< WRONG
/tmp/x.go:7:19-25: x.Method undefined (type int has no field or method Method)
%

The problem (I assume) is that the switch is operating on a value e of unknown type, so the cases are not type-checked at all. The use of fmt is not seen, leading to the incorrect imported and not used error.

I feel like we've had other bugs related to not checking inside switch cases in this situation before.

/cc @griesemer @rfindley

Comment From: gabyhelp

Similar Issues

  • https://github.com/golang/go/issues/2162
  • https://github.com/golang/go/issues/50493

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: rfindley

@findleyr

Comment From: gopherbot

Change https://go.dev/cl/592555 mentions this issue: go/types, types2: typecheck cases even if switch expression is invalid