Hello Zig forum, i am very fairly new to zig, and at the moment i’m trying to write a small chat client-server project to check out the language.
For this i am using a binary format known as bincode, and fourtunately a implementation exists in Zig, but 0.12.0 seems to be problematic in this library.
A pull request above does fix a fair share of issues, but given a struct that has a const u8, the compiler is not happy:
bincode.zig:202:62: error: expected type '@typeInfo(@typeInfo(@TypeOf(bincode.read__anon_4260)).Fn.return_type.?).ErrorUnion.error_set!usize', found 'u64'
.unsigned => std.math.cast(U, z) orelse return error.FailedToCastZZ,
I have tried to use 0.11.0, and here there is no issues in question. I have been scratching my head for the past 4 days, so i came here for a different perspective, hopefully
Adding to what @AndrewCodeDev posted, this is also common when you actually use a try but in a function that does not return an error. In that case you have to catch the error and handle it.
This code from the testing code scope still causes the issue. I wish i could explain it better, but can you setup a similar environment and test it out?
Reading a slice from a stream of bytes seems… odd… to me. Slices are pointers so I’m not sure what you’d be getting from that operation. Philosophically speaking, it seems like prohibiting slices makes sense.
I’ll have to look at it more a bit later, but if you remove the slice, it works?
I’d like to know if that’s actually a bug, though. It compiles in 0.11.0, but is that actually correct?
Since a slice is supposed to tell me “go here to get data” (again, it’s just a pointer), you’d be reading its length and address from a stream of bytes.
Now, I can clearly see in your case that we can guarantee that the address will be valid, but that isn’t going to be true in general.
On this line, you are setting the slice to static string data:
.decimals = "1234",
However, that slice can hold any generic address. What does it mean to read that off a series of bytes in the context of a larger program where we don’t know if the address and length that is read is accurate?
I don’t know, i’m not sure. The thing that’s troubling is that the original author of this library last updated it when 0.11.0 was the latest release. I managed to compile it like you said, on 0.11.0.
Okay, because I think you need the answer to that question first here (I could be wrong) but here’s my thinking…
If you serialize something like decimals: [N]u8, decimal_count: u32 or something like that, then you can always guarantee you know where the decimals are and you know how many you have.
You may have been getting a false positive on your last test if you were setting it up like how it’s happening above. That’s guarenteed to work. But if I just read a stream of bytes off the disk and it tells me that I have string data at address x and it has length n, that seems like it would be a silent setup to a fatal error.
As in not known at all? As in “it could be 3, or it could be greater than 10 million” or is it within some expressible range? If it is, you can set N to be the size of your range and say how many of them are in use.
If that’s the case, then I can’t see how that would work. You’d need to set the address of the slice to valid memory after you have deserialized it because it could just be pointing to garbage memory.
Either way, the error message is essentially saying this:
bincode.zig:202:62: error: expected type '@typeInfo(@typeInfo(@TypeOf(bincode.read__anon_4260)).Fn.return_type.?).ErrorUnion.error_set!usize', found 'u64'
Refers to the return type of the function. Since it’s a generic function, you get read__anon_4260 which is its monomorphized handle. The return_type.? is getting the return of the function because this part…
'@typeInfo(...).ErrorUnion.error_set!usize',
Is extracting the error union type that it can return and joining that to usize. So something is failing because it’s saying it expects "Every Erroy from Read or usize" and it’s just getting usize instead.
Okay, so I dug into the code a bit more and I’m narrowing it down… for anyone following along at home, here’s the branch of the read function we’re talking about:
That gets unrolled from a Struct branch that walks through the field types.
So what’s happening here is that it write stores the slice bytes in place and then read allocates a new slice and then copies them one at a time. So I was half right - they take that into account by reading values off of the bytes by reading the child type for each value. So that’s what handles the slice issue.
I’ll download it tonight and play around with it to see what’s causing your error.
No problem - 4 days seems like a painful amount of time. Someone may snipe this answer before I get around to downloading it but I’ll help you get an answer by tonight