On the other hand, if NULL is not an expected value, then how often do you really find the logic error at the same spot that the panic occurred? Not very often in my experience. We have callstacks for a reason. You usually find the NullPointerException at the bottom of the stacktrace or the None.panic() after 100-something other function calls in significantly complex codebases. No, if a function expects a value 100% of the time, and it was passed a NULL value, that's the caller's problem. And Option<T> won't help you if the user-facing calling code is still passing None or std::nullopt for whatever misguided or erroneous reason they may be doing so.
Certainly I agree there're benefits to encoding this kind of behaviour into the type system, but I don't agree that it's ultimately a solution to the '4 billion dollar mistake', since mistakes ultimately still happen. You just swap NULL for None and you still have a bug in your logic, just no longer a bug in the types. It's kicking the can.