val := s.evalPipeline(dot, pipe)
truth, ok := isTrue(val)
if !ok {
- s.errorf("if/with can't use value of type %T", val.Interface())
+ s.errorf("if/with can't use %v", val)
}
if truth {
if typ == parse.NodeWith {
// isTrue returns whether the value is 'true', in the sense of not the zero of its type,
// and whether the value has a meaningful truth value.
func isTrue(val reflect.Value) (truth, ok bool) {
+ if !val.IsValid() {
+ // Something like var x interface{}, never set. It's a form of nil.
+ return false, true
+ }
switch val.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
truth = val.Len() > 0
truth = val.Bool()
case reflect.Complex64, reflect.Complex128:
truth = val.Complex() != 0
- case reflect.Chan, reflect.Func, reflect.Ptr:
+ case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
truth = !val.IsNil()
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
truth = val.Int() != 0
// Was taking address of interface field, so method set was empty.
{"bug2", "{{$.NonEmptyInterface.Method0}}", "M0", tVal, true},
// Struct values were not legal in with - mere oversight.
- {"bug4", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
+ {"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
+ // Nil interface values in if.
+ {"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true},
}
func zeroArgs() string {