"func sys.mapiter1 (hiter *any) (key any)\n"
"func sys.mapiter2 (hiter *any) (key any, val any)\n"
"func sys.newchan (elemsize int, elemalg int, hint int) (hchan chan any)\n"
- "func sys.chanrecv1 (hchan chan any) (elem any)\n"
- "func sys.chanrecv2 (hchan chan any) (elem any, pres bool)\n"
- "func sys.chanrecv3 (hchan chan any, elem *any) (pres bool)\n"
- "func sys.chansend1 (hchan chan any, elem any)\n"
- "func sys.chansend2 (hchan chan any, elem any) (pres bool)\n"
- "func sys.closechan (hchan chan any)\n"
- "func sys.closedchan (hchan chan any) (? bool)\n"
+ "func sys.chanrecv1 (hchan <-chan any) (elem any)\n"
+ "func sys.chanrecv2 (hchan <-chan any) (elem any, pres bool)\n"
+ "func sys.chanrecv3 (hchan <-chan any, elem *any) (pres bool)\n"
+ "func sys.chansend1 (hchan chan<- any, elem any)\n"
+ "func sys.chansend2 (hchan chan<- any, elem any) (pres bool)\n"
+ "func sys.closechan (hchan any)\n"
+ "func sys.closedchan (hchan any) (? bool)\n"
"func sys.newselect (size int) (sel *uint8)\n"
- "func sys.selectsend (sel *uint8, hchan chan any, elem any) (selected bool)\n"
- "func sys.selectrecv (sel *uint8, hchan chan any, elem *any) (selected bool)\n"
+ "func sys.selectsend (sel *uint8, hchan chan<- any, elem any) (selected bool)\n"
+ "func sys.selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
"func sys.selectdefault (sel *uint8) (selected bool)\n"
"func sys.selectgo (sel *uint8)\n"
"func sys.newarray (nel int, cap int, width int) (ary []any)\n"
{
/* types of channel */
Cxxx,
- Cboth,
- Crecv,
- Csend,
+ Crecv = 1<<0,
+ Csend = 1<<1,
+ Cboth = Crecv | Csend,
};
enum
case Crecv:
return fmtprint(fp, "<-chan %T", t->type);
case Csend:
+ if(t->type != T && t->type->etype == TCHAN)
+ return fmtprint(fp, "chan<- (%T)", t->type);
return fmtprint(fp, "chan<- %T", t->type);
}
return fmtprint(fp, "chan %T", t->type);
if(t1->bound == t2->bound)
break;
return 0;
+
+ case TCHAN:
+ if(t1->chan == t2->chan)
+ break;
+ return 0;
}
return eqtype1(t1->type, t2->type, d+1, names);
}
func mapiter2(hiter *any) (key any, val any);
func newchan(elemsize int, elemalg int, hint int) (hchan chan any);
-func chanrecv1(hchan chan any) (elem any);
-func chanrecv2(hchan chan any) (elem any, pres bool);
-func chanrecv3(hchan chan any, elem *any) (pres bool);
-func chansend1(hchan chan any, elem any);
-func chansend2(hchan chan any, elem any) (pres bool);
-func closechan(hchan chan any);
-func closedchan(hchan chan any) bool;
+func chanrecv1(hchan <-chan any) (elem any);
+func chanrecv2(hchan <-chan any) (elem any, pres bool);
+func chanrecv3(hchan <-chan any, elem *any) (pres bool);
+func chansend1(hchan chan<- any, elem any);
+func chansend2(hchan chan<- any, elem any) (pres bool);
+func closechan(hchan any);
+func closedchan(hchan any) bool;
func newselect(size int) (sel *byte);
-func selectsend(sel *byte, hchan chan any, elem any) (selected bool);
-func selectrecv(sel *byte, hchan chan any, elem *any) (selected bool);
+func selectsend(sel *byte, hchan chan<- any, elem any) (selected bool);
+func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool);
func selectdefault(sel *byte) (selected bool);
func selectgo(sel *byte);
if(t == T)
return N;
+ if(!(t->chan & Csend)) {
+ yyerror("cannot send on %T", t);
+ return N;
+ }
+
convlit(c->right, t->type);
if(!ascompat(t->type, c->right->type)) {
badtype(c->op, t->type, c->right->type);
if(t == T)
return N;
+ if(!(t->chan & Crecv)) {
+ yyerror("cannot receive from %T", t);
+ return N;
+ }
+
// selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
on = syslook("selectrecv", 1);
argtype(on, t->type);
if(t == T)
return N;
+ if(!(t->chan & Crecv)) {
+ yyerror("cannot receive from %T", t);
+ return N;
+ }
+
walktype(c->left, Elv); // elem
convlit(c->left, t->type);
if(!ascompat(t->type, c->left->type)) {
if(dst == T || src == T)
return 0;
+ if(dst->etype == TCHAN && src->etype == TCHAN) {
+ if(!eqtype(dst->type, src->type))
+ return 0;
+ if(dst->chan & ~src->chan)
+ return 0;
+ return 1;
+ }
+
if(isslice(dst)
&& isptr[src->etype]
&& isfixedarray(src->type)
r = a;
on = syslook("closechan", 1);
- argtype(on, t->type); // any-1
+ argtype(on, t); // any-1
r = nod(OCALL, on, r);
walktype(r, top);
r = a;
on = syslook("closedchan", 1);
- argtype(on, t->type); // any-1
+ argtype(on, t); // any-1
r = nod(OCALL, on, r);
walktype(r, top);
if(t == T)
break;
+ if(!(t->chan & Crecv)) {
+ yyerror("cannot receive from %T", t);
+ break;
+ }
+
a = n->right->left; // chan
r = a;
if(t == T)
break;
+ if(!(t->chan & Crecv)) {
+ yyerror("cannot receive from %T", t);
+ break;
+ }
+
a = n->left; // chan
r = a;
t = fixchan(n->left->type);
if(t == T)
break;
+ if(!(t->chan & Csend)) {
+ yyerror("cannot send to %T", t);
+ break;
+ }
+
if(top != Etop)
goto send2;
// chansend1(hchan *chan any, elem any);
- t = fixchan(n->left->type);
- if(t == T)
- break;
-
a = n->right; // e
r = a;
a = n->left; // chan
send2:
// chansend2(hchan *chan any, val any) (pres bool);
- t = fixchan(n->left->type);
- if(t == T)
- break;
-
a = n->right; // e
r = a;
a = n->left; // chan
if(r != N && r->op == OEMPTY)
r = N;
-loop:
while(r != N) {
if(r == N)
break;