cmd/compile/internal/types2: use compiler version error when configured for compiler
Fixes #49368.
Change-Id: I7c7575ae8bb6271160747e3f1888b144c3ab24c4
Reviewed-on: https://go-review.googlesource.com/c/go/+/361411
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index 548d55e..ade4c0a 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -574,7 +574,7 @@
case _Add:
// unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer
if !check.allowVersion(check.pkg, 1, 17) {
- check.error(call.Fun, "unsafe.Add requires go1.17 or later")
+ check.versionErrorf(call.Fun, "go1.17", "unsafe.Add")
return
}
@@ -700,7 +700,7 @@
case _Slice:
// unsafe.Slice(ptr *T, len IntegerType) []T
if !check.allowVersion(check.pkg, 1, 17) {
- check.error(call.Fun, "unsafe.Slice requires go1.17 or later")
+ check.versionErrorf(call.Fun, "go1.17", "unsafe.Slice")
return
}
diff --git a/src/cmd/compile/internal/types2/call.go b/src/cmd/compile/internal/types2/call.go
index 49cae5a..74edd4d 100644
--- a/src/cmd/compile/internal/types2/call.go
+++ b/src/cmd/compile/internal/types2/call.go
@@ -16,7 +16,7 @@
// The operand x must be the evaluation of inst.X and its type must be a signature.
func (check *Checker) funcInst(x *operand, inst *syntax.IndexExpr) {
if !check.allowVersion(check.pkg, 1, 18) {
- check.softErrorf(inst.Pos(), "function instantiation requires go1.18 or later")
+ check.versionErrorf(inst.Pos(), "go1.18", "function instantiation")
}
xlist := unpackExpr(inst.Index)
@@ -363,9 +363,9 @@
if sig.TypeParams().Len() > 0 {
if !check.allowVersion(check.pkg, 1, 18) {
if iexpr, _ := call.Fun.(*syntax.IndexExpr); iexpr != nil {
- check.softErrorf(iexpr.Pos(), "function instantiation requires go1.18 or later")
+ check.versionErrorf(iexpr.Pos(), "go1.18", "function instantiation")
} else {
- check.softErrorf(call.Pos(), "implicit function instantiation requires go1.18 or later")
+ check.versionErrorf(call.Pos(), "go1.18", "implicit function instantiation")
}
}
// TODO(gri) provide position information for targs so we can feed
diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go
index 44e8aad..ccabbaf 100644
--- a/src/cmd/compile/internal/types2/conversions.go
+++ b/src/cmd/compile/internal/types2/conversions.go
@@ -7,6 +7,7 @@
package types2
import (
+ "fmt"
"go/constant"
"unicode"
)
@@ -181,11 +182,9 @@
}
// check != nil
if cause != nil {
+ *cause = "conversion of slices to array pointers requires go1.17 or later"
if check.conf.CompilerErrorMessages {
- // compiler error message assumes a -lang flag
- *cause = "conversion of slices to array pointers only supported as of -lang=go1.17"
- } else {
- *cause = "conversion of slices to array pointers requires go1.17 or later"
+ *cause += fmt.Sprintf(" (-lang was set to %s; check go.mod)", check.conf.GoVersion)
}
}
return false
diff --git a/src/cmd/compile/internal/types2/decl.go b/src/cmd/compile/internal/types2/decl.go
index 5d2a6c5..5219f7e 100644
--- a/src/cmd/compile/internal/types2/decl.go
+++ b/src/cmd/compile/internal/types2/decl.go
@@ -555,7 +555,7 @@
check.validType(obj.typ, nil)
// If typ is local, an error was already reported where typ is specified/defined.
if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(tdecl.Type.Pos(), "using type constraint %s requires go1.18 or later", rhs)
+ check.versionErrorf(tdecl.Type.Pos(), "go1.18", "using type constraint %s", rhs)
}
}).describef(obj, "validType(%s)", obj.Name())
@@ -570,11 +570,7 @@
// alias declaration
if alias {
if !check.allowVersion(check.pkg, 1, 9) {
- if check.conf.CompilerErrorMessages {
- check.error(tdecl, "type aliases only supported as of -lang=go1.9")
- } else {
- check.error(tdecl, "type aliases requires go1.9 or later")
- }
+ check.versionErrorf(tdecl, "go1.9", "type aliases")
}
obj.typ = Typ[Invalid]
diff --git a/src/cmd/compile/internal/types2/errors.go b/src/cmd/compile/internal/types2/errors.go
index b56d11a..c39652f 100644
--- a/src/cmd/compile/internal/types2/errors.go
+++ b/src/cmd/compile/internal/types2/errors.go
@@ -230,6 +230,16 @@
check.err(at, check.sprintf(format, args...), true)
}
+func (check *Checker) versionErrorf(at poser, goVersion string, format string, args ...interface{}) {
+ msg := check.sprintf(format, args...)
+ if check.conf.CompilerErrorMessages {
+ msg = fmt.Sprintf("%s requires %s or later (-lang was set to %s; check go.mod)", msg, goVersion, check.conf.GoVersion)
+ } else {
+ msg = fmt.Sprintf("%s requires %s or later", msg, goVersion)
+ }
+ check.err(at, msg, true)
+}
+
// posFor reports the left (= start) position of at.
func posFor(at poser) syntax.Pos {
switch x := at.(type) {
diff --git a/src/cmd/compile/internal/types2/expr.go b/src/cmd/compile/internal/types2/expr.go
index d618ebd..d24532d 100644
--- a/src/cmd/compile/internal/types2/expr.go
+++ b/src/cmd/compile/internal/types2/expr.go
@@ -869,7 +869,7 @@
x.mode = invalid
return
} else if !allUnsigned(y.typ) && !check.allowVersion(check.pkg, 1, 13) {
- check.errorf(y, invalidOp+"signed shift count %s requires go1.13 or later", y)
+ check.versionErrorf(y, "go1.13", invalidOp+"signed shift count %s", y)
x.mode = invalid
return
}
diff --git a/src/cmd/compile/internal/types2/typeset.go b/src/cmd/compile/internal/types2/typeset.go
index 445a62f..c37a20e 100644
--- a/src/cmd/compile/internal/types2/typeset.go
+++ b/src/cmd/compile/internal/types2/typeset.go
@@ -271,7 +271,7 @@
tset := computeInterfaceTypeSet(check, pos, u)
// If typ is local, an error was already reported where typ is specified/defined.
if check != nil && check.isImportedConstraint(typ) && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(pos, "embedding constraint interface %s requires go1.18 or later", typ)
+ check.versionErrorf(pos, "go1.18", "embedding constraint interface %s", typ)
continue
}
if tset.comparable {
@@ -283,7 +283,7 @@
terms = tset.terms
case *Union:
if check != nil && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(pos, "embedding interface element %s requires go1.18 or later", u)
+ check.versionErrorf(pos, "go1.18", "embedding interface element %s", u)
continue
}
tset := computeUnionTypeSet(check, pos, u)
@@ -300,7 +300,7 @@
continue
}
if check != nil && !check.allowVersion(check.pkg, 1, 18) {
- check.errorf(pos, "embedding non-interface type %s requires go1.18 or later", typ)
+ check.versionErrorf(pos, "go1.18", "embedding non-interface type %s", typ)
continue
}
terms = termlist{{false, typ}}
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index 95893fd..dcd7cfe 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -264,7 +264,7 @@
case *syntax.IndexExpr:
if !check.allowVersion(check.pkg, 1, 18) {
- check.softErrorf(e.Pos(), "type instantiation requires go1.18 or later")
+ check.versionErrorf(e.Pos(), "go1.18", "type instantiation")
}
return check.instantiatedType(e.X, unpackExpr(e.Index), def)
diff --git a/src/cmd/compile/internal/types2/version.go b/src/cmd/compile/internal/types2/version.go
index d9d18b6..b649f09 100644
--- a/src/cmd/compile/internal/types2/version.go
+++ b/src/cmd/compile/internal/types2/version.go
@@ -21,7 +21,7 @@
}
// len(s) > 2
if strings.Contains(s, "_") {
- check.error(lit, "underscores in numeric literals requires go1.13 or later")
+ check.versionErrorf(lit, "go1.13", "underscores in numeric literals")
return
}
if s[0] != '0' {
@@ -29,15 +29,15 @@
}
radix := s[1]
if radix == 'b' || radix == 'B' {
- check.error(lit, "binary literals requires go1.13 or later")
+ check.versionErrorf(lit, "go1.13", "binary literals")
return
}
if radix == 'o' || radix == 'O' {
- check.error(lit, "0o/0O-style octal literals requires go1.13 or later")
+ check.versionErrorf(lit, "go1.13", "0o/0O-style octal literals")
return
}
if lit.Kind != syntax.IntLit && (radix == 'x' || radix == 'X') {
- check.error(lit, "hexadecimal floating-point literals requires go1.13 or later")
+ check.versionErrorf(lit, "go1.13", "hexadecimal floating-point literals")
}
}
diff --git a/src/cmd/go/testdata/script/mod_edit_go.txt b/src/cmd/go/testdata/script/mod_edit_go.txt
index 38321d0..7e9740f 100644
--- a/src/cmd/go/testdata/script/mod_edit_go.txt
+++ b/src/cmd/go/testdata/script/mod_edit_go.txt
@@ -2,7 +2,7 @@
env GO111MODULE=on
! go build
-stderr 'type aliases only supported as of'
+stderr ' type aliases requires'
go mod edit -go=1.9
grep 'go 1.9' go.mod
go build
@@ -11,7 +11,7 @@
# the cached 1.9 build. (https://golang.org/issue/37804)
go mod edit -go=1.8
! go build
-stderr 'type aliases only supported as of'
+stderr 'type aliases requires'
-- go.mod --
diff --git a/test/fixedbugs/issue49368.go b/test/fixedbugs/issue49368.go
new file mode 100644
index 0000000..2339048
--- /dev/null
+++ b/test/fixedbugs/issue49368.go
@@ -0,0 +1,11 @@
+// errorcheck -lang=go1.17
+
+// 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
+
+type _ interface {
+ int // ERROR "embedding non-interface type int requires go1\.18 or later \(-lang was set to go1\.17; check go.mod\)"
+}