aboutsummaryrefslogtreecommitdiff
path: root/cmp/internal
diff options
context:
space:
mode:
authorJoe Tsai <joetsai@digital-static.net>2020-06-17 17:25:47 -0700
committerGitHub <noreply@github.com>2020-06-17 17:25:47 -0700
commit77ae86f624cb174e21763cffcbbf070eb06cb016 (patch)
treedd32bd59eb58b50d44dee2efa06ac36f8daa92a1 /cmp/internal
parentc49bfce0ac9115b09320b47c3b9534cc5afd4579 (diff)
downloadgo-cmp-77ae86f624cb174e21763cffcbbf070eb06cb016.tar.gz
Improve reporting of values with cycles (#217)
Previously, the reporter could handle formatting values with cycles in that it did not crash with a stack overflow. However, the output was not particularly understandable as it did not surface to the user why a particular value was truncated, and if it was truncated due to a cyclic reference, what was the referent. This change annotates the reporter tree with pointer information so that a later pass can inject reference information if it is needed to produce more understandable output. Consider the following example: map[string]*cmp_test.CycleAlpha{ "Foo": &⟪ref#0⟫{ Name: "Foo", Bravos: map[string]*cmp_test.CycleBravo{ "FooBravo": &{ - ID: 101, + ID: 0, Name: "FooBravo", Mods: 100, Alphas: {"Foo": &⟪ref#0⟫(...)}, }, }, }, } This graph contains a cycle. To ensure that a graph can be formatted, the cycle is truncated as indicated with: &⟪ref#0⟫(...). The referent was identified earlier with: &⟪ref#0⟫{...}.
Diffstat (limited to 'cmp/internal')
-rw-r--r--cmp/internal/value/pointer_purego.go10
-rw-r--r--cmp/internal/value/pointer_unsafe.go10
2 files changed, 20 insertions, 0 deletions
diff --git a/cmp/internal/value/pointer_purego.go b/cmp/internal/value/pointer_purego.go
index 0a01c47..e9e384a 100644
--- a/cmp/internal/value/pointer_purego.go
+++ b/cmp/internal/value/pointer_purego.go
@@ -21,3 +21,13 @@ func PointerOf(v reflect.Value) Pointer {
// assumes that the GC implementation does not use a moving collector.
return Pointer{v.Pointer(), v.Type()}
}
+
+// IsNil reports whether the pointer is nil.
+func (p Pointer) IsNil() bool {
+ return p.p == 0
+}
+
+// Uintptr returns the pointer as a uintptr.
+func (p Pointer) Uintptr() uintptr {
+ return p.p
+}
diff --git a/cmp/internal/value/pointer_unsafe.go b/cmp/internal/value/pointer_unsafe.go
index da134ae..b50c17e 100644
--- a/cmp/internal/value/pointer_unsafe.go
+++ b/cmp/internal/value/pointer_unsafe.go
@@ -24,3 +24,13 @@ func PointerOf(v reflect.Value) Pointer {
// which is necessary if the GC ever uses a moving collector.
return Pointer{unsafe.Pointer(v.Pointer()), v.Type()}
}
+
+// IsNil reports whether the pointer is nil.
+func (p Pointer) IsNil() bool {
+ return p.p == nil
+}
+
+// Uintptr returns the pointer as a uintptr.
+func (p Pointer) Uintptr() uintptr {
+ return uintptr(p.p)
+}