Skip to content

Commit

Permalink
Suggest use of cmpopts.EquateErrors (#234)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dsnet authored Aug 18, 2020
1 parent db9de43 commit d2fcc89
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 1 deletion.
13 changes: 13 additions & 0 deletions cmp/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
}}
}

Expand Down
5 changes: 4 additions & 1 deletion cmp/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d2fcc89

Please sign in to comment.