#Compiler bug?

1 messages · Page 1 of 1 (latest)

delicate kraken
#

I know for a fact that the isSlice property of the String returned from Int.toString() is false, but the compiler insists that it's true even when I explicity set it to false right before calling padStart.

pub fn padStart(self: *String, width: u32, str: anytype) void {
    if (self.isSlice) {
        @compileError("cannot pad a slice");
    }
    const padAmount = width - self.len();
    if (padAmount > 0) {
        var temp = String.new(width);
        temp.concat(str);
        temp.repeat(padAmount / temp.len());
        temp.concat(self.*);

        self.free();
        self.bytes = temp.bytes;
    }
}

//...

var offsetStr = Int.toString(offset, 10);
defer offsetStr.free();
offsetStr.isSlice = false;
offsetStr.padStart(4, "0");
src/lib/vexlib.zig:1266:13: error: cannot pad a slice
            @compileError("cannot pad a slice");
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
covert socket
#

self isn't comptime known

#

rather than thinking about the compileError happening when the condition is true, think of it as happening when the if statement is analyzed

#

when the condition is comptime known those are the same think but if it's a runtime condition it's always analyzed

delicate kraken
#

so how can I always error when it's called on a slice of a String?

#

but not error when it's unknown at compile time

covert socket
#

restructure your code so the condition is comptime known

delicate kraken
#

I think the compiler should be able to figure out that isSlice will never be true

foggy dove
#

the compiler disagrees

delicate kraken
#

I mean I set it to false right before calling it

offsetStr.isSlice = false;
offsetStr.padStart(4, "0");
#

it's pretty obvious that false is not true

foggy dove
#

not the the compiler.

delicate kraken
#

I guess I'll just do

if (self.isSlice) {
    std.debug.print("cannot pad a slice", .{});
    unreachable;
}
foggy dove
#

the comptime propagation system is quite simple.
if a function's argument isn't marked comptime, the compiler treats it as runtime known, all of it. it will not bother checking all callsites to deduce extra information.

foggy dove
delicate kraken
#

cool, that works

foggy dove
#

@compileError's intended usage is very different.
it is used to halt compilation in case some compile-time calculation broke some invariant

foggy dove
delicate kraken
#

doesn't @panic just call std.debug.panic?

foggy dove
#

they both wrap around std.builtin.panic