In the following code, the first double(3) call is treated as in a comptime scope, but the second one is not. I can understand the design. Just wonder whether or not it is a good idea to also treat the second one also as in comptime scope, implicitly, just like initializers of global declarations?
fn double(n: u64) @TypeOf(n) {
return n + n;
}
pub fn main() void {
const std = @import("std");
comptime var x: u64 = double(3); // The call must not be marked with comptime
x = x;
comptime var y: u64 = undefined;
y = double(3); // error: The call is required to be marked with comptime
std.debug.print("x = {}, y = {}\n", .{ x, y });
}
To be honest I’m more surprised that the first comptime var declaration places the initial assignment expression in a comptime scope. It’s legal for an inline fn to return a comptime-only result but take runtime-known arguments and have runtime side effects, but the current behavior means that to assign a comptime var from an inline function call with side effects you need to declare it and assign it as separate statements:
const std = @import("std");
pub fn main() void {
var x: i32 = 0;
const y: comptime_int = f(&x);
//comptime var z: comptime_int = f(&x); // error: unable to resolve comptime value
//_ = &z;
comptime var z: comptime_int = undefined;
z = f(&x);
std.debug.print("x = {}, y = {}, z = {}\n", .{ x, y, z });
// prints: x = 2, y = 0, z = 0
}
inline fn f(x: *i32) comptime_int {
x.* += 1;
return if (@inComptime()) 1 else 0;
}
If assigning a comptime var always placed the assignment expression in a comptime scope then you wouldn’t be able to perform the assignment above at all.
I think it would be more sound to require comptime on both sides, i.e.