gets the current runtime safety, so we can enable/disable custom safety checks.
Checking the build mode is less granular than zigs built-in safety checks.
Using a global or build options is as granular as you want/need, but its more obscure to users of your library.
A similiar proposal to this already exists:
opened 02:41AM - 09 Apr 25 UTC
proposal
## Problem Statement 1: Error Reporting
For example, in formatted printing, whe… n you make a mistake, it looks like this:
```
/home/andy/dev/zig/lib/std/fmt.zig:191:13: error: too few arguments
@compileError("too few arguments");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
print__anon_672: /home/andy/dev/zig/lib/std/io/Writer.zig:24:26
print__anon_413: /home/andy/dev/zig/lib/std/io.zig:312:47
1 reference(s) hidden; use '-freference-trace=3' to see all references
```
One typically has to use `-freference-trace` to make the error output useful, and even then, it's not obvious to beginners which point in the trace is the relevant one.
## Problem Statement 2: Mixing Optimization Modes
Let's say I want to compile all my dependencies with ReleaseFast but I want my application code to use Debug. Sounds good in theory, but the problem is that if the std lib is compiled in ReleaseFast it means that all the safety checks which live in ArrayList, for example, will now be disabled, even though those safety checks were logically covering behavior of the application.
In reality it is not the optimization mode of the standard library that ArrayList wants to use, nor the optimization mode of the application. Generally, it is the mode of the *call site* where the type is constructed, that is the proper one.
## Proposed Changes
`@returnAddress()` can be called at compile-time which returns a value representing the caller in the comptime stack. In such case, it makes the current function *generic* as if it took an additional comptime parameter.
This value can then be passed to `@compileError`, causing it to report the error at that location. This solves the first problem completely, resulting in always reporting the error in the correct place.
And then next there needs to be a way to access the builtin import (`@import("builtin")`) relative to a given comptime callsite. Inventing syntax for that, combining with #978, we end up with something like this in ArrayList:
```zig
pub fn ArrayList(comptime T: type) type {
const mode = @import(@returnAddress(), "builtin").mode;
return struct {
comptime {
@optimizeFor(mode); // note this applies to the struct scope
}
// ...
};
}
```
This means that `ArrayList(u8)` created by one module will not equal `ArrayList(u8)` created by another module, if those modules have different optimization modes. That might be a little confusing to encounter, but I think it's a fundamental complexity that arises from the extremely compelling use case of mixing optimization modes. The mitigation is quite reasonable: when an array list is used as part of a given API, that API should create a type alias for API users, so that they share the same version. Or, if the array list will be primarily used by the API user, then it should be constructed with the optimization mode of the API user. Either choice will be available to module authors.
For interoperability with `@src()`, `@src()` would be changed to accept the comptime callsite value as a parameter, and could then be redefined like this:
```zig
pub inline fn src() Src {
comptime return @src(@returnAddress());
}
```
Note this also makes it possible to get source information without an explicit parameter, at the cost of making the function generic.
The result of calling `@returnAddress()` should probably have its own type, or it could be an opaque defined in `std.builtin`.
Finally, it might make sense to introduce a new builtin rather than double-purposing `@returnAddress()`. The deciding factor would be whether anyone could come up with example code that would work both at runtime and at comptime that uses `@returnAddress()`.
If this gets accepted you could do this:
const mode = @import(@returnAddress(), "builtin").mode;
to get the optimization mode at the call site.
cool, but the optimisation mode only tells you the default release safety setting.
Maybe I’m misunderstanding the proposal, I don’t think it’s quite clear whether @import(@returnAddress(), "builtin")
will return the default mode of the call site or the actual optimization mode set with @optimizeFor()
which this proposal kind of depends on (at least the part about mixing optimization modes).
i miss remembered @optimizeFor
proposal