-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
when multiple union fields share a body in a switch prong, use a peer result type cast, rather than requiring identical types #2812
Comments
How about explicitly typing the coercion to prevent accidental rogue casts? .A, .C => |e: u16| |
Can you give an example of an accidental rogue cast? |
I'm afraid of situations where changing the field type should trigger an error. Example: const Union = union(enum) {
.A: u8,
.B: u8,
// .C: u8,
.C: u16,
.D: u16,
}; In the current proposal, any switches that previously had A+B+C will automatically be "upgraded" to |
I don't think this is an example of a rogue cast, so far everything is fine in this example. |
I don't like this as it is not obvious that coercion is happening and there is no language-level way to annotate the type of the capture. I'd much rather see #7224 accepted which would remove the need for this if I understand correctly while bringing considerable other benefits. |
I think those are separate use cases. #7224 requires separate code gen for each case, which could cause unnecessary code bloat. Especially on embedded platforms, the variant in this issue is preferred. The rules of coercion are designed so that it should not cause problems. I haven't seen any examples brought forth where the coercion would cause unintended issues, and I can't think of any. |
This is a bit harder than it seems at first glance. Actually resolving the type is the easy part: the interesting thing is actually getting the capture value. We split this into three cases: * If all payload types are the same (as is required in status quo), we can just do what we already do: get the first field value. * If all payloads are in-memory coercible to the resolved type, we still fetch the first field, but we also emit a `bitcast` to convert to the resolved type. * Otherwise, we need to handle each case separately. We emit a nested `switch_br` which, for each possible case, gets the corresponding union field, and coerces it to the resolved type. As an optimization, the inner switch's 'else' prong is used for any peer which is in-memory coercible to the target type, and the bitcast approach described above is used. Pointer captures have the additional constraint that all payload types must be in-memory coercible to the resolved type. Resolves: ziglang#2812
This is a bit harder than it seems at first glance. Actually resolving the type is the easy part: the interesting thing is actually getting the capture value. We split this into three cases: * If all payload types are the same (as is required in status quo), we can just do what we already do: get the first field value. * If all payloads are in-memory coercible to the resolved type, we still fetch the first field, but we also emit a `bitcast` to convert to the resolved type. * Otherwise, we need to handle each case separately. We emit a nested `switch_br` which, for each possible case, gets the corresponding union field, and coerces it to the resolved type. As an optimization, the inner switch's 'else' prong is used for any peer which is in-memory coercible to the target type, and the bitcast approach described above is used. Pointer captures have the additional constraint that all payload types must be in-memory coercible to the resolved type. Resolves: ziglang#2812
This is a bit harder than it seems at first glance. Actually resolving the type is the easy part: the interesting thing is actually getting the capture value. We split this into three cases: * If all payload types are the same (as is required in status quo), we can just do what we already do: get the first field value. * If all payloads are in-memory coercible to the resolved type, we still fetch the first field, but we also emit a `bitcast` to convert to the resolved type. * Otherwise, we need to handle each case separately. We emit a nested `switch_br` which, for each possible case, gets the corresponding union field, and coerces it to the resolved type. As an optimization, the inner switch's 'else' prong is used for any peer which is in-memory coercible to the target type, and the bitcast approach described above is used. Pointer captures have the additional constraint that all payload types must be in-memory coercible to the resolved type. Resolves: ziglang#2812
This is a bit harder than it seems at first glance. Actually resolving the type is the easy part: the interesting thing is actually getting the capture value. We split this into three cases: * If all payload types are the same (as is required in status quo), we can just do what we already do: get the first field value. * If all payloads are in-memory coercible to the resolved type, we still fetch the first field, but we also emit a `bitcast` to convert to the resolved type. * Otherwise, we need to handle each case separately. We emit a nested `switch_br` which, for each possible case, gets the corresponding union field, and coerces it to the resolved type. As an optimization, the inner switch's 'else' prong is used for any peer which is in-memory coercible to the target type, and the bitcast approach described above is used. Pointer captures have the additional constraint that all payload types must be in-memory coercible to the resolved type. Resolves: ziglang#2812
Followup from #1107.
This test passes now:
But this diff:
Gives this error:
However, I propose this should work. peer type resolution would make the type of
e
beu16
and everything is fine. Likewise aT
could be grouped with a?T
.The text was updated successfully, but these errors were encountered: