From bc32ebfe1cf7b0baf9765d657ba1a5f277936e76 Mon Sep 17 00:00:00 2001 From: Dane Harrigan <72265290+dane@users.noreply.github.com> Date: Wed, 1 Dec 2021 23:45:50 -0800 Subject: [PATCH] Each function passes the correct value or pointer to rules. The combination of Elem().Interface() does not return a pointer, even if the original variable was a pointer. Passing by value to validation rules becomes a problem when the value is a struct with a private mutex. This is the case with structs generated with protoc-gen-go. `go vet`'s copylocks check identifies the problem. --- each.go | 2 +- each_test.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/each.go b/each.go index 2cc7253..8eb022c 100644 --- a/each.go +++ b/each.go @@ -78,7 +78,7 @@ func (r EachRule) getInterface(value reflect.Value) interface{} { if value.IsNil() { return nil } - return value.Elem().Interface() + return value.Interface() default: return value.Interface() } diff --git a/each_test.go b/each_test.go index 4199afd..731059e 100644 --- a/each_test.go +++ b/each_test.go @@ -72,3 +72,16 @@ func TestEachWithContext(t *testing.T) { assertError(t, test.err, err, test.tag) } } + +func TestEachAndBy(t *testing.T) { + var byAddr bool + var s string + Each(By(func(v interface{}) error { + _, byAddr = v.(*string) + return nil + })).Validate([]*string{&s}) + + if !byAddr { + t.Fatal("slice of pointers does not get passed to `By` function by ref") + } +}