Skip to content
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

spec: switch with no value uses bool rather than untyped bool #6398

Closed
ianlancetaylor opened this issue Sep 16, 2013 · 16 comments
Closed

spec: switch with no value uses bool rather than untyped bool #6398

ianlancetaylor opened this issue Sep 16, 2013 · 16 comments
Labels
Documentation Issues describing a change to documentation. FrozenDueToAge
Milestone

Comments

@ianlancetaylor
Copy link
Member

package main

type B bool

func main() {
    var a B
    if a == true {
        println("1")
    }
    switch true {
    case a:
        println("2")
    }
    switch {
    case a:
        println("3")
    }
}


Currently this gets two errors at compile time:

foo.go:11: invalid case a in switch on true (mismatched types B and bool)
foo.go:15: invalid case a in switch (mismatched types B and bool)

The spec says "the cases contain expressions that are compared against the value of
the switch expression."  It's a little vague but it seems plausible that they
should be compared using ==.  In that case it's hard to see why an if statement and a
switch statement would act differently here.

Note that gccgo acts like cmd/gc here, so we could also change the spec.  But in this
case I think the spec is right and the compilers are wrong.

Too late for Go 1.2 but should be fixed for Go 1.3.
@rsc
Copy link
Contributor

rsc commented Sep 16, 2013

Comment 1:

I am not convinced this is a bug. Where do you draw the line?
http://play.golang.org/p/uymdQ7c1U8

@adg
Copy link
Contributor

adg commented Sep 18, 2013

Comment 2:

At the behavior of == ?

@adg
Copy link
Contributor

adg commented Sep 18, 2013

Comment 3:

To be less terse:
If the switch value is an untyped constant true (explicit or implicit) then it should
behave the same as "== true", IMO.

@rsc
Copy link
Contributor

rsc commented Sep 18, 2013

Comment 4:

Did you look at the playground example I posted? Why is true special? Is 0
also special?

@adg
Copy link
Contributor

adg commented Sep 18, 2013

Comment 5:

Ah, yes, well I'd extend it to any untyped constant.
It is very surprising to me that the comparisons in a switch are not the same as ==.
Is there a compelling reason not to do this?

@rsc
Copy link
Contributor

rsc commented Sep 18, 2013

Comment 6:

Yes, the compelling reason not to do this is that a switch is defined to
evaluate the switch expression just once, presumably store it somewhere,
and then use that stored result repeatedly for each == test. If you switch
f() it does not turn into == f() at each use. The storing it somewhere
implies a specific type.
I think it's pretty magical to make untyped constants not follow this rule.
Russ

@adg
Copy link
Contributor

adg commented Sep 18, 2013

Comment 7:

The spec says:
"In an expression switch, the switch expression is evaluated and the case expressions,
which need not be constants, are evaluated left-to-right and top-to-bottom; the first
one that equals the switch expression triggers execution of the statements of the
associated case; the other cases are skipped."
As for the evaluated expression, I don't see where the spec says that an expression must
have a type. In fact, as per the grammar "2 * 3" and "true || false" are both
expressions, but they are untyped.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 8:

Labels changed: added release-go1.3.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 9:

Labels changed: removed go1.3.

@rsc
Copy link
Contributor

rsc commented Dec 4, 2013

Comment 10:

Labels changed: added repo-main.

@griesemer
Copy link
Contributor

Comment 11:

This is related to issue #5769 which proposes that "only field selectors should
auto-dereference pointers to structs". If we accept 5769, this example would indeed
expose a bug in gc (and gccgo for that matter).

@rsc
Copy link
Contributor

rsc commented Apr 3, 2014

Comment 13:

I remain unconvinced that this is a bug in the compilers. Perhaps the spec needs to be
revised.
I don't see a connection to issue #5769; there are no pointers in this program. Perhaps
you meant to add comment #11 to some other issue, gri?

Labels changed: removed release-go1.3.

@griesemer
Copy link
Contributor

Comment 14:

I agree that comment #11 is misplaced and probably should have gone elsewhere. Will
delete.
I think one could follow the spec to the word (switches are equivalent to if-else-if
sequences) and then this would be a compiler bug. But such a direct interpretation would
not easily explain that a switch tag that is a function call is only executed once. So
perhaps we indeed do need to update the spec.

@rsc
Copy link
Contributor

rsc commented May 21, 2014

Comment 15:

Labels changed: added release-none.

@griesemer
Copy link
Contributor

Comment 16:

Labels changed: added documentation.

Owner changed to @griesemer.

@ianlancetaylor ianlancetaylor added accepted Documentation Issues describing a change to documentation. labels Sep 10, 2014
@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@gopherbot
Copy link
Contributor

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

@mikioh mikioh modified the milestones: Go1.5, Unplanned Jul 31, 2015
@golang golang locked and limited conversation to collaborators Aug 5, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation Issues describing a change to documentation. FrozenDueToAge
Projects
None yet
Development

No branches or pull requests

6 participants