Don't flag var typing when the RHS is an untyped constant
and the LHS type is not its default type.
diff --git a/lint.go b/lint.go
index 17d7ec8..f1b01d4 100644
--- a/lint.go
+++ b/lint.go
@@ -645,8 +645,8 @@
if _, ok := v.Type.(*ast.InterfaceType); ok {
return false
}
- // If the RHS is an int literal, only warn if the LHS type is "int".
- if isIntLiteral(rhs) && !isIdent(v.Type, "int") {
+ // If the RHS is an untyped const, only warn if the LHS type is its default type.
+ if defType, ok := isUntypedConst(rhs); ok && !isIdent(v.Type, defType) {
return false
}
f.errorf(v.Type, 0.8, "", "should omit type %s from declaration of var %s; it will be inferred from the right-hand side", f.render(v.Type), v.Names[0])
@@ -948,6 +948,27 @@
return ok && lit.Kind == token.INT && lit.Value == "1"
}
+var basicLitKindTypes = map[token.Token]string{
+ token.FLOAT: "float64",
+ token.IMAG: "complex128",
+ token.CHAR: "rune",
+ token.STRING: "string",
+}
+
+// isUntypedConst reports whether expr is an untyped constant,
+// and indicates what its default type is.
+func isUntypedConst(expr ast.Expr) (defType string, ok bool) {
+ if isIntLiteral(expr) {
+ return "int", true
+ }
+ if bl, ok := expr.(*ast.BasicLit); ok {
+ if dt, ok := basicLitKindTypes[bl.Kind]; ok {
+ return dt, true
+ }
+ }
+ return "", false
+}
+
func isIntLiteral(expr ast.Expr) bool {
// Either a BasicLit with Kind token.INT,
// or some combination of a UnaryExpr with Op token.SUB (for "-<lit>")
diff --git a/testdata/var-decl.go b/testdata/var-decl.go
index 01c9dd6..bbc687c 100644
--- a/testdata/var-decl.go
+++ b/testdata/var-decl.go
@@ -34,6 +34,13 @@
var parenID int64 = (17)
var crazyID int64 = -(-(-(-9)))
+// Same, but for strings and floats.
+type stringT string
+type floatT float64
+
+var stringV stringT = "abc"
+var floatV floatT = 123.45
+
// No warning because the LHS names an interface type.
var data interface{} = googleIPs