Skip to content

Commit b1537b5

Browse files
committed
Merge branch 'LemonBoy-fix-4749'
Closes #4750 Closes #4749
2 parents 013ada1 + 11a4ce4 commit b1537b5

File tree

5 files changed

+70
-27
lines changed

5 files changed

+70
-27
lines changed

lib/std/zig/parser_test.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,8 @@ test "zig fmt: error set declaration" {
15091509
\\const Error = error{OutOfMemory};
15101510
\\const Error = error{};
15111511
\\
1512+
\\const Error = error{ OutOfMemory, OutOfTime };
1513+
\\
15121514
);
15131515
}
15141516

lib/std/zig/render.zig

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,25 +1268,51 @@ fn renderExpression(
12681268
}
12691269

12701270
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;
12731271

1274-
var it = err_set_decl.decls.iterator(0);
1275-
while (it.next()) |node| {
1276-
try stream.writeByteNTimes(' ', new_indent);
1272+
const src_has_trailing_comma = blk: {
1273+
const maybe_comma = tree.prevToken(err_set_decl.rbrace_token);
1274+
break :blk tree.tokens.at(maybe_comma).id == .Comma;
1275+
};
12771276

1278-
if (it.peek()) |next_node| {
1279-
try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.None);
1280-
try renderToken(tree, stream, tree.nextToken(node.*.lastToken()), new_indent, start_col, Space.Newline); // ,
1277+
if (src_has_trailing_comma) {
1278+
try renderToken(tree, stream, lbrace, indent, start_col, Space.Newline); // {
1279+
const new_indent = indent + indent_delta;
12811280

1282-
try renderExtraNewline(tree, stream, start_col, next_node.*);
1283-
} else {
1284-
try renderExpression(allocator, stream, tree, new_indent, start_col, node.*, Space.Comma);
1281+
var it = err_set_decl.decls.iterator(0);
1282+
while (it.next()) |node| {
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+
}
12851293
}
1286-
}
12871294

1288-
try stream.writeByteNTimes(' ', indent);
1289-
return renderToken(tree, stream, err_set_decl.rbrace_token, indent, start_col, space); // }
1295+
try stream.writeByteNTimes(' ', indent);
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+
}
12901316
},
12911317

12921318
.ErrorTag => {
@@ -1589,8 +1615,7 @@ fn renderExpression(
15891615
}
15901616
} else {
15911617
var it = switch_case.items.iterator(0);
1592-
while (true) {
1593-
const node = it.next().?;
1618+
while (it.next()) |node| {
15941619
if (it.peek()) |next_node| {
15951620
try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.None);
15961621

@@ -1601,7 +1626,6 @@ fn renderExpression(
16011626
} else {
16021627
try renderExpression(allocator, stream, tree, indent, start_col, node.*, Space.Comma);
16031628
try stream.writeByteNTimes(' ', indent);
1604-
break;
16051629
}
16061630
}
16071631
}

src/analyze.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -803,13 +803,7 @@ ZigType *get_array_type(CodeGen *g, ZigType *child_type, uint64_t array_size, Zi
803803
}
804804
buf_appendf(&entry->name, "]%s", buf_ptr(&child_type->name));
805805

806-
size_t full_array_size;
807-
if (array_size == 0) {
808-
full_array_size = 0;
809-
} else {
810-
full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
811-
}
812-
806+
size_t full_array_size = array_size + ((sentinel != nullptr) ? 1 : 0);
813807
entry->size_in_bits = child_type->size_in_bits * full_array_size;
814808
entry->abi_align = child_type->abi_align;
815809
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
11971191
LazyValueArrayType *lazy_array_type =
11981192
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
11991193

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) {
12011196
*is_zero_bits = true;
12021197
return ErrorNone;
12031198
}
@@ -1452,7 +1447,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
14521447
case LazyValueIdArrayType: {
14531448
LazyValueArrayType *lazy_array_type =
14541449
reinterpret_cast<LazyValueArrayType *>(type_val->data.x_lazy);
1455-
if (lazy_array_type->length < 1)
1450+
if (lazy_array_type->length == 0)
14561451
return OnePossibleValueYes;
14571452
return type_val_resolve_has_one_possible_value(g, lazy_array_type->elem_type->value);
14581453
}

src/codegen.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3584,7 +3584,9 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val) {
35843584
}
35853585
return true;
35863586
} 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);
35883590
} else if (const_val->type->id == ZigTypeIdVector) {
35893591
return value_is_all_undef_array(g, const_val, const_val->type->data.vector.len);
35903592
} else {

test/stage1/behavior/array.zig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,23 @@ test "type deduction for array subscript expression" {
376376
S.doTheTest();
377377
comptime S.doTheTest();
378378
}
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+
}

0 commit comments

Comments
 (0)