zig icon indicating copy to clipboard operation
zig copied to clipboard

Error message "value with comptime-only type 'type' depends on runtime control flow"

Open Srekel opened this issue 2 years ago • 5 comments

Zig Version

0.11.0-dev.3031+f40539e5d

Steps to Reproduce and Observed Output

I had code like this:

        const res = myCFuncThatReturnsInt();
        switch (res) {
            c.JPC_PHYSICS_UPDATE_ERROR_NONE => return error.JPC_PHYSICS_UPDATE_ERROR_NONE,
            else => void, // correct here is {}
        }

Got this error:

error: value with comptime-only type 'type' depends on runtime control flow
        switch (res) {
        ^~~~~~

And I didn't understand it. It feels like it probably has all of the information needed for someone who understands the language spec perfectly, and absolutely nothing more :D

Expected Output

First of all it would be nice if the error indicator was on the void part.

   else => void
           ^~~~

Second, could it change "type 'type'" to "type 'void'" ?

Third, could it be changed to something like...

"run-time switch statement has case that returns a type 'void', which can only be done during comp-time".

I dunno this can probably be improved but I think currently it's quite hard to understand.

Can Zig have more descriptive texts in addition to the terse error? If so the original terse text could be fine, if there was a more user-friendly text to go along with it.

Srekel avatar May 17 '23 13:05 Srekel

First of all it would be nice if the error indicator was on the void part.

There is a TODO next to where that error is implemented stating that it needs a better source location.

Second, could it change "type 'type'" to "type 'void'" ?

That would be incorrect, the type of the expression is type not void.

Can Zig have more descriptive texts in addition to the terse error?

It would be much better for there to only be one clear error.

Vexu avatar May 17 '23 14:05 Vexu

There is a TODO next to where that error is implemented stating that it needs a better source location.

Great! :)

That would be incorrect, the type of the expression is type not void.

Oh! if you say so :) Could it be rephrased so that it does include "void" in the error message? type type is not trivial to understand what it means.

It would be much better for there to only be one clear error.

Hmm, I disagree, if I understand you correctly. Sure there should be one error message, that you can search for and refer to. But providing additional context or more information seems like it would potentially be quite helpful to the programmer.

I found an example (from Rust, but that's not particularly important) that I think is the type of error message that can make the programmer resolve the bug in seconds rather than minutes (or worse).

image

For context, in this particular case I stumbled onto the compile error yesterday, wasn't sure what to make of it, put it aside to work on other stuff, and today I had to I get the solution by posting to the zig-help channel in Discord. I'd rather the compiler assume I'm a total noob and help me solve the problem in seconds, even if it meant producing a more verbose message.

Srekel avatar May 17 '23 15:05 Srekel

Oh! if you say so :) Could it be rephrased so that it does include "void" in the error message? type type is not trivial to understand what it means.

It would be a bit strange for the error message to include void - this would be equivalent to the following invalid code (with no result type, so the 2 is a comptime_int):

const x = switch (res) {
    .thing => return error.Foo,
    else => 2,
};

...giving an error message that specifically mentions the value 2. It's possible, but it's (imo) kind of odd. This would be better fixed with the source location improvement discussed.

The phrasing "type 'type'" isn't really a confusing concept once you've gained a familiarity with Zig - one of the central tenets of comptime is that types are values of type type which can be manipulated at comptime. That is, just like "hi" is a value with type *const [2:0]u8, also *const [2:0]u8 is a value with type type. I personally don't think there's a particularly strong need to make this message clearer (aside from the source location issue).

mlugg avatar May 18 '23 06:05 mlugg

types are values of type type

Aha, that explains it. (FWIW I've soon been coding zig for 4 years, but admittedly I rarely do much with comptime or errors)

A minimal suggestion then would be changing this:

value with comptime-only type 'type' depends on runtime control flow

to

value 'void' with comptime-only type 'type' depends on runtime control flow

Personally I still think it's a bit too terse (for lack of a better term) and would prefer error messages to be understandable over technically correct. I'm probably not explaining myself well but I would like to not have to look at the error message and "figure out" what it means, rather I would like it to plainly tell me what the problem so I can go and fix it. I haven't looked at the Zig code but if it it knows it's in a switch context, maybe:

value 'void' with comptime-only type 'type' can not be returned from a runtime switch case.

Srekel avatar May 18 '23 07:05 Srekel

Stumbled into the same error in below

fn getMoveScore(move: Move) i8 { const result = switch (move) { .rock => 1, .paper => 2, .scissors => 3, }; return result;

I just added the type for the result and it did it for me. Explicitly assigning i8 type to result solved the issue

fn getMoveScore(move: Move) i8 { const result i8 = switch (move) { .rock => 1, .paper => 2, .scissors => 3, }; return result;

ToniTann avatar Apr 24 '24 06:04 ToniTann