Robert Griesemer has uploaded this change for review.
go/types, types2: better error message for invalid array length
If an invalid array length is just an identifier, mention
"array length" so that it's clear this is an invalid array
declaration and not a (invalid) generic type declaration.
Fixes #51145.
Change-Id: I8878cbb6c7b1277fc0a9a014712ec8d55499c5c7
---
M src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go2
A src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go
M src/cmd/compile/internal/types2/typexpr.go
M src/go/types/errorcodes.go
M src/go/types/testdata/fixedbugs/issue43527.go2
A src/go/types/testdata/fixedbugs/issue51145.go
M src/go/types/typexpr.go
7 files changed, 83 insertions(+), 19 deletions(-)
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go2
index e4bcee5..2955c26 100644
--- a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go2
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go2
@@ -9,7 +9,7 @@
type (
_ [L]struct{}
_ [A /* ERROR undeclared name A for array length */ ]struct{}
- _ [B /* ERROR not an expression */ ]struct{}
+ _ [B /* ERROR invalid array length B */ ]struct{}
_[A any] struct{}
B int
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go
new file mode 100644
index 0000000..b84391d
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go
@@ -0,0 +1,18 @@
+// Copyright 2022 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 "fmt"
+
+type (
+ _ [fmt /* ERROR invalid array length fmt */ ]int
+ _ [float64 /* ERROR invalid array length float64 */ ]int
+ _ [f /* ERROR invalid array length f */ ]int
+ _ [nil /* ERROR invalid array length nil */ ]int
+)
+
+func f()
+
+var _ fmt.Stringer // use fmt
diff --git a/src/cmd/compile/internal/types2/typexpr.go b/src/cmd/compile/internal/types2/typexpr.go
index de778fb..149bd5b 100644
--- a/src/cmd/compile/internal/types2/typexpr.go
+++ b/src/cmd/compile/internal/types2/typexpr.go
@@ -502,12 +502,20 @@
// and returns the constant length >= 0, or a value < 0
// to indicate an error (and thus an unknown length).
func (check *Checker) arrayLength(e syntax.Expr) int64 {
- // If e is an undeclared identifier, the array declaration might be an
- // attempt at a parameterized type declaration with missing constraint.
- // Provide a better error message than just "undeclared name: X".
- if name, _ := e.(*syntax.Name); name != nil && check.lookup(name.Value) == nil {
- check.errorf(name, "undeclared name %s for array length", name.Value)
- return -1
+ // If e is an identifier, the array declaration might be an
+ // attempt at a parameterized type declaration with missing
+ // constraint. Provide an error message that mentions array
+ // length.
+ if name, _ := e.(*syntax.Name); name != nil {
+ obj := check.lookup(name.Value)
+ if obj == nil {
+ check.errorf(name, "undeclared name %s for array length", name.Value)
+ return -1
+ }
+ if _, ok := obj.(*Const); !ok {
+ check.errorf(name, "invalid array length %s", name.Value)
+ return -1
+ }
}
var x operand
diff --git a/src/go/types/errorcodes.go b/src/go/types/errorcodes.go
index 51f091a..a7514b3 100644
--- a/src/go/types/errorcodes.go
+++ b/src/go/types/errorcodes.go
@@ -98,13 +98,10 @@
// _InvalidDeclCycle occurs when a declaration cycle is not valid.
//
// Example:
- // import "unsafe"
- //
- // type T struct {
- // a [n]int
+ // type S struct {
+ // S
// }
//
- // var n = unsafe.Sizeof(T{})
_InvalidDeclCycle
// _InvalidTypeCycle occurs when a cycle in type definitions results in a
diff --git a/src/go/types/testdata/fixedbugs/issue43527.go2 b/src/go/types/testdata/fixedbugs/issue43527.go2
index e4bcee5..2955c26 100644
--- a/src/go/types/testdata/fixedbugs/issue43527.go2
+++ b/src/go/types/testdata/fixedbugs/issue43527.go2
@@ -9,7 +9,7 @@
type (
_ [L]struct{}
_ [A /* ERROR undeclared name A for array length */ ]struct{}
- _ [B /* ERROR not an expression */ ]struct{}
+ _ [B /* ERROR invalid array length B */ ]struct{}
_[A any] struct{}
B int
diff --git a/src/go/types/testdata/fixedbugs/issue51145.go b/src/go/types/testdata/fixedbugs/issue51145.go
new file mode 100644
index 0000000..b84391d
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue51145.go
@@ -0,0 +1,18 @@
+// Copyright 2022 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 "fmt"
+
+type (
+ _ [fmt /* ERROR invalid array length fmt */ ]int
+ _ [float64 /* ERROR invalid array length float64 */ ]int
+ _ [f /* ERROR invalid array length f */ ]int
+ _ [nil /* ERROR invalid array length nil */ ]int
+)
+
+func f()
+
+var _ fmt.Stringer // use fmt
diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go
index 00c250b..db6a904 100644
--- a/src/go/types/typexpr.go
+++ b/src/go/types/typexpr.go
@@ -487,12 +487,20 @@
// and returns the constant length >= 0, or a value < 0
// to indicate an error (and thus an unknown length).
func (check *Checker) arrayLength(e ast.Expr) int64 {
- // If e is an undeclared identifier, the array declaration might be an
- // attempt at a parameterized type declaration with missing constraint.
- // Provide a better error message than just "undeclared name: X".
- if name, _ := e.(*ast.Ident); name != nil && check.lookup(name.Name) == nil {
- check.errorf(name, _InvalidArrayLen, "undeclared name %s for array length", name.Name)
- return -1
+ // If e is an identifier, the array declaration might be an
+ // attempt at a parameterized type declaration with missing
+ // constraint. Provide an error message that mentions array
+ // length.
+ if name, _ := e.(*ast.Ident); name != nil {
+ obj := check.lookup(name.Name)
+ if obj == nil {
+ check.errorf(name, _InvalidArrayLen, "undeclared name %s for array length", name.Name)
+ return -1
+ }
+ if _, ok := obj.(*Const); !ok {
+ check.errorf(name, _InvalidArrayLen, "invalid array length %s", name.Name)
+ return -1
+ }
}
var x operand
To view, visit change 385255. To unsubscribe, or for help writing mail filters, visit settings.
Attention is currently required from: Robert Griesemer.
Patch set 1:Code-Review +2
Attention is currently required from: Robert Griesemer.
Robert Griesemer uploaded patch set #2 to this change.
go/types, types2: better error message for invalid array length
If an invalid array length is just an identifier, mention
"array length" so that it's clear this is an invalid array
declaration and not a (invalid) generic type declaration.
Fixes #51145.
Change-Id: I8878cbb6c7b1277fc0a9a014712ec8d55499c5c7
---
M src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go2
A src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go
M src/cmd/compile/internal/types2/typexpr.go
M src/go/types/errorcodes.go
M src/go/types/testdata/fixedbugs/issue43527.go2
A src/go/types/testdata/fixedbugs/issue51145.go
M src/go/types/typexpr.go
M test/fixedbugs/bug255.go
8 files changed, 90 insertions(+), 25 deletions(-)
To view, visit change 385255. To unsubscribe, or for help writing mail filters, visit settings.
Robert Griesemer submitted this change.
1 is the latest approved patch-set.
The change was submitted with unreviewed changes in the following files:
```
The name of the file: test/fixedbugs/bug255.go
Insertions: 7, Deletions: 6.
@@ -6,12 +6,13 @@
package main
-var a [10]int // ok
-var b [1e1]int // ok
-var c [1.5]int // ERROR "truncated|must be integer"
-var d ["abc"]int // ERROR "invalid array bound|not numeric|must be integer"
-var e [nil]int // ERROR "use of untyped nil|invalid array bound|not numeric|must be constant"
-var f [e]int // ok: error already reported for e
+var a [10]int // ok
+var b [1e1]int // ok
+var c [1.5]int // ERROR "truncated|must be integer"
+var d ["abc"]int // ERROR "invalid array bound|not numeric|must be integer"
+var e [nil]int // ERROR "use of untyped nil|invalid array (bound|length)|not numeric|must be constant"
+// var f [e]int // ok with Go 1.17 because an error was reported for e; leads to an error for Go 1.18
+var f [ee]int // ERROR "undefined|undeclared"
var g [1 << 65]int // ERROR "array bound is too large|overflows|must be integer"
var h [len(a)]int // ok
```
go/types, types2: better error message for invalid array length
If an invalid array length is just an identifier, mention
"array length" so that it's clear this is an invalid array
declaration and not a (invalid) generic type declaration.
Fixes #51145.
Change-Id: I8878cbb6c7b1277fc0a9a014712ec8d55499c5c7
Reviewed-on: https://go-review.googlesource.com/c/go/+/385255
Trust: Robert Griesemer <g...@golang.org>
Run-TryBot: Robert Griesemer <g...@golang.org>
Reviewed-by: Robert Findley <rfin...@google.com>
TryBot-Result: Gopher Robot <go...@golang.org>
---
M src/cmd/compile/internal/types2/testdata/fixedbugs/issue43527.go2
A src/cmd/compile/internal/types2/testdata/fixedbugs/issue51145.go
M src/cmd/compile/internal/types2/typexpr.go
M src/go/types/errorcodes.go
M src/go/types/testdata/fixedbugs/issue43527.go2
A src/go/types/testdata/fixedbugs/issue51145.go
M src/go/types/typexpr.go
M test/fixedbugs/bug255.go
8 files changed, 95 insertions(+), 25 deletions(-)
diff --git a/test/fixedbugs/bug255.go b/test/fixedbugs/bug255.go
index 38df781..184ff2d 100644
--- a/test/fixedbugs/bug255.go
+++ b/test/fixedbugs/bug255.go
@@ -6,12 +6,13 @@
package main
-var a [10]int // ok
-var b [1e1]int // ok
-var c [1.5]int // ERROR "truncated|must be integer"
-var d ["abc"]int // ERROR "invalid array bound|not numeric|must be integer"
-var e [nil]int // ERROR "use of untyped nil|invalid array bound|not numeric|must be constant"
-var f [e]int // ok: error already reported for e
+var a [10]int // ok
+var b [1e1]int // ok
+var c [1.5]int // ERROR "truncated|must be integer"
+var d ["abc"]int // ERROR "invalid array bound|not numeric|must be integer"
+var e [nil]int // ERROR "use of untyped nil|invalid array (bound|length)|not numeric|must be constant"
+// var f [e]int // ok with Go 1.17 because an error was reported for e; leads to an error for Go 1.18
+var f [ee]int // ERROR "undefined|undeclared"
var g [1 << 65]int // ERROR "array bound is too large|overflows|must be integer"
var h [len(a)]int // ok
To view, visit change 385255. To unsubscribe, or for help writing mail filters, visit settings.