diff --git a/lib/std/zig/fmt.zig b/lib/std/zig/fmt.zig index 1066852064..4351ab7987 100644 --- a/lib/std/zig/fmt.zig +++ b/lib/std/zig/fmt.zig @@ -23,6 +23,7 @@ pub fn fmtId(bytes: []const u8) std.fmt.Formatter(formatId) { } pub fn isValidId(bytes: []const u8) bool { + if (mem.eql(u8, bytes, "_")) return false; for (bytes) |c, i| { switch (c) { '_', 'a'...'z', 'A'...'Z' => {}, diff --git a/src/stage1/astgen.cpp b/src/stage1/astgen.cpp index 88587c5805..cc8ccefad7 100644 --- a/src/stage1/astgen.cpp +++ b/src/stage1/astgen.cpp @@ -3821,9 +3821,6 @@ static Stage1ZirInst *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode const_instruction->value->special = ConstValSpecialStatic; const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard; return &const_instruction->base; - } else { - add_node_error(ag->codegen, node, buf_sprintf("`_` may only be used to assign things to")); - return ag->codegen->invalid_inst_src; } } diff --git a/src/translate_c.zig b/src/translate_c.zig index 3792e21550..707f8cc485 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -4951,10 +4951,6 @@ fn transMacroDefine(c: *Context, m: *MacroCtx) ParseError!void { const scope = &c.global_scope.base; const init_node = try parseCExpr(c, m, scope); - if (init_node.castTag(.identifier)) |ident_node| { - if (mem.eql(u8, "_", ident_node.data)) - return m.fail(c, "unable to translate C expr: illegal identifier _", .{}); - } const last = m.next().?; if (last != .Eof and last != .Nl) return m.fail(c, "unable to translate C expr: unexpected token .{s}", .{@tagName(last)}); diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 03f06ed8ca..4953896636 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -1647,4 +1647,16 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { \\ if (a != 1) abort(); \\} , ""); + + cases.add("Underscore identifiers", + \\#include + \\int _ = 10; + \\typedef struct { int _; } S; + \\int main(void) { + \\ if (_ != 10) abort(); + \\ S foo = { ._ = _ }; + \\ if (foo._ != _) abort(); + \\ return 0; + \\} + , ""); } diff --git a/test/translate_c.zig b/test/translate_c.zig index 22aa67c774..2ba42fef07 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -3616,9 +3616,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\} }); - cases.add("Don't allow underscore identifier in macros", + cases.add("Use @ syntax for bare underscore identifier in macro or public symbol", \\#define FOO _ + \\int _ = 42; , &[_][]const u8{ - \\pub const FOO = @compileError("unable to translate C expr: illegal identifier _"); + \\pub const FOO = @"_"; + , + \\pub export var @"_": c_int = 42; }); }