Commit 3c1b7bc7 authored by Robert Griesemer's avatar Robert Griesemer

go/types: fix internal comments and add additional test case

https://go-review.googlesource.com/c/go/+/132355 addressed
a crash and inadvertently fixed #27346; however the comment
added to the type-checker was incorrect and misleading.

This CL fixes the comment, and adds a test case for #27346.

Fixes #27346.
Updates #22467.

Change-Id: Ib6d5caedf302fd42929c4dacc55e973c1aebfe85
Reviewed-on: https://go-review.googlesource.com/133415
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRebecca Stambler <rstambler@golang.org>
parent 48af3a8b
...@@ -1156,15 +1156,20 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { ...@@ -1156,15 +1156,20 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
goto Error goto Error
} }
n := check.indexedElts(e.Elts, utyp.elem, utyp.len) 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 array of unknown length (usually [...]T arrays, but also
// and record the type for [...] (usually done by check.typExpr which is // arrays [n]T where n is invalid) set the length now that we know it and
// not called for [...]). // record the type for the array (usually done by check.typ which is not
// called for [...]T). We handle [...]T arrays and arrays with invalid
// length the same here because it makes sense to "guess" the length for
// the latter if we have a composite literal; e.g. for [n]int{1, 2, 3}
// where n is invalid for some reason, it seems fair to assume it should
// be 3 (see also Checked.arrayLength and issue #27346).
if utyp.len < 0 { if utyp.len < 0 {
utyp.len = n utyp.len = n
// e.Type may be missing in case of errors. // e.Type is missing if we have a composite literal element
// In "map[string][...]int{"": {1, 2, 3}}}, // that is itself a composite literal with omitted type. In
// an error is reported for the outer literal, // that case there is nothing to record (there is no type in
// then [...]int is used as a hint for the inner literal. // the source at that point).
if e.Type != nil { if e.Type != nil {
check.recordTypeAndValue(e.Type, typexpr, utyp, nil) check.recordTypeAndValue(e.Type, typexpr, utyp, nil)
} }
......
...@@ -294,3 +294,11 @@ type registry struct { ...@@ -294,3 +294,11 @@ type registry struct {
type allocator struct { type allocator struct {
_ [int(preloadLimit)]int _ [int(preloadLimit)]int
} }
// Test that we don't crash when type-checking composite literals
// containing errors in the type.
var issue27346 = [][n /* ERROR undeclared */ ]int{
0: {},
}
var issue22467 = map[int][... /* ERROR invalid use of ... */ ]int{0: {}}
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