diff --git a/cty/function/stdlib/collection.go b/cty/function/stdlib/collection.go index 279a20ee..ae5e3ab5 100644 --- a/cty/function/stdlib/collection.go +++ b/cty/function/stdlib/collection.go @@ -525,6 +525,11 @@ func flattener(flattenList cty.Value) ([]cty.Value, []cty.ValueMarks, bool) { if len(flattenListMarks) > 0 { markses = append(markses, flattenListMarks) } + + if flattenList.IsNull() { + return nil, markses, true + } + if !flattenList.Length().IsKnown() { // If we don't know the length of what we're flattening then we can't // predict the length of our result yet either. diff --git a/cty/function/stdlib/collection_test.go b/cty/function/stdlib/collection_test.go index 0d5d5e83..e15295ae 100644 --- a/cty/function/stdlib/collection_test.go +++ b/cty/function/stdlib/collection_test.go @@ -2064,6 +2064,54 @@ func TestFlatten(t *testing.T) { cty.UnknownVal(cty.DynamicPseudoType), "", }, + { + // null of an unknown type + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.DynamicPseudoType), + cty.True, + }), + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.DynamicPseudoType), + cty.True, + }), + "", + }, + { + // null of a string type + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.String), + cty.True, + }), + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.String), + cty.True, + }), + "", + }, + { + // null of a list type + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.List(cty.String)), + cty.True, + }), + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.List(cty.String)), + cty.True, + }), + "", + }, + { + // null of a tuple type + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.EmptyTuple), + cty.True, + }), + cty.TupleVal([]cty.Value{ + cty.NullVal(cty.EmptyTuple), + cty.True, + }), + "", + }, } for _, test := range tests {