@ptrCast(arg.?) and @ptrCast(arg) are functionally equivalent, unless the destination pointer type is also optional or allowzero, in which case the explicitly unwrapping one will invoke safety-checked UB.
This seems like poor advice and a strange proposal. As @castholm correctly states above, the explicit .? unwrap makes zero difference to the behavior here. Address 0 is not valid for a non-optional pointer, so rather than “allowing address 0 for the result pointer” it of course triggers Safety-Checked Illegal Behavior to perform such a cast – just like .? would.
Either way, to be clear, you should only perform this pointer cast if you know for a fact that arg is not null, and is in fact a valid pointer to a ResetEvent – safety checks are not a substitute for error handling! In other words, if the application should panic in the null case, don’t rely on the safety check: do it explicitly with e.g. arg orelse @panic("null").
Regarding your idea that it should be a compile error, I don’t see any reason for that. @ptrCast is a fundamentally dangerous builtin: in accepted (but not yet implemented) semantics, it is Illegal Behavior (sometimes with a safety check) to @ptrCast a pointer to an “incorrect” type. @ptrCast means “yes, I know the type system doesn’t know that this pointer is a *T, but I promise it actually is”. Why should asserting a pointer is not address 0 be an exception to this definition?
To add a bit of context for future readers, I was providing a callback to a c library that allows the user to pass a pointer (sometimes called userdata) to go along with whatever data the callback is returning.
The type of such a “userdata” pointer is typically ?*anyopaque.
The key thing to understand here is that zig uses the zero address as null for “normal” optional pointers. So there is no size / alignment difference between an optional pointer and a non-optional pointers, which makes the @ptrCast valid whether the item is unwrapped or not.