mirror of https://github.com/golang/go.git
gc: remove func, map compare
R=ken, ken CC=golang-dev https://golang.org/cl/5373079
This commit is contained in:
parent
efb74460c3
commit
5bb54b8e9c
|
|
@ -491,12 +491,12 @@ typeinit(void)
|
||||||
okforeq[TPTR64] = 1;
|
okforeq[TPTR64] = 1;
|
||||||
okforeq[TUNSAFEPTR] = 1;
|
okforeq[TUNSAFEPTR] = 1;
|
||||||
okforeq[TINTER] = 1;
|
okforeq[TINTER] = 1;
|
||||||
okforeq[TMAP] = 1;
|
|
||||||
okforeq[TCHAN] = 1;
|
okforeq[TCHAN] = 1;
|
||||||
okforeq[TFUNC] = 1;
|
|
||||||
okforeq[TSTRING] = 1;
|
okforeq[TSTRING] = 1;
|
||||||
okforeq[TBOOL] = 1;
|
okforeq[TBOOL] = 1;
|
||||||
okforeq[TARRAY] = 1; // refined in typecheck
|
okforeq[TMAP] = 1; // nil only; refined in typecheck
|
||||||
|
okforeq[TFUNC] = 1; // nil only; refined in typecheck
|
||||||
|
okforeq[TARRAY] = 1; // nil slice only; refined in typecheck
|
||||||
|
|
||||||
okforcmp[TSTRING] = 1;
|
okforcmp[TSTRING] = 1;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -547,6 +547,8 @@ maptype(Type *key, Type *val)
|
||||||
switch(key->etype) {
|
switch(key->etype) {
|
||||||
case TARRAY:
|
case TARRAY:
|
||||||
case TSTRUCT:
|
case TSTRUCT:
|
||||||
|
case TMAP:
|
||||||
|
case TFUNC:
|
||||||
yyerror("invalid map key type %T", key);
|
yyerror("invalid map key type %T", key);
|
||||||
break;
|
break;
|
||||||
case TFORW:
|
case TFORW:
|
||||||
|
|
|
||||||
|
|
@ -811,6 +811,7 @@ void
|
||||||
typecheckswitch(Node *n)
|
typecheckswitch(Node *n)
|
||||||
{
|
{
|
||||||
int top, lno, ptr;
|
int top, lno, ptr;
|
||||||
|
char *nilonly;
|
||||||
Type *t, *missing, *have;
|
Type *t, *missing, *have;
|
||||||
NodeList *l, *ll;
|
NodeList *l, *ll;
|
||||||
Node *ncase, *nvar;
|
Node *ncase, *nvar;
|
||||||
|
|
@ -818,6 +819,7 @@ typecheckswitch(Node *n)
|
||||||
|
|
||||||
lno = lineno;
|
lno = lineno;
|
||||||
typechecklist(n->ninit, Etop);
|
typechecklist(n->ninit, Etop);
|
||||||
|
nilonly = nil;
|
||||||
|
|
||||||
if(n->ntest != N && n->ntest->op == OTYPESW) {
|
if(n->ntest != N && n->ntest->op == OTYPESW) {
|
||||||
// type switch
|
// type switch
|
||||||
|
|
@ -835,6 +837,16 @@ typecheckswitch(Node *n)
|
||||||
t = n->ntest->type;
|
t = n->ntest->type;
|
||||||
} else
|
} else
|
||||||
t = types[TBOOL];
|
t = types[TBOOL];
|
||||||
|
if(t) {
|
||||||
|
if(!okforeq[t->etype] || isfixedarray(t))
|
||||||
|
yyerror("cannot switch on %lN", n->ntest);
|
||||||
|
else if(t->etype == TARRAY)
|
||||||
|
nilonly = "slice";
|
||||||
|
else if(t->etype == TFUNC)
|
||||||
|
nilonly = "func";
|
||||||
|
else if(t->etype == TMAP)
|
||||||
|
nilonly = "map";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
n->type = t;
|
n->type = t;
|
||||||
|
|
||||||
|
|
@ -865,6 +877,8 @@ typecheckswitch(Node *n)
|
||||||
yyerror("invalid case %N in switch on %N (mismatched types %T and %T)", ll->n, n->ntest, ll->n->type, t);
|
yyerror("invalid case %N in switch on %N (mismatched types %T and %T)", ll->n, n->ntest, ll->n->type, t);
|
||||||
else
|
else
|
||||||
yyerror("invalid case %N in switch (mismatched types %T and bool)", ll->n, n->ntest, ll->n->type, t);
|
yyerror("invalid case %N in switch (mismatched types %T and bool)", ll->n, n->ntest, ll->n->type, t);
|
||||||
|
} else if(nilonly && !isconst(ll->n, CTNIL)) {
|
||||||
|
yyerror("invalid case %N in switch (can only compare %s %N to nil)", ll->n, nilonly, n->ntest);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Etype: // type switch
|
case Etype: // type switch
|
||||||
|
|
|
||||||
|
|
@ -445,8 +445,8 @@ reswitch:
|
||||||
yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(et));
|
yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(et));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
// okfor allows any array == array;
|
// okfor allows any array == array, map == map, func == func.
|
||||||
// restrict to slice == nil and nil == slice.
|
// restrict to slice/map/func == nil and nil == slice/map/func.
|
||||||
if(l->type->etype == TARRAY && !isslice(l->type))
|
if(l->type->etype == TARRAY && !isslice(l->type))
|
||||||
goto notokfor;
|
goto notokfor;
|
||||||
if(r->type->etype == TARRAY && !isslice(r->type))
|
if(r->type->etype == TARRAY && !isslice(r->type))
|
||||||
|
|
@ -455,6 +455,15 @@ reswitch:
|
||||||
yyerror("invalid operation: %N (slice can only be compared to nil)", n);
|
yyerror("invalid operation: %N (slice can only be compared to nil)", n);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
if(l->type->etype == TMAP && !isnil(l) && !isnil(r)) {
|
||||||
|
yyerror("invalid operation: %N (map can only be compared to nil)", n);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if(l->type->etype == TFUNC && !isnil(l) && !isnil(r)) {
|
||||||
|
yyerror("invalid operation: %N (func can only be compared to nil)", n);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
t = l->type;
|
t = l->type;
|
||||||
if(iscmp[n->op]) {
|
if(iscmp[n->op]) {
|
||||||
evconst(n);
|
evconst(n);
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,6 @@ func h() {
|
||||||
|
|
||||||
func newfunc() func(int) int { return func(x int) int { return x } }
|
func newfunc() func(int) int { return func(x int) int { return x } }
|
||||||
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
go f()
|
go f()
|
||||||
check([]int{1, 4, 5, 4})
|
check([]int{1, 4, 5, 4})
|
||||||
|
|
@ -90,10 +89,6 @@ func main() {
|
||||||
check([]int{100, 200, 101, 201, 500, 101, 201, 500})
|
check([]int{100, 200, 101, 201, 500, 101, 201, 500})
|
||||||
|
|
||||||
x, y := newfunc(), newfunc()
|
x, y := newfunc(), newfunc()
|
||||||
if x == y {
|
|
||||||
println("newfunc returned same func")
|
|
||||||
panic("fail")
|
|
||||||
}
|
|
||||||
if x(1) != 1 || y(2) != 2 {
|
if x(1) != 1 || y(2) != 2 {
|
||||||
println("newfunc returned broken funcs")
|
println("newfunc returned broken funcs")
|
||||||
panic("fail")
|
panic("fail")
|
||||||
|
|
|
||||||
28
test/cmp6.go
28
test/cmp6.go
|
|
@ -11,7 +11,7 @@ func use(bool) {}
|
||||||
type T1 *int
|
type T1 *int
|
||||||
type T2 *int
|
type T2 *int
|
||||||
|
|
||||||
type T3 struct {}
|
type T3 struct{}
|
||||||
|
|
||||||
var t3 T3
|
var t3 T3
|
||||||
|
|
||||||
|
|
@ -21,12 +21,12 @@ func main() {
|
||||||
// so chan int can be compared against
|
// so chan int can be compared against
|
||||||
// directional channels but channel of different
|
// directional channels but channel of different
|
||||||
// direction cannot be compared against each other.
|
// direction cannot be compared against each other.
|
||||||
var c1 chan <-int
|
var c1 chan<- int
|
||||||
var c2 <-chan int
|
var c2 <-chan int
|
||||||
var c3 chan int
|
var c3 chan int
|
||||||
|
|
||||||
use(c1 == c2) // ERROR "invalid operation|incompatible"
|
use(c1 == c2) // ERROR "invalid operation|incompatible"
|
||||||
use(c2 == c1) // ERROR "invalid operation|incompatible"
|
use(c2 == c1) // ERROR "invalid operation|incompatible"
|
||||||
use(c1 == c3)
|
use(c1 == c3)
|
||||||
use(c2 == c2)
|
use(c2 == c2)
|
||||||
use(c3 == c1)
|
use(c3 == c1)
|
||||||
|
|
@ -36,14 +36,22 @@ func main() {
|
||||||
var p1 T1
|
var p1 T1
|
||||||
var p2 T2
|
var p2 T2
|
||||||
var p3 *int
|
var p3 *int
|
||||||
|
|
||||||
use(p1 == p2) // ERROR "invalid operation|incompatible"
|
use(p1 == p2) // ERROR "invalid operation|incompatible"
|
||||||
use(p2 == p1) // ERROR "invalid operation|incompatible"
|
use(p2 == p1) // ERROR "invalid operation|incompatible"
|
||||||
use(p1 == p3)
|
use(p1 == p3)
|
||||||
use(p2 == p2)
|
use(p2 == p2)
|
||||||
use(p3 == p1)
|
use(p3 == p1)
|
||||||
use(p3 == p2)
|
use(p3 == p2)
|
||||||
|
|
||||||
// Comparison of structs should have a good message
|
// Comparison of structs should have a good message
|
||||||
use(t3 == t3) // ERROR "struct|expected"
|
use(t3 == t3) // ERROR "struct|expected"
|
||||||
|
|
||||||
|
// Slices, functions, and maps too.
|
||||||
|
var x []int
|
||||||
|
var f func()
|
||||||
|
var m map[int]int
|
||||||
|
use(x == x) // ERROR "slice can only be compared to nil"
|
||||||
|
use(f == f) // ERROR "func can only be compared to nil"
|
||||||
|
use(m == m) // ERROR "map can only be compared to nil"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,20 +45,6 @@ func main() {
|
||||||
mp[p] = 42
|
mp[p] = 42
|
||||||
mp[&T{7}] = 42
|
mp[&T{7}] = 42
|
||||||
|
|
||||||
type F func(x int)
|
|
||||||
f := func(x int) {}
|
|
||||||
mf := make(map[F]int)
|
|
||||||
mf[nil] = 42
|
|
||||||
mf[f] = 42
|
|
||||||
mf[func(x int) {}] = 42
|
|
||||||
|
|
||||||
type M map[int]int
|
|
||||||
m := make(M)
|
|
||||||
mm := make(map[M]int)
|
|
||||||
mm[nil] = 42
|
|
||||||
mm[m] = 42
|
|
||||||
mm[make(M)] = 42
|
|
||||||
|
|
||||||
type C chan int
|
type C chan int
|
||||||
c := make(C)
|
c := make(C)
|
||||||
mc := make(map[C]int)
|
mc := make(map[C]int)
|
||||||
|
|
|
||||||
30
test/map1.go
30
test/map1.go
|
|
@ -12,16 +12,16 @@ type v bool
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// valid
|
// valid
|
||||||
_ map[int8]v
|
_ map[int8]v
|
||||||
_ map[uint8]v
|
_ map[uint8]v
|
||||||
_ map[int16]v
|
_ map[int16]v
|
||||||
_ map[uint16]v
|
_ map[uint16]v
|
||||||
_ map[int32]v
|
_ map[int32]v
|
||||||
_ map[uint32]v
|
_ map[uint32]v
|
||||||
_ map[int64]v
|
_ map[int64]v
|
||||||
_ map[uint64]v
|
_ map[uint64]v
|
||||||
_ map[int]v
|
_ map[int]v
|
||||||
_ map[uint]v
|
_ map[uint]v
|
||||||
_ map[uintptr]v
|
_ map[uintptr]v
|
||||||
_ map[float32]v
|
_ map[float32]v
|
||||||
_ map[float64]v
|
_ map[float64]v
|
||||||
|
|
@ -30,12 +30,12 @@ var (
|
||||||
_ map[bool]v
|
_ map[bool]v
|
||||||
_ map[string]v
|
_ map[string]v
|
||||||
_ map[chan int]v
|
_ map[chan int]v
|
||||||
_ map[func()]v
|
|
||||||
_ map[*int]v
|
_ map[*int]v
|
||||||
_ map[map[int]int]v
|
|
||||||
|
|
||||||
// invalid
|
// invalid
|
||||||
_ map[struct{}]v // ERROR "invalid map key"
|
_ map[struct{}]v // ERROR "invalid map key"
|
||||||
_ map[[]int]v // ERROR "invalid map key"
|
_ map[[]int]v // ERROR "invalid map key"
|
||||||
_ map[[10]int]v // ERROR "invalid map key"
|
_ map[[10]int]v // ERROR "invalid map key"
|
||||||
|
_ map[func()]v // ERROR "invalid map key"
|
||||||
|
_ map[map[int]int]v // ERROR "invalid map key"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
281
test/switch.go
281
test/switch.go
|
|
@ -19,48 +19,75 @@ func main() {
|
||||||
hello := "hello"
|
hello := "hello"
|
||||||
|
|
||||||
switch true {
|
switch true {
|
||||||
case i5 < 5: assert(false, "<")
|
case i5 < 5:
|
||||||
case i5 == 5: assert(true, "!")
|
assert(false, "<")
|
||||||
case i5 > 5: assert(false, ">")
|
case i5 == 5:
|
||||||
|
assert(true, "!")
|
||||||
|
case i5 > 5:
|
||||||
|
assert(false, ">")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case i5 < 5: assert(false, "<")
|
case i5 < 5:
|
||||||
case i5 == 5: assert(true, "!")
|
assert(false, "<")
|
||||||
case i5 > 5: assert(false, ">")
|
case i5 == 5:
|
||||||
|
assert(true, "!")
|
||||||
|
case i5 > 5:
|
||||||
|
assert(false, ">")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch x := 5; true {
|
switch x := 5; true {
|
||||||
case i5 < x: assert(false, "<")
|
case i5 < x:
|
||||||
case i5 == x: assert(true, "!")
|
assert(false, "<")
|
||||||
case i5 > x: assert(false, ">")
|
case i5 == x:
|
||||||
|
assert(true, "!")
|
||||||
|
case i5 > x:
|
||||||
|
assert(false, ">")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch x := 5; true {
|
switch x := 5; true {
|
||||||
case i5 < x: assert(false, "<")
|
case i5 < x:
|
||||||
case i5 == x: assert(true, "!")
|
assert(false, "<")
|
||||||
case i5 > x: assert(false, ">")
|
case i5 == x:
|
||||||
|
assert(true, "!")
|
||||||
|
case i5 > x:
|
||||||
|
assert(false, ">")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch i5 {
|
switch i5 {
|
||||||
case 0: assert(false, "0")
|
case 0:
|
||||||
case 1: assert(false, "1")
|
assert(false, "0")
|
||||||
case 2: assert(false, "2")
|
case 1:
|
||||||
case 3: assert(false, "3")
|
assert(false, "1")
|
||||||
case 4: assert(false, "4")
|
case 2:
|
||||||
case 5: assert(true, "5")
|
assert(false, "2")
|
||||||
case 6: assert(false, "6")
|
case 3:
|
||||||
case 7: assert(false, "7")
|
assert(false, "3")
|
||||||
case 8: assert(false, "8")
|
case 4:
|
||||||
case 9: assert(false, "9")
|
assert(false, "4")
|
||||||
default: assert(false, "default")
|
case 5:
|
||||||
|
assert(true, "5")
|
||||||
|
case 6:
|
||||||
|
assert(false, "6")
|
||||||
|
case 7:
|
||||||
|
assert(false, "7")
|
||||||
|
case 8:
|
||||||
|
assert(false, "8")
|
||||||
|
case 9:
|
||||||
|
assert(false, "9")
|
||||||
|
default:
|
||||||
|
assert(false, "default")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch i5 {
|
switch i5 {
|
||||||
case 0,1,2,3,4: assert(false, "4")
|
case 0, 1, 2, 3, 4:
|
||||||
case 5: assert(true, "5")
|
assert(false, "4")
|
||||||
case 6,7,8,9: assert(false, "9")
|
case 5:
|
||||||
default: assert(false, "default")
|
assert(true, "5")
|
||||||
|
case 6, 7, 8, 9:
|
||||||
|
assert(false, "9")
|
||||||
|
default:
|
||||||
|
assert(false, "default")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch i5 {
|
switch i5 {
|
||||||
|
|
@ -68,72 +95,188 @@ func main() {
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
case 4: assert(false, "4")
|
case 4:
|
||||||
case 5: assert(true, "5")
|
assert(false, "4")
|
||||||
|
case 5:
|
||||||
|
assert(true, "5")
|
||||||
case 6:
|
case 6:
|
||||||
case 7:
|
case 7:
|
||||||
case 8:
|
case 8:
|
||||||
case 9:
|
case 9:
|
||||||
default: assert(i5 == 5, "good")
|
default:
|
||||||
|
assert(i5 == 5, "good")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch i5 {
|
switch i5 {
|
||||||
case 0: dummy := 0; _ = dummy; fallthrough
|
case 0:
|
||||||
case 1: dummy := 0; _ = dummy; fallthrough
|
dummy := 0
|
||||||
case 2: dummy := 0; _ = dummy; fallthrough
|
_ = dummy
|
||||||
case 3: dummy := 0; _ = dummy; fallthrough
|
fallthrough
|
||||||
case 4: dummy := 0; _ = dummy; assert(false, "4")
|
case 1:
|
||||||
case 5: dummy := 0; _ = dummy; fallthrough
|
dummy := 0
|
||||||
case 6: dummy := 0; _ = dummy; fallthrough
|
_ = dummy
|
||||||
case 7: dummy := 0; _ = dummy; fallthrough
|
fallthrough
|
||||||
case 8: dummy := 0; _ = dummy; fallthrough
|
case 2:
|
||||||
case 9: dummy := 0; _ = dummy; fallthrough
|
dummy := 0
|
||||||
default: dummy := 0; _ = dummy; assert(i5 == 5, "good")
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 3:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 4:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
assert(false, "4")
|
||||||
|
case 5:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 6:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 7:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 8:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 9:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
assert(i5 == 5, "good")
|
||||||
}
|
}
|
||||||
|
|
||||||
fired := false
|
fired := false
|
||||||
switch i5 {
|
switch i5 {
|
||||||
case 0: dummy := 0; _ = dummy; fallthrough; // tests scoping of cases
|
case 0:
|
||||||
case 1: dummy := 0; _ = dummy; fallthrough
|
dummy := 0
|
||||||
case 2: dummy := 0; _ = dummy; fallthrough
|
_ = dummy
|
||||||
case 3: dummy := 0; _ = dummy; fallthrough
|
fallthrough // tests scoping of cases
|
||||||
case 4: dummy := 0; _ = dummy; assert(false, "4")
|
case 1:
|
||||||
case 5: dummy := 0; _ = dummy; fallthrough
|
dummy := 0
|
||||||
case 6: dummy := 0; _ = dummy; fallthrough
|
_ = dummy
|
||||||
case 7: dummy := 0; _ = dummy; fallthrough
|
fallthrough
|
||||||
case 8: dummy := 0; _ = dummy; fallthrough
|
case 2:
|
||||||
case 9: dummy := 0; _ = dummy; fallthrough
|
dummy := 0
|
||||||
default: dummy := 0; _ = dummy; fired = !fired; assert(i5 == 5, "good")
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 3:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 4:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
assert(false, "4")
|
||||||
|
case 5:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 6:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 7:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 8:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
case 9:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
dummy := 0
|
||||||
|
_ = dummy
|
||||||
|
fired = !fired
|
||||||
|
assert(i5 == 5, "good")
|
||||||
}
|
}
|
||||||
assert(fired, "fired")
|
assert(fired, "fired")
|
||||||
|
|
||||||
count := 0
|
count := 0
|
||||||
switch i5 {
|
switch i5 {
|
||||||
case 0: count = count + 1; fallthrough
|
case 0:
|
||||||
case 1: count = count + 1; fallthrough
|
count = count + 1
|
||||||
case 2: count = count + 1; fallthrough
|
fallthrough
|
||||||
case 3: count = count + 1; fallthrough
|
case 1:
|
||||||
case 4: count = count + 1; assert(false, "4")
|
count = count + 1
|
||||||
case 5: count = count + 1; fallthrough
|
fallthrough
|
||||||
case 6: count = count + 1; fallthrough
|
case 2:
|
||||||
case 7: count = count + 1; fallthrough
|
count = count + 1
|
||||||
case 8: count = count + 1; fallthrough
|
fallthrough
|
||||||
case 9: count = count + 1; fallthrough
|
case 3:
|
||||||
default: assert(i5 == count, "good")
|
count = count + 1
|
||||||
|
fallthrough
|
||||||
|
case 4:
|
||||||
|
count = count + 1
|
||||||
|
assert(false, "4")
|
||||||
|
case 5:
|
||||||
|
count = count + 1
|
||||||
|
fallthrough
|
||||||
|
case 6:
|
||||||
|
count = count + 1
|
||||||
|
fallthrough
|
||||||
|
case 7:
|
||||||
|
count = count + 1
|
||||||
|
fallthrough
|
||||||
|
case 8:
|
||||||
|
count = count + 1
|
||||||
|
fallthrough
|
||||||
|
case 9:
|
||||||
|
count = count + 1
|
||||||
|
fallthrough
|
||||||
|
default:
|
||||||
|
assert(i5 == count, "good")
|
||||||
}
|
}
|
||||||
assert(fired, "fired")
|
assert(fired, "fired")
|
||||||
|
|
||||||
switch hello {
|
switch hello {
|
||||||
case "wowie": assert(false, "wowie")
|
case "wowie":
|
||||||
case "hello": assert(true, "hello")
|
assert(false, "wowie")
|
||||||
case "jumpn": assert(false, "jumpn")
|
case "hello":
|
||||||
default: assert(false, "default")
|
assert(true, "hello")
|
||||||
|
case "jumpn":
|
||||||
|
assert(false, "jumpn")
|
||||||
|
default:
|
||||||
|
assert(false, "default")
|
||||||
}
|
}
|
||||||
|
|
||||||
fired = false
|
fired = false
|
||||||
switch i := i5 + 2; i {
|
switch i := i5 + 2; i {
|
||||||
case i7: fired = true
|
case i7:
|
||||||
default: assert(false, "fail")
|
fired = true
|
||||||
|
default:
|
||||||
|
assert(false, "fail")
|
||||||
}
|
}
|
||||||
assert(fired, "var")
|
assert(fired, "var")
|
||||||
|
|
||||||
|
// switch on nil-only comparison types
|
||||||
|
switch f := func() {}; f {
|
||||||
|
case nil:
|
||||||
|
assert(false, "f should not be nil")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
switch m := make(map[int]int); m {
|
||||||
|
case nil:
|
||||||
|
assert(false, "m should not be nil")
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
switch a := make([]int, 1); a {
|
||||||
|
case nil:
|
||||||
|
assert(false, "m should not be nil")
|
||||||
|
default:
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,8 @@
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
||||||
type I interface {
|
type I interface {
|
||||||
M()
|
M()
|
||||||
}
|
}
|
||||||
|
|
||||||
func bad() {
|
func bad() {
|
||||||
|
|
@ -16,11 +15,32 @@ func bad() {
|
||||||
var s string
|
var s string
|
||||||
|
|
||||||
switch i {
|
switch i {
|
||||||
case s: // ERROR "mismatched types string and I"
|
case s: // ERROR "mismatched types string and I"
|
||||||
}
|
}
|
||||||
|
|
||||||
switch s {
|
switch s {
|
||||||
case i: // ERROR "mismatched types I and string"
|
case i: // ERROR "mismatched types I and string"
|
||||||
|
}
|
||||||
|
|
||||||
|
var m, m1 map[int]int
|
||||||
|
switch m {
|
||||||
|
case nil:
|
||||||
|
case m1: // ERROR "can only compare map m to nil"
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
var a, a1 []int
|
||||||
|
switch a {
|
||||||
|
case nil:
|
||||||
|
case a1: // ERROR "can only compare slice a to nil"
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
var f, f1 func()
|
||||||
|
switch f {
|
||||||
|
case nil:
|
||||||
|
case f1: // ERROR "can only compare func f to nil"
|
||||||
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,9 +82,9 @@ func main() {
|
||||||
case []int:
|
case []int:
|
||||||
assert(x[3] == 3 && i == Array, "array")
|
assert(x[3] == 3 && i == Array, "array")
|
||||||
case map[string]int:
|
case map[string]int:
|
||||||
assert(x == m && i == Map, "map")
|
assert(x != nil && i == Map, "map")
|
||||||
case func(i int) interface{}:
|
case func(i int) interface{}:
|
||||||
assert(x == f && i == Func, "fun")
|
assert(x != nil && i == Func, "fun")
|
||||||
default:
|
default:
|
||||||
assert(false, "unknown")
|
assert(false, "unknown")
|
||||||
}
|
}
|
||||||
|
|
@ -111,5 +111,4 @@ func main() {
|
||||||
default:
|
default:
|
||||||
assert(false, "switch 4 unknown")
|
assert(false, "switch 4 unknown")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue