Skip to content

Commit d2fcc89

Browse files
authored
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
1 parent db9de43 commit d2fcc89

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

cmp/compare_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,19 @@ func comparerTests() []test {
696696
},
697697
wantEqual: true,
698698
reason: "verify that exporter does not leak implementation details",
699+
}, {
700+
label: label + "/ErrorPanic",
701+
x: io.EOF,
702+
y: io.EOF,
703+
wantPanic: "consider using cmpopts.EquateErrors",
704+
reason: "suggest cmpopts.EquateErrors when accessing unexported fields of error types",
705+
}, {
706+
label: label + "/ErrorEqual",
707+
x: io.EOF,
708+
y: io.EOF,
709+
opts: []cmp.Option{cmpopts.EquateErrors()},
710+
wantEqual: true,
711+
reason: "cmpopts.EquateErrors should equate these two errors as sentinel values",
699712
}}
700713
}
701714

cmp/options.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,14 @@ func (validator) apply(s *state, vx, vy reflect.Value) {
225225

226226
// Unable to Interface implies unexported field without visibility access.
227227
if !vx.CanInterface() || !vy.CanInterface() {
228-
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"
228+
help := "consider using a custom Comparer; if you control the implementation of type, you can also consider using an Exporter, AllowUnexported, or cmpopts.IgnoreUnexported"
229229
var name string
230230
if t := s.curPath.Index(-2).Type(); t.Name() != "" {
231231
// Named type with unexported fields.
232232
name = fmt.Sprintf("%q.%v", t.PkgPath(), t.Name()) // e.g., "path/to/package".MyType
233+
if _, ok := reflect.New(t).Interface().(error); ok {
234+
help = "consider using cmpopts.EquateErrors to compare error values"
235+
}
233236
} else {
234237
// Unnamed type with unexported fields. Derive PkgPath from field.
235238
var pkgPath string

0 commit comments

Comments
 (0)