zig icon indicating copy to clipboard operation
zig copied to clipboard

stage2: cannot determine length of array in comptime block

Open ominitay opened this issue 3 years ago • 1 comments

Zig Version

0.10.0-dev.3313+cff5d9c80 (stage2)

Steps to Reproduce

Attempt to compile one of the following examples:

var bytes: [1024]u8 = undefined;

export const length = bytes.len;
var bytes: [1024]u8 = undefined;

comptime { _ = bytes.len; }

Expected Behavior

The examples compile successfully (or, more accurately, errors out because there's no main function).

Actual Behavior

The examples both reach a compile error, of the form:

test.zig:3:23: error: cannot load runtime value in comptime block
export const length = bytes.len;
                      ^~~~~~~~~~~

Hint: The following examples do not reach a compile error:

const bytes: [1024]u8 = undefined;

export const length = bytes.len;
var bytes: [1024]u8 = undefined;

test { comptime _ = bytes.len; }

ominitay avatar Jul 25 '22 22:07 ominitay

Thank you @topolarity for helping to reduce this!

ominitay avatar Jul 25 '22 22:07 ominitay

Related:

  • #12215
  • #12638

Compile error is emitted on the decl_val before it has a chance to look at the len field:

    > %9 = decl_val("bytes") 
      %10 = field_val(%9, "len") 

Resolution is unclear. Will require some reworking of AstGen/ZIR with regards to the decl_val instruction.

andrewrk avatar Oct 16 '22 18:10 andrewrk

I tried solving this in AstGen today and while I was able to get all the examples in the issue working it is still easy to break for example by adding a cast @as([1024u8, bytes). Maybe it'd be better to allow runtime instructions in outside of function bodies and rely on other mechanisms to get comptime known where they are needed as stage1 seems to be doing.

This approach could also result in better compile errors by turning the error in:

var cc: std.builtin.CallingConvention = .C;
export fn foo() callconv(cc) void {}

from

error: cannot load runtime value in comptime block
export fn foo() callconv(cc) void {}
                         ^~

to

error: unable to resolve comptime value
export fn foo() callconv(cc) void {}
                         ^~
note: calling convention must be comptime-known

Vexu avatar Oct 17 '22 17:10 Vexu

bytes.len should be comptime known though, the issue is that there's any error at all

doing @as in a comptime scope shouldn't change that

nektro avatar Oct 17 '22 18:10 nektro

bytes.len should be comptime known though, the issue is that there's any error at all

Yes but bytes is not comptime known and Zir works by first loading bytes and then doing field access on that.

doing @as in a comptime scope shouldn't change that

That's why I said that my AstGen based solution isn't that good.

Vexu avatar Oct 17 '22 18:10 Vexu