cmd/compile: require 'go 1.16' go.mod line for //go:embed

This will produce better errors when earlier versions of
Go compile code using //go:embed. (The import will cause
a compilation error but then the go command will add to
the output that the Go toolchain in use looks too old
and maybe that's the problem.)

This CL also adds a test for disallowing embed of a var inside a func.
It's a bit too difficult to rebase down into that CL.

The build system configuration check is delayed in order to
make it possible to use errorcheck for these tests.

Change-Id: I12ece4ff2d8d53380b63f54866e8f3497657d54c
Reviewed-on: https://go-review.googlesource.com/c/go/+/282718
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Jay Conrod <jayconrod@google.com>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
Russ Cox 2021-01-08 17:02:41 -05:00
Родитель ccb2e90688
Коммит 0575e35e50
4 изменённых файлов: 41 добавлений и 4 удалений

Просмотреть файл

@ -67,10 +67,6 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma
p.yyerrorpos(pos, "invalid go:embed: missing import \"embed\"") p.yyerrorpos(pos, "invalid go:embed: missing import \"embed\"")
return return
} }
if embedCfg.Patterns == nil {
p.yyerrorpos(pos, "invalid go:embed: build system did not supply embed configuration")
return
}
if len(names) > 1 { if len(names) > 1 {
p.yyerrorpos(pos, "go:embed cannot apply to multiple vars") p.yyerrorpos(pos, "go:embed cannot apply to multiple vars")
return return
@ -186,6 +182,18 @@ func dumpembeds() {
// initEmbed emits the init data for a //go:embed variable, // initEmbed emits the init data for a //go:embed variable,
// which is either a string, a []byte, or an embed.FS. // which is either a string, a []byte, or an embed.FS.
func initEmbed(v *Node) { func initEmbed(v *Node) {
commentPos := v.Name.Param.EmbedList()[0].Pos
if !langSupported(1, 16, localpkg) {
lno := lineno
lineno = commentPos
yyerrorv("go1.16", "go:embed")
lineno = lno
return
}
if embedCfg.Patterns == nil {
yyerrorl(commentPos, "invalid go:embed: build system did not supply embed configuration")
return
}
kind := embedKind(v.Type) kind := embedKind(v.Type)
if kind == embedUnknown { if kind == embedUnknown {
yyerrorl(v.Pos, "go:embed cannot apply to var of type %v", v.Type) yyerrorl(v.Pos, "go:embed cannot apply to var of type %v", v.Type)

Просмотреть файл

@ -155,6 +155,8 @@ func TestStdTest(t *testing.T) {
testTestDir(t, filepath.Join(runtime.GOROOT(), "test"), testTestDir(t, filepath.Join(runtime.GOROOT(), "test"),
"cmplxdivide.go", // also needs file cmplxdivide1.go - ignore "cmplxdivide.go", // also needs file cmplxdivide1.go - ignore
"directive.go", // tests compiler rejection of bad directive placement - ignore "directive.go", // tests compiler rejection of bad directive placement - ignore
"embedfunc.go", // tests //go:embed
"embedvers.go", // tests //go:embed
) )
} }

15
test/embedfunc.go Normal file
Просмотреть файл

@ -0,0 +1,15 @@
// errorcheck
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
import _ "embed"
func f() {
//go:embed x.txt // ERROR "go:embed cannot apply to var inside func"
var x string
_ = x
}

12
test/embedvers.go Normal file
Просмотреть файл

@ -0,0 +1,12 @@
// errorcheck -lang=go1.15
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
import _ "embed"
//go:embed x.txt // ERROR "go:embed requires go1.16 or later"
var x string