diff --git a/src/analyze.cpp b/src/analyze.cpp index 4f58fd07f65881f0afcea7255c1ff557719884dd..a1b1c56670b2a0f8ccc03fc403e106822940f19c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -981,6 +981,17 @@ ZigType *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node) { return g->builtin_types.entry_invalid; assert(result->special != ConstValSpecialRuntime); + // Reject undefined as valid `type` type even though the specification + // allows it to be casted to anything. + // See also ir_resolve_type() + if (result->special == ConstValSpecialUndef) { + add_node_error(g, node, + buf_sprintf("expected type 'type', found '%s'", + buf_ptr(&g->builtin_types.entry_undef->name))); + return g->builtin_types.entry_invalid; + } + + assert(result->data.x_type != nullptr); return result->data.x_type; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index d151b31343cf6923e17ed452fbe9327c19ec3d11..0d28ac493230bde1035d2d87b75208ab678dbc7e 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,23 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "undefined as field type is rejected", + \\const Foo = struct { + \\ a: undefined, + \\}; + \\const Bar = union { + \\ a: undefined, + \\}; + \\pub fn main() void { + \\ const foo: Foo = undefined; + \\ const bar: Bar = undefined; + \\} + , + "tmp.zig:2:8: error: expected type 'type', found '(undefined)'", + "tmp.zig:5:8: error: expected type 'type', found '(undefined)'", + ); + cases.add( "@hasDecl with non-container", \\export fn entry() void {