Commit 2354cbafdb

jacob gw <jacoblevgw@gmail.com>
2021-04-28 23:01:24
stage2: implement #8364
1 parent c90e52b
Changed files (2)
src
test
stage2
src/AstGen.zig
@@ -247,7 +247,11 @@ pub const align_rl: ResultLoc = .{ .ty = .u16_type };
 pub const bool_rl: ResultLoc = .{ .ty = .bool_type };
 
 pub fn typeExpr(gz: *GenZir, scope: *Scope, type_node: ast.Node.Index) InnerError!Zir.Inst.Ref {
-    return expr(gz, scope, .{ .ty = .type_type }, type_node);
+    const prev_force_comptime = gz.force_comptime;
+    gz.force_comptime = true;
+    const e = expr(gz, scope, .{ .ty = .type_type }, type_node);
+    gz.force_comptime = prev_force_comptime;
+    return e;
 }
 
 fn lvalExpr(gz: *GenZir, scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
@@ -821,7 +825,8 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
         .char_literal => return charLiteral(gz, scope, rl, node),
         .error_set_decl => return errorSetDecl(gz, scope, rl, node),
         .array_access => return arrayAccess(gz, scope, rl, node),
-        .@"comptime" => return comptimeExpr(gz, scope, rl, node_datas[node].lhs),
+        // we use comptimeExprFromAst here as it is explicitly put there by the user, `comptimeExpr` can be used by the compiler, even in a comptime scope
+        .@"comptime" => return comptimeExprFromAst(gz, scope, rl, node_datas[node].lhs),
         .@"switch", .switch_comma => return switchExpr(gz, scope, rl, node),
 
         .@"nosuspend" => return nosuspendExpr(gz, scope, rl, node),
@@ -1460,6 +1465,22 @@ pub fn comptimeExpr(
     return result;
 }
 
+pub fn comptimeExprFromAst(
+    gz: *GenZir,
+    scope: *Scope,
+    rl: ResultLoc,
+    node: ast.Node.Index,
+) InnerError!Zir.Inst.Ref {
+    const astgen = gz.astgen;
+    if (gz.force_comptime) {
+        return astgen.failNode(node, "redundant comptime keyword in already comptime scope", .{});
+    }
+    gz.force_comptime = true;
+    const result = try expr(gz, scope, rl, node);
+    gz.force_comptime = false;
+    return result;
+}
+
 fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) InnerError!Zir.Inst.Ref {
     const astgen = parent_gz.astgen;
     const tree = &astgen.file.tree;
test/stage2/test.zig
@@ -1008,7 +1008,7 @@ pub fn addCases(ctx: *TestContext) !void {
             "Hello, World!\n",
         );
         try case.files.append(.{
-            .src = 
+            .src =
             \\pub fn print() void {
             \\    asm volatile ("syscall"
             \\        :
@@ -1024,6 +1024,25 @@ pub fn addCases(ctx: *TestContext) !void {
             .path = "print.zig",
         });
     }
+    {
+        var case = ctx.exe("redundant comptime", linux_x64);
+        case.addError(
+            \\export fn _start() void {
+            \\    var a: comptime u32 = 0;
+            \\}
+        ,
+            &.{":2:21: error: redundant comptime keyword in already comptime scope"},
+        );
+        case.addError(
+            \\export fn _start() void {
+            \\    comptime {
+            \\        var a: u32 = comptime 0;
+            \\    }
+            \\}
+        ,
+            &.{":3:31: error: redundant comptime keyword in already comptime scope"},
+        );
+    }
     {
         var case = ctx.exe("import private", linux_x64);
         case.addError(
@@ -1048,7 +1067,7 @@ pub fn addCases(ctx: *TestContext) !void {
             },
         );
         try case.files.append(.{
-            .src = 
+            .src =
             \\// dummy comment to make print be on line 2
             \\fn print() void {
             \\    asm volatile ("syscall"