#capture in 'else' in switch on tagged union

1 messages · Page 1 of 1 (latest)

jagged ridge
#

I have a somewhat big tagged union (big as in 40+ members). Most members have the same type (a struct with a heap allocated string). I have a slice of these I want to free, so I iterate over the slice and switch on the tagged union value. I dont want to list each member in the switch, I want to handle the few "special" cases and then in the 'else' prong I want to free the heap allocated string inside. Like this:
switch (token.*) { .NUMBER => |*data| self.allocator.free(data.lexeme), .STRING => |*data| self.allocator.free(data.lexeme), .EOF => {}, else => { const ptr: *Lexeme = @ptrCast(token); self.allocator.free(ptr.lexeme); }, }
That else branch is dangerous but works because the payload is the first member of the union struct followed by the tag. However, the compiler SHOULD know that the token payload is of type Lexeme here (only NUMBER, STRING, EOF are of different types). But this doesnt work:
switch (token.*) { .NUMBER => |*data| self.allocator.free(data.lexeme), .STRING => |*data| self.allocator.free(data.lexeme), .EOF => {}, else => |*data| self.allocator.free(data.lexeme), }
How would a Professional Zig Software Developer(tm) solve this? Why can't the compiler deduce that data MUST be of type *Lexeme in this case?

knotty kiln
#

Try inline else instead of just else

jagged ridge
#

Im new to zig, what does inline else look like and how does it work?

knotty kiln
#

All that looks different is the keyword inline before the else. It generates the prong for every single case it has to handle. This allows each prong to have a different capture type

jagged ridge
#

Okay I got my 2nd code sample to work as I expected by putting "inline" before "else". Thanks!

#

Ahh so it's like a compile time macro that expands to all of the missing cases?

knotty kiln
#

Sort of? It's similar to inline for, which will generate the code for each iteration of the for loop

jagged ridge
#

Thats actually a really cool feature

#

My only complaint is that ZLS cant show me the type (or do intellisense) on "data" but I suppose that makes sense given that "data" could have a different type in every prong

#

Closing this, thanks so much for the help

cinder island
jagged ridge
#

what is the difference between inline switch and inline else in a switch?

cinder island
#

Oh sorry I meant inline else

jagged ridge
#

Ah okay cool, would the type be enum or unsigned integer in that case?

knotty kiln
#

It'll be the enum tag that's associated with that type