@@ -788,21 +788,24 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
788
788
})
789
789
return cty .UnknownVal (resultType ), diags
790
790
}
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 ()
796
791
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 )
799
801
802
+ if ! condResult .IsKnown () {
800
803
trueRange := trueResult .Range ()
801
804
falseRange := falseResult .Range ()
802
805
803
806
// if both branches are known to be null, then the result must still be null
804
807
if trueResult .IsNull () && falseResult .IsNull () {
805
- return cty .NullVal (resultType ).WithMarks (resMarks ), diags
808
+ return cty .NullVal (resultType ).WithMarks (resMarks ... ), diags
806
809
}
807
810
808
811
// 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
841
844
ref = ref .NumberRangeUpperBound (hi , hiInc )
842
845
}
843
846
844
- return ref .NewValue ().WithMarks (resMarks ), diags
847
+ return ref .NewValue ().WithMarks (resMarks ... ), diags
845
848
}
846
849
847
850
if trueResult .Type ().IsCollectionType () && falseResult .Type ().IsCollectionType () {
@@ -867,15 +870,15 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
867
870
}
868
871
869
872
ref = ref .CollectionLengthLowerBound (lo ).CollectionLengthUpperBound (hi )
870
- return ref .NewValue ().WithMarks (resMarks ), diags
873
+ return ref .NewValue ().WithMarks (resMarks ... ), diags
871
874
}
872
875
}
873
876
874
877
ret := cty .UnknownVal (resultType )
875
878
if trueRange .DefinitelyNotNull () && falseRange .DefinitelyNotNull () {
876
879
ret = ret .RefineNotNull ()
877
880
}
878
- return ret .WithMarks (resMarks ), diags
881
+ return ret .WithMarks (resMarks ... ), diags
879
882
}
880
883
881
884
condResult , err := convert .Convert (condResult , cty .Bool )
@@ -892,8 +895,6 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
892
895
return cty .UnknownVal (resultType ), diags
893
896
}
894
897
895
- // Unmark result before testing for truthiness
896
- condResult , _ = condResult .UnmarkDeep ()
897
898
if condResult .True () {
898
899
diags = append (diags , trueDiags ... )
899
900
if convs [0 ] != nil {
@@ -916,7 +917,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
916
917
trueResult = cty .UnknownVal (resultType )
917
918
}
918
919
}
919
- return trueResult , diags
920
+ return trueResult . WithMarks ( resMarks ... ) , diags
920
921
} else {
921
922
diags = append (diags , falseDiags ... )
922
923
if convs [1 ] != nil {
@@ -939,7 +940,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic
939
940
falseResult = cty .UnknownVal (resultType )
940
941
}
941
942
}
942
- return falseResult , diags
943
+ return falseResult . WithMarks ( resMarks ... ) , diags
943
944
}
944
945
}
945
946
@@ -1429,9 +1430,9 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1429
1430
})
1430
1431
return cty .DynamicVal , diags
1431
1432
}
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
1435
1436
1436
1437
// Before we start we'll do an early check to see if any CondExpr we've
1437
1438
// 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) {
1459
1460
})
1460
1461
return cty .DynamicVal , diags
1461
1462
}
1463
+
1464
+ _ , condMarks = result .Unmark ()
1465
+
1462
1466
_ , err := convert .Convert (result , cty .Bool )
1463
1467
if err != nil {
1464
1468
diags = append (diags , & hcl.Diagnostic {
@@ -1477,6 +1481,10 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1477
1481
}
1478
1482
}
1479
1483
1484
+ if ! collVal .IsKnown () {
1485
+ return cty .DynamicVal .WithMarks (append (marks , condMarks )... ), diags
1486
+ }
1487
+
1480
1488
if e .KeyExpr != nil {
1481
1489
// Producing an object
1482
1490
var vals map [string ]cty.Value
@@ -1517,6 +1525,12 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1517
1525
known = false
1518
1526
continue
1519
1527
}
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
+
1520
1534
include , err := convert .Convert (includeRaw , cty .Bool )
1521
1535
if err != nil {
1522
1536
if known {
@@ -1540,7 +1554,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1540
1554
1541
1555
// Extract and merge marks from the include expression into the
1542
1556
// main set of marks
1543
- includeUnmarked , includeMarks := include .Unmark ()
1557
+ includeUnmarked , _ := include .Unmark ()
1544
1558
marks = append (marks , includeMarks )
1545
1559
if includeUnmarked .False () {
1546
1560
// Skip this element
@@ -1565,6 +1579,10 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1565
1579
known = false
1566
1580
continue
1567
1581
}
1582
+
1583
+ _ , keyMarks := keyRaw .Unmark ()
1584
+ marks = append (marks , keyMarks )
1585
+
1568
1586
if ! keyRaw .IsKnown () {
1569
1587
known = false
1570
1588
continue
@@ -1587,8 +1605,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1587
1605
continue
1588
1606
}
1589
1607
1590
- key , keyMarks := key .Unmark ()
1591
- marks = append (marks , keyMarks )
1608
+ key , _ = key .Unmark ()
1592
1609
1593
1610
val , valDiags := e .ValExpr .Value (childCtx )
1594
1611
diags = append (diags , valDiags ... )
@@ -1618,7 +1635,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1618
1635
}
1619
1636
1620
1637
if ! known {
1621
- return cty .DynamicVal , diags
1638
+ return cty .DynamicVal . WithMarks ( marks ... ) , diags
1622
1639
}
1623
1640
1624
1641
if e .Group {
@@ -1664,6 +1681,12 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1664
1681
known = false
1665
1682
continue
1666
1683
}
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
+
1667
1690
if ! includeRaw .IsKnown () {
1668
1691
// We will eventually return DynamicVal, but we'll continue
1669
1692
// iterating in case there are other diagnostics to gather
@@ -1689,10 +1712,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1689
1712
continue
1690
1713
}
1691
1714
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 ()
1696
1716
if includeUnmarked .False () {
1697
1717
// Skip this element
1698
1718
continue
@@ -1705,7 +1725,7 @@ func (e *ForExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
1705
1725
}
1706
1726
1707
1727
if ! known {
1708
- return cty .DynamicVal , diags
1728
+ return cty .DynamicVal . WithMarks ( marks ... ) , diags
1709
1729
}
1710
1730
1711
1731
return cty .TupleVal (vals ).WithMarks (marks ... ), diags
0 commit comments