aboutsummaryrefslogtreecommitdiff
path: root/cmp
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2019-02-16 21:41:22 -0800
committerGitHub <noreply@github.com>2019-02-16 21:41:22 -0800
commit01193de5d3d14be0bf1844802a51f8c29eab34a8 (patch)
treef4809be296ef45f9c9a248a34257547dbac670cd /cmp
parent8ca8745eefdc2a98d5e00dab0e88b036d7bcd62c (diff)
downloadgo-cmp-01193de5d3d14be0bf1844802a51f8c29eab34a8.tar.gz
Commit to not comparing NaN keys (#110)
Go 1.12 adds the ability to range over NaN keys. However, it turns out that even with this functionality, there is still no obvious way to compare the values. Thus, commit to behavior of just panicking and letting obscure maps like this be handled by a custom Comparer. Fixes #93
Diffstat (limited to 'cmp')
-rw-r--r--cmp/compare.go25
1 files changed, 15 insertions, 10 deletions
diff --git a/cmp/compare.go b/cmp/compare.go
index 7d172ba..a7bcaab 100644
--- a/cmp/compare.go
+++ b/cmp/compare.go
@@ -36,12 +36,6 @@ import (
"github.com/google/go-cmp/cmp/internal/value"
)
-// BUG(dsnet): Maps with keys containing NaN values cannot be properly compared due to
-// the reflection package's inability to retrieve such entries. Equal will panic
-// anytime it comes across a NaN key, but this behavior may change.
-//
-// See https://golang.org/issue/11104 for more details.
-
var nothing = reflect.Value{}
// Equal reports whether x and y are equal by recursively applying the
@@ -504,10 +498,21 @@ func (s *state) compareMap(vx, vy reflect.Value, t reflect.Type) {
s.report(false, nothing, vvy)
default:
// It is possible for both vvx and vvy to be invalid if the
- // key contained a NaN value in it. There is no way in
- // reflection to be able to retrieve these values.
- // See https://golang.org/issue/11104
- panic(fmt.Sprintf("%#v has map key with NaNs", s.curPath))
+ // key contained a NaN value in it.
+ //
+ // Even with the ability to retrieve NaN keys in Go 1.12,
+ // there still isn't a sensible way to compare the values since
+ // a NaN key may map to multiple unordered values.
+ // The most reasonable way to compare NaNs would be to compare the
+ // set of values. However, this is impossible to do efficiently
+ // since set equality is provably an O(n^2) operation given only
+ // an Equal function. If we had a Less function or Hash function,
+ // this could be done in O(n*log(n)) or O(n), respectively.
+ //
+ // Rather than adding complex logic to deal with NaNs, make it
+ // the user's responsibility to compare such obscure maps.
+ const help = "consider providing a Comparer to compare the map"
+ panic(fmt.Sprintf("%#v has map key with NaNs\n%s", s.curPath, help))
}
}
}