From 3c1b7bc7212cd894dae684ae064f4e7708b080ec Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 4 Sep 2018 17:18:22 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- src/go/types/expr.go | 19 ++++++++++++------- src/go/types/testdata/issues.src | 8 ++++++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/go/types/expr.go b/src/go/types/expr.go index f0acc7845d..c65c9e7681 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1156,15 +1156,20 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind { goto Error } n := check.indexedElts(e.Elts, utyp.elem, utyp.len) - // 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 we have an array of unknown length (usually [...]T arrays, but also + // arrays [n]T where n is invalid) set the length now that we know it and + // 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 { utyp.len = n - // e.Type may be missing in case of errors. - // In "map[string][...]int{"": {1, 2, 3}}}, - // an error is reported for the outer literal, - // then [...]int is used as a hint for the inner literal. + // e.Type is missing if we have a composite literal element + // that is itself a composite literal with omitted type. In + // that case there is nothing to record (there is no type in + // the source at that point). if e.Type != nil { check.recordTypeAndValue(e.Type, typexpr, utyp, nil) } diff --git a/src/go/types/testdata/issues.src b/src/go/types/testdata/issues.src index d85e04e68c..13f8309c82 100644 --- a/src/go/types/testdata/issues.src +++ b/src/go/types/testdata/issues.src @@ -294,3 +294,11 @@ type registry struct { type allocator struct { _ [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: {}} -- 2.50.0