diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2023-05-28 01:45:15 +0100 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2023-06-13 12:55:22 +0100 |
| commit | bcb673d94ac09ec381e5b1ad1edf64b603ac68f1 (patch) | |
| tree | 7624448f2c157b81b003935583deeaae5ec264df /test/cases/compile_errors | |
| parent | 85e94fed1e058720460560823ac09d7b64e49b97 (diff) | |
| download | zig-bcb673d94ac09ec381e5b1ad1edf64b603ac68f1.tar.gz zig-bcb673d94ac09ec381e5b1ad1edf64b603ac68f1.zip | |
Sema: resolve union payload switch captures with peer type resolution
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: #2812
Diffstat (limited to 'test/cases/compile_errors')
| -rw-r--r-- | test/cases/compile_errors/switch_capture_incompatible_types.zig | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/test/cases/compile_errors/switch_capture_incompatible_types.zig b/test/cases/compile_errors/switch_capture_incompatible_types.zig new file mode 100644 index 0000000000..b6de7d5bf5 --- /dev/null +++ b/test/cases/compile_errors/switch_capture_incompatible_types.zig @@ -0,0 +1,27 @@ +export fn f() void { + const U = union(enum) { a: u32, b: *u8 }; + var u: U = undefined; + switch (u) { + .a, .b => |val| _ = val, + } +} + +export fn g() void { + const U = union(enum) { a: u64, b: u32 }; + var u: U = undefined; + switch (u) { + .a, .b => |*ptr| _ = ptr, + } +} + +// error +// backend=stage2 +// target=native +// +// :5:20: error: capture group with incompatible types +// :5:20: note: incompatible types: 'u32' and '*u8' +// :5:10: note: type 'u32' here +// :5:14: note: type '*u8' here +// :13:20: error: capture group with incompatible types +// :13:14: note: pointer type child 'u32' cannot cast into resolved pointer type child 'u64' +// :13:20: note: this coercion is only possible when capturing by value |
