[tools] go/analysis/passes/printf: fix %w for non-fmt.Errorf functions

339 views
Skip to first unread message

Damien Neil (Gerrit)

unread,
Aug 17, 2021, 1:01:42 PM8/17/21
to Chressie Himpel, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go Bot, kokoro, Zvonimir Pavlinovic, Michael Matloob, Tim King, Guodong Li, golang-co...@googlegroups.com

Damien Neil submitted this change.

View Change

Approvals: Damien Neil: Looks good to me, approved; Trusted Zvonimir Pavlinovic: Looks good to me, approved
go/analysis/passes/printf: fix %w for non-fmt.Errorf functions

Previously all functions that were named Errorf have been treated like a
fmt.Errorf-based function. But only fmt.Errorf (and functions based on
fmt.Errorf) accept the %w verb. Fix that.

Updates golang/go#47641.

Change-Id: Iec5d0ae674c7dc817e85291dcfa064303eafba7e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/340409
Reviewed-by: Zvonimir Pavlinovic <zpavl...@google.com>
Reviewed-by: Damien Neil <dn...@google.com>
Trust: Damien Neil <dn...@google.com>
---
M go/analysis/passes/printf/printf.go
M go/analysis/passes/printf/testdata/src/a/a.go
2 files changed, 47 insertions(+), 12 deletions(-)

3 is the latest approved patch-set. The change was submitted with unreviewed changes in the following files: The name of the file: go/analysis/passes/printf/testdata/src/a/a.go Insertions: 3, Deletions: 3. ``` @@ -335:336, +335:336 @@ - fmt.Printf("%w", err) // want `fmt.Printf call has error-wrapping directive %w` + fmt.Printf("%w", err) // want `fmt.Printf does not support error-wrapping directive %w` @@ -337:338, +337:338 @@ - wt.Errorf("%w", err) // want `\(\*testing.common\).Errorf call has error-wrapping directive %w, which is only supported for functions backed by fmt.Errorf` + wt.Errorf("%w", err) // want `\(\*testing.common\).Errorf does not support error-wrapping directive %w` @@ -341:342, +341:342 @@ - Errorf(0, "%w", err) // want `a.Errorf call has error-wrapping directive %w, which is only supported for functions backed by fmt.Errorf` + Errorf(0, "%w", err) // want `a.Errorf does not support error-wrapping directive %w` ```
diff --git a/go/analysis/passes/printf/printf.go b/go/analysis/passes/printf/printf.go
index 53b3f2b..de0369a 100644
--- a/go/analysis/passes/printf/printf.go
+++ b/go/analysis/passes/printf/printf.go
@@ -490,7 +490,7 @@
_, ok = isPrint[strings.ToLower(fn.Name())]
}
if ok {
- if fn.Name() == "Errorf" {
+ if fn.FullName() == "fmt.Errorf" {
kind = KindErrorf
} else if strings.HasSuffix(fn.Name(), "f") {
kind = KindPrintf
diff --git a/go/analysis/passes/printf/testdata/src/a/a.go b/go/analysis/passes/printf/testdata/src/a/a.go
index 378bdff..89ef9ba 100644
--- a/go/analysis/passes/printf/testdata/src/a/a.go
+++ b/go/analysis/passes/printf/testdata/src/a/a.go
@@ -327,14 +327,26 @@
dbg("", 1) // no error "call has arguments but no formatting directive"

// %w
- _ = fmt.Errorf("%w", err)
- _ = fmt.Errorf("%#w", err)
- _ = fmt.Errorf("%[2]w %[1]s", "x", err)
- _ = fmt.Errorf("%[2]w %[1]s", e, "x") // want `fmt.Errorf format %\[2\]w has arg "x" of wrong type string`
- _ = fmt.Errorf("%w", "x") // want `fmt.Errorf format %w has arg "x" of wrong type string`
- _ = fmt.Errorf("%w %w", err, err) // want `fmt.Errorf call has more than one error-wrapping directive %w`
- fmt.Printf("%w", err) // want `fmt.Printf does not support error-wrapping directive %w`
- Errorf(0, "%w", err)
+ _ = fmt.Errorf("%w", err) // OK
+ _ = fmt.Errorf("%#w", err) // OK
+ _ = fmt.Errorf("%[2]w %[1]s", "x", err) // OK
+ _ = fmt.Errorf("%[2]w %[1]s", e, "x") // want `fmt.Errorf format %\[2\]w has arg "x" of wrong type string`
+ _ = fmt.Errorf("%w", "x") // want `fmt.Errorf format %w has arg "x" of wrong type string`
+ _ = fmt.Errorf("%w %w", err, err) // want `fmt.Errorf call has more than one error-wrapping directive %w`
+ fmt.Printf("%w", err) // want `fmt.Printf does not support error-wrapping directive %w`
+ var wt *testing.T
+ wt.Errorf("%w", err) // want `\(\*testing.common\).Errorf does not support error-wrapping directive %w`
+ wt.Errorf("%[1][3]d x", 1, 2) // want `\(\*testing.common\).Errorf format %\[1\]\[ has unknown verb \[`
+ wt.Errorf("%[1]d x", 1, 2) // OK
+ // Errorf is a printfWrapper, not an errorfWrapper.
+ Errorf(0, "%w", err) // want `a.Errorf does not support error-wrapping directive %w`
+ // %w should work on fmt.Errorf-based wrappers.
+ var es errorfStruct
+ var eis errorfIntStruct
+ var ess errorfStringStruct
+ es.Errorf("%w", err) // OK
+ eis.Errorf(0, "%w", err) // OK
+ ess.Errorf("ERROR", "%w", err) // OK
}

func someString() string { return "X" }
@@ -379,13 +391,36 @@

// Errorf is used by the test for a case in which the first parameter
// is not a format string.
-func Errorf(i int, format string, args ...interface{}) { // want Errorf:"errorfWrapper"
- _ = fmt.Errorf(format, args...)
+func Errorf(i int, format string, args ...interface{}) { // want Errorf:"printfWrapper"
+ fmt.Sprintf(format, args...)
}

// errorf is used by the test for a case in which the function accepts multiple
// string parameters before variadic arguments
-func errorf(level, format string, args ...interface{}) { // want errorf:"errorfWrapper"
+func errorf(level, format string, args ...interface{}) { // want errorf:"printfWrapper"
+ fmt.Sprintf(format, args...)
+}
+
+type errorfStruct struct{}
+
+// Errorf is used to test %w works on errorf wrappers.
+func (errorfStruct) Errorf(format string, args ...interface{}) { // want Errorf:"errorfWrapper"
+ _ = fmt.Errorf(format, args...)
+}
+
+type errorfStringStruct struct{}
+
+// Errorf is used by the test for a case in which the function accepts multiple
+// string parameters before variadic arguments
+func (errorfStringStruct) Errorf(level, format string, args ...interface{}) { // want Errorf:"errorfWrapper"
+ _ = fmt.Errorf(format, args...)
+}
+
+type errorfIntStruct struct{}
+
+// Errorf is used by the test for a case in which the first parameter
+// is not a format string.
+func (errorfIntStruct) Errorf(i int, format string, args ...interface{}) { // want Errorf:"errorfWrapper"
_ = fmt.Errorf(format, args...)
}


To view, visit change 340409. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Iec5d0ae674c7dc817e85291dcfa064303eafba7e
Gerrit-Change-Number: 340409
Gerrit-PatchSet: 5
Gerrit-Owner: Chressie Himpel <chre...@google.com>
Gerrit-Reviewer: Damien Neil <dn...@google.com>
Gerrit-Reviewer: Go Bot <go...@golang.org>
Gerrit-Reviewer: Michael Matloob <mat...@golang.org>
Gerrit-Reviewer: Zvonimir Pavlinovic <zpavl...@google.com>
Gerrit-Reviewer: kokoro <noreply...@google.com>
Gerrit-CC: Guodong Li <guod...@google.com>
Gerrit-CC: Tim King <tak...@google.com>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages