Skip to content

Commit 73483df

Browse files
committed
cmd/compile/internal/syntax: better error message for missing type constraint
For #43527. Change-Id: I8c706e68572286d5675383eb2dfd75b5618b646b Reviewed-on: https://go-review.googlesource.com/c/go/+/348730 Trust: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent e1c3f21 commit 73483df

File tree

4 files changed

+44
-11
lines changed

4 files changed

+44
-11
lines changed

src/cmd/compile/internal/syntax/parser.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,8 +1908,9 @@ func (p *parser) paramList(name *Name, close token, requireNames bool) (list []*
19081908
defer p.trace("paramList")()
19091909
}
19101910

1911-
var named int // number of parameters that have an explicit name and type/bound
1912-
p.list(_Comma, close, func() bool {
1911+
var named int // number of parameters that have an explicit name and type
1912+
var typed int // number of parameters that have an explicit type
1913+
end := p.list(_Comma, close, func() bool {
19131914
par := p.paramDeclOrNil(name)
19141915
name = nil // 1st name was consumed if present
19151916
if par != nil {
@@ -1919,6 +1920,9 @@ func (p *parser) paramList(name *Name, close token, requireNames bool) (list []*
19191920
if par.Name != nil && par.Type != nil {
19201921
named++
19211922
}
1923+
if par.Type != nil {
1924+
typed++
1925+
}
19221926
list = append(list, par)
19231927
}
19241928
return false
@@ -1939,10 +1943,11 @@ func (p *parser) paramList(name *Name, close token, requireNames bool) (list []*
19391943
}
19401944
} else if named != len(list) {
19411945
// some named => all must have names and types
1942-
var pos Pos // left-most error position (or unknown)
1943-
var typ Expr
1946+
var pos Pos // left-most error position (or unknown)
1947+
var typ Expr // current type (from right to left)
19441948
for i := len(list) - 1; i >= 0; i-- {
1945-
if par := list[i]; par.Type != nil {
1949+
par := list[i]
1950+
if par.Type != nil {
19461951
typ = par.Type
19471952
if par.Name == nil {
19481953
pos = typ.Pos()
@@ -1961,7 +1966,12 @@ func (p *parser) paramList(name *Name, close token, requireNames bool) (list []*
19611966
if pos.IsKnown() {
19621967
var msg string
19631968
if requireNames {
1964-
msg = "type parameters must be named"
1969+
if named == typed {
1970+
pos = end // position error at closing ]
1971+
msg = "missing type constraint"
1972+
} else {
1973+
msg = "type parameters must be named"
1974+
}
19651975
} else {
19661976
msg = "mixed named and unnamed parameters"
19671977
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
type (
8+
// 0 and 1-element []-lists are syntactically valid
9+
_[A, B /* ERROR missing type constraint */ ] int
10+
_[A, /* ERROR type parameters must be named */ interface{}] int
11+
_[A, B, C /* ERROR missing type constraint */ ] int
12+
_[A B, C /* ERROR missing type constraint */ ] int
13+
_[A B, /* ERROR type parameters must be named */ interface{}] int
14+
_[A B, /* ERROR type parameters must be named */ interface{}, C D] int
15+
_[A B, /* ERROR type parameters must be named */ interface{}, C, D] int
16+
_[A B, /* ERROR type parameters must be named */ interface{}, C, interface{}] int
17+
_[A B, C interface{}, D, /* ERROR type parameters must be named */ interface{}] int
18+
)
19+
20+
// function type parameters use the same parsing routine - just have a couple of tests
21+
22+
func _[A, B /* ERROR missing type constraint */ ]() {}
23+
func _[A, /* ERROR type parameters must be named */ interface{}]() {}

src/cmd/compile/internal/syntax/testdata/tparams.go2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
package p
66

7-
type t[ /* ERROR type parameters must be named */ a, b] struct{}
8-
type t[a t, b t, /* ERROR type parameters must be named */ c] struct{}
7+
type t[a, b /* ERROR missing type constraint */ ] struct{}
8+
type t[a t, b t, c /* ERROR missing type constraint */ ] struct{}
99
type t struct {
1010
t [n]byte
1111
t[a]
@@ -18,5 +18,5 @@ type t interface {
1818
}
1919

2020
func f[ /* ERROR empty type parameter list */ ]()
21-
func f[ /* ERROR type parameters must be named */ a, b]()
22-
func f[a t, b t, /* ERROR type parameters must be named */ c]()
21+
func f[a, b /* ERROR missing type constraint */ ]()
22+
func f[a t, b t, c /* ERROR missing type constraint */ ]()

src/cmd/compile/internal/types2/testdata/fixedbugs/issue47996.go2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
package p
66

77
// don't crash
8-
func T /* ERROR missing */ [P /* ERROR named */ ] m /* ERROR m */ () /* ERROR \) */ { /* ERROR { */ } /* ERROR } */
8+
func T /* ERROR missing */ [P] /* ERROR missing */ m /* ERROR unexpected */ () /* ERROR \) */ { /* ERROR { */ } /* ERROR } */

0 commit comments

Comments
 (0)