New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
popOrNull and friends: Cannot tell the difference between empty list and null element #3158
Comments
I think the problem is that pub fn pop(self: *Self) T {
self.len -= 1;
return self.items[self.len];
} if that would return |
I don't understand this issue. The given code works as I would expect (not panicking) because It needs to work this way so that totally generic code can be programmed against the |
I just tried running the code: const std = @import("std");
pub fn main() !u8 {
const THRESHOLD = 14;
var list = std.ArrayList(?u64).init(std.debug.global_allocator);
try list.append(null);
const maybe_value = list.popOrNull() orelse unreachable; // fails
//if (maybe_value) |n| {
// return if(n < THRESHOLD) u8(1) else u8(0);
//}
return 0;
} and got:
Which is a completely different issue I think? |
@CurtisFenner The point is that:
This pattern of returning |
const std = @import("std");
pub fn ArrayList(comptime T: type) type {
return struct {
const Self = @This();
items: []T,
len: usize,
pub fn pop(self: *Self) T {
self.len -= 1;
return self.items[self.len];
}
pub fn popOrNull(self: *Self) ?T {
if (self.len == 0) return null;
// manually inlining this makes the issue go away too
return self.pop();
// self.len -= 1;
// return self.items[self.len];
}
};
}
const A = ArrayList(?u64);
pub fn main() !void {
var list = A{
.items = [_]?u64{null},
.len = 1,
};
const maybe_value = list.popOrNull() orelse return error.Foo; // actually throws (the bug)
// inlining .popOrNull works:
// const maybe_value = ((??u64)(if (list.len == 0) null else list.pop())) orelse return error.Foo;
} |
The symptom of this now appears to be a compile error. test "" {
var array = std.ArrayList(?bool).init(testing.allocator);
_ = array.popOrNull();
} gives
Tested on |
Can confirm on the compiler error, and built the compiler in debug mode, the full error is as follows
(Compiler version was the latest master branch as of writing this) |
Closes ziglang#2746 Closes ziglang#2802 Closes ziglang#2855 Closes ziglang#2895 Closes ziglang#2981 Closes ziglang#3054 Closes ziglang#3158 Closes ziglang#3259 Closes ziglang#3371 Closes ziglang#3376 Closes ziglang#3387 Closes ziglang#3529 Closes ziglang#3653 Closes ziglang#3750 Closes ziglang#3778 Closes ziglang#3882 Closes ziglang#3915 Closes ziglang#3929 Closes ziglang#3961 Closes ziglang#3988 Closes ziglang#4123 Closes ziglang#7448
Closes ziglang#1994 Closes ziglang#2140 Closes ziglang#2746 Closes ziglang#2802 Closes ziglang#2855 Closes ziglang#2895 Closes ziglang#2981 Closes ziglang#3054 Closes ziglang#3158 Closes ziglang#3234 Closes ziglang#3259 Closes ziglang#3371 Closes ziglang#3376 Closes ziglang#3387 Closes ziglang#3529 Closes ziglang#3653 Closes ziglang#3750 Closes ziglang#3778 Closes ziglang#3882 Closes ziglang#3915 Closes ziglang#3929 Closes ziglang#3961 Closes ziglang#3988 Closes ziglang#4123 Closes ziglang#7448
Closes ziglang#1957 Closes ziglang#1994 Closes ziglang#2140 Closes ziglang#2746 Closes ziglang#2802 Closes ziglang#2855 Closes ziglang#2895 Closes ziglang#2981 Closes ziglang#3054 Closes ziglang#3158 Closes ziglang#3234 Closes ziglang#3259 Closes ziglang#3371 Closes ziglang#3376 Closes ziglang#3387 Closes ziglang#3529 Closes ziglang#3653 Closes ziglang#3750 Closes ziglang#3778 Closes ziglang#3882 Closes ziglang#3915 Closes ziglang#3929 Closes ziglang#3961 Closes ziglang#3988 Closes ziglang#4123 Closes ziglang#7448
Closes ziglang#1957 Closes ziglang#1994 Closes ziglang#2140 Closes ziglang#2746 Closes ziglang#2802 Closes ziglang#2855 Closes ziglang#2895 Closes ziglang#2981 Closes ziglang#3054 Closes ziglang#3158 Closes ziglang#3234 Closes ziglang#3259 Closes ziglang#3371 Closes ziglang#3376 Closes ziglang#3387 Closes ziglang#3529 Closes ziglang#3653 Closes ziglang#3750 Closes ziglang#3778 Closes ziglang#3882 Closes ziglang#3915 Closes ziglang#3929 Closes ziglang#3961 Closes ziglang#3988 Closes ziglang#4123 Closes ziglang#7448
Closes ziglang#1957 Closes ziglang#1994 Closes ziglang#2140 Closes ziglang#2746 Closes ziglang#2802 Closes ziglang#2855 Closes ziglang#2895 Closes ziglang#2981 Closes ziglang#3054 Closes ziglang#3158 Closes ziglang#3234 Closes ziglang#3259 Closes ziglang#3371 Closes ziglang#3376 Closes ziglang#3387 Closes ziglang#3529 Closes ziglang#3653 Closes ziglang#3750 Closes ziglang#3778 Closes ziglang#3882 Closes ziglang#3915 Closes ziglang#3929 Closes ziglang#3961 Closes ziglang#3988 Closes ziglang#4123 Closes ziglang#7448
Closes ziglang#1957 Closes ziglang#1994 Closes ziglang#2140 Closes ziglang#2746 Closes ziglang#2802 Closes ziglang#2855 Closes ziglang#2895 Closes ziglang#2981 Closes ziglang#3054 Closes ziglang#3158 Closes ziglang#3234 Closes ziglang#3259 Closes ziglang#3371 Closes ziglang#3376 Closes ziglang#3387 Closes ziglang#3529 Closes ziglang#3653 Closes ziglang#3750 Closes ziglang#3778 Closes ziglang#3882 Closes ziglang#3915 Closes ziglang#3929 Closes ziglang#3961 Closes ziglang#3988 Closes ziglang#4123 Closes ziglang#7448
Consider a
std.ArrayList(?u64)
...You want to pop the last element and do something
if it'sdepending on whether the element is null or not.The
orelse unreachable
, and of course.?
as well, cannot tell the difference betweenpopOrNull
saying "the list is empty" and the element being returned but beingnull
.This seems like a bit of a footgun.
The text was updated successfully, but these errors were encountered: