aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/vet/structtag.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/vet/structtag.go')
-rw-r--r--src/cmd/vet/structtag.go25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/cmd/vet/structtag.go b/src/cmd/vet/structtag.go
index 814bbda594..872fde79ce 100644
--- a/src/cmd/vet/structtag.go
+++ b/src/cmd/vet/structtag.go
@@ -54,14 +54,37 @@ func checkCanonicalFieldTag(f *File, field *ast.Field, seen *map[[2]string]token
if val == "" || val == "-" || val[0] == ',' {
continue
}
+ if key == "xml" && len(field.Names) > 0 && field.Names[0].Name == "XMLName" {
+ // XMLName defines the XML element name of the struct being
+ // checked. That name cannot collide with element or attribute
+ // names defined on other fields of the struct. Vet does not have a
+ // check for untagged fields of type struct defining their own name
+ // by containing a field named XMLName; see issue 18256.
+ continue
+ }
if i := strings.Index(val, ","); i >= 0 {
+ if key == "xml" {
+ // Use a separate namespace for XML attributes.
+ for _, opt := range strings.Split(val[i:], ",") {
+ if opt == "attr" {
+ key += " attribute" // Key is part of the error message.
+ break
+ }
+ }
+ }
val = val[:i]
}
if *seen == nil {
*seen = map[[2]string]token.Pos{}
}
if pos, ok := (*seen)[[2]string{key, val}]; ok {
- f.Badf(field.Pos(), "struct field %s repeats %s tag %q also at %s", field.Names[0].Name, key, val, f.loc(pos))
+ var name string
+ if len(field.Names) > 0 {
+ name = field.Names[0].Name
+ } else {
+ name = field.Type.(*ast.Ident).Name
+ }
+ f.Badf(field.Pos(), "struct field %s repeats %s tag %q also at %s", name, key, val, f.loc(pos))
} else {
(*seen)[[2]string{key, val}] = field.Pos()
}