diff --git a/src/Module.zig b/src/Module.zig index ccf6996cae..933917d948 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -4582,17 +4582,7 @@ 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()); -} - -/// `scope` is only used for error reporting. -pub fn identifierTokenStringTreeArena( - mod: *Module, - scope: *Scope, - token: ast.TokenIndex, - tree: *const ast.Tree, - arena: *Allocator, -) InnerError![]const u8 { + const tree = scope.tree(); const token_tags = tree.tokens.items(.tag); assert(token_tags[token] == .identifier); const ident_name = tree.tokenSlice(token); @@ -4602,10 +4592,31 @@ pub fn identifierTokenStringTreeArena( 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); + 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![]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 arena.dupe(u8, ident_name); + } + var buf: ArrayListUnmanaged(u8) = .{}; + defer buf.deinit(mod.gpa); + try parseStrLit(mod, scope, token, &buf, ident_name, 1); + return arena.dupe(u8, buf.items); +} + /// Given an identifier token, obtain the string for it (possibly parsing as a string /// literal if it is @"" syntax), and append the string to `buf`. /// See also `identifierTokenString` and `parseStrLit`. diff --git a/src/Sema.zig b/src/Sema.zig index 134e569948..a0be08ed71 100644 --- a/src/Sema.zig +++ b/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); diff --git a/test/stage2/cbe.zig b/test/stage2/cbe.zig index b0386f6246..3cf95ab6d6 100644 --- a/test/stage2/cbe.zig +++ b/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,