Commit 8944240aec

Andrew Kelley <andrew@ziglang.org>
2021-04-30 04:56:01
AstGen: represent global variables directly
Rather than with `block_inline_var`. This matches how function declarations work and how extern variables work.
1 parent 86d564e
src/AstGen.zig
@@ -1854,7 +1854,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: ast.Node.Index) Inner
             .bit_or,
             .block,
             .block_inline,
-            .block_inline_var,
             .suspend_block,
             .loop,
             .bool_br_and,
@@ -2917,10 +2916,9 @@ fn globalVarDecl(
     const token_tags = tree.tokens.items(.tag);
 
     const is_mutable = token_tags[var_decl.ast.mut_token] == .keyword_var;
-    const tag: Zir.Inst.Tag = if (is_mutable) .block_inline_var else .block_inline;
     // We do this at the beginning so that the instruction index marks the range start
     // of the top level declaration.
-    const block_inst = try gz.addBlock(tag, node);
+    const block_inst = try gz.addBlock(.block_inline, node);
 
     var block_scope: GenZir = .{
         .parent = scope,
@@ -2961,7 +2959,7 @@ fn globalVarDecl(
 
     assert(var_decl.comptime_token == null); // handled by parser
 
-    if (var_decl.ast.init_node != 0) {
+    const var_inst: Zir.Inst.Ref = if (var_decl.ast.init_node != 0) vi: {
         if (is_extern) {
             return astgen.failNode(
                 var_decl.ast.init_node,
@@ -2970,43 +2968,55 @@ fn globalVarDecl(
             );
         }
 
-        const init_result_loc: AstGen.ResultLoc = if (var_decl.ast.type_node != 0) .{
-            .ty = try expr(
+        const type_inst: Zir.Inst.Ref = if (var_decl.ast.type_node != 0)
+            try expr(
                 &block_scope,
                 &block_scope.base,
                 .{ .ty = .type_type },
                 var_decl.ast.type_node,
-            ),
-        } else .none;
+            )
+        else
+            .none;
 
         const init_inst = try expr(
             &block_scope,
             &block_scope.base,
-            init_result_loc,
+            if (type_inst != .none) .{ .ty = type_inst } else .none,
             var_decl.ast.init_node,
         );
 
-        // We do this at the end so that the instruction index marks the end
-        // range of a top level declaration.
-        _ = try block_scope.addBreak(.break_inline, block_inst, init_inst);
+        if (is_mutable) {
+            const var_inst = try block_scope.addVar(.{
+                .var_type = type_inst,
+                .lib_name = 0,
+                .align_inst = .none, // passed via the decls data
+                .init = init_inst,
+                .is_extern = false,
+            });
+            break :vi var_inst;
+        } else {
+            break :vi init_inst;
+        }
     } else if (!is_extern) {
         return astgen.failNode(node, "variables must be initialized", .{});
-    } else if (var_decl.ast.type_node != 0) {
+    } else if (var_decl.ast.type_node != 0) vi: {
         // Extern variable which has an explicit type.
         const type_inst = try typeExpr(&block_scope, &block_scope.base, var_decl.ast.type_node);
 
         const var_inst = try block_scope.addVar(.{
             .var_type = type_inst,
             .lib_name = lib_name,
-            .align_inst = .none, // passed in the decls data
+            .align_inst = .none, // passed via the decls data
             .init = .none,
             .is_extern = true,
         });
-
-        _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);
+        break :vi var_inst;
     } else {
         return astgen.failNode(node, "unable to infer variable type", .{});
-    }
+    };
+    // We do this at the end so that the instruction index marks the end
+    // range of a top level declaration.
+    _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);
     try block_scope.setBlockBody(block_inst);
 
     const name_token = var_decl.ast.mut_token + 1;
src/Module.zig
@@ -3478,7 +3478,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
         }
         return type_changed or is_inline != prev_is_inline;
     } else {
-        const is_mutable = zir_tags[zir_block_index] == .block_inline_var;
+        const is_mutable = decl_tv.val.tag() == .variable;
 
         var is_threadlocal = false; // TODO implement threadlocal variables
         var is_extern = false; // TODO implement extern variables
src/Sema.zig
@@ -439,7 +439,7 @@ pub fn analyzeBody(
                 i = 0;
                 continue;
             },
-            .block_inline, .block_inline_var => blk: {
+            .block_inline => blk: {
                 // Directly analyze the block body without introducing a new block.
                 const inst_data = datas[inst].pl_node;
                 const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index);
src/Zir.zig
@@ -214,8 +214,6 @@ pub const Inst = struct {
         /// a noreturn instruction.
         /// Uses the `pl_node` union field. Payload is `Block`.
         block_inline,
-        /// Same as `block_inline` but it additionally marks a decl as being a variable.
-        block_inline_var,
         /// Implements `suspend {...}`.
         /// Uses the `pl_node` union field. Payload is `Block`.
         suspend_block,
@@ -982,7 +980,6 @@ pub const Inst = struct {
                 .bit_or,
                 .block,
                 .block_inline,
-                .block_inline_var,
                 .suspend_block,
                 .loop,
                 .bool_br_and,
@@ -1240,7 +1237,6 @@ pub const Inst = struct {
                 .bit_or = .pl_node,
                 .block = .pl_node,
                 .block_inline = .pl_node,
-                .block_inline_var = .pl_node,
                 .suspend_block = .pl_node,
                 .bool_and = .pl_node,
                 .bool_not = .un_node,
@@ -2517,7 +2513,7 @@ pub const Inst = struct {
     ///          - if name == 0 `is_exported` determines which one: 0=comptime,1=usingnamespace
     ///        - 1 means test decl with no name.
     ///        value: Index,
-    ///        - one of: block_inline, block_inline_var
+    ///        - one of: block_inline
     ///        align: Ref, // if corresponding bit is set
     ///        link_section: Ref, // if corresponding bit is set
     ///    }
@@ -2933,7 +2929,6 @@ const Writer = struct {
 
             .block,
             .block_inline,
-            .block_inline_var,
             .suspend_block,
             .loop,
             .validate_struct_init_ptr,