authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-10-17 15:52:19+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-17 16:06:40-04:00
log51be575745adfe21a5367f206c156f2d589ad436
treea888b7e8eb55a0c91c7686ef5b0570c8085bc11d
parent98a37dfb23202e3f56e1596a19be3fa563f65eeb

std: Fix endless loop in fmt impl

Apparently there's a stage1 bug that may sometimes lead to an endless loop being generated when unrolling the fmt impl. Closes #9961

1 files changed, 16 insertions(+), 14 deletions(-)

lib/std/fmt.zig+16-14
......@@ -295,21 +295,21 @@ pub fn format(
295295 }
296296
297297 // Parse the width parameter
298 options.width = init: {
299 if (comptime parser.maybe('[')) {
300 const arg_name = comptime parser.until(']');
298 options.width = comptime init: {
299 if (parser.maybe('[')) {
300 const arg_name = parser.until(']');
301301
302 if (!comptime parser.maybe(']')) {
302 if (!parser.maybe(']')) {
303303 @compileError("Expected closing ]");
304304 }
305305
306 const index = comptime meta.fieldIndex(ArgsType, arg_name) orelse
306 const index = meta.fieldIndex(ArgsType, arg_name) orelse
307307 @compileError("No argument with name '" ++ arg_name ++ "'");
308 const arg_index = comptime arg_state.nextArg(index);
308 const arg_index = arg_state.nextArg(index);
309309
310310 break :init @field(args, fields_info[arg_index].name);
311311 } else {
312 break :init comptime parser.number();
312 break :init parser.number();
313313 }
314314 };
315315
......@@ -321,21 +321,21 @@ pub fn format(
321321 }
322322
323323 // Parse the precision parameter
324 options.precision = init: {
325 if (comptime parser.maybe('[')) {
326 const arg_name = comptime parser.until(']');
324 options.precision = comptime init: {
325 if (parser.maybe('[')) {
326 const arg_name = parser.until(']');
327327
328 if (!comptime parser.maybe(']')) {
328 if (!parser.maybe(']')) {
329329 @compileError("Expected closing ]");
330330 }
331331
332 const arg_i = comptime meta.fieldIndex(ArgsType, arg_name) orelse
332 const arg_i = meta.fieldIndex(ArgsType, arg_name) orelse
333333 @compileError("No argument with name '" ++ arg_name ++ "'");
334 const arg_to_use = comptime arg_state.nextArg(arg_i);
334 const arg_to_use = arg_state.nextArg(arg_i);
335335
336336 break :init @field(args, fields_info[arg_to_use].name);
337337 } else {
338 break :init comptime parser.number();
338 break :init parser.number();
339339 }
340340 };
341341
......@@ -2576,6 +2576,8 @@ test "runtime width specifier" {
25762576 var width: usize = 9;
25772577 try expectFmt("~~hello~~", "{s:~^[1]}", .{ "hello", width });
25782578 try expectFmt("~~hello~~", "{s:~^[width]}", .{ .string = "hello", .width = width });
2579 try expectFmt(" hello", "{s:[1]}", .{ "hello", width });
2580 try expectFmt("42 hello", "{d} {s:[2]}", .{ 42, "hello", width });
25792581}
25802582
25812583test "runtime precision specifier" {