I’m here to argue that the language semantics should be changed so that the @constCast here is not needed, and instead any potential const mismatch be identified at the call sites instead:
This would allow the same function to be used for both const and non-const pointers without compromising const-safety.
const in this case is a little bit unintuitive, because it essentially widens the set of possible input of a function, while it does the opposite to the output.
Do you have any real usecases where this would help? In my experience I take a *T if I change anything in T (thus requiring a mutable pointer) and a *const T otherwise (allowing both cases), which hasnt let me down yet.
In this vein I do see some use for propagating sentinels, which Ive ran into using std.mem.cut* with a [:0]const u8.
In general this is already possible with fn (v: anytype) @TypeOf(v) { ... }, but its clunky
I’m using this function both in the game logic which takes *Game (and assigns it to *Entity), and in the renderer which takes *const Game (and must assign it to *const Entity).
The solution for this Ive seen used here and there is to have fn get() as well as fn getConst() which is mostly fine if the code is a trivial typesafe getter like this imo. Not a fan of the duplication but there isnt a good fix.
To go deeper into your proposal, this would bring the type forwarding system (I think its called RLS) to funtion return types. The immediate problem I see is how you keep sane function signatures, something like fn fooGetter(*maybeconst Foo) *maybeconst Bar but then you just have anytype wrapped in a fairly niche blanket. There might be existing issues (id guess on github), you might find something more substantial there than what Im saying here.
I think that what you’re asking here is tantamount to having the language implicitly infer return type. We can certainly argue about whether this is a good idea, but what you’re describing is already possible in zig just by being explicit about the return type.