Commit 0287d8ed authored by Robert Griesemer's avatar Robert Griesemer

go/types: collect type info for type ...T in variadic functions

Because the code type-checks T rather than ...T (and then corrects
the type to []T "manually"), it didn't automatically record the
type for the ast.Expr corresponding to ...T. Do it manually.

Fixes #28277.

Change-Id: I3d9aae310c90b01f52d189e70c48dd9007f72207
Reviewed-on: https://go-review.googlesource.com/c/143317Reviewed-by: default avatarAlan Donovan <adonovan@google.com>
parent 41c0b9eb
...@@ -257,6 +257,16 @@ func TestTypesInfo(t *testing.T) { ...@@ -257,6 +257,16 @@ func TestTypesInfo(t *testing.T) {
`(string, bool)`, `(string, bool)`,
}, },
// issue 28277
{`package issue28277_a; func f(...int)`,
`...int`,
`[]int`,
},
{`package issue28277_b; func f(a, b, c ...[]struct{})`,
`...[]struct{}`,
`[][]struct{}`,
},
// tests for broken code that doesn't parse or type-check // tests for broken code that doesn't parse or type-check
{`package x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`}, {`package x0; func _() { var x struct {f string}; x.f := 0 }`, `x.f`, `string`},
{`package x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`}, {`package x1; func _() { var z string; type x struct {f string}; y := &x{q: z}}`, `z`, `string`},
...@@ -389,6 +399,8 @@ func TestPredicatesInfo(t *testing.T) { ...@@ -389,6 +399,8 @@ func TestPredicatesInfo(t *testing.T) {
{`package t0; type _ int`, `int`, `type`}, {`package t0; type _ int`, `int`, `type`},
{`package t1; type _ []int`, `[]int`, `type`}, {`package t1; type _ []int`, `[]int`, `type`},
{`package t2; type _ func()`, `func()`, `type`}, {`package t2; type _ func()`, `func()`, `type`},
{`package t3; type _ func(int)`, `int`, `type`},
{`package t3; type _ func(...int)`, `...int`, `type`},
// built-ins // built-ins
{`package b0; var _ = len("")`, `len`, `builtin`}, {`package b0; var _ = len("")`, `len`, `builtin`},
......
...@@ -451,9 +451,12 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO ...@@ -451,9 +451,12 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO
} }
// For a variadic function, change the last parameter's type from T to []T. // For a variadic function, change the last parameter's type from T to []T.
if variadic && len(params) > 0 { // Since we type-checked T rather than ...T, we also need to retro-actively
// record the type for ...T.
if variadic {
last := params[len(params)-1] last := params[len(params)-1]
last.typ = &Slice{elem: last.typ} last.typ = &Slice{elem: last.typ}
check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
} }
return return
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment