diff options
author | Joe Tsai <joetsai@digital-static.net> | 2020-08-18 12:37:11 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-18 12:37:11 -0700 |
commit | d2fcc899bdc2d134b7c00e36137260db963e193c (patch) | |
tree | c8b2079fb7f32dab92d072a80cfb45688b9a0f94 /cmp | |
parent | db9de4321f4e5db7c6f996d170ebce7953f22f8e (diff) | |
download | go-cmp-d2fcc899bdc2d134b7c00e36137260db963e193c.tar.gz |
Suggest use of cmpopts.EquateErrors (#234)
If cmp panics because it is trying to access an unexported field,
specially suggest the use of cmpopts.EquateErrors if the parent type
implements the error interface.
Fixes #233
Diffstat (limited to 'cmp')
-rw-r--r-- | cmp/compare_test.go | 13 | ||||
-rw-r--r-- | cmp/options.go | 5 |
2 files changed, 17 insertions, 1 deletions
diff --git a/cmp/compare_test.go b/cmp/compare_test.go index ba39bde..bdcc06b 100644 --- a/cmp/compare_test.go +++ b/cmp/compare_test.go @@ -696,6 +696,19 @@ func comparerTests() []test { }, wantEqual: true, reason: "verify that exporter does not leak implementation details", + }, { + label: label + "/ErrorPanic", + x: io.EOF, + y: io.EOF, + wantPanic: "consider using cmpopts.EquateErrors", + reason: "suggest cmpopts.EquateErrors when accessing unexported fields of error types", + }, { + label: label + "/ErrorEqual", + x: io.EOF, + y: io.EOF, + opts: []cmp.Option{cmpopts.EquateErrors()}, + wantEqual: true, + reason: "cmpopts.EquateErrors should equate these two errors as sentinel values", }} } diff --git a/cmp/options.go b/cmp/options.go index abbd2a6..4b0407a 100644 --- a/cmp/options.go +++ b/cmp/options.go @@ -225,11 +225,14 @@ func (validator) apply(s *state, vx, vy reflect.Value) { // Unable to Interface implies unexported field without visibility access. if !vx.CanInterface() || !vy.CanInterface() { - const help = "consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported" + help := "consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported" var name string if t := s.curPath.Index(-2).Type(); t.Name() != "" { // Named type with unexported fields. name = fmt.Sprintf("%q.%v", t.PkgPath(), t.Name()) // e.g., "path/to/package".MyType + if _, ok := reflect.New(t).Interface().(error); ok { + help = "consider using cmpopts.EquateErrors to compare error values" + } } else { // Unnamed type with unexported fields. Derive PkgPath from field. var pkgPath string |