summaryrefslogtreecommitdiff
path: root/src/cmd/vet/taglit.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/vet/taglit.go')
-rw-r--r--src/cmd/vet/taglit.go54
1 files changed, 36 insertions, 18 deletions
diff --git a/src/cmd/vet/taglit.go b/src/cmd/vet/taglit.go
index 0324e37b0..bcad2fe0a 100644
--- a/src/cmd/vet/taglit.go
+++ b/src/cmd/vet/taglit.go
@@ -9,32 +9,52 @@ package main
import (
"flag"
"go/ast"
- "go/types"
"strings"
)
var compositeWhiteList = flag.Bool("compositewhitelist", true, "use composite white list; for testing only")
-// checkUntaggedLiteral checks if a composite literal is an struct literal with
+// checkUntaggedLiteral checks if a composite literal is a struct literal with
// untagged fields.
func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
if !vet("composites") {
return
}
- // Check that the CompositeLit's type is a slice or array (which needs no tag), if possible.
- typ := f.pkg.types[c]
- if typ != nil {
- // If it's a named type, pull out the underlying type.
- if namedType, ok := typ.(*types.NamedType); ok {
- typ = namedType.Underlying
- }
- switch typ.(type) {
- case *types.Slice:
- return
- case *types.Array:
- return
+ typ := c.Type
+ for {
+ if typ1, ok := c.Type.(*ast.ParenExpr); ok {
+ typ = typ1
+ continue
}
+ break
+ }
+
+ switch typ.(type) {
+ case *ast.ArrayType:
+ return
+ case *ast.MapType:
+ return
+ case *ast.StructType:
+ return // a literal struct type does not need to use tags
+ case *ast.Ident:
+ // A simple type name like t or T does not need tags either,
+ // since it is almost certainly declared in the current package.
+ // (The exception is names being used via import . "pkg", but
+ // those are already breaking the Go 1 compatibility promise,
+ // so not reporting potential additional breakage seems okay.)
+ return
+ }
+
+ // Otherwise the type is a selector like pkg.Name.
+ // We only care if pkg.Name is a struct, not if it's a map, array, or slice.
+ isStruct, typeString := f.pkg.isStruct(c)
+ if !isStruct {
+ return
+ }
+
+ if typeString == "" { // isStruct doesn't know
+ typeString = f.gofmt(typ)
}
// It's a struct, or we can't tell it's not a struct because we don't have types.
@@ -64,7 +84,7 @@ func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
// Convert the package name to an import path, and compare to a whitelist.
path := pkgPath(f, pkg.Name)
if path == "" {
- f.Warnf(c.Pos(), "unresolvable package for %s.%s literal", pkg.Name, s.Sel.Name)
+ f.Badf(c.Pos(), "unresolvable package for %s.%s literal", pkg.Name, s.Sel.Name)
return
}
typeName := path + "." + s.Sel.Name
@@ -72,7 +92,7 @@ func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
return
}
- f.Warnf(c.Pos(), "%s composite literal uses untagged fields", typ)
+ f.Warn(c.Pos(), typeString+" composite literal uses untagged fields")
}
// pkgPath returns the import path "image/png" for the package name "png".
@@ -119,8 +139,6 @@ var untaggedLiteralWhitelist = map[string]bool{
"encoding/xml.CharData": true,
"encoding/xml.Comment": true,
"encoding/xml.Directive": true,
- "exp/norm.Decomposition": true,
- "exp/types.ObjList": true,
"go/scanner.ErrorList": true,
"image/color.Palette": true,
"net.HardwareAddr": true,