cmd/gc: comma-ok assignments produce untyped bool as 2nd result
LGTM=rsc
R=gri, rsc
CC=golang-codereviews
https://golang.org/cl/127950043
diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c
index 728defe..59231a0 100644
--- a/src/cmd/gc/order.c
+++ b/src/cmd/gc/order.c
@@ -593,7 +593,10 @@
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 92e9ad5..c295cf6 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -2965,7 +2965,7 @@
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 e50b917..7ae75e5 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -673,7 +673,7 @@
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 @@
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 @@
*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 0000000..e697945
--- /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 62b874c..febad64 100644
--- a/test/named1.go
+++ b/test/named1.go
@@ -41,21 +41,21 @@
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