From b97b26d9f6b7bf2d9cc9337ab22917da1b354089 Mon Sep 17 00:00:00 2001 From: Noah Treuhaft Date: Wed, 18 Mar 2026 13:52:44 -0400 Subject: [PATCH] remove implicit cast from enum to uint64 index The arithmetic operators implicitly cast an enum value to a uint64 corresponding to the value's index in the enum type. The "==" and "!=" comparison operators (but no others) also perform this implicit cast in sam (but not in vam). This isn't an important feature, so rather than make the comparison behavior more consistent, remove it. --- runtime/sam/expr/eval.go | 10 +--------- runtime/vam/expr/arith.go | 16 ++-------------- runtime/ztests/expr/cast/bool.yaml | 2 ++ runtime/ztests/expr/cast/bytes.yaml | 2 ++ runtime/ztests/expr/cast/duration.yaml | 2 ++ runtime/ztests/expr/cast/float.yaml | 2 ++ runtime/ztests/expr/cast/int.yaml | 2 ++ runtime/ztests/expr/cast/ip.yaml | 2 ++ runtime/ztests/expr/cast/map.yaml | 2 ++ runtime/ztests/expr/cast/net.yaml | 2 ++ runtime/ztests/expr/cast/record.yaml | 2 ++ runtime/ztests/expr/cast/time.yaml | 2 ++ runtime/ztests/expr/cast/type.yaml | 2 ++ runtime/ztests/expr/cast/uint.yaml | 2 ++ runtime/ztests/expr/enum.yaml | 13 ------------- 15 files changed, 27 insertions(+), 36 deletions(-) delete mode 100644 runtime/ztests/expr/enum.yaml diff --git a/runtime/sam/expr/eval.go b/runtime/sam/expr/eval.go index f627db2fc4..72e3cf1742 100644 --- a/runtime/sam/expr/eval.go +++ b/runtime/sam/expr/eval.go @@ -273,15 +273,7 @@ func (n *numeric) eval(this super.Value) (super.Value, super.Value, *super.Value if rhs.IsError() { return super.Null, super.Null, &rhs } - return enumToIndex(lhs), enumToIndex(rhs), nil -} - -// enumToIndex converts an enum to its index value. -func enumToIndex(val super.Value) super.Value { - if _, ok := val.Type().(*super.TypeEnum); ok { - return super.NewValue(super.TypeUint64, val.Bytes()) - } - return val + return lhs, rhs, nil } type Compare struct { diff --git a/runtime/vam/expr/arith.go b/runtime/vam/expr/arith.go index 04420c0775..7b7f2cef42 100644 --- a/runtime/vam/expr/arith.go +++ b/runtime/vam/expr/arith.go @@ -31,8 +31,8 @@ func (a *Arith) eval(vecs ...vector.Any) (out vector.Any) { if vec, ok := CheckForNullThenError(vecs); ok { return vec } - lhs := enumToIndex(vector.Under(vecs[0])) - rhs := enumToIndex(vector.Under(vecs[1])) + lhs := vector.Under(vecs[0]) + rhs := vector.Under(vecs[1]) lhs, rhs, errVal := coerceVals(a.sctx, lhs, rhs) if errVal != nil { return errVal @@ -71,18 +71,6 @@ func (a *Arith) eval(vecs ...vector.Any) (out vector.Any) { return f(lhs, rhs) } -func enumToIndex(vec vector.Any) vector.Any { - switch vec := vec.(type) { - case *vector.View: - if enum, ok := vec.Any.(*vector.Enum); ok { - return vector.Pick(enum.Uint, vec.Index) - } - case *vector.Enum: - return vec.Uint - } - return vec -} - func (a *Arith) evalDivideByZero(kind vector.Kind, lhs, rhs vector.Any) vector.Any { var errs []uint32 var out vector.Any diff --git a/runtime/ztests/expr/cast/bool.yaml b/runtime/ztests/expr/cast/bool.yaml index 5db99035e9..74d3e61423 100644 --- a/runtime/ztests/expr/cast/bool.yaml +++ b/runtime/ztests/expr/cast/bool.yaml @@ -24,6 +24,7 @@ input: | [1,2] |[1,2]| |{"x":1}| + "e2"::enum(e1,e2) output: | true @@ -47,3 +48,4 @@ output: | error({message:"cannot cast to bool",on:[1,2]}) error({message:"cannot cast to bool",on:|[1,2]|}) error({message:"cannot cast to bool",on:|{"x":1}|}) + error({message:"cannot cast to bool",on:"e2"::enum(e1,e2)}) diff --git a/runtime/ztests/expr/cast/bytes.yaml b/runtime/ztests/expr/cast/bytes.yaml index fe85be9441..a7d60a7d6e 100644 --- a/runtime/ztests/expr/cast/bytes.yaml +++ b/runtime/ztests/expr/cast/bytes.yaml @@ -10,6 +10,7 @@ input: | null null::({}|null) {x:"foo"} + "e2"::enum(e1,e2) error("bad") output: | @@ -20,4 +21,5 @@ output: | null::(bytes|null) null::(bytes|null) error({message:"cannot cast to bytes",on:{x:"foo"}}) + error({message:"cannot cast to bytes",on:"e2"::enum(e1,e2)}) error("bad") diff --git a/runtime/ztests/expr/cast/duration.yaml b/runtime/ztests/expr/cast/duration.yaml index 90e69cceb1..7d08557787 100644 --- a/runtime/ztests/expr/cast/duration.yaml +++ b/runtime/ztests/expr/cast/duration.yaml @@ -17,6 +17,7 @@ input: | [1,2] |[1,2]| |{"x":1}| + "e2"::enum(e1,e2) output: | 10d @@ -33,3 +34,4 @@ output: | error({message:"cannot cast to duration",on:[1,2]}) error({message:"cannot cast to duration",on:|[1,2]|}) error({message:"cannot cast to duration",on:|{"x":1}|}) + error({message:"cannot cast to duration",on:"e2"::enum(e1,e2)}) diff --git a/runtime/ztests/expr/cast/float.yaml b/runtime/ztests/expr/cast/float.yaml index 7eb711e9e4..a4e3c851f1 100644 --- a/runtime/ztests/expr/cast/float.yaml +++ b/runtime/ztests/expr/cast/float.yaml @@ -58,6 +58,7 @@ input: | [1,2] |[1,2]| |{"x":1}| + "e2"::enum(e1,e2) output: | error("bad") @@ -65,3 +66,4 @@ output: | error({message:"cannot cast to float64",on:[1,2]}) error({message:"cannot cast to float64",on:|[1,2]|}) error({message:"cannot cast to float64",on:|{"x":1}|}) + error({message:"cannot cast to float64",on:"e2"::enum(e1,e2)}) diff --git a/runtime/ztests/expr/cast/int.yaml b/runtime/ztests/expr/cast/int.yaml index 8485eba79a..ffb2dd6353 100644 --- a/runtime/ztests/expr/cast/int.yaml +++ b/runtime/ztests/expr/cast/int.yaml @@ -74,6 +74,7 @@ input: | [1,2] |[1,2]| |{"x":1}| + "e2"::enum(e1,e2) output: | error("bad") @@ -81,3 +82,4 @@ output: | error({message:"cannot cast to int64",on:[1,2]}) error({message:"cannot cast to int64",on:|[1,2]|}) error({message:"cannot cast to int64",on:|{"x":1}|}) + error({message:"cannot cast to int64",on:"e2"::enum(e1,e2)}) diff --git a/runtime/ztests/expr/cast/ip.yaml b/runtime/ztests/expr/cast/ip.yaml index 4f6b63337f..b163f16af8 100644 --- a/runtime/ztests/expr/cast/ip.yaml +++ b/runtime/ztests/expr/cast/ip.yaml @@ -12,6 +12,7 @@ input: | 1.1.1.2::=named 34 35 + "e2"::enum(e1,e2) error("bad") output: | @@ -24,4 +25,5 @@ output: | 1.1.1.2 error({message:"cannot cast to ip",on:34}) error({message:"cannot cast to ip",on:35}) + error({message:"cannot cast to ip",on:"e2"::enum(e1,e2)}) error("bad") diff --git a/runtime/ztests/expr/cast/map.yaml b/runtime/ztests/expr/cast/map.yaml index 47843d0941..007761eec7 100644 --- a/runtime/ztests/expr/cast/map.yaml +++ b/runtime/ztests/expr/cast/map.yaml @@ -9,6 +9,7 @@ input: | null null::({}|null) 1 + "e2"::enum(e1,e2) error("bad") output: | @@ -17,4 +18,5 @@ output: | null::(null||{int64:|{string:int64}|}|) null::(null||{int64:|{string:int64}|}|) error({message:"cannot cast to |{int64:|{string:int64}|}|",on:1}) + error({message:"cannot cast to |{int64:|{string:int64}|}|",on:"e2"::enum(e1,e2)}) error("bad") diff --git a/runtime/ztests/expr/cast/net.yaml b/runtime/ztests/expr/cast/net.yaml index 016b001d03..8ffcfcb5e1 100644 --- a/runtime/ztests/expr/cast/net.yaml +++ b/runtime/ztests/expr/cast/net.yaml @@ -11,6 +11,7 @@ input: | 10.0.0.0/8::=named -35 34 + "e2"::enum(e1,e2) error("bad") output: | @@ -22,4 +23,5 @@ output: | 10.0.0.0/8 error({message:"cannot cast to net",on:-35}) error({message:"cannot cast to net",on:34}) + error({message:"cannot cast to net",on:"e2"::enum(e1,e2)}) error("bad") diff --git a/runtime/ztests/expr/cast/record.yaml b/runtime/ztests/expr/cast/record.yaml index 6e4d958e9c..99b71808a3 100644 --- a/runtime/ztests/expr/cast/record.yaml +++ b/runtime/ztests/expr/cast/record.yaml @@ -12,6 +12,7 @@ input: | null null::({}|null) 1 + "e2"::enum(e1,e2) error("bad") output: | @@ -23,4 +24,5 @@ output: | null::(null|{a:int64,b:string,c:{},d:[{e:string,f:int64}]}) null::(null|{a:int64,b:string,c:{},d:[{e:string,f:int64}]}) error({message:"cannot cast to {a:int64,b:string,c:{},d:[{e:string,f:int64}]}",on:1}) + error({message:"cannot cast to {a:int64,b:string,c:{},d:[{e:string,f:int64}]}",on:"e2"::enum(e1,e2)}) error("bad") diff --git a/runtime/ztests/expr/cast/time.yaml b/runtime/ztests/expr/cast/time.yaml index 672a45487e..149c100979 100644 --- a/runtime/ztests/expr/cast/time.yaml +++ b/runtime/ztests/expr/cast/time.yaml @@ -20,6 +20,7 @@ input: | [1,2] |[1,2]| |{"x":1}| + "e2"::enum(e1,e2) output: | 2023-10-19T23:11:20.999803Z @@ -39,3 +40,4 @@ output: | error({message:"cannot cast to time",on:[1,2]}) error({message:"cannot cast to time",on:|[1,2]|}) error({message:"cannot cast to time",on:|{"x":1}|}) + error({message:"cannot cast to time",on:"e2"::enum(e1,e2)}) diff --git a/runtime/ztests/expr/cast/type.yaml b/runtime/ztests/expr/cast/type.yaml index 4392e67ad0..ee1f947e69 100644 --- a/runtime/ztests/expr/cast/type.yaml +++ b/runtime/ztests/expr/cast/type.yaml @@ -9,6 +9,7 @@ input: | "{x:\"foo\"}" "" 1 + "e2"::enum(e1,e2) null null::({}|null) error("bad") @@ -20,6 +21,7 @@ output: | error({message:"cannot cast to type",on:"{x:\"foo\"}"}) error({message:"cannot cast to type",on:""}) error({message:"cannot cast to type",on:1}) + error({message:"cannot cast to type",on:"e2"::enum(e1,e2)}) null::(type|null) null::(type|null) error("bad") diff --git a/runtime/ztests/expr/cast/uint.yaml b/runtime/ztests/expr/cast/uint.yaml index d41b8fb920..8cdb967309 100644 --- a/runtime/ztests/expr/cast/uint.yaml +++ b/runtime/ztests/expr/cast/uint.yaml @@ -49,6 +49,7 @@ input: | [1,2] |[1,2]| |{"x":1}| + "e2"::enum(e1,e2) output: | error("bad") @@ -56,3 +57,4 @@ output: | error({message:"cannot cast to uint64",on:[1,2]}) error({message:"cannot cast to uint64",on:|[1,2]|}) error({message:"cannot cast to uint64",on:|{"x":1}|}) + error({message:"cannot cast to uint64",on:"e2"::enum(e1,e2)}) diff --git a/runtime/ztests/expr/enum.yaml b/runtime/ztests/expr/enum.yaml deleted file mode 100644 index a5877ea171..0000000000 --- a/runtime/ztests/expr/enum.yaml +++ /dev/null @@ -1,13 +0,0 @@ -spq: "put s:=e::string, v:=e+1" - -vector: true - -input: | - {e:"foo"::enum(foo,bar,baz)} - {e:"bar"::enum(foo,bar,baz)} - {e:"baz"::enum(foo,bar,baz)} - -output: | - {e:"foo"::enum(foo,bar,baz),s:"foo",v:1} - {e:"bar"::enum(foo,bar,baz),s:"bar",v:2} - {e:"baz"::enum(foo,bar,baz),s:"baz",v:3}