diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c index 728defe7c3..59231a0f1c 100644 --- a/src/cmd/gc/order.c +++ b/src/cmd/gc/order.c @@ -593,7 +593,10 @@ orderstmt(Node *n, Order *order) orderexpr(&n->rlist->n->left, order); // arg to recv ch = n->rlist->n->left->type; tmp1 = ordertemp(ch->type, order, haspointers(ch->type)); - tmp2 = ordertemp(types[TBOOL], order, 0); + if(!isblank(n->list->next->n)) + tmp2 = ordertemp(n->list->next->n->type, order, 0); + else + tmp2 = ordertemp(types[TBOOL], order, 0); order->out = list(order->out, n); r = nod(OAS, n->list->n, tmp1); typecheck(&r, Etop); diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 92e9ad5215..c295cf6d21 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -2965,7 +2965,7 @@ typecheckas2(Node *n) if(l->defn == n) l->type = r->type; l = n->list->next->n; - if(l->type != T) + if(l->type != T && l->type->etype != TBOOL) checkassignto(types[TBOOL], l); if(l->defn == n && l->ntype == N) l->type = types[TBOOL]; diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index e50b917709..7ae75e5617 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -673,7 +673,7 @@ walkexpr(Node **np, NodeList **init) n1 = nod(OADDR, n->list->n, N); n1->etype = 1; // addr does not escape fn = chanfn("chanrecv2", 2, r->left->type); - r = mkcall1(fn, types[TBOOL], init, typename(r->left->type), r->left, n1); + r = mkcall1(fn, n->list->next->n->type, init, typename(r->left->type), r->left, n1); n = nod(OAS, n->list->next->n, r); typecheck(&n, Etop); goto ret; @@ -723,6 +723,12 @@ walkexpr(Node **np, NodeList **init) var->typecheck = 1; fn = mapfn(p, t); r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key); + + // mapaccess2* returns a typed bool, but due to spec changes, + // the boolean result of i.(T) is now untyped so we make it the + // same type as the variable on the lhs. + if(!isblank(n->list->next->n)) + r->type->type->down->type = n->list->next->n->type; n->rlist = list1(r); n->op = OAS2FUNC; n->list->n = var; @@ -770,6 +776,12 @@ walkexpr(Node **np, NodeList **init) *p = '\0'; fn = syslook(buf, 1); + + // runtime.assert(E|I)2TOK returns a typed bool, but due + // to spec changes, the boolean result of i.(T) is now untyped + // so we make it the same type as the variable on the lhs. + if(!isblank(n->list->next->n)) + fn->type->type->down->type->type = n->list->next->n->type; ll = list1(typename(r->type)); ll = list(ll, r->left); argtype(fn, r->left->type); diff --git a/test/fixedbugs/issue8475.go b/test/fixedbugs/issue8475.go new file mode 100644 index 0000000000..e69794534c --- /dev/null +++ b/test/fixedbugs/issue8475.go @@ -0,0 +1,25 @@ +// build + +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Issue 8745: comma-ok assignments should produce untyped bool as 2nd result. + +package main + +type mybool bool + +func main() { + var ok mybool + _ = ok + + var i interface{} + _, ok = i.(int) + + var m map[int]int + _, ok = m[0] + + var c chan int + _, ok = <-c +} diff --git a/test/named1.go b/test/named1.go index 62b874c5cb..febad64ece 100644 --- a/test/named1.go +++ b/test/named1.go @@ -41,21 +41,21 @@ func main() { asBool(1 != 2) // ok now asBool(i < j) // ok now - _, b = m[2] // ERROR "cannot .* bool.*type Bool" + _, b = m[2] // ok now var inter interface{} - _, b = inter.(Map) // ERROR "cannot .* bool.*type Bool" + _, b = inter.(Map) // ok now _ = b var minter interface { M() } - _, b = minter.(Map) // ERROR "cannot .* bool.*type Bool" + _, b = minter.(Map) // ok now _ = b _, bb := <-c asBool(bb) // ERROR "cannot use.*type bool.*as type Bool" - _, b = <-c // ERROR "cannot .* bool.*type Bool" + _, b = <-c // ok now _ = b asString(String(slice)) // ok