zig icon indicating copy to clipboard operation
zig copied to clipboard

ability for global variables to be initialized with address of each other

Open andrewrk opened this issue 10 years ago • 1 comments

const std = @import("std");
const expect = std.testing.expect;

const Node = struct {
    next: *Node,
};

const a: Node = .{ .next = &b };
const b: Node = .{ .next = &a };

test "example" {
    expect(a.next == &b);
    expect(b.next == &a);
}

Currently, this test case produces the following results:

test.zig:8:1: error: dependency loop detected
const a: Node = .{ .next = &b };
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    a: test.zig:8:29
    b: test.zig:9:29
    remaining reference traces hidden; use '-freference-trace' to see all reference traces

andrewrk avatar Mar 01 '16 03:03 andrewrk

I looked into this today and determined a prerequisite change that is needed in order to solve this.

Here is the ZIR code for the a declaration in the above test case:

  [166] a line(7) hash(27fe22bcab14905c326dd23192f524ff): %15 = block_inline({
+    %16 = decl_val("Node") token_offset:8:10 to :8:14
+    %17 = as_node(@InternPool.Index.type_type, %16) node_offset:8:10 to :8:14
    %18 = field_type(%17, next) node_offset:8:28 to :8:30
    %19 = decl_ref("b") token_offset:8:29 to :8:30
    %20 = as_node(%18, %19) node_offset:8:28 to :8:30
    %21 = struct_init_anon([next=%20]) node_offset:8:17 to :8:32
+    %22 = as_node(%17, %21) node_offset:8:17 to :8:32
    %23 = break_inline(%15, %22)
  }) node_offset:8:1 to :8:32

I have used diff syntax highlighting to indicate the lines related to how the type is stored, which is via value coercion.

In order to avoid a dependency loop, referencing a decl needs to access its type without forcing its value to be evaluated. But this ZIR makes it so that the type and value are computed always together. Instead, ZIR will need to be reworked so that decl types are available independently from their values. Then, the Sema analysis of the decl_ref ZIR instruction can force only the type to be evaluated, and queue up the value to be evaluated.

This will help make Sema more parallelizable as well, since the work is queued up rather than blocked on.

andrewrk avatar Jun 15 '23 05:06 andrewrk