@@ -73,6 +73,12 @@ type varScope struct {
7373type info struct {
7474 method bool
7575 fn * ast.Function
76+
77+ // elem is element type of array or map.
78+ // Arrays created with type []any, but
79+ // we would like to detect expressions
80+ // like `42 in ["a"]` as invalid.
81+ elem reflect.Type
7682}
7783
7884func (v * checker ) visit (node ast.Node ) (reflect.Type , info ) {
@@ -227,7 +233,7 @@ func (v *checker) UnaryNode(node *ast.UnaryNode) (reflect.Type, info) {
227233
228234func (v * checker ) BinaryNode (node * ast.BinaryNode ) (reflect.Type , info ) {
229235 l , _ := v .visit (node .Left )
230- r , _ := v .visit (node .Right )
236+ r , ri := v .visit (node .Right )
231237
232238 l = deref (l )
233239 r = deref (r )
@@ -351,6 +357,9 @@ func (v *checker) BinaryNode(node *ast.BinaryNode) (reflect.Type, info) {
351357 if ! isComparable (l , r .Elem ()) {
352358 return v .error (node , "cannot use %v as type %v in array" , l , r .Elem ())
353359 }
360+ if ! isComparable (l , ri .elem ) {
361+ return v .error (node , "cannot use %v as type %v in array" , l , ri .elem )
362+ }
354363 return boolType , info {}
355364 }
356365 if isAny (l ) && anyOf (r , isString , isArray , isMap ) {
@@ -1067,8 +1076,21 @@ func (v *checker) ConditionalNode(node *ast.ConditionalNode) (reflect.Type, info
10671076}
10681077
10691078func (v * checker ) ArrayNode (node * ast.ArrayNode ) (reflect.Type , info ) {
1070- for _ , node := range node .Nodes {
1071- v .visit (node )
1079+ var prev reflect.Type
1080+ allElementsAreSameType := true
1081+ for i , node := range node .Nodes {
1082+ curr , _ := v .visit (node )
1083+ if i > 0 {
1084+ if curr == nil || prev == nil {
1085+ allElementsAreSameType = false
1086+ } else if curr .Kind () != prev .Kind () {
1087+ allElementsAreSameType = false
1088+ }
1089+ }
1090+ prev = curr
1091+ }
1092+ if allElementsAreSameType && prev != nil {
1093+ return arrayType , info {elem : prev }
10721094 }
10731095 return arrayType , info {}
10741096}
0 commit comments