Below is a repro case that exhibits some surprising implicit pointer conversion.
Consider the line with const a = pool.c(3)
. Isn’t this promoting a Pool
value to *Pool
(pointer)? I’d expect a compiler error from the call pool.c(3)
given how the Pool.c()
function is declared to accept a Pool
pointer.
In this case the code works but I can imagine cases where this behavior might mask away accidentally passing stuff by value when passing by reference was intended.
const std = @import("std");
pub const Pool = struct {
pub const Node = struct {
pub const Kind = enum {
c,
};
kind: Kind,
data: f32 = 0,
};
alloc: std.mem.Allocator,
pub fn init(alloc: std.mem.Allocator) Pool {
return Pool{ .alloc = alloc };
}
pub fn allocNode(self: *@This()) *Node {
return self.alloc.create(Node) catch unreachable;
}
pub fn new(pool: *Pool, kind: Node.Kind, v: f32) *Node {
var n = pool.allocNode();
n.* = Node{ .kind = kind, .data = v };
return n;
}
pub fn c(p: *Pool, v: f32) *Node {
return new(p, Node.Kind.c, v);
}
};
fn usePool(p: *Pool) void {
const x = p.c(4);
_ = x;
}
test "repro" {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
var pool = Pool.init(gpa.allocator());
const a = pool.c(3); // why is this not an error? "this" implicitly promoted from Pool to *Pool??
_ = a;
usePool(&pool);
}