From 6624dc01b347d552411d596a7b981cec39a11922 Mon Sep 17 00:00:00 2001 From: Tau Date: Tue, 16 Jul 2024 18:43:12 +0200 Subject: [PATCH] Suppress other messages when there are mismatched parentheses --- lib/std/zig/AstGen.zig | 45 ++++++++++++++++--- lib/std/zig/Parse.zig | 10 ++--- .../compile_errors/invalid_unicode_escape.zig | 2 +- test/compile_errors.zig | 3 -- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index f54998e26d1b..693023481fee 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -1,6 +1,8 @@ //! Ingests an AST and produces ZIR code. const AstGen = @This(); +const Parse = @import("Parse.zig"); + const std = @import("std"); const Ast = std.zig.Ast; const mem = std.mem; @@ -13870,11 +13872,12 @@ fn lowerAstErrors(astgen: *AstGen) !void { const gpa = astgen.gpa; const parse_err = tree.errors[0]; + const err_tok = parse_err.token + @intFromBool(parse_err.token_is_prev); const token_starts = tree.tokens.items(.start); const token_tags = tree.tokens.items(.tag); - if (try @import("Parse.zig").findUnmatchedParen(astgen.gpa, token_tags)) |tok| { + if (try Parse.findUnmatchedParen(astgen.gpa, token_tags)) |tok| { const text: []const u8 = switch (token_tags[tok]) { .l_paren => "unclosed parenthesis", .l_brace => "unclosed curly brace", @@ -13885,6 +13888,37 @@ fn lowerAstErrors(astgen: *AstGen) !void { else => unreachable, }; try astgen.appendErrorTok(tok, "{s}", .{text}); + // Unmatched parentheses are often an underlying cause of + // otherwise more obscure errors, so we only report the parse + // error if it probably wasn't caused by this. + switch (parse_err.tag) { + .asterisk_after_ptr_deref, + .chained_comparison_operators, + .expected_inlinable, + .expected_labelable, + .expected_prefix_expr, + .expected_return_type, + .extern_fn_body, + .extra_addrspace_qualifier, + .extra_align_qualifier, + .extra_allowzero_qualifier, + .extra_const_qualifier, + .extra_volatile_qualifier, + .ptr_mod_on_array_child_type, + .invalid_bit_range, + .same_line_doc_comment, + .test_doc_comment, + .comptime_doc_comment, + .varargs_nonfinal, + .expected_continue_expr, + .mismatched_binary_op_whitespace, + .invalid_ampersand_ampersand, + .extra_for_capture, + .for_input_not_captured, + => {}, + .expected_token => if (token_tags[err_tok] != .invalid) return, + else => return, + } } var msg: std.ArrayListUnmanaged(u8) = .{}; @@ -13893,11 +13927,10 @@ fn lowerAstErrors(astgen: *AstGen) !void { var notes: std.ArrayListUnmanaged(u32) = .{}; defer notes.deinit(gpa); - const tok = parse_err.token + @intFromBool(parse_err.token_is_prev); - if (token_tags[tok] == .invalid) { - const bad_off: u32 = @intCast(tree.tokenSlice(tok).len); - const byte_abs = token_starts[tok] + bad_off; - try notes.append(gpa, try astgen.errNoteTokOff(tok, bad_off, "invalid byte: '{'}'", .{ + if (token_tags[err_tok] == .invalid) { + const bad_off: u32 = @intCast(tree.tokenSlice(err_tok).len); + const byte_abs = token_starts[err_tok] + bad_off; + try notes.append(gpa, try astgen.errNoteTokOff(err_tok, bad_off, "invalid byte: '{'}'", .{ std.zig.fmtEscapes(tree.source[byte_abs..][0..1]), })); } diff --git a/lib/std/zig/Parse.zig b/lib/std/zig/Parse.zig index 68e891b50b1d..271b87fedf75 100644 --- a/lib/std/zig/Parse.zig +++ b/lib/std/zig/Parse.zig @@ -216,7 +216,7 @@ pub fn findUnmatchedParen(gpa: Allocator, token_tags: []const Token.Tag) !?Token switch (t) { .l_paren, .l_brace, .l_bracket => try stack.append(.{ .tag = t, .idx = @intCast(i) }), .r_paren, .r_brace, .r_bracket => { - if (stack.items.len == 0 or !parenMatch(stack.pop().tag, t)) + if (stack.items.len == 0 or t != closingParen(stack.pop().tag)) return @intCast(i); }, else => {}, @@ -227,11 +227,11 @@ pub fn findUnmatchedParen(gpa: Allocator, token_tags: []const Token.Tag) !?Token return null; } -fn parenMatch(a: Token.Tag, b: Token.Tag) bool { +fn closingParen(a: Token.Tag) Token.Tag { return switch (a) { - .l_paren => b == .r_paren, - .l_brace => b == .r_brace, - .l_bracket => b == .r_bracket, + .l_paren => .r_paren, + .l_brace => .r_brace, + .l_bracket => .r_bracket, else => unreachable, }; } diff --git a/test/cases/compile_errors/invalid_unicode_escape.zig b/test/cases/compile_errors/invalid_unicode_escape.zig index 1555f2be801a..9251022e1f23 100644 --- a/test/cases/compile_errors/invalid_unicode_escape.zig +++ b/test/cases/compile_errors/invalid_unicode_escape.zig @@ -1,5 +1,5 @@ export fn entry() void { - const a = '\u{12z34}'; + const a = '\u{12z34'; } // error diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 055d4262dfe0..81ce2cbe1cdd 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -71,7 +71,6 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void { \\} , &[_][]const u8{ ":3:1: error: unmatched curly brace", - ":2:2: error: expected 'EOF', found '}'", }); } @@ -84,7 +83,6 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void { \\}; , &[_][]const u8{ ":2:1: error: unmatched parenthesis", - ":2:1: error: expected statement, found ')'", }); } @@ -102,7 +100,6 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void { \\} , &[_][]const u8{ ":8:1: error: unmatched curly brace", - ":5:15: error: expected type expression, found '{'", }); }