| author | |
| committer | |
| log | b1537b525fa0cd8d51ff89519254db0f066fc04b |
| tree | 7947d3da28ca685619fc46248634003b4331cb3f |
| parent | 013ada1b59e50bbbab19acab0a79dae72133999a |
| parent | 11a4ce42c16c17422cd272f154c9c33231bcc61a |
| signature |
Closes #4750
Closes #47495 files changed, 70 insertions(+), 27 deletions(-)
lib/std/zig/parser_test.zig+2| ... | @@ -1509,6 +1509,8 @@ test "zig fmt: error set declaration" { | ... | @@ -1509,6 +1509,8 @@ test "zig fmt: error set declaration" { |
| 1509 | \\const Error = error{OutOfMemory}; | 1509 | \\const Error = error{OutOfMemory}; |
| 1510 | \\const Error = error{}; | 1510 | \\const Error = error{}; |
| 1511 | \\ | 1511 | \\ |
| 1512 | \\const Error = error{ OutOfMemory, OutOfTime }; | ||
| 1513 | \\ | ||
| 1512 | ); | 1514 | ); |
| 1513 | } | 1515 | } |
| 1514 | 1516 |
lib/std/zig/render.zig+41-17| ... | @@ -1268,25 +1268,51 @@ fn renderExpression( | ... | @@ -1268,25 +1268,51 @@ fn renderExpression( |
| 1268 | } | 1268 | } |
| 1269 | 1269 | ||
| 1270 | try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error | 1270 | try renderToken(tree, stream, err_set_decl.error_token, indent, start_col, Space.None); // error |
| 1271 | try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // { | ||
| 1272 | const new_indent = indent + indent_delta; | ||
| 1273 | 1271 | ||
| 1274 | var it = err_set_decl.decls.iterator(0); | 1272 | const src_has_trailing_comma = blk: { |
| 1275 | while (it.next()) |node| { | 1273 | const maybe_comma = tree.prevToken(err_set_decl.rbrace_token); |
| 1276 | try stream.writeByteNTimes(' ', new_indent); | 1274 | break :blk tree.tokens.at(maybe_comma).id == .Comma; |
| 1275 | }; | ||
| 1277 | 1276 | ||
| 1278 | if (it.peek()) |next_node| { | 1277 | if (src_has_trailing_comma) { |
| 1279 | try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None); | 1278 | try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // { |
| 1280 | try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // , | 1279 | const new_indent = indent + indent_delta; |
| 1281 | 1280 | ||
| 1282 | try renderExtraNewline(tree, stream, start_col, next_node.*); | 1281 | var it = err_set_decl.decls.iterator(0); |
| 1283 | } else { | 1282 | while (it.next()) |node| { |
| 1284 | try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma); | 1283 | try stream.writeByteNTimes(' ', new_indent); |
| 1284 | |||
| 1285 | if (it.peek()) |next_node| { | ||
| 1286 | try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None); | ||
| 1287 | try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // , | ||
| 1288 | |||
| 1289 | try renderExtraNewline(tree, stream, start_col, next_node.*); | ||
| 1290 | } else { | ||
| 1291 | try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma); | ||
| 1292 | } | ||
| 1285 | } | 1293 | } |
| 1286 | } | ||
| 1287 | 1294 | ||
| 1288 | try stream.writeByteNTimes(' ', indent); | 1295 | try stream.writeByteNTimes(' ', indent); |
| 1289 | return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // } | 1296 | return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // } |
| 1297 | } else { | ||
| 1298 | try renderToken(tree, stream, lbrace, indent, start_col, Space.Space); // { | ||
| 1299 | |||
| 1300 | var it = err_set_decl.decls.iterator(0); | ||
| 1301 | while (it.next()) |node| { | ||
| 1302 | if (it.peek()) |next_node| { | ||
| 1303 | try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None); | ||
| 1304 | |||
| 1305 | const comma_token = tree.nextToken(node.*.lastToken()); | ||
| 1306 | assert(tree.tokens.at(comma_token).id == .Comma); | ||
| 1307 | try renderToken(tree, stream, comma_token, indent, start_col, Space.Space); // , | ||
| 1308 | try renderExtraNewline(tree, stream, start_col, next_node.*); | ||
| 1309 | } else { | ||
| 1310 | try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Space); | ||
| 1311 | } | ||
| 1312 | } | ||
| 1313 | |||
| 1314 | return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // } | ||
| 1315 | } | ||
| 1290 | }, | 1316 | }, |
| 1291 | 1317 | ||
| 1292 | .ErrorTag => { | 1318 | .ErrorTag => { |
| ... | @@ -1589,8 +1615,7 @@ fn renderExpression( | ... | @@ -1589,8 +1615,7 @@ fn renderExpression( |
| 1589 | } | 1615 | } |
| 1590 | } else { | 1616 | } else { |
| 1591 | var it = switch_case.items.iterator(0); | 1617 | var it = switch_case.items.iterator(0); |
| 1592 | while (true) { | 1618 | while (it.next()) |node| { |
| 1593 | const node = it.next().?; | ||
| 1594 | if (it.peek()) |next_node| { | 1619 | if (it.peek()) |next_node| { |
| 1595 | try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None); | 1620 | try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None); |
| 1596 | 1621 | ||
| ... | @@ -1601,7 +1626,6 @@ fn renderExpression( | ... | @@ -1601,7 +1626,6 @@ fn renderExpression( |
| 1601 | } else { | 1626 | } else { |
| 1602 | try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma); | 1627 | try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma); |
| 1603 | try stream.writeByteNTimes(' ', indent); | 1628 | try stream.writeByteNTimes(' ', indent); |
| 1604 | break; | ||
| 1605 | } | 1629 | } |
| 1606 | } | 1630 | } |
| 1607 | } | 1631 | } |
src/analyze.cpp+4-9| ... | @@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi | ... | @@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi |
| 803 | } | 803 | } |
| 804 | buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name)); | 804 | buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name)); |
| 805 | 805 | ||
| 806 | size_t full_array_size; | 806 | size_t full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0); |
| 807 | if (array_size == 0) { | ||
| 808 | full_array_size = 0; | ||
| 809 | } else { | ||
| 810 | full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0); | ||
| 811 | } | ||
| 812 | |||
| 813 | entry->size_in_bits = child_type->size_in_bits * full_array_size; | 807 | entry->size_in_bits = child_type->size_in_bits * full_array_size; |
| 814 | entry->abi_align = child_type->abi_align; | 808 | entry->abi_align = child_type->abi_align; |
| 815 | entry->abi_size = child_type->abi_size * full_array_size; | 809 | entry->abi_size = child_type->abi_size * full_array_size; |
| ... | @@ -1197,7 +1191,8 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent | ... | @@ -1197,7 +1191,8 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent |
| 1197 | LazyValueArrayType *lazy_array_type = | 1191 | LazyValueArrayType *lazy_array_type = |
| 1198 | reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy); | 1192 | reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy); |
| 1199 | 1193 | ||
| 1200 | if (lazy_array_type->length < 1) { | 1194 | // The sentinel counts as an extra element |
| 1195 | if (lazy_array_type->length == 0 && lazy_array_type->sentinel == nullptr) { | ||
| 1201 | *is_zero_bits = true; | 1196 | *is_zero_bits = true; |
| 1202 | return ErrorNone; | 1197 | return ErrorNone; |
| 1203 | } | 1198 | } |
| ... | @@ -1452,7 +1447,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV | ... | @@ -1452,7 +1447,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV |
| 1452 | case LazyValueIdArrayType: { | 1447 | case LazyValueIdArrayType: { |
| 1453 | LazyValueArrayType *lazy_array_type = | 1448 | LazyValueArrayType *lazy_array_type = |
| 1454 | reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy); | 1449 | reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy); |
| 1455 | if (lazy_array_type->length < 1) | 1450 | if (lazy_array_type->length == 0) |
| 1456 | return OnePossibleValueYes; | 1451 | return OnePossibleValueYes; |
| 1457 | return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value); | 1452 | return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value); |
| 1458 | } | 1453 | } |
src/codegen.cpp+3-1| ... | @@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) { | ... | @@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) { |
| 3584 | } | 3584 | } |
| 3585 | return true; | 3585 | return true; |
| 3586 | } else if (const_val->type->id == ZigTypeIdArray) { | 3586 | } else if (const_val->type->id == ZigTypeIdArray) { |
| 3587 | return value_is_all_undef_array(g, const_val, const_val->type->data.array.len); | 3587 | const size_t full_len = const_val->type->data.array.len + |
| 3588 | (const_val->type->data.array.sentinel != nullptr); | ||
| 3589 | return value_is_all_undef_array(g, const_val, full_len); | ||
| 3588 | } else if (const_val->type->id == ZigTypeIdVector) { | 3590 | } else if (const_val->type->id == ZigTypeIdVector) { |
| 3589 | return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len); | 3591 | return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len); |
| 3590 | } else { | 3592 | } else { |
test/stage1/behavior/array.zig+20| ... | @@ -376,3 +376,23 @@ test "type deduction for array subscript expression" { | ... | @@ -376,3 +376,23 @@ test "type deduction for array subscript expression" { |
| 376 | S.doTheTest(); | 376 | S.doTheTest(); |
| 377 | comptime S.doTheTest(); | 377 | comptime S.doTheTest(); |
| 378 | } | 378 | } |
| 379 | |||
| 380 | test "sentinel element count towards the ABI size calculation" { | ||
| 381 | const S = struct { | ||
| 382 | fn doTheTest() void { | ||
| 383 | const T = packed struct { | ||
| 384 | fill_pre: u8 = 0x55, | ||
| 385 | data: [0:0]u8 = undefined, | ||
| 386 | fill_post: u8 = 0xAA, | ||
| 387 | }; | ||
| 388 | var x = T{}; | ||
| 389 | var as_slice = mem.asBytes(&x); | ||
| 390 | expectEqual(@as(usize, 3), as_slice.len); | ||
| 391 | expectEqual(@as(u8, 0x55), as_slice[0]); | ||
| 392 | expectEqual(@as(u8, 0xAA), as_slice[2]); | ||
| 393 | } | ||
| 394 | }; | ||
| 395 | |||
| 396 | S.doTheTest(); | ||
| 397 | comptime S.doTheTest(); | ||
| 398 | } |