aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-04-03 22:58:10 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2016-04-03 23:35:40 +0000
commit386c0e6598eadab18e01d3fa60f8e21872cbe70c (patch)
tree6c17f2ed73e18400b25dcb492e7c0a939931ccdb /src
parent73edd7b20868825223bce7947587fb1a1ddab213 (diff)
downloadgo-386c0e6598eadab18e01d3fa60f8e21872cbe70c.tar.xz
cmd/compile: give ChanDir a type
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>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/gc/bimport.go2
-rw-r--r--src/cmd/compile/internal/gc/fmt.go4
-rw-r--r--src/cmd/compile/internal/gc/go.go12
-rw-r--r--src/cmd/compile/internal/gc/parser.go12
-rw-r--r--src/cmd/compile/internal/gc/range.go2
-rw-r--r--src/cmd/compile/internal/gc/syntax.go2
-rw-r--r--src/cmd/compile/internal/gc/type.go6
-rw-r--r--src/cmd/compile/internal/gc/typecheck.go8
8 files changed, 27 insertions, 21 deletions
diff --git a/src/cmd/compile/internal/gc/bimport.go b/src/cmd/compile/internal/gc/bimport.go
index 0a51ab037f..4bf6f1d286 100644
--- a/src/cmd/compile/internal/gc/bimport.go
+++ b/src/cmd/compile/internal/gc/bimport.go
@@ -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:
diff --git a/src/cmd/compile/internal/gc/fmt.go b/src/cmd/compile/internal/gc/fmt.go
index 94805594c7..5eb99489bd 100644
--- a/src/cmd/compile/internal/gc/fmt.go
+++ b/src/cmd/compile/internal/gc/fmt.go
@@ -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)
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index 117836d2cd..fdea1f2fba 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -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"
diff --git a/src/cmd/compile/internal/gc/parser.go b/src/cmd/compile/internal/gc/parser.go
index b71cf8fef4..4649c4593b 100644
--- a/src/cmd/compile/internal/gc/parser.go
+++ b/src/cmd/compile/internal/gc/parser.go
@@ -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
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go
index 6a28c3ceb5..6adf8e0d6d 100644
--- a/src/cmd/compile/internal/gc/range.go
+++ b/src/cmd/compile/internal/gc/range.go
@@ -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
}
diff --git a/src/cmd/compile/internal/gc/syntax.go b/src/cmd/compile/internal/gc/syntax.go
index b23b466088..2f3b98a8ef 100644
--- a/src/cmd/compile/internal/gc/syntax.go
+++ b/src/cmd/compile/internal/gc/syntax.go
@@ -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
diff --git a/src/cmd/compile/internal/gc/type.go b/src/cmd/compile/internal/gc/type.go
index d207a046d7..b89c5dbf22 100644
--- a/src/cmd/compile/internal/gc/type.go
+++ b/src/cmd/compile/internal/gc/type.go
@@ -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
}
diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
index 6b566210d7..0b8eb8c75b 100644
--- a/src/cmd/compile/internal/gc/typecheck.go
+++ b/src/cmd/compile/internal/gc/typecheck.go
@@ -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