Exercise 74: the comptime statement is no longer needed in the latest zig version
chrboesch opened this issue ยท 7 comments
I ran exercise 74 with zig version 0.10.0-dev.3672+cd5a9ba1f
without any changes on the source and got
PASSED:
My llama value is 2.
๐ค
You wrote "..it's sometimes surprising how few places actually need the keyword." Now it's one less. ๐
LOL. Thanks!
I've called in the cavalry for this one: https://old.reddit.com/r/Zig/comments/x12faa/when_is_the_comptime_keyword_required/?
Summary: a regression in the self-hosted compiler
makeLlamas
is only called at compile time because it is used for a global variable initialization value. In order to restore the example, put the variable declaration inside a function block like this:
--- a/exercises/074_comptime9.zig
+++ b/exercises/074_comptime9.zig
@@ -32,11 +32,6 @@ const print = @import("std").debug.print;
// implicitly required to be known compile time.
const llama_count = 5;
-// Again, this value's type and size must be known at compile
-// time, but we're letting the compiler infer both from the
-// return type of a function.
-const llamas = makeLlamas(llama_count);
-
// And here's the function. Note that the return value type
// depends on one of the input arguments!
fn makeLlamas(count: usize) [count]u8 {
@@ -52,6 +47,11 @@ fn makeLlamas(count: usize) [count]u8 {
}
pub fn main() void {
+ // Again, this value's type and size must be known at compile
+ // time, but we're letting the compiler infer both from the
+ // return type of a function.
+ const llamas = makeLlamas(llama_count);
+
print("My llama value is {}.\n", .{llamas[2]});
}
//
However, with this, the error becomes:
test.zig:39:9: error: variable of type 'comptime_int' must be const or comptime
var i = 0;
^
test.zig:39:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
test.zig:53:30: note: called from here
const llamas = makeLlamas(llama_count);
~~~~~~~~~~^~~~~~~~~~~~~
This happens because zig is trying to generate a makeLlamas
function that can be called at runtime. The intended solution no longer works with a runtime call to the function; it gives the same error as above.
With makeLlamas
only called at compile-time, as in status quo, the new behavior is correct! Ironically the central point of the lesson rings even more true.
As for a suggestion on how to restore the exercise, I'm actually not sure, because when I make the following change...
- var i = 0;
+ var i: u8 = 0;
...I noticed that it still passes, despite no use of the comptime
keyword. After examining this closely, I discovered that in this case, Zig is inlining the function call to makeLlamas
when no comptime
keyword is present. This is suspicious behavior, so I will examine the related code carefully in search for an analysis bug. Thanks for pinging me!
Bug filed upstream: ziglang/zig#12679
Thanks to @Vexu this issue is fixed in Zig master branch. Ziglings exercise 074 now gives:
test.zig:42:30: error: unable to resolve comptime value
fn makeLlamas(count: usize) [count]u8 {
^~~~~
test.zig:42:30: note: array length must be comptime known
Which arguably is an improvement over stage1:
./test.zig:42:30: error: use of undeclared identifier 'count'
fn makeLlamas(count: usize) [count]u8 {
^
The original intended solution now works for stage2 as well as stage1.
Furthermore, the makeLlamas
function has found its way into the Zig compiler test suite ๐
Awesome, @andrewrk , thanks for the excellent write-up! And I'm laughing with joy that ๐ฆ ๐ฆ ๐ฆ makeLlamas()
๐ฆ ๐ฆ ๐ฆ is now a Zig compiler test. ๐คฃ
Yahoo! The upstream fix is now in the master build. I've bumped the Ziglings minimum version requirement to 0.10.0-dev.3880+
. Thanks again for catching this, @chrboesch !