From: Robert Griesemer Date: Thu, 18 Aug 2016 00:05:31 +0000 (-0700) Subject: go/types: set Info.Types.Type for array composite literals of the form [...]T X-Git-Tag: go1.8beta1~1791 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=021f2432131d9bdaa4e89592129a540324f9f22d;p=gostls13.git go/types: set Info.Types.Type for array composite literals of the form [...]T Fixes #14092. Change-Id: I00692f60a416348e38cab256b94fda07e334d258 Reviewed-on: https://go-review.googlesource.com/27316 Reviewed-by: Matthew Dempsky --- diff --git a/src/go/types/api_test.go b/src/go/types/api_test.go index 1084de3164..e011e6daef 100644 --- a/src/go/types/api_test.go +++ b/src/go/types/api_test.go @@ -1140,3 +1140,56 @@ func TestIssue15305(t *testing.T) { } t.Errorf("CallExpr has no type") } + +// TestCompositeLitTypes verifies that Info.Types registers the correct +// types for composite literal expressions and composite literal type +// expressions. +func TestCompositeLitTypes(t *testing.T) { + for _, test := range []struct { + lit, typ string + }{ + {`[16]byte{}`, `[16]byte`}, + {`[...]byte{}`, `[0]byte`}, // test for issue #14092 + {`[...]int{1, 2, 3}`, `[3]int`}, // test for issue #14092 + {`[...]int{90: 0, 98: 1, 2}`, `[100]int`}, // test for issue #14092 + {`[]int{}`, `[]int`}, + {`map[string]bool{"foo": true}`, `map[string]bool`}, + {`struct{}{}`, `struct{}`}, + {`struct{x, y int; z complex128}{}`, `struct{x int; y int; z complex128}`}, + } { + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, test.lit, "package p; var _ = "+test.lit, 0) + if err != nil { + t.Fatalf("%s: %v", test.lit, err) + } + + info := &Info{ + Types: make(map[ast.Expr]TypeAndValue), + } + if _, err = new(Config).Check("p", fset, []*ast.File{f}, info); err != nil { + t.Fatalf("%s: %v", test.lit, err) + } + + cmptype := func(x ast.Expr, want string) { + tv, ok := info.Types[x] + if !ok { + t.Errorf("%s: no Types entry found", test.lit) + return + } + if tv.Type == nil { + t.Errorf("%s: type is nil", test.lit) + return + } + if got := tv.Type.String(); got != want { + t.Errorf("%s: got %v, want %s", test.lit, got, want) + } + } + + // test type of composite literal expression + rhs := f.Decls[0].(*ast.GenDecl).Specs[0].(*ast.ValueSpec).Values[0] + cmptype(rhs, test.typ) + + // test type of composite literal type expression + cmptype(rhs.(*ast.CompositeLit).Type, test.typ) + } +} diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 4430c45d14..634c568e2c 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1106,9 +1106,12 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { case *Array: n := check.indexedElts(e.Elts, utyp.elem, utyp.len) - // if we have an "open" [...]T array, set the length now that we know it + // If we have an "open" [...]T array, set the length now that we know it + // and record the type for [...] (usually done by check.typExpr which is + // not called for [...]). if openArray { utyp.len = n + check.recordTypeAndValue(e.Type, typexpr, utyp, nil) } case *Slice: