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 <adonovan@google.com>
This commit is contained in:
Robert Griesemer 2015-01-09 14:46:21 -08:00
parent 473fd854f8
commit af0a4481dd
2 changed files with 44 additions and 2 deletions

View File

@ -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)

View File

@ -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"