hashicorp / hil

HIL is a small embedded language for string interpolations.
Mozilla Public License 2.0
396 stars 34 forks source link

Allow partially-unknown collection values #51

Closed apparentlymart closed 7 years ago

apparentlymart commented 7 years ago

Previously there was a hard rule that if a list or map contains any unknown values then the collection as a whole is unknown. This kept the handling of this situation in one spot, but was non-ideal since it is safe to use the index operator [...] on a partially-unknown list or map and access the values that are known.

This change removes the unilateral rule that any nested unknowns immediately collapse to a single top-level unknown, which then requires each of the eval node implementations to provide their own handling of unknowns. In return for this extra complexity, we are able to make an exception in the handling of the index operator to allow the retrieval of any known values in a partially-unknown collection.

The new rules are:

These new rules are covered by some additional test cases since now it's well worth testing the TypeUnknown handling for each node type separately.

The primary use-case for this is dealing with Terraform's "splat syntax", which allows retrieving a list of attribute values from a list of instances of a single resource, like aws_instance.foo.*.id. Currently this is problematic because adding a new instance (by increasing "count") adds a new computed item to the end of this list and in turn makes the whole list become Unknown. With this change, only the values correponding to the new instances will be considered as Unknown, leaving existing resources undisturbed. This use-case is discussed in more detail in hashicorp/terraform#3449 .

apparentlymart commented 7 years ago

After further testing I found that there are some cases not caught here, because the type-checker is still short-circuiting in certain cases and ending up passing through things that the evaluator doesn't understand.

I'm going to work on a follow-up change to fix this.