]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: give ChanDir a type
authorBrad Fitzpatrick <bradfitz@golang.org>
Sun, 3 Apr 2016 22:58:10 +0000 (22:58 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Sun, 3 Apr 2016 23:35:40 +0000 (23:35 +0000)
Change-Id: I03621db79637b04982e1f0e7b4268c4ed2db6d22
Reviewed-on: https://go-review.googlesource.com/21484
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/parser.go
src/cmd/compile/internal/gc/range.go
src/cmd/compile/internal/gc/syntax.go
src/cmd/compile/internal/gc/type.go
src/cmd/compile/internal/gc/typecheck.go

index 0a51ab037fe6ab22bdcf80b551fd765a378c5871..4bf6f1d286a607e14f99effd85ca13fdbfcca434 100644 (file)
@@ -316,7 +316,7 @@ func (p *importer) typ() *Type {
 
        case chanTag:
                t = p.newtyp(TCHAN)
-               t.Chan = uint8(p.int())
+               t.Chan = ChanDir(p.int())
                t.Type = p.typ()
 
        default:
index 94805594c7dd093533af9ec5c900c17e2d03220d..5eb99489bdfae0804995b5bc2e632987cd4fdae6 100644 (file)
@@ -1154,7 +1154,7 @@ func exprfmt(n *Node, prec int) string {
                return fmt.Sprintf("map[%v]%v", n.Left, n.Right)
 
        case OTCHAN:
-               switch n.Etype {
+               switch ChanDir(n.Etype) {
                case Crecv:
                        return fmt.Sprintf("<-chan %v", n.Left)
 
@@ -1162,7 +1162,7 @@ func exprfmt(n *Node, prec int) string {
                        return fmt.Sprintf("chan<- %v", n.Left)
 
                default:
-                       if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && n.Left.Etype == Crecv {
+                       if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && ChanDir(n.Left.Etype) == Crecv {
                                return fmt.Sprintf("chan (%v)", n.Left)
                        } else {
                                return fmt.Sprintf("chan %v", n.Left)
index 117836d2cd290a89d8ed7ead030b24c1eaffd114..fdea1f2fbacca209cf7ef4502405229d4a61e70a 100644 (file)
@@ -128,12 +128,18 @@ const (
        CTNIL
 )
 
+// ChanDir is whether a channel can send, receive, or both.
+type ChanDir uint8
+
+func (c ChanDir) CanRecv() bool { return c&Crecv != 0 }
+func (c ChanDir) CanSend() bool { return c&Csend != 0 }
+
 const (
        // types of channel
        // must match ../../../../reflect/type.go:/ChanDir
-       Crecv = 1 << 0
-       Csend = 1 << 1
-       Cboth = Crecv | Csend
+       Crecv ChanDir = 1 << 0
+       Csend ChanDir = 1 << 1
+       Cboth ChanDir = Crecv | Csend
 )
 
 // The Class of a variable/function describes the "storage class"
index b71cf8fef424668693666c6dd4148c6179cc6a2e..4649c4593b56caea72a0fb0028816c92f1b73186 100644 (file)
@@ -1187,17 +1187,17 @@ func (p *parser) uexpr() *Node {
 
                if x.Op == OTCHAN {
                        // x is a channel type => re-associate <-
-                       dir := EType(Csend)
+                       dir := Csend
                        t := x
                        for ; t.Op == OTCHAN && dir == Csend; t = t.Left {
-                               dir = t.Etype
+                               dir = ChanDir(t.Etype)
                                if dir == Crecv {
                                        // t is type <-chan E but <-<-chan E is not permitted
                                        // (report same error as for "type _ <-<-chan E")
                                        p.syntax_error("unexpected <-, expecting chan")
                                        // already progressed, no need to advance
                                }
-                               t.Etype = Crecv
+                               t.Etype = EType(Crecv)
                        }
                        if dir == Csend {
                                // channel dir is <- but channel element E is not a channel
@@ -1697,7 +1697,7 @@ func (p *parser) try_ntype() *Node {
                p.next()
                p.want(LCHAN)
                t := Nod(OTCHAN, p.chan_elem(), nil)
-               t.Etype = Crecv
+               t.Etype = EType(Crecv)
                return t
 
        case LFUNC:
@@ -1726,9 +1726,9 @@ func (p *parser) try_ntype() *Node {
                // LCHAN non_recvchantype
                // LCHAN LCOMM ntype
                p.next()
-               var dir EType = Cboth
+               var dir = EType(Cboth)
                if p.got(LCOMM) {
-                       dir = Csend
+                       dir = EType(Csend)
                }
                t := Nod(OTCHAN, p.chan_elem(), nil)
                t.Etype = dir
index 6a28c3ceb5e582a050c2b960238694eaa448948c..6adf8e0d6dc93572e4209edd127acbe26ea402e2 100644 (file)
@@ -58,7 +58,7 @@ func typecheckrange(n *Node) {
                t2 = t.Val()
 
        case TCHAN:
-               if t.ChanDir()&Crecv == 0 {
+               if !t.ChanDir().CanRecv() {
                        Yyerror("invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
                        goto out
                }
index b23b46608866dba4417664146c7d563b0df56e4f..2f3b98a8ef84be40d9375ccd07f5946905fffe90 100644 (file)
@@ -52,7 +52,7 @@ type Node struct {
        Op        Op
        Ullman    uint8 // sethi/ullman number
        Addable   bool  // addressable
-       Etype     EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg
+       Etype     EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN
        Bounded   bool  // bounds check unnecessary
        Class     Class // PPARAM, PAUTO, PEXTERN, etc
        Embedded  uint8 // ODCLFIELD embedded type
index d207a046d74a28c4c9a497e8ed0ab8919f6ce351..b89c5dbf22f0f20de1686739b3908ab2cdb22f8d 100644 (file)
@@ -110,7 +110,7 @@ var (
 type Type struct {
        Etype       EType
        Noalg       bool
-       Chan        uint8
+       Chan        ChanDir
        Trecur      uint8 // to detect loops
        Printed     bool
        Funarg      bool // on TSTRUCT and TFIELD
@@ -266,7 +266,7 @@ func typDDDArray(elem *Type) *Type {
 }
 
 // typChan returns a new chan Type with direction dir.
-func typChan(elem *Type, dir uint8) *Type {
+func typChan(elem *Type, dir ChanDir) *Type {
        t := typ(TCHAN)
        t.Type = elem
        t.Chan = dir
@@ -957,7 +957,7 @@ func (t *Type) SetNumElem(n int64) {
 
 // ChanDir returns the direction of a channel type t.
 // The direction will be one of Crecv, Csend, or Cboth.
-func (t *Type) ChanDir() uint8 {
+func (t *Type) ChanDir() ChanDir {
        t.wantEtype(TCHAN)
        return t.Chan
 }
index 6b566210d78188cf4376e1869069f4ce73692659..0b8eb8c75bdc830312d17c4c3635643e00bd0888 100644 (file)
@@ -414,7 +414,7 @@ OpSwitch:
                        n.Type = nil
                        return n
                }
-               t := typChan(l.Type, uint8(n.Etype)) // TODO(marvin): Fix Node.EType type union.
+               t := typChan(l.Type, ChanDir(n.Etype)) // TODO(marvin): Fix Node.EType type union.
                n.Op = OTYPE
                n.Type = t
                n.Left = nil
@@ -1048,7 +1048,7 @@ OpSwitch:
                        return n
                }
 
-               if t.ChanDir()&Crecv == 0 {
+               if !t.ChanDir().CanRecv() {
                        Yyerror("invalid operation: %v (receive from send-only type %v)", n, t)
                        n.Type = nil
                        return n
@@ -1075,7 +1075,7 @@ OpSwitch:
                        return n
                }
 
-               if t.ChanDir()&Csend == 0 {
+               if !t.ChanDir().CanSend() {
                        Yyerror("invalid operation: %v (send to receive-only type %v)", n, t)
                        n.Type = nil
                        return n
@@ -1528,7 +1528,7 @@ OpSwitch:
                        return n
                }
 
-               if t.ChanDir()&Csend == 0 {
+               if !t.ChanDir().CanSend() {
                        Yyerror("invalid operation: %v (cannot close receive-only channel)", n)
                        n.Type = nil
                        return n