Skip to content

Commit 8709d8a

Browse files
committed
cue: simplify the reflect checks in Value.Decode
reflect.Value.CanSet is documented as: A Value can be changed only if it is addressable and was not obtained by the use of unexported struct fields. We call reflect.ValueOf ourselves here, so we cannot have reached for an unexported struct field via reflect.Value.Field. The only other requirement is that the value must be addressable, which can only be met if x was a non-nil pointer that we dereferenced. This was already the expectation that Decode had on x; it just wasn't documented very clearly, but now it is. We can then replace the CanSet check with a check for a non-nil pointer, which exactly matches the logic from APIs like encoding/json.Unmarshal. Signed-off-by: Daniel Martí <[email protected]> Change-Id: I919026530c683a2c9b10f1484910f9cb66fee861 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1168928 Unity-Result: CUE porcuepine <[email protected]> Reviewed-by: Roger Peppe <[email protected]> TryBot-Result: CUEcueckoo <[email protected]>
1 parent b8cb9a4 commit 8709d8a

File tree

1 file changed

+7
-10
lines changed

1 file changed

+7
-10
lines changed

cue/decode.go

+7-10
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,18 @@ import (
3030
"cuelang.org/go/internal/core/adt"
3131
)
3232

33-
// Decode initializes x with Value v. If x is a struct, it will validate the
34-
// constraints specified in the field tags.
33+
// Decode initializes the value pointed to by x with Value v.
34+
// An error is returned if x is nil or not a pointer.
35+
//
36+
// If x is a struct, Decode will validate the constraints specified in the field tags.
3537
func (v Value) Decode(x interface{}) error {
3638
var d decoder
3739
w := reflect.ValueOf(x)
38-
switch {
39-
case !reflect.Indirect(w).CanSet():
40+
if w.Kind() != reflect.Pointer || w.IsNil() {
4041
d.addErr(errors.Newf(v.Pos(), "cannot decode into unsettable value"))
41-
42-
default:
43-
if w.Kind() == reflect.Ptr {
44-
w = w.Elem()
45-
}
46-
d.decode(w, v, false)
42+
return d.errs
4743
}
44+
d.decode(w.Elem(), v, false)
4845
return d.errs
4946
}
5047

0 commit comments

Comments
 (0)