@@ -788,21 +788,24 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
788788 })
789789 return cty .UnknownVal (resultType ), diags
790790 }
791- if ! condResult .IsKnown () {
792- // we use the unmarked values throughout the unknown branch
793- _ , condResultMarks := condResult .Unmark ()
794- trueResult , trueResultMarks := trueResult .Unmark ()
795- falseResult , falseResultMarks := falseResult .Unmark ()
796791
797- // use a value to merge marks
798- _ , resMarks := cty .DynamicVal .WithMarks (condResultMarks , trueResultMarks , falseResultMarks ).Unmark ()
792+ // Now that we have all three values, collect all the marks for the result.
793+ // Since it's possible that a condition value could be unknown, and the
794+ // consumer needs to deal with any marks from either branch anyway, we must
795+ // always combine them for consistent results.
796+ condResult , condResultMarks := condResult .Unmark ()
797+ trueResult , trueResultMarks := trueResult .Unmark ()
798+ falseResult , falseResultMarks := falseResult .Unmark ()
799+ var resMarks []cty.ValueMarks
800+ resMarks = append (resMarks , condResultMarks , trueResultMarks , falseResultMarks )
799801
802+ if ! condResult .IsKnown () {
800803 trueRange := trueResult .Range ()
801804 falseRange := falseResult .Range ()
802805
803806 // if both branches are known to be null, then the result must still be null
804807 if trueResult .IsNull () && falseResult .IsNull () {
805- return cty .NullVal (resultType ).WithMarks (resMarks ), diags
808+ return cty .NullVal (resultType ).WithMarks (resMarks ... ), diags
806809 }
807810
808811 // We might be able to offer a refined range for the result based on
@@ -841,7 +844,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
841844 ref = ref .NumberRangeUpperBound (hi , hiInc )
842845 }
843846
844- return ref .NewValue ().WithMarks (resMarks ), diags
847+ return ref .NewValue ().WithMarks (resMarks ... ), diags
845848 }
846849
847850 if trueResult .Type ().IsCollectionType () && falseResult .Type ().IsCollectionType () {
@@ -867,15 +870,15 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
867870 }
868871
869872 ref = ref .CollectionLengthLowerBound (lo ).CollectionLengthUpperBound (hi )
870- return ref .NewValue ().WithMarks (resMarks ), diags
873+ return ref .NewValue ().WithMarks (resMarks ... ), diags
871874 }
872875 }
873876
874877 ret := cty .UnknownVal (resultType )
875878 if trueRange .DefinitelyNotNull () && falseRange .DefinitelyNotNull () {
876879 ret = ret .RefineNotNull ()
877880 }
878- return ret .WithMarks (resMarks ), diags
881+ return ret .WithMarks (resMarks ... ), diags
879882 }
880883
881884 condResult , err := convert .Convert (condResult , cty .Bool )
@@ -892,8 +895,6 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
892895 return cty .UnknownVal (resultType ), diags
893896 }
894897
895- // Unmark result before testing for truthiness
896- condResult , _ = condResult .UnmarkDeep ()
897898 if condResult .True () {
898899 diags = append (diags , trueDiags ... )
899900 if convs [0 ] != nil {
@@ -916,7 +917,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
916917 trueResult = cty .UnknownVal (resultType )
917918 }
918919 }
919- return trueResult , diags
920+ return trueResult . WithMarks ( resMarks ... ) , diags
920921 } else {
921922 diags = append (diags , falseDiags ... )
922923 if convs [1 ] != nil {
@@ -939,7 +940,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
939940 falseResult = cty .UnknownVal (resultType )
940941 }
941942 }
942- return falseResult , diags
943+ return falseResult . WithMarks ( resMarks ... ) , diags
943944 }
944945}
945946
@@ -1429,9 +1430,9 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
14291430 })
14301431 return cty .DynamicVal , diags
14311432 }
1432- if ! collVal . IsKnown () {
1433- return cty . DynamicVal , diags
1434- }
1433+
1434+ // Grab the CondExpr marks when we're returning early with an unknown
1435+ var condMarks cty. ValueMarks
14351436
14361437 // Before we start we'll do an early check to see if any CondExpr we've
14371438 // been given is of the wrong type. This isn't 100% reliable (it may
@@ -1459,6 +1460,9 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
14591460 })
14601461 return cty .DynamicVal , diags
14611462 }
1463+
1464+ _ , condMarks = result .Unmark ()
1465+
14621466 _ , err := convert .Convert (result , cty .Bool )
14631467 if err != nil {
14641468 diags = append (diags , & hcl.Diagnostic {
@@ -1477,6 +1481,10 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
14771481 }
14781482 }
14791483
1484+ if ! collVal .IsKnown () {
1485+ return cty .DynamicVal .WithMarks (append (marks , condMarks )... ), diags
1486+ }
1487+
14801488 if e .KeyExpr != nil {
14811489 // Producing an object
14821490 var vals map [string ]cty.Value
@@ -1517,6 +1525,12 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
15171525 known = false
15181526 continue
15191527 }
1528+
1529+ // Extract and merge marks from the include expression into the
1530+ // main set of marks
1531+ _ , includeMarks := includeRaw .Unmark ()
1532+ marks = append (marks , includeMarks )
1533+
15201534 include , err := convert .Convert (includeRaw , cty .Bool )
15211535 if err != nil {
15221536 if known {
@@ -1540,7 +1554,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
15401554
15411555 // Extract and merge marks from the include expression into the
15421556 // main set of marks
1543- includeUnmarked , includeMarks := include .Unmark ()
1557+ includeUnmarked , _ := include .Unmark ()
15441558 marks = append (marks , includeMarks )
15451559 if includeUnmarked .False () {
15461560 // Skip this element
@@ -1565,6 +1579,10 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
15651579 known = false
15661580 continue
15671581 }
1582+
1583+ _ , keyMarks := keyRaw .Unmark ()
1584+ marks = append (marks , keyMarks )
1585+
15681586 if ! keyRaw .IsKnown () {
15691587 known = false
15701588 continue
@@ -1587,8 +1605,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
15871605 continue
15881606 }
15891607
1590- key , keyMarks := key .Unmark ()
1591- marks = append (marks , keyMarks )
1608+ key , _ = key .Unmark ()
15921609
15931610 val , valDiags := e .ValExpr .Value (childCtx )
15941611 diags = append (diags , valDiags ... )
@@ -1618,7 +1635,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
16181635 }
16191636
16201637 if ! known {
1621- return cty .DynamicVal , diags
1638+ return cty .DynamicVal . WithMarks ( marks ... ) , diags
16221639 }
16231640
16241641 if e .Group {
@@ -1664,6 +1681,12 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
16641681 known = false
16651682 continue
16661683 }
1684+
1685+ // Extract and merge marks from the include expression into the
1686+ // main set of marks
1687+ _ , includeMarks := includeRaw .Unmark ()
1688+ marks = append (marks , includeMarks )
1689+
16671690 if ! includeRaw .IsKnown () {
16681691 // We will eventually return DynamicVal, but we'll continue
16691692 // iterating in case there are other diagnostics to gather
@@ -1689,10 +1712,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
16891712 continue
16901713 }
16911714
1692- // Extract and merge marks from the include expression into the
1693- // main set of marks
1694- includeUnmarked , includeMarks := include .Unmark ()
1695- marks = append (marks , includeMarks )
1715+ includeUnmarked , _ := include .Unmark ()
16961716 if includeUnmarked .False () {
16971717 // Skip this element
16981718 continue
@@ -1705,7 +1725,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
17051725 }
17061726
17071727 if ! known {
1708- return cty .DynamicVal , diags
1728+ return cty .DynamicVal . WithMarks ( marks ... ) , diags
17091729 }
17101730
17111731 return cty .TupleVal (vals ).WithMarks (marks ... ), diags
0 commit comments