master
  1const std = @import("std");
  2const builtin = @import("builtin");
  3const assert = std.debug.assert;
  4const expect = std.testing.expect;
  5
  6test "simple destructure" {
  7    const S = struct {
  8        fn doTheTest() !void {
  9            var x: u32 = undefined;
 10            x, const y, var z: u64 = .{ 1, @as(u16, 2), 3 };
 11            _ = &z;
 12
 13            comptime assert(@TypeOf(y) == u16);
 14
 15            try expect(x == 1);
 16            try expect(y == 2);
 17            try expect(z == 3);
 18        }
 19    };
 20
 21    try S.doTheTest();
 22    try comptime S.doTheTest();
 23}
 24
 25test "destructure with comptime syntax" {
 26    const S = struct {
 27        fn doTheTest() !void {
 28            {
 29                comptime var x: f32 = undefined;
 30                comptime x, const y, var z = .{ 0.5, 123, 456 }; // z is a comptime var
 31                _ = &z;
 32
 33                comptime assert(@TypeOf(y) == comptime_int);
 34                comptime assert(@TypeOf(z) == comptime_int);
 35                comptime assert(x == 0.5);
 36                comptime assert(y == 123);
 37                comptime assert(z == 456);
 38            }
 39            {
 40                var w: u8, var x: u8 = .{ 1, 2 };
 41                w, var y: u8 = .{ 3, 4 };
 42                var z: u8, x = .{ 5, 6 };
 43                y, z = .{ 7, 8 };
 44                {
 45                    w += 1;
 46                    x -= 2;
 47                    y *= 3;
 48                    z /= 4;
 49                }
 50                try expect(w == 4);
 51                try expect(x == 4);
 52                try expect(y == 21);
 53                try expect(z == 2);
 54            }
 55            {
 56                comptime var w, var x = .{ 1, 2 };
 57                comptime w, var y = .{ 3, 4 };
 58                comptime var z, x = .{ 5, 6 };
 59                comptime y, z = .{ 7, 8 };
 60                comptime {
 61                    w += 1;
 62                    x -= 2;
 63                    y *= 3;
 64                    z /= 4;
 65                }
 66                comptime assert(w == 4);
 67                comptime assert(x == 4);
 68                comptime assert(y == 21);
 69                comptime assert(z == 2);
 70            }
 71        }
 72    };
 73
 74    try S.doTheTest();
 75    try comptime S.doTheTest();
 76}
 77
 78test "destructure from labeled block" {
 79    const S = struct {
 80        fn doTheTest(rt_true: bool) !void {
 81            const x: u32, const y: u8, const z: i64 = blk: {
 82                if (rt_true) break :blk .{ 1, 2, 3 };
 83                break :blk .{ 4, 5, 6 };
 84            };
 85
 86            try expect(x == 1);
 87            try expect(y == 2);
 88            try expect(z == 3);
 89        }
 90    };
 91
 92    try S.doTheTest(true);
 93    try comptime S.doTheTest(true);
 94}
 95
 96test "destructure tuple value" {
 97    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 98
 99    const tup: struct { f32, u32, i64 } = .{ 10.0, 20, 30 };
100    const x, const y, const z = tup;
101
102    comptime assert(@TypeOf(x) == f32);
103    comptime assert(@TypeOf(y) == u32);
104    comptime assert(@TypeOf(z) == i64);
105
106    try expect(x == 10.0);
107    try expect(y == 20);
108    try expect(z == 30);
109}
110
111test "destructure array value" {
112    const arr: [3]u32 = .{ 10, 20, 30 };
113    const x, const y, const z = arr;
114
115    comptime assert(@TypeOf(x) == u32);
116    comptime assert(@TypeOf(y) == u32);
117    comptime assert(@TypeOf(z) == u32);
118
119    try expect(x == 10);
120    try expect(y == 20);
121    try expect(z == 30);
122}
123
124test "destructure from struct init with named tuple fields" {
125    const Tuple = struct { u8, u16, u32 };
126    const x, const y, const z = Tuple{
127        .@"0" = 100,
128        .@"1" = 200,
129        .@"2" = 300,
130    };
131
132    comptime assert(@TypeOf(x) == u8);
133    comptime assert(@TypeOf(y) == u16);
134    comptime assert(@TypeOf(z) == u32);
135
136    try expect(x == 100);
137    try expect(y == 200);
138    try expect(z == 300);
139}
140
141test "destructure of comptime-known tuple is comptime-known" {
142    const x, const y = .{ 1, 2 };
143
144    comptime assert(@TypeOf(x) == comptime_int);
145    comptime assert(x == 1);
146
147    comptime assert(@TypeOf(y) == comptime_int);
148    comptime assert(y == 2);
149}
150
151test "destructure of comptime-known tuple where some destinations are runtime-known is comptime-known" {
152    var z: u32 = undefined;
153    var x: u8, const y, z = .{ 1, 2, 3 };
154    _ = &x;
155
156    comptime assert(@TypeOf(y) == comptime_int);
157    comptime assert(y == 2);
158
159    try expect(x == 1);
160    try expect(z == 3);
161}
162
163test "destructure of tuple with comptime fields results in some comptime-known values" {
164    var runtime: u32 = 42;
165    _ = &runtime;
166    const a, const b, const c, const d = .{ 123, runtime, 456, runtime };
167
168    // a, c are comptime-known
169    // b, d are runtime-known
170
171    comptime assert(@TypeOf(a) == comptime_int);
172    comptime assert(@TypeOf(b) == u32);
173    comptime assert(@TypeOf(c) == comptime_int);
174    comptime assert(@TypeOf(d) == u32);
175
176    comptime assert(a == 123);
177    comptime assert(c == 456);
178
179    try expect(b == 42);
180    try expect(d == 42);
181}
182
183test "destructure vector" {
184    const vec: @Vector(2, i32) = .{ 1, 2 };
185    const x, const y = vec;
186
187    comptime assert(@TypeOf(x) == i32);
188    comptime assert(@TypeOf(y) == i32);
189
190    try expect(x == 1);
191    try expect(y == 2);
192}