Skip to content

Commit 3a30333

Browse files
committed
refinements of collections must use Range()
When attempting to determine the final length range for a conditional expression with collections, the length values may still be unknown. Always use `Range()` to get the lower and upper bounds.
1 parent 63067e8 commit 3a30333

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

hclsyntax/expression.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -725,16 +725,14 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
725725
falseLen := falseResult.Length()
726726
if gt := trueLen.GreaterThan(falseLen); gt.IsKnown() {
727727
b := cty.UnknownVal(resultType).Refine()
728-
trueLen, _ := trueLen.AsBigFloat().Int64()
729-
falseLen, _ := falseLen.AsBigFloat().Int64()
730728
if gt.True() {
731729
b = b.
732-
CollectionLengthLowerBound(int(falseLen)).
733-
CollectionLengthUpperBound(int(trueLen))
730+
CollectionLengthLowerBound(falseResult.Range().LengthLowerBound()).
731+
CollectionLengthUpperBound(trueResult.Range().LengthUpperBound())
734732
} else {
735733
b = b.
736-
CollectionLengthLowerBound(int(trueLen)).
737-
CollectionLengthUpperBound(int(falseLen))
734+
CollectionLengthLowerBound(trueResult.Range().LengthLowerBound()).
735+
CollectionLengthUpperBound(falseResult.Range().LengthUpperBound())
738736
}
739737
b = b.NotNull() // If neither of the results is null then the result can't be either
740738
return b.NewValue().WithSameMarks(condResult).WithSameMarks(trueResult).WithSameMarks(falseResult), diags
@@ -1244,9 +1242,9 @@ func (e *ObjectConsKeyExpr) UnwrapExpression() Expression {
12441242

12451243
// ForExpr represents iteration constructs:
12461244
//
1247-
// tuple = [for i, v in list: upper(v) if i > 2]
1248-
// object = {for k, v in map: k => upper(v)}
1249-
// object_of_tuples = {for v in list: v.key: v...}
1245+
// tuple = [for i, v in list: upper(v) if i > 2]
1246+
// object = {for k, v in map: k => upper(v)}
1247+
// object_of_tuples = {for v in list: v.key: v...}
12501248
type ForExpr struct {
12511249
KeyVar string // empty if ignoring the key
12521250
ValVar string

hclsyntax/expression_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1957,6 +1957,20 @@ EOT
19571957
cty.ListValEmpty(cty.String), // deduced through refinements
19581958
0,
19591959
},
1960+
{
1961+
`unknown ? ar : br`,
1962+
&hcl.EvalContext{
1963+
Variables: map[string]cty.Value{
1964+
"unknown": cty.UnknownVal(cty.Bool),
1965+
"ar": cty.UnknownVal(cty.Set(cty.String)).Refine().
1966+
CollectionLengthLowerBound(1).CollectionLengthUpperBound(2).NewValue(),
1967+
"br": cty.UnknownVal(cty.Set(cty.String)).Refine().
1968+
CollectionLengthLowerBound(3).CollectionLengthUpperBound(4).NewValue(),
1969+
},
1970+
},
1971+
cty.UnknownVal(cty.Set(cty.String)).Refine().NotNull().CollectionLengthLowerBound(1).CollectionLengthUpperBound(4).NewValue(), // deduced through refinements
1972+
0,
1973+
},
19601974
{
19611975
`unknown ? a : b`,
19621976
&hcl.EvalContext{

0 commit comments

Comments
 (0)