Skip to content

spec: clarify allowed implementation restrictions for switch statements #15896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
josharian opened this issue May 30, 2016 · 5 comments
Closed
Milestone

Comments

@josharian
Copy link
Contributor

The spec (version January 5, 2016) says in the Expression switches section:

Implementation restriction: A compiler may disallow multiple case expressions evaluating to the same constant. For instance, the current compilers disallow duplicate integer, floating point, or string constants in case expressions.

Three questions about this:

  • cmd/compile also disallows duplicate concrete type cases in type switches:
func f(e interface{}) {
    switch e.(type) {
    case int:
    case int:
    }
}

This generates the error duplicate case int in type switch. But this implementation restriction is not currently allowed by the spec. Should it be? Does it matter?

  • cmd/compile also disallows unreachable type cases in type switches:
func f(e error) {
    switch e.(type) {
    case int:
    }
}

This generates the error impossible type switch case: e (type error) cannot have dynamic type int (missing Error method). But this implementation restriction is not currently allowed by the spec. Should it be? Does it matter?

type A [1]int

func f(x A) {
    switch x {
    case A([1]int{1}):
    case A([1]int{1}):
    }
}

Currently, this fails to compile, but it is a bug (#15895). One could argue that such composite literals "evaluate to the same constant", but it's not a constant in the sense usually used in the spec.

@josharian josharian added this to the Go1.8 milestone May 30, 2016
@josharian josharian changed the title spec: clarify allowed implementation restrictions for switch expressions spec: clarify allowed implementation restrictions for switch statements May 30, 2016
@josharian
Copy link
Contributor Author

I guess the last one would break backwards compatibility. I have another implementation approach for such dead cases (including duplicate nil cases in type switches). We might want to add a vet check for detectably duplicate cases, if the compiler isn't going to reject them, since they're almost certainly bugs. I'll file a separate issue for that.

@griesemer
Copy link
Contributor

For type switches, the spec says (x is from x.(type)):

Cases then match actual types T against the dynamic type of the expression x. As with type assertions, x must be of interface type, and each non-interface type T listed in a case must implement the type of x.

That is, the spec already disallows using int as T if x is of type error per the example above (and int doesn't implement error).

Furthermore, given that the semantics of the type switch is essentially an if-else-if sequence, a duplicate entry is never reached. But all, gc, gccgo, and go/types complain about duplicate entries, so we should probably document that by disallowing them in the spec.

Finally, I've tried to disallow certain duplicate entries for expression switches before, several years back, and it met with some resistance. We most likely cannot change something here if the compiler allowed it until now otherwise we are violating the Go 1.0 guarantee.

@griesemer
Copy link
Contributor

Since the compiler's don't permit duplicate types in type switches, we should probably disallow duplicate nils in type switches as well, per discussion with @randall77 and @ianlancetaylor . The nil case in type switches was added later, and it's arguably an oversight (bug) that compilers permitted them. go/types doesn't permit it.

@josharian
Copy link
Contributor Author

Thanks, Robert. I filed #15906 for a possible vet check. So it sounds like the only outstanding todo here is to document that compilers may disallow duplicate entries in type switches.

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/23584 mentions this issue.

@golang golang locked and limited conversation to collaborators May 31, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants