go: cmd/compile: suppress typecheck errors in a type switch case with broken type
package p
func f(e interface{}) {
switch e := e.(type) {
case T:
e.M()
}
}
$ go tool compile x.go
x.go:5:7: undefined: T
x.go:6:4: e.M undefined (type interface {} is interface with no methods)
The first error message is accurate and helpful. We should suppress the second error message, which is confusing.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 19 (17 by maintainers)
Thanks for checking in. This fell off my radar. I am unlikely to look before early next week. If you haven’t heard from me by late next week, please do ping again.
Two related cases that might be worth looking into (not necessarily as part of CL 158617):
“case 42” in a type switch is currently treated as “case int” (aside from emitting an error). It might be better to treat the case as broken, like we do “case doesnotexist:”. For example:
The problem here is we’re not checking
ncase.List.First().Op == OTYPE
before settingnvar.Type = ncase.List.First().Type
.We should try to still typecheck broken case bodies, because there’s possibly still code that doesn’t depend on the type switch variable that we can produce meaningful errors about.
Theoretically this should be as simple as just setting
nvar.Type = nil
and continuing with typechecking, but I couldn’t immediately figure out how to prevent typecheckdef from giving false positive warnings about using.(type)
outside of a switch statement.No prob. Please abandon the old CL when you get a chance.
I think it’d be simpler to just suppress the second error and sufficiently informative.
Yes.
The compiler continues (for a while) past many errors, since it is often helpful to print out multiple errors instead of the first one. What is needed here is to either mark the body of the case as typechecked without actually typechecking it, or mark the original type of e with Broke() so no further errors involving e get reported. Neither is perfect. With the former, if there are multiple missing type cases they will all get errors reported; with the latter, unrelated typechecking errors in the body will get reported. But this isn’t mission critical, so probably do whatever is cleanest in the code. And don’t forget to add a test—see “errorcheck” style tests in GOROOT/test.