Hi! I am trying to follow Robert Nystrom's book Crafting Interpreters book in zig, and I am in the first section, writing a lexer. The core of the lexer is the scanToken function and it includes a large switch statement. The issue is that the switch expression should return a Token or an error, which is caught, but the compiler thinks a certain switch case returns void instead.
const tok: Token = switch(c) {
...
'"' => blk: {
const string_start = self.idx_current;
while (self.bytesLeft() > 0) {
self.idx_current += 1;
if (self.match('\n', 0)) {
self.idx_line += 1;
}
if (self.match('"', 0)) {
break :blk Token{ .token_type = .STRING, .literal = Literal{ .string = self.source[string_start + 1 .. self.idx_current] } };
}
}
else {
break :blk LexError.UnterminatedString;
}
},
...
'A' => blk: {
while (self.bytesLeft() > 0) {
break :blk LexError.Impossible;
}
},
} catch |err| switch (err) {
...
}
Here the first switch statement that matches a string literal compiles and works perfectly fine, it also includes while and break statements. However, the compiler thinks the second case returns a void somehow.
src/tokenizer.zig:173:28: error: incompatible types: 'tokenizer.Token' and 'error{UnknownCharacter,UnexpectedCharacter,NoToken,UnterminatedString,Impossible}!void'
const tok: Token = switch (c) {
^~~~~~
src/tokenizer.zig:174:25: note: type 'tokenizer.Token' here
'(' => Token{ .token_type = .LEFT_PAREN },
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/tokenizer.zig:264:25: note: type 'error{UnknownCharacter,UnexpectedCharacter,NoToken,UnterminatedString,Impossible}!void' here
'A' => blk: {
~~~~~^