diff --git a/src/analyze.cpp b/src/analyze.cpp index d6396832c40a..ef02e6404ce1 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 d151b31343cf..0d28ac493230 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 {