Skip to content

Commit 05e9281

Browse files
committed
copy value on channel send (fixes gopherjs#262)
1 parent 2043519 commit 05e9281

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

compiler/statements.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ func (c *funcContext) translateStmt(stmt ast.Stmt, label *types.Label) {
442442
chanType := c.p.Types[s.Chan].Type.Underlying().(*types.Chan)
443443
call := &ast.CallExpr{
444444
Fun: c.newIdent("$send", types.NewSignature(nil, types.NewTuple(types.NewVar(0, nil, "", chanType), types.NewVar(0, nil, "", chanType.Elem())), nil, false)),
445-
Args: []ast.Expr{s.Chan, s.Value},
445+
Args: []ast.Expr{s.Chan, c.newIdent(c.translateImplicitConversionWithCloning(s.Value, chanType.Elem()).String(), chanType.Elem())},
446446
}
447447
c.Blocking[call] = true
448448
c.translateStmt(&ast.ExprStmt{X: call}, label)
@@ -463,7 +463,8 @@ func (c *funcContext) translateStmt(stmt ast.Stmt, label *types.Label) {
463463
case *ast.AssignStmt:
464464
channels = append(channels, c.formatExpr("[%e]", astutil.RemoveParens(comm.Rhs[0]).(*ast.UnaryExpr).X).String())
465465
case *ast.SendStmt:
466-
channels = append(channels, c.formatExpr("[%e, %e]", comm.Chan, comm.Value).String())
466+
chanType := c.p.Types[comm.Chan].Type.Underlying().(*types.Chan)
467+
channels = append(channels, c.formatExpr("[%e, %s]", comm.Chan, c.translateImplicitConversionWithCloning(comm.Value, chanType.Elem())).String())
467468
default:
468469
panic(fmt.Sprintf("unhandled: %T", comm))
469470
}

tests/misc_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,23 @@ func TestMethodExprCall(t *testing.T) {
399399
t.Fail()
400400
}
401401
}
402+
403+
func TestCopyOnSend(t *testing.T) {
404+
type S struct{ i int }
405+
c := make(chan S, 2)
406+
go func() {
407+
var s S
408+
s.i = 42
409+
c <- s
410+
select {
411+
case c <- s:
412+
}
413+
s.i = 10
414+
}()
415+
if (<-c).i != 42 {
416+
t.Fail()
417+
}
418+
if (<-c).i != 42 {
419+
t.Fail()
420+
}
421+
}

0 commit comments

Comments
 (0)