Commit e730172e47
Changed files (3)
test
stage2
src/Module.zig
@@ -4582,28 +4582,39 @@ pub fn optimizeMode(mod: Module) std.builtin.Mode {
/// Otherwise, returns a reference to the source code bytes directly.
/// See also `appendIdentStr` and `parseStrLit`.
pub fn identifierTokenString(mod: *Module, scope: *Scope, token: ast.TokenIndex) InnerError![]const u8 {
- return mod.identifierTokenStringTreeArena(scope, token, scope.tree(), scope.arena());
+ const tree = scope.tree();
+ const token_tags = tree.tokens.items(.tag);
+ assert(token_tags[token] == .identifier);
+ const ident_name = tree.tokenSlice(token);
+ if (!mem.startsWith(u8, ident_name, "@")) {
+ return ident_name;
+ }
+ var buf: ArrayListUnmanaged(u8) = .{};
+ defer buf.deinit(mod.gpa);
+ try parseStrLit(mod, scope, token, &buf, ident_name, 1);
+ const duped = try scope.arena().dupe(u8, buf.items);
+ return duped;
}
/// `scope` is only used for error reporting.
+/// The string is stored in `arena` regardless of whether it uses @"" syntax.
pub fn identifierTokenStringTreeArena(
mod: *Module,
scope: *Scope,
token: ast.TokenIndex,
tree: *const ast.Tree,
arena: *Allocator,
-) InnerError![]const u8 {
+) InnerError![]u8 {
const token_tags = tree.tokens.items(.tag);
assert(token_tags[token] == .identifier);
const ident_name = tree.tokenSlice(token);
if (!mem.startsWith(u8, ident_name, "@")) {
- return ident_name;
+ return arena.dupe(u8, ident_name);
}
var buf: ArrayListUnmanaged(u8) = .{};
defer buf.deinit(mod.gpa);
try parseStrLit(mod, scope, token, &buf, ident_name, 1);
- const duped = try arena.dupe(u8, buf.items);
- return duped;
+ return arena.dupe(u8, buf.items);
}
/// Given an identifier token, obtain the string for it (possibly parsing as a string
src/Sema.zig
@@ -2789,6 +2789,8 @@ fn analyzeSwitch(
var seen_fields = try gpa.alloc(?AstGen.SwitchProngSrc, operand.ty.enumFieldCount());
defer gpa.free(seen_fields);
+ mem.set(?AstGen.SwitchProngSrc, seen_fields, null);
+
var extra_index: usize = special.end;
{
var scalar_i: u32 = 0;
@@ -2849,12 +2851,6 @@ fn analyzeSwitch(
.{},
);
errdefer msg.destroy(sema.gpa);
- try mod.errNoteNonLazy(
- operand.ty.declSrcLoc(),
- msg,
- "enum '{}' declared here",
- .{operand.ty},
- );
for (seen_fields) |seen_src, i| {
if (seen_src != null) continue;
@@ -2865,10 +2861,16 @@ fn analyzeSwitch(
&block.base,
src,
msg,
- "unhandled enumeration value: '{s}",
+ "unhandled enumeration value: '{s}'",
.{field_name},
);
}
+ try mod.errNoteNonLazy(
+ operand.ty.declSrcLoc(),
+ msg,
+ "enum '{}' declared here",
+ .{operand.ty},
+ );
break :msg msg;
};
return mod.failWithOwnedErrorMsg(&block.base, msg);
test/stage2/cbe.zig
@@ -702,6 +702,21 @@ pub fn addCases(ctx: *TestContext) !void {
":3:15: error: enum 'E' has no tag with value 3",
":1:11: note: enum declared here",
});
+
+ case.addError(
+ \\const E = enum { a, b, c };
+ \\export fn foo() void {
+ \\ var x: E = .a;
+ \\ switch (x) {
+ \\ .a => {},
+ \\ .c => {},
+ \\ }
+ \\}
+ , &.{
+ ":4:5: error: switch must handle all possibilities",
+ ":4:5: note: unhandled enumeration value: 'b'",
+ ":1:11: note: enum 'E' declared here",
+ });
}
ctx.c("empty start function", linux_x64,