From 3e41b18a46ea0cf033be4d9baa2d99f7c8c985dc Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 4 Nov 2021 20:00:51 -0700 Subject: [PATCH] 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 Reviewed-by: Robert Findley --- src/cmd/compile/internal/types2/builtins.go | 4 ++-- src/cmd/compile/internal/types2/call.go | 6 +++--- src/cmd/compile/internal/types2/conversions.go | 7 +++---- src/cmd/compile/internal/types2/decl.go | 8 ++------ src/cmd/compile/internal/types2/errors.go | 10 ++++++++++ src/cmd/compile/internal/types2/expr.go | 2 +- src/cmd/compile/internal/types2/typeset.go | 6 +++--- src/cmd/compile/internal/types2/typexpr.go | 2 +- src/cmd/compile/internal/types2/version.go | 8 ++++---- src/cmd/go/testdata/script/mod_edit_go.txt | 4 ++-- test/fixedbugs/issue49368.go | 11 +++++++++++ 11 files changed, 42 insertions(+), 26 deletions(-) create mode 100644 test/fixedbugs/issue49368.go diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go index 548d55e10c..ade4c0a49f 100644 --- a/src/cmd/compile/internal/types2/builtins.go +++ b/src/cmd/compile/internal/types2/builtins.go @@ -574,7 +574,7 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( 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 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( 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 49cae5a930..74edd4d442 100644 --- a/src/cmd/compile/internal/types2/call.go +++ b/src/cmd/compile/internal/types2/call.go @@ -16,7 +16,7 @@ import ( // 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 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T 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 44e8aad84f..ccabbaf0d7 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 @@ func (x *operand) convertibleTo(check *Checker, T Type, cause *string) bool { } // 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 5d2a6c531b..5219f7e7c5 100644 --- a/src/cmd/compile/internal/types2/decl.go +++ b/src/cmd/compile/internal/types2/decl.go @@ -555,7 +555,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named 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 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named // 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 b56d11a28b..c39652fe5e 100644 --- a/src/cmd/compile/internal/types2/errors.go +++ b/src/cmd/compile/internal/types2/errors.go @@ -230,6 +230,16 @@ func (check *Checker) softErrorf(at poser, format string, args ...interface{}) { 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 d618ebd372..d24532d780 100644 --- a/src/cmd/compile/internal/types2/expr.go +++ b/src/cmd/compile/internal/types2/expr.go @@ -869,7 +869,7 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) { 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 445a62f9e0..c37a20e73e 100644 --- a/src/cmd/compile/internal/types2/typeset.go +++ b/src/cmd/compile/internal/types2/typeset.go @@ -271,7 +271,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_ 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 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_ 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 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *_ 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 95893fd1e1..dcd7cfebe8 100644 --- a/src/cmd/compile/internal/types2/typexpr.go +++ b/src/cmd/compile/internal/types2/typexpr.go @@ -264,7 +264,7 @@ func (check *Checker) typInternal(e0 syntax.Expr, def *Named) (T Type) { 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 d9d18b6f7a..b649f09c3a 100644 --- a/src/cmd/compile/internal/types2/version.go +++ b/src/cmd/compile/internal/types2/version.go @@ -21,7 +21,7 @@ func (check *Checker) langCompat(lit *syntax.BasicLit) { } // 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 @@ func (check *Checker) langCompat(lit *syntax.BasicLit) { } 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 38321d071f..7e9740fec4 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 @@ go build # 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 0000000000..2339048e3d --- /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\)" +} -- 2.48.1