-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Proposal: coercing undefined
payload to an optional creates a definitely non-null
value at comptime
#7091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
As terrible as it is, I'm actually leaning towards the thing I called out as "not a good solution". I'm going to use the name "uninitialized" instead of "undefined" in my explanation, because I think that name makes the decision clearer. The "uninitialized" value at comptime is like javascript undefined - a well-defined sentinel value that can be stored in any non-zero-sized type, can be safely stored in an optional, and can be checked. Runtime variables that have been initialized from the comptime value "uninitialized" are the scary UB beast. It has to be this way because the compiler needs to know if a comptime variable has the special value "uninitialized". If you make a |
I'm not sure where else you would employ these semantics, but just for the use case of reflecting on default values, we could just change the Zig explicitly wants you to write |
We could make this support both comptime and runtime values. For comptime values, it would always be accurate. For runtime values, it would have the possibility of false negatives but no false positives. The use case for runtime value support is safety checking. For example to solve #3568 it will do this under the covers: Original source: if (condition) {
foo();
} Under the covers: if (@isUndefined(condition)) {
@panic("branch on undefined condition");
}
if (condition) {
foo();
} |
what about making the |
I think that's equivalent, assuming undefined is transitive at compile time: const x: *u32 = undefined;
const T = struct {
value: *u32 = x, // is this recognized as undefined?
};
// if so, we can implement the check in user code:
pub fn isUndefined(comptime x: anytype) {
const S = struct { field: @TypeOf(x) = x };
return @TypeOf(S).Struct.fields[0].default_value == .undefined;
} If they are equivalent, I think I prefer the optional that can contain undefined. It's easier to use when processing type info. #7115 may also be relevant here. |
The original point of this issue has actually been solved now; because we removed However, leaving open to track the proposal in here. |
undefined
payload to an optional creates a definitely non-null
value at comptime
This currently manifests as a compiler crash:
But the problem is in the design. The decision in #1831 means that there is no way to construct an optional with an undefined value but defined nullity. So the
default_value
field of StructField, which normally has the type?field_type
, cannot represent a default value ofundefined
. I'm not really sure what the right answer is in this situation. One option would be to say thatundefined
is a special defined value at comptime, and therefore@as(?T, @as(T, undefined))
produces a defined nonnull value at comptime but not at runtime. This is pretty weird though, I don't think it's a good solution.undefined
could generate a sentinel value inStructField.default_value
, but that would make it harder to use. We could separatedefault_value
into a flag and a value, but that's also pretty ugly.The text was updated successfully, but these errors were encountered: