From ed6d4bf93b5d9b862dae35dcd605f4d609d3dd7c Mon Sep 17 00:00:00 2001 From: Kazuma Watanabe Date: Wed, 30 Aug 2023 15:05:21 +0000 Subject: [PATCH] ext/typeexpr: Avoid refinements on dynamic values --- ext/typeexpr/defaults.go | 2 +- ext/typeexpr/defaults_test.go | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ext/typeexpr/defaults.go b/ext/typeexpr/defaults.go index 43a2539d..d3d6be29 100644 --- a/ext/typeexpr/defaults.go +++ b/ext/typeexpr/defaults.go @@ -95,7 +95,7 @@ func (d *Defaults) apply(v cty.Value) cty.Value { } values[key] = defaultValue } - if defaultRng := defaultValue.Range(); defaultRng.DefinitelyNotNull() { + if defaultRng := defaultValue.Range(); defaultRng.DefinitelyNotNull() && values[key].Type() != cty.DynamicPseudoType { values[key] = values[key].RefineNotNull() } } diff --git a/ext/typeexpr/defaults_test.go b/ext/typeexpr/defaults_test.go index 5f0588f5..dc3a3f42 100644 --- a/ext/typeexpr/defaults_test.go +++ b/ext/typeexpr/defaults_test.go @@ -898,6 +898,23 @@ func TestDefaults_Apply(t *testing.T) { "foo": cty.UnknownVal(cty.String).RefineNotNull(), }), }, + "optional attribute with dynamic value can be null": { + defaults: &Defaults{ + Type: cty.ObjectWithOptionalAttrs(map[string]cty.Type{ + "foo": cty.String, + }, []string{"foo"}), + DefaultValues: map[string]cty.Value{ + "foo": cty.StringVal("bar"), // Important: default is non-null + }, + }, + value: cty.ObjectVal(map[string]cty.Value{ + "foo": cty.DynamicVal, + }), + want: cty.ObjectVal(map[string]cty.Value{ + // The default value is itself non-null, but dynamic value cannot be refined. + "foo": cty.DynamicVal, + }), + }, } for name, tc := range testCases {