| ... | ... | @@ -1471,7 +1471,7 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options: |
| 1471 | 1471 | var fields_seen = [_]bool{false} ** structInfo.fields.len; |
| 1472 | 1472 | errdefer { |
| 1473 | 1473 | inline for (structInfo.fields) |field, i| { |
| 1474 | | if (fields_seen[i]) { |
| 1474 | if (fields_seen[i] and !field.is_comptime) { |
| 1475 | 1475 | parseFree(field.field_type, @field(r, field.name), options); |
| 1476 | 1476 | } |
| 1477 | 1477 | } |
| ... | ... | @@ -1504,7 +1504,15 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options: |
| 1504 | 1504 | parseFree(field.field_type, @field(r, field.name), options); |
| 1505 | 1505 | } |
| 1506 | 1506 | } |
| 1507 | | @field(r, field.name) = try parse(field.field_type, tokens, options); |
| 1507 | if (field.is_comptime) { |
| 1508 | const value = try parse(field.field_type, tokens, options); |
| 1509 | defer parseFree(field.field_type, value, options); |
| 1510 | if (value != @field(r, field.name)) { |
| 1511 | return error.UnexpectedValue; |
| 1512 | } |
| 1513 | } else { |
| 1514 | @field(r, field.name) = try parse(field.field_type, tokens, options); |
| 1515 | } |
| 1508 | 1516 | fields_seen[i] = true; |
| 1509 | 1517 | found = true; |
| 1510 | 1518 | break; |
| ... | ... | @@ -1518,7 +1526,9 @@ fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options: |
| 1518 | 1526 | inline for (structInfo.fields) |field, i| { |
| 1519 | 1527 | if (!fields_seen[i]) { |
| 1520 | 1528 | if (field.default_value) |default| { |
| 1521 | | @field(r, field.name) = default; |
| 1529 | if (!field.is_comptime) { |
| 1530 | @field(r, field.name) = default; |
| 1531 | } |
| 1522 | 1532 | } else { |
| 1523 | 1533 | return error.MissingField; |
| 1524 | 1534 | } |
| ... | ... | @@ -1789,6 +1799,19 @@ test "parseFree descends into tagged union" { |
| 1789 | 1799 | testing.expectEqual(@as(usize, 1), fail_alloc.deallocations); |
| 1790 | 1800 | } |
| 1791 | 1801 | |
| 1802 | test "parse with comptime field" { |
| 1803 | const T = struct { |
| 1804 | comptime a: i32 = 0, |
| 1805 | b: bool, |
| 1806 | }; |
| 1807 | testing.expectEqual(T{ .a = 0, .b = true }, try parse(T, &TokenStream.init( |
| 1808 | \\{ |
| 1809 | \\ "a": 0, |
| 1810 | \\ "b": true |
| 1811 | \\} |
| 1812 | ), ParseOptions{})); |
| 1813 | } |
| 1814 | |
| 1792 | 1815 | test "parse into struct with no fields" { |
| 1793 | 1816 | const T = struct {}; |
| 1794 | 1817 | testing.expectEqual(T{}, try parse(T, &TokenStream.init("{}"), ParseOptions{})); |