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