diff --git a/src/cmd/vet/composite.go b/src/cmd/vet/composite.go index f704f181bf..fc48033182 100644 --- a/src/cmd/vet/composite.go +++ b/src/cmd/vet/composite.go @@ -38,7 +38,15 @@ func checkUnkeyedLiteral(f *File, node ast.Node) { // skip whitelisted types return } - if _, ok := typ.Underlying().(*types.Struct); !ok { + under := typ.Underlying() + for { + ptr, ok := under.(*types.Pointer) + if !ok { + break + } + under = ptr.Elem().Underlying() + } + if _, ok := under.(*types.Struct); !ok { // skip non-struct composite literals return } @@ -69,6 +77,10 @@ func isLocalType(f *File, typeName string) bool { return true } + // make *foo.bar, **foo.bar, etc match with the "foo." prefix + // below + typeName = strings.TrimLeft(typeName, "*") + pkgname := f.pkg.path if strings.HasPrefix(typeName, pkgname+".") { return true diff --git a/src/cmd/vet/testdata/composite.go b/src/cmd/vet/testdata/composite.go index 2e6ce262cc..ce9bc78e49 100644 --- a/src/cmd/vet/testdata/composite.go +++ b/src/cmd/vet/testdata/composite.go @@ -62,6 +62,11 @@ var Okay6 = []MyStruct{ {"aa", "bb", "cc"}, } +var Okay7 = []*MyStruct{ + {"foo", "bar", "baz"}, + {"aa", "bb", "cc"}, +} + // Testing is awkward because we need to reference things from a separate package // to trigger the warnings. @@ -101,3 +106,15 @@ var whitelistedPoint = image.Point{1, 2} // Do not check type from unknown package. // See issue 15408. var unknownPkgVar = unknownpkg.Foobar{"foo", "bar"} + +// A named pointer slice of CaseRange to test issue 23539. In +// particular, we're interested in how some slice elements omit their +// type. +var goodNamedPointerSliceLiteral = []*unicode.CaseRange{ + {Lo: 1, Hi: 2}, + &unicode.CaseRange{Lo: 1, Hi: 2}, +} +var badNamedPointerSliceLiteral = []*unicode.CaseRange{ + {1, 2}, // ERROR "unkeyed fields" + &unicode.CaseRange{1, 2}, // ERROR "unkeyed fields" +}