cmd/gc: comma-ok assignments produce untyped bool as 2nd result

LGTM=rsc
R=gri, rsc
CC=golang-codereviews
https://golang.org/cl/127950043
This commit is contained in:
Chris Manghane 2014-08-11 16:11:55 -07:00
parent b5674a2b72
commit 897f7a31fa
5 changed files with 47 additions and 7 deletions

View file

@ -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);

View file

@ -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];

View file

@ -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);

View file

@ -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
}

View file

@ -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