diff options
author | Joe Tsai <joetsai@digital-static.net> | 2020-06-17 17:25:47 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-17 17:25:47 -0700 |
commit | 77ae86f624cb174e21763cffcbbf070eb06cb016 (patch) | |
tree | dd32bd59eb58b50d44dee2efa06ac36f8daa92a1 /cmp/internal | |
parent | c49bfce0ac9115b09320b47c3b9534cc5afd4579 (diff) | |
download | go-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.go | 10 | ||||
-rw-r--r-- | cmp/internal/value/pointer_unsafe.go | 10 |
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) +} |