Skip to content

Commit

Permalink
splat expression on unknown should be unknown
Browse files Browse the repository at this point in the history
When a splat expression is used to upgrade an unknown value to a list
with a single value, the result must be entirely unknown. For example,
if `ukstr` is an unknown string value, then `unkstr.*` could either
result in a list of 1 string value, or an empty list, depending on
whether the result is a string or null.
  • Loading branch information
jbardin committed Nov 18, 2021
1 parent ca99bd2 commit c3f2300
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
15 changes: 14 additions & 1 deletion hclsyntax/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -1432,9 +1432,22 @@ func (e *SplatExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
return cty.DynamicVal, diags
}

upgradedUnknown := false
if autoUpgrade {
// If we're upgrading an unknown value to a tuple/list, the result
// cannot be known. Otherwise a tuple containing an unknown value will
// upgrade to a different number of elements depending on whether
// sourceVal becomes null or not.
// We record this condition here so we can process any remaining
// expression after the * to derive the correct type. For example, it
// is valid to use a splat on a single object to retrieve a list of a
// single attribute, which means the final expression type still needs
// to be determined.
upgradedUnknown = !sourceVal.IsKnown()

sourceVal = cty.TupleVal([]cty.Value{sourceVal})
sourceTy = sourceVal.Type()

}

// We'll compute our result type lazily if we need it. In the normal case
Expand Down Expand Up @@ -1499,7 +1512,7 @@ func (e *SplatExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
}
e.Item.clearValue(ctx) // clean up our temporary value

if !isKnown {
if !isKnown || upgradedUnknown {
// We'll ingore the resultTy diagnostics in this case since they
// will just be the same errors we saw while iterating above.
ty, _ := resultTy()
Expand Down
14 changes: 11 additions & 3 deletions hclsyntax/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,16 @@ upper(
}),
0,
},
{
`unkstr[*]`,
&hcl.EvalContext{
Variables: map[string]cty.Value{
"unkstr": cty.UnknownVal(cty.String),
},
},
cty.UnknownVal(cty.Tuple([]cty.Type{cty.String})),
0,
},
{
`unkstr.*.name`,
&hcl.EvalContext{
Expand Down Expand Up @@ -1164,9 +1174,7 @@ upper(
})),
},
},
cty.TupleVal([]cty.Value{
cty.UnknownVal(cty.String),
}),
cty.UnknownVal(cty.Tuple([]cty.Type{cty.String})),
0,
},
{
Expand Down

0 comments on commit c3f2300

Please sign in to comment.