Skip to content

Commit

Permalink
function/stdlib: ElementFunc handles negative index into tuple
Browse files Browse the repository at this point in the history
An earlier commit added support for negative indices but only dealt with
the Impl function. Since the length of a tuple is part of its type, the
Type callback also needs to deal with the possibility of negative indices
when deciding what type to return.
  • Loading branch information
apparentlymart committed Jan 21, 2025
1 parent 0ed0ebb commit d13b46e
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# 1.16.2 (Unreleased)

* `function/stdlib`: `ElementFunc` no longer crashes when asked for a negative index into a tuple. This fixes a miss in the negative index support added back in v1.15.0. ([#200](https://github.com/zclconf/go-cty/pull/200))

# 1.16.1 (January 13, 2025)

Expand Down
3 changes: 3 additions & 0 deletions cty/function/stdlib/collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ var ElementFunc = function.New(&function.Spec{
return cty.DynamicPseudoType, errors.New("cannot use element function with an empty list")
}
index = index % len(etys)
if index < 0 {
index += len(etys)
}
return etys[index], nil
default:
return cty.DynamicPseudoType, fmt.Errorf("cannot read elements from %s", listTy.FriendlyName())
Expand Down
98 changes: 98 additions & 0 deletions cty/function/stdlib/collection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,18 @@ func TestElement(t *testing.T) {
cty.StringVal("brown").Mark("fox"),
cty.UnknownVal(cty.String),
})
tuple := cty.TupleVal([]cty.Value{
cty.StringVal("the"),
cty.UnknownVal(cty.String),
cty.StringVal("brown"),
cty.False,
})
unknownTuple := cty.UnknownVal(cty.Tuple([]cty.Type{
cty.String,
cty.String,
cty.String,
cty.Bool,
}))

tests := []struct {
List cty.Value
Expand Down Expand Up @@ -1253,6 +1265,92 @@ func TestElement(t *testing.T) {
cty.StringVal("fox"),
true,
},

{
tuple,
cty.NumberIntVal(0),
cty.StringVal("the"),
false,
},
{
tuple,
cty.NumberIntVal(1),
cty.UnknownVal(cty.String),
false,
},
{
tuple,
cty.NumberIntVal(3),
cty.False,
false,
},
{
tuple,
cty.NumberIntVal(4),
cty.StringVal("the"),
false,
},
{
tuple,
cty.NumberIntVal(10),
cty.StringVal("brown"),
false,
},
{
tuple,
cty.NumberIntVal(-1),
cty.False,
false,
},
{
tuple,
cty.NumberIntVal(-6),
cty.StringVal("brown"),
false,
},

{
unknownTuple,
cty.NumberIntVal(0),
cty.UnknownVal(cty.String),
false,
},
{
unknownTuple,
cty.NumberIntVal(1),
cty.UnknownVal(cty.String),
false,
},
{
unknownTuple,
cty.NumberIntVal(3),
cty.UnknownVal(cty.Bool),
false,
},
{
unknownTuple,
cty.NumberIntVal(4),
cty.UnknownVal(cty.String),
false,
},
{
unknownTuple,
cty.NumberIntVal(10),
cty.UnknownVal(cty.String),
false,
},
{
unknownTuple,
cty.NumberIntVal(-1),
cty.UnknownVal(cty.Bool),
false,
},
{
unknownTuple,
cty.NumberIntVal(-6),
cty.UnknownVal(cty.String),
false,
},
}

for _, test := range tests {
Expand Down

0 comments on commit d13b46e

Please sign in to comment.