Skip to content

Commit e119df4

Browse files
committed
handle invalid bytes in string literals, rework error
1 parent 5fa6cf3 commit e119df4

12 files changed

+31
-34
lines changed

lib/docs/wasm/html_render.zig

-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ pub fn fileSourceHtml(
171171
try out.appendSlice(gpa, "</span>");
172172
},
173173

174-
.comment,
175174
.doc_comment,
176175
.container_doc_comment,
177176
=> {

lib/std/zig/Ast.zig

+10
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,12 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
458458
return stream.writeAll("for input is not captured");
459459
},
460460

461+
.invalid_byte => {
462+
return stream.print("string/comment contains invalid byte: '{'}'", .{
463+
std.zig.fmtEscapes(tree.source[(tree.tokens.items(.start)[parse_error.token] + parse_error.extra.offset)..][0..1]),
464+
});
465+
},
466+
461467
.expected_token => {
462468
const found_tag = token_tags[parse_error.token + @intFromBool(parse_error.token_is_prev)];
463469
const expected_symbol = parse_error.extra.expected_tag.symbol();
@@ -2926,6 +2932,7 @@ pub const Error = struct {
29262932
extra: union {
29272933
none: void,
29282934
expected_tag: Token.Tag,
2935+
offset: usize,
29292936
} = .{ .none = {} },
29302937

29312938
pub const Tag = enum {
@@ -2996,6 +3003,9 @@ pub const Error = struct {
29963003

29973004
/// `expected_tag` is populated.
29983005
expected_token,
3006+
3007+
/// `offset` is populated
3008+
invalid_byte,
29993009
};
30003010
};
30013011

lib/std/zig/AstGen.zig

+5-18
Original file line numberDiff line numberDiff line change
@@ -13986,8 +13986,9 @@ fn lowerAstErrors(astgen: *AstGen) !void {
1398613986
const parse_err = tree.errors[0];
1398713987
const tok = parse_err.token + @intFromBool(parse_err.token_is_prev);
1398813988
const tok_start = token_starts[tok];
13989+
const start_char = tree.source[tok_start];
1398913990

13990-
if (token_tags[tok] == .invalid and (tree.source[tok_start] == '\\' or tree.source[tok_start] == '/')) {
13991+
if (token_tags[tok] == .invalid and (start_char == '\"' or start_char == '\\' or start_char == '/')) {
1399113992
const tok_len: u32 = @intCast(tree.tokenSlice(tok).len);
1399213993
const tok_end = tok_start + tok_len;
1399313994
const bad_off = blk: {
@@ -14001,28 +14002,14 @@ fn lowerAstErrors(astgen: *AstGen) !void {
1400114002
break :blk idx - tok_start;
1400214003
};
1400314004

14004-
const byte_abs = tok_start + bad_off;
14005-
try notes.append(gpa, try astgen.errNoteTokOff(tok, bad_off, "invalid byte: '{'}'", .{
14006-
std.zig.fmtEscapes(tree.source[byte_abs..][0..1]),
14007-
}));
14008-
const expected_tag = switch (tree.source[tok_start]) {
14009-
'\\' => std.zig.Token.Tag.multiline_string_literal_line,
14010-
'/' => blk: {
14011-
if (std.mem.indexOf(u8, tree.source[tok_start..tok_end], "///")) |idx| {
14012-
if (idx == 0) break :blk std.zig.Token.Tag.doc_comment;
14013-
}
14014-
break :blk std.zig.Token.Tag.comment;
14015-
},
14016-
else => unreachable,
14017-
};
1401814005
const err: Ast.Error = .{
14019-
.tag = Ast.Error.Tag.expected_token,
14006+
.tag = Ast.Error.Tag.invalid_byte,
1402014007
.token = tok,
14021-
.extra = .{ .expected_tag = expected_tag },
14008+
.extra = .{ .offset = bad_off },
1402214009
};
1402314010
msg.clearRetainingCapacity();
1402414011
try tree.renderError(err, msg.writer(gpa));
14025-
return try astgen.appendErrorTokNotes(tok, "{s}", .{msg.items}, notes.items);
14012+
return try astgen.appendErrorTokNotesOff(tok, bad_off, "{s}", .{msg.items}, notes.items);
1402614013
}
1402714014

1402814015
var cur_err = tree.errors[0];

lib/std/zig/tokenizer.zig

-3
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ pub const Token = struct {
137137
angle_bracket_angle_bracket_right_equal,
138138
tilde,
139139
number_literal,
140-
comment,
141140
doc_comment,
142141
container_doc_comment,
143142
keyword_addrspace,
@@ -200,7 +199,6 @@ pub const Token = struct {
200199
.eof,
201200
.builtin,
202201
.number_literal,
203-
.comment,
204202
.doc_comment,
205203
.container_doc_comment,
206204
=> null,
@@ -329,7 +327,6 @@ pub const Token = struct {
329327
.eof => "EOF",
330328
.builtin => "a builtin function",
331329
.number_literal => "a number literal",
332-
.comment => "a comment",
333330
.doc_comment, .container_doc_comment => "a document comment",
334331
else => unreachable,
335332
};

test/cases/compile_errors/normal_string_with_newline.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ b";
55
// backend=stage2
66
// target=native
77
//
8-
// :1:13: error: expected expression, found 'invalid token'
8+
// :1:15: error: string/comment contains invalid byte: '\n'

test/cases/compile_errors/tab_inside_comment.zig

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ export fn entry() void {}
55
// backend=stage2
66
// target=native
77
//
8-
// :1:1: error: expected 'a comment', found invalid bytes
9-
// :1:8: note: invalid byte: '\t'
8+
// :1:8: error: string/comment contains invalid byte: '\t'

test/cases/compile_errors/tab_inside_doc_comment.zig

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@ export fn entry() void {}
55
// backend=stage2
66
// target=native
77
//
8-
// :1:1: error: expected 'a document comment', found invalid bytes
9-
// :1:13: note: invalid byte: '\t'
8+
// :1:13: error: string/comment contains invalid byte: '\t'

test/cases/compile_errors/tab_inside_multiline_string.zig

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@ export fn entry() void {
1010
// backend=stage2
1111
// target=native
1212
//
13-
// :4:9: error: expected 'a string literal', found invalid bytes
14-
// :4:11: note: invalid byte: '\t'
13+
// :4:11: error: string/comment contains invalid byte: '\t'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export fn entry() void {
2+
const foo = " hello";
3+
_ = foo;
4+
}
5+
6+
// error
7+
// backend=stage2
8+
// target=native
9+
//
10+
// :2:18: error: string/comment contains invalid byte: '\t'

test/compile_errors.zig

+2-3
Original file line numberDiff line numberDiff line change
@@ -217,16 +217,15 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void {
217217
const case = ctx.obj("invalid byte in string", b.graph.host);
218218

219219
case.addError("_ = \"\x01Q\";", &[_][]const u8{
220-
":1:5: error: expected expression, found 'invalid token'",
220+
":1:6: error: string/comment contains invalid byte: '\\x01'",
221221
});
222222
}
223223

224224
{
225225
const case = ctx.obj("invalid byte in comment", b.graph.host);
226226

227227
case.addError("//\x01Q", &[_][]const u8{
228-
":1:1: error: expected 'a comment', found invalid bytes",
229-
":1:3: note: invalid byte: '\\x01'",
228+
":1:3: error: string/comment contains invalid byte: '\\x01'",
230229
});
231230
}
232231

tools/docgen.zig

-1
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,6 @@ fn tokenizeAndPrintRaw(
782782
try out.writeAll("</span>");
783783
},
784784

785-
.comment,
786785
.doc_comment,
787786
.container_doc_comment,
788787
=> {

tools/doctest.zig

-1
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,6 @@ fn tokenizeAndPrint(arena: Allocator, out: anytype, raw_src: []const u8) !void {
677677
try out.writeAll("</span>");
678678
},
679679

680-
.comment,
681680
.doc_comment,
682681
.container_doc_comment,
683682
=> {

0 commit comments

Comments
 (0)