Commit 6a053ffcc8
Changed files (3)
src-self-hosted
test
src-self-hosted/Module.zig
@@ -1485,6 +1485,7 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
const type_node = var_decl.getTrailer("type_node") orelse
break :blk null;
+ // Temporary arena for the zir instructions.
var type_scope_arena = std.heap.ArenaAllocator.init(self.gpa);
defer type_scope_arena.deinit();
var type_scope: Scope.GenZIR = .{
@@ -1539,7 +1540,8 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
try self.coerce(&inner_block.base, some, ret.operand)
else
ret.operand;
- const val = try self.resolveConstValue(&inner_block.base, coerced);
+ const val = coerced.value() orelse
+ return self.fail(&block_scope.base, inst.src, "unable to resolve comptime value", .{});
var_type = explicit_type orelse try ret.operand.ty.copy(block_scope.arena);
break :blk try val.copy(block_scope.arena);
@@ -1603,7 +1605,41 @@ fn astGenAndAnalyzeDecl(self: *Module, decl: *Decl) !bool {
}
return type_changed;
},
- .Comptime => @panic("TODO comptime decl"),
+ .Comptime => {
+ const comptime_decl = @fieldParentPtr(ast.Node.Comptime, "base", ast_node);
+
+ decl.analysis = .in_progress;
+
+ // A comptime decl does not store any value so we can just deinit this arena after analysis is done.
+ var analysis_arena = std.heap.ArenaAllocator.init(self.gpa);
+ defer analysis_arena.deinit();
+ var gen_scope: Scope.GenZIR = .{
+ .decl = decl,
+ .arena = &analysis_arena.allocator,
+ .parent = decl.scope,
+ };
+ defer gen_scope.instructions.deinit(self.gpa);
+
+ // TODO comptime scope here
+ _ = try astgen.expr(self, &gen_scope.base, .none, comptime_decl.expr);
+
+ var block_scope: Scope.Block = .{
+ .parent = null,
+ .func = null,
+ .decl = decl,
+ .instructions = .{},
+ .arena = &analysis_arena.allocator,
+ };
+ defer block_scope.instructions.deinit(self.gpa);
+
+ _ = try zir_sema.analyzeBody(self, &block_scope.base, .{
+ .instructions = gen_scope.instructions.items,
+ });
+
+ decl.analysis = .complete;
+ decl.generation = self.generation;
+ return true;
+ },
.Use => @panic("TODO usingnamespace decl"),
else => unreachable,
}
@@ -1794,7 +1830,16 @@ fn analyzeRootSrcFile(self: *Module, root_scope: *Scope.File) !void {
}
}
} else if (src_decl.castTag(.Comptime)) |comptime_node| {
- log.err("TODO: analyze comptime decl", .{});
+ const name_index = self.getNextAnonNameIndex();
+ const name = try std.fmt.allocPrint(self.gpa, "__comptime_{}", .{name_index});
+ defer self.gpa.free(name);
+
+ const name_hash = root_scope.fullyQualifiedNameHash(name);
+ const contents_hash = std.zig.hashSrc(tree.getNodeSource(src_decl));
+
+ const new_decl = try self.createNewDecl(&root_scope.base, name, decl_i, name_hash, contents_hash);
+ root_scope.decls.appendAssumeCapacity(new_decl);
+ self.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl });
} else if (src_decl.castTag(.ContainerField)) |container_field| {
log.err("TODO: analyze container field", .{});
} else if (src_decl.castTag(.TestDecl)) |test_decl| {
test/stage2/compare_output.zig
@@ -23,11 +23,6 @@ pub fn addCases(ctx: *TestContext) !void {
case.addError("", &[_][]const u8{":1:1: error: no entry point found"});
- case.addError(
- \\export fn _start() noreturn {
- \\}
- , &[_][]const u8{":2:1: error: expected noreturn, found void"});
-
// Regular old hello world
case.addCompareOutput(
\\export fn _start() noreturn {
test/stage2/compile_errors.zig
@@ -67,6 +67,18 @@ pub fn addCases(ctx: *TestContext) !void {
\\fn entry() void {}
, &[_][]const u8{":2:4: error: redefinition of 'entry'"});
+ ctx.compileError("incorrect return type", linux_x64,
+ \\export fn _start() noreturn {
+ \\}
+ , &[_][]const u8{":2:1: error: expected noreturn, found void"});
+
+ ctx.compileError("extern variable has no type", linux_x64,
+ \\comptime {
+ \\ _ = foo;
+ \\}
+ \\extern var foo;
+ , &[_][]const u8{":4:1: error: unable to infer variable type"});
+
//ctx.incrementalFailure("function redefinition", linux_x64,
// \\fn entry() void {}
// \\fn entry() void {}
@@ -108,28 +120,4 @@ pub fn addCases(ctx: *TestContext) !void {
// \\ return 36893488147419103232;
// \\}
//, "1.zig", 2, 12, "integer value '36893488147419103232' cannot be stored in type 'c_int'");
-
- //ctx.testCompileError(
- // \\comptime {
- // \\ var a: *align(4) align(4) i32 = 0;
- // \\}
- //, "1.zig", 2, 22, "Extra align qualifier");
-
- //ctx.testCompileError(
- // \\comptime {
- // \\ var b: *const const i32 = 0;
- // \\}
- //, "1.zig", 2, 19, "Extra align qualifier");
-
- //ctx.testCompileError(
- // \\comptime {
- // \\ var c: *volatile volatile i32 = 0;
- // \\}
- //, "1.zig", 2, 22, "Extra align qualifier");
-
- //ctx.testCompileError(
- // \\comptime {
- // \\ var d: *allowzero allowzero i32 = 0;
- // \\}
- //, "1.zig", 2, 23, "Extra align qualifier");
}