From af0a4481dd36113fd967a37a64d887d4b9d3425e Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Fri, 9 Jan 2015 14:46:21 -0800 Subject: [PATCH] go/types: permit type elision from composite literal map keys Per pending https://go-review.googlesource.com/2591 . Depends on: https://go-review.googlesource.com/2621 . Change-Id: I2aa82916454504b5852518b3ef7fc8637126d0c7 Reviewed-on: https://go-review.googlesource.com/2623 Reviewed-by: Alan Donovan --- go/types/expr.go | 3 ++- go/types/testdata/expr3.src | 43 ++++++++++++++++++++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/go/types/expr.go b/go/types/expr.go index 67b91dad..1fb0a360 100644 --- a/go/types/expr.go +++ b/go/types/expr.go @@ -998,6 +998,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { } } if typ == nil { + // TODO(gri) provide better error messages depending on context check.error(e.Pos(), "missing type in composite literal") goto Error } @@ -1094,7 +1095,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { check.error(e.Pos(), "missing key in map literal") continue } - check.expr(x, kv.Key) + check.exprWithHint(x, kv.Key, utyp.key) if !check.assignment(x, utyp.key) { if x.mode != invalid { check.errorf(x.pos(), "cannot use %s as %s key in map literal", x, utyp.key) diff --git a/go/types/testdata/expr3.src b/go/types/testdata/expr3.src index 125a8503..57720954 100644 --- a/go/types/testdata/expr3.src +++ b/go/types/testdata/expr3.src @@ -186,7 +186,7 @@ func struct_literals() { _ = T1{a: 0, s: "foo", u: 0, a /* ERROR "duplicate field" */: 10} _ = T1{a: "foo" /* ERROR "cannot convert" */ } _ = T1{c /* ERROR "unknown field" */ : 0} - _ = T1{T0: { /* ERROR "missing type" */ }} + _ = T1{T0: { /* ERROR "missing type" */ }} // struct literal element type may not be elided _ = T1{T0: T0{}} _ = T1{T0 /* ERROR "invalid field name" */ .a: 0} @@ -265,6 +265,15 @@ func array_literals() { a4 := [...]complex128{0, 1, 2, 1<<10-2: -1i, 1i, 400: 10, 12, 14} assert(len(a4) == 1024) + // composite literal element types may be elided + type T []int + _ = [10]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}} + a6 := [...]T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}} + assert(len(a6) == 8) + + // recursively so + _ = [10][10]T{{}, [10]T{{}}, {{1, 2, 3}}} + // from the spec type Point struct { x, y float32 } _ = [...]Point{Point{1.5, -3.5}, Point{0, 0}} @@ -308,6 +317,13 @@ func slice_literals() { _ = S0{f /* ERROR "truncated" */ : 0} _ = S0{s /* ERROR "cannot convert" */ : 0} + // composite literal element types may be elided + type T []int + _ = []T{T{}, {}, 5: T{1, 2, 3}, 7: {1, 2, 3}} + _ = [][]int{{1, 2, 3}, {4, 5}} + + // recursively so + _ = [][]T{{}, []T{{}}, {{1, 2, 3}}} } const index2 int = 2 @@ -352,6 +368,31 @@ func map_literals() { var value int _ = M1{true: 1, false: 0} _ = M2{nil: 0, &value: 1} + + // composite literal element types may be elided + type T [2]int + _ = map[int]T{0: T{3, 4}, 1: {5, 6}} + + // recursively so + _ = map[int][]T{0: {}, 1: {{}, T{1, 2}}} + + // composite literal key types may be elided + _ = map[T]int{T{3, 4}: 0, {5, 6}: 1} + + // recursively so + _ = map[[2]T]int{{}: 0, {{}}: 1, [2]T{{}}: 2, {T{1, 2}}: 3} + + // composite literal element and key types may be elided + _ = map[T]T{{}: {}, {1, 2}: T{3, 4}, T{4, 5}: {}} + _ = map[T]M0{{} : {}, T{1, 2}: M0{"foo": 0}, {1, 3}: {"foo": 1}} + + // recursively so + _ = map[[2]T][]T{{}: {}, {{}}: {{}, T{1, 2}}, [2]T{{}}: nil, {T{1, 2}}: {{}, {}}} + + // from the spec + type Point struct { x, y float32 } + _ = map[string]Point{"orig": {0, 0}} + _ = map[*Point]string{{0, 0}: "orig"} } var key2 string = "bar"