@@ -13955,6 +13955,39 @@ fn lowerAstErrors(astgen: *AstGen) !void {
13955
13955
var notes: std.ArrayListUnmanaged(u32) = .empty;
13956
13956
defer notes.deinit(gpa);
13957
13957
13958
+ const token_starts = tree.tokens.items(.start);
13959
+ const token_tags = tree.tokens.items(.tag);
13960
+ const tok = parse_err.token + @intFromBool(parse_err.token_is_prev);
13961
+ const tok_start = token_starts[tok];
13962
+
13963
+ if (token_tags[tok] == .invalid and tree.source[tok_start] == '\\') {
13964
+ const bad_off = blk: {
13965
+ const tok_len: u32 = @intCast(tree.tokenSlice(tok).len);
13966
+ const tok_end = tok_start + tok_len;
13967
+ var idx = tok_start;
13968
+ while (idx < tok_end) : (idx += 1) {
13969
+ switch (tree.source[idx]) {
13970
+ 0x00...0x09, 0x0b...0x1f, 0x7f => break,
13971
+ else => {},
13972
+ }
13973
+ }
13974
+ break :blk idx - tok_start;
13975
+ };
13976
+
13977
+ const byte_abs = tok_start + bad_off;
13978
+ try notes.append(gpa, try astgen.errNoteTokOff(tok, bad_off, "invalid byte: '{'}'", .{
13979
+ std.zig.fmtEscapes(tree.source[byte_abs..][0..1]),
13980
+ }));
13981
+ const err: Ast.Error = .{
13982
+ .tag = Ast.Error.Tag.expected_token,
13983
+ .token = tok,
13984
+ .extra = .{ .expected_tag = std.zig.Token.Tag.multiline_string_literal_line },
13985
+ };
13986
+ msg.clearRetainingCapacity();
13987
+ try tree.renderError(err, msg.writer(gpa));
13988
+ return try astgen.appendErrorTokNotes(tok, "{s}", .{msg.items}, notes.items);
13989
+ }
13990
+
13958
13991
for (tree.errors[1..]) |note| {
13959
13992
if (!note.is_note) break;
13960
13993
0 commit comments