diff --git a/interp/interp_chan_test.go b/interp/interp_chan_test.go new file mode 100644 index 00000000..8729ec6b --- /dev/null +++ b/interp/interp_chan_test.go @@ -0,0 +1,92 @@ +package interp_test + +import ( + "reflect" + "testing" + + "github.com/traefik/yaegi/interp" +) + +// IntChan is a channel type alias for testing. +type IntChan chan int + +// NewIntChan creates a new IntChan. +func NewIntChan() IntChan { + return make(IntChan, 1) +} + +func TestSendToBinaryChannelTypeAlias(t *testing.T) { + i := interp.New(interp.Options{}) + + err := i.Use(interp.Exports{ + "mypkg/mypkg": { + "IntChan": reflect.ValueOf((*IntChan)(nil)), + "NewIntChan": reflect.ValueOf(NewIntChan), + }, + }) + if err != nil { + t.Fatal(err) + } + + _, err = i.Eval(` +package main + +import "mypkg" + +func main() { + ch := mypkg.NewIntChan() + ch <- 42 + val := <-ch + if val != 42 { + panic("unexpected value") + } +} +`) + if err != nil { + t.Fatal(err) + } +} + +func TestSendToSourceDefinedChannel(t *testing.T) { + i := interp.New(interp.Options{}) + + // Test with a channel defined purely in interpreted code + _, err := i.Eval(` +package main + +func main() { + ch := make(chan int, 1) + ch <- 42 + val := <-ch + if val != 42 { + panic("unexpected value") + } +} +`) + if err != nil { + t.Fatal(err) + } +} + +func TestSendToSourceDefinedChannelTypeAlias(t *testing.T) { + i := interp.New(interp.Options{}) + + // Test with a channel type alias defined in interpreted code + _, err := i.Eval(` +package main + +type MyChan chan int + +func main() { + ch := make(MyChan, 1) + ch <- 42 + val := <-ch + if val != 42 { + panic("unexpected value") + } +} +`) + if err != nil { + t.Fatal(err) + } +} diff --git a/interp/run.go b/interp/run.go index 74efae61..c033e53d 100644 --- a/interp/run.go +++ b/interp/run.go @@ -3763,7 +3763,7 @@ func send(n *node) { next := getExec(n.tnext) c0, c1 := n.child[0], n.child[1] value0 := genValue(c0) // Send channel. - value1 := genDestValue(c0.typ.val, c1) + value1 := genDestValue(c0.typ.elem(), c1) if !n.interp.cancelChan { // Send is non-cancellable, has the least overhead.