Skip to content

Commit

Permalink
cmd/compile: disallow embed of var inside func
Browse files Browse the repository at this point in the history
Allowing embedding into []byte inside a func creates an
unfortunate problem: either all calls start with the same
underlying data and can see each other's changes to the
underlying data (surprising and racy!) or all calls start
by making their own copy of the underlying data
(surprising and expensive!).

After discussion on #43216, the consensus was to remove
support for all vars embedded inside functions.

Fixes #43216.


Change-Id: I01e62b5f0dcd9e8566c6d2286218e97803f54704
Reviewed-on: https://go-review.googlesource.com/c/go/+/282714
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
  • Loading branch information
rsc committed Jan 15, 2021
1 parent b386c73 commit 54198b0
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 42 deletions.
9 changes: 2 additions & 7 deletions src/cmd/compile/internal/gc/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,8 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma

v := names[0]
if dclcontext != PEXTERN {
numLocalEmbed++
v = newnamel(v.Pos, lookupN("embed.", numLocalEmbed))
v.Sym.Def = asTypesNode(v)
v.Name.Param.Ntype = typ
v.SetClass(PEXTERN)
externdcl = append(externdcl, v)
exprs = []*Node{v}
p.yyerrorpos(pos, "go:embed cannot apply to var inside func")
return exprs
}

v.Name.Param.SetEmbedFiles(list)
Expand Down
32 changes: 11 additions & 21 deletions src/embed/internal/embedtest/embed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,11 @@ func TestGlobal(t *testing.T) {
testString(t, string(glass), "glass", "I can eat glass and it doesn't hurt me.\n")
}

func TestLocal(t *testing.T) {
//go:embed testdata/k*.txt
var local embed.FS
testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")

//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")

//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
}
//go:embed testdata
var testDirAll embed.FS

func TestDir(t *testing.T) {
//go:embed testdata
var all embed.FS

all := testDirAll
testFiles(t, all, "testdata/hello.txt", "hello, world\n")
testFiles(t, all, "testdata/i/i18n.txt", "internationalization\n")
testFiles(t, all, "testdata/i/j/k/k8s.txt", "kubernetes\n")
Expand All @@ -102,12 +89,15 @@ func TestDir(t *testing.T) {
testDir(t, all, "testdata/i/j/k", "k8s.txt")
}

func TestHidden(t *testing.T) {
//go:embed testdata
var dir embed.FS
//go:embed testdata
var testHiddenDir embed.FS

//go:embed testdata/*
var star embed.FS
//go:embed testdata/*
var testHiddenStar embed.FS

func TestHidden(t *testing.T) {
dir := testHiddenDir
star := testHiddenStar

t.Logf("//go:embed testdata")

Expand Down
14 changes: 0 additions & 14 deletions src/embed/internal/embedtest/embedx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,3 @@ func TestXGlobal(t *testing.T) {
}
bbig[0] = old
}

func TestXLocal(t *testing.T) {
//go:embed testdata/*o.txt
var local embed.FS
testFiles(t, local, "testdata/hello.txt", "hello, world\n")

//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")

//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
}

0 comments on commit 54198b0

Please sign in to comment.