authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-07-30 18:45:58-07:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-22 12:21:43+02:00
log65924d31e4ed3234303d6c6ca72cf30cda0cbaa3
treef23aa313ea7f64d02cae0d7988a6dc3e510a4841
parenta25a20160258b9936ff402e5da404420004fecff

Fix precedence upgrade when two lower prec operators surround a higher one

For example, `a | b << c | d` gives two errors: one for `a | b << c` which would have been evaluated as `a | (b << c)` in 0.16.x and one for `b << c | d` which would have been evaluated as `(b << c) | d` in 0.16.x. This would have caused the `<<` to be the operator token for a hint_operator_precedence_right and a hint_operator_precedence_left note, which the fmt implementation could not handle.

1 files changed, 10 insertions(+), 3 deletions(-)

src/fmt.zig+10-3
......@@ -400,14 +400,21 @@ fn fmtPathFile(
400400 defer operators_to_fix.deinit(gpa);
401401
402402 // Gather ambiguous operator precedence error tokens for quick lookup later
403 var remaining_errors: usize = tree.errors.len;
403404 for (tree.errors) |err| {
404405 switch (err.tag) {
405406 .hint_operator_precedence_left => {
406 try operators_to_fix.putNoClobber(gpa, err.token - @as(u32, @intCast(err.extra.offset)), {});
407 try operators_to_fix.put(gpa, err.token - @as(u32, @intCast(err.extra.offset)), {});
408 remaining_errors -= 1;
407409 },
408410 .hint_operator_precedence_right => {
409 try operators_to_fix.putNoClobber(gpa, err.token, {});
411 try operators_to_fix.put(gpa, err.token, {});
412 remaining_errors -= 1;
410413 },
414 .ambiguous_operator_precedence,
415 .illegal_chained_operators,
416 .previous_ambiguous_operator,
417 => remaining_errors -= 1,
411418 else => continue,
412419 }
413420 }
......@@ -415,7 +422,7 @@ fn fmtPathFile(
415422 if (operators_to_fix.count() == 0) break :fix;
416423
417424 // Build a new error list without the ambiguous operator precedence errors/notes
418 var fixed_errors: std.ArrayList(std.zig.Ast.Error) = try .initCapacity(gpa, tree.errors.len - (operators_to_fix.count() * 3));
425 var fixed_errors: std.ArrayList(std.zig.Ast.Error) = try .initCapacity(gpa, remaining_errors);
419426 for (tree.errors) |err| {
420427 switch (err.tag) {
421428 .ambiguous_operator_precedence,