]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: collect type info for type ...T in variadic functions
authorRobert Griesemer <gri@golang.org>
Fri, 19 Oct 2018 04:21:46 +0000 (21:21 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 19 Oct 2018 18:54:01 +0000 (18:54 +0000)
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/143317
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/types/api_test.go
src/go/types/typexpr.go

index c34ecbf9d160d37b9f131284851ccdccaab35708..85de9f6079392f1b4d8d4d2166ca8026767166fd 100644 (file)
@@ -257,6 +257,16 @@ func TestTypesInfo(t *testing.T) {
                        `(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
                {`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`},
@@ -389,6 +399,8 @@ func TestPredicatesInfo(t *testing.T) {
                {`package t0; type _ int`, `int`, `type`},
                {`package t1; type _ []int`, `[]int`, `type`},
                {`package t2; type _ func()`, `func()`, `type`},
+               {`package t3; type _ func(int)`, `int`, `type`},
+               {`package t3; type _ func(...int)`, `...int`, `type`},
 
                // built-ins
                {`package b0; var _ = len("")`, `len`, `builtin`},
index e6d61b7ec746649413eebe56015cb5a4b6be183e..8512ca1b80bbf896677f8ee091374d56b144330e 100644 (file)
@@ -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.
-       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.typ = &Slice{elem: last.typ}
+               check.recordTypeAndValue(list.List[len(list.List)-1].Type, typexpr, last.typ, nil)
        }
 
        return