]> Cypherpunks repositories - gostls13.git/commitdiff
exp/template: truth for interface values.
authorRob Pike <r@golang.org>
Wed, 10 Aug 2011 22:27:16 +0000 (08:27 +1000)
committerRob Pike <r@golang.org>
Wed, 10 Aug 2011 22:27:16 +0000 (08:27 +1000)
Also protect against invalid (zero Value) reflect.Values.

R=rsc, gri
CC=golang-dev
https://golang.org/cl/4810094

src/pkg/exp/template/exec.go
src/pkg/exp/template/exec_test.go

index 7d7a9c73268921f1f8f4a0b4c91daec94649bf9c..dafdaee914e09f696fb03a5f8b9c37298d1c93c4 100644 (file)
@@ -148,7 +148,7 @@ func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.
        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 {
@@ -164,6 +164,10 @@ func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.
 // 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
@@ -171,7 +175,7 @@ func isTrue(val reflect.Value) (truth, ok bool) {
                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
index b7884744027e6d68151359848002cf5113ec6800..4013f2ef49bd1910096332ee07c190a971e764c4 100644 (file)
@@ -366,7 +366,9 @@ var execTests = []execTest{
        // 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 {