authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-07-04 05:00:32+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-07-04 21:01:42+01:00
log0e5335aaf5e0ac646fbd46a319710019d10c2971
treebb5a2e4184a64985f8e8788f0d11b867213aaf3b
parent2f0f1efa6fa50ca27a44d5f7a0c38a6cafbbfb7c
signaturelock-open Commit is signed but in an unrecognized format.

compiler: rework type resolution, fully resolve all types

I'm so sorry. This commit was just meant to be making all types fully resolve by queueing resolution at the moment of their creation. Unfortunately, a lot of dominoes ended up falling. Here's what happened: * I added a work queue job to fully resolve a type. * I realised that from here we could eliminate `Sema.types_to_resolve` if we made function codegen a separate job. This is desirable for simplicity of both spec and implementation. * This led to a new AIR traversal to detect whether any required type is unresolved. If a type in the AIR failed to resolve, then we can't run codegen. * Because full type resolution now occurs by the work queue job, a bug was exposed whereby error messages for type resolution were associated with the wrong `Decl`, resulting in duplicate error messages when the type was also resolved "by" its owner `Decl` (which really *all* resolution should be done on). * A correct fix for this requires using a different `Sema` when performing type resolution: we need a `Sema` owned by the type. Also note that this fix is necessary for incremental compilation. * This means a whole bunch of functions no longer need to take `Sema`s. * First-order effects: `resolveTypeFields`, `resolveTypeLayout`, etc * Second-order effects: `Type.abiAlignmentAdvanced`, `Value.orderAgainstZeroAdvanced`, etc The end result of this is, in short, a more correct compiler and a simpler language specification. This regressed a few error notes in the test cases, but nothing that seems worth blocking this change. Oh, also, I ripped out the old code in `test/src/Cases.zig` which introduced a dependency on `Compilation`. This dependency was problematic at best, and this code has been unused for a while. When we re-enable incremental test cases, we must rewrite their executor to use the compiler server protocol.

20 files changed, 1850 insertions(+), 2026 deletions(-)

build.zig+6-22
...@@ -82,15 +82,6 @@ pub fn build(b: *std.Build) !void {...@@ -82,15 +82,6 @@ pub fn build(b: *std.Build) !void {
82 docs_step.dependOn(langref_step);82 docs_step.dependOn(langref_step);
83 docs_step.dependOn(std_docs_step);83 docs_step.dependOn(std_docs_step);
8484
85 const check_case_exe = b.addExecutable(.{
86 .name = "check-case",
87 .root_source_file = b.path("test/src/Cases.zig"),
88 .target = b.graph.host,
89 .optimize = optimize,
90 .single_threaded = single_threaded,
91 });
92 check_case_exe.stack_size = stack_size;
93
94 const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false;85 const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false;
95 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;86 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
96 const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;87 const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;
...@@ -222,7 +213,6 @@ pub fn build(b: *std.Build) !void {...@@ -222,7 +213,6 @@ pub fn build(b: *std.Build) !void {
222 if (target.result.os.tag == .windows and target.result.abi == .gnu) {213 if (target.result.os.tag == .windows and target.result.abi == .gnu) {
223 // LTO is currently broken on mingw, this can be removed when it's fixed.214 // LTO is currently broken on mingw, this can be removed when it's fixed.
224 exe.want_lto = false;215 exe.want_lto = false;
225 check_case_exe.want_lto = false;
226 }216 }
227217
228 const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend");218 const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend");
...@@ -245,7 +235,6 @@ pub fn build(b: *std.Build) !void {...@@ -245,7 +235,6 @@ pub fn build(b: *std.Build) !void {
245235
246 if (link_libc) {236 if (link_libc) {
247 exe.linkLibC();237 exe.linkLibC();
248 check_case_exe.linkLibC();
249 }238 }
250239
251 const is_debug = optimize == .Debug;240 const is_debug = optimize == .Debug;
...@@ -339,21 +328,17 @@ pub fn build(b: *std.Build) !void {...@@ -339,21 +328,17 @@ pub fn build(b: *std.Build) !void {
339 }328 }
340329
341 try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx);330 try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx);
342 try addCmakeCfgOptionsToExe(b, cfg, check_case_exe, use_zig_libcxx);
343 } else {331 } else {
344 // Here we are -Denable-llvm but no cmake integration.332 // Here we are -Denable-llvm but no cmake integration.
345 try addStaticLlvmOptionsToExe(exe);333 try addStaticLlvmOptionsToExe(exe);
346 try addStaticLlvmOptionsToExe(check_case_exe);
347 }334 }
348 if (target.result.os.tag == .windows) {335 if (target.result.os.tag == .windows) {
349 inline for (.{ exe, check_case_exe }) |artifact| {336 // LLVM depends on networking as of version 18.
350 // LLVM depends on networking as of version 18.337 exe.linkSystemLibrary("ws2_32");
351 artifact.linkSystemLibrary("ws2_32");
352338
353 artifact.linkSystemLibrary("version");339 exe.linkSystemLibrary("version");
354 artifact.linkSystemLibrary("uuid");340 exe.linkSystemLibrary("uuid");
355 artifact.linkSystemLibrary("ole32");341 exe.linkSystemLibrary("ole32");
356 }
357 }342 }
358 }343 }
359344
...@@ -394,7 +379,6 @@ pub fn build(b: *std.Build) !void {...@@ -394,7 +379,6 @@ pub fn build(b: *std.Build) !void {
394 const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};379 const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};
395380
396 const test_cases_options = b.addOptions();381 const test_cases_options = b.addOptions();
397 check_case_exe.root_module.addOptions("build_options", test_cases_options);
398382
399 test_cases_options.addOption(bool, "enable_tracy", false);383 test_cases_options.addOption(bool, "enable_tracy", false);
400 test_cases_options.addOption(bool, "enable_debug_extensions", enable_debug_extensions);384 test_cases_options.addOption(bool, "enable_debug_extensions", enable_debug_extensions);
...@@ -458,7 +442,7 @@ pub fn build(b: *std.Build) !void {...@@ -458,7 +442,7 @@ pub fn build(b: *std.Build) !void {
458 test_step.dependOn(check_fmt);442 test_step.dependOn(check_fmt);
459443
460 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");444 const test_cases_step = b.step("test-cases", "Run the main compiler test cases");
461 try tests.addCases(b, test_cases_step, test_filters, check_case_exe, target, .{445 try tests.addCases(b, test_cases_step, test_filters, target, .{
462 .skip_translate_c = skip_translate_c,446 .skip_translate_c = skip_translate_c,
463 .skip_run_translated_c = skip_run_translated_c,447 .skip_run_translated_c = skip_run_translated_c,
464 }, .{448 }, .{
src/Air.zig+2
...@@ -1801,3 +1801,5 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {...@@ -1801,3 +1801,5 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
1801 .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtrIp(ip),1801 .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtrIp(ip),
1802 };1802 };
1803}1803}
1804
1805pub const typesFullyResolved = @import("Air/types_resolved.zig").typesFullyResolved;
src/Air/types_resolved.zig created+521
...@@ -0,0 +1,521 @@
1const Air = @import("../Air.zig");
2const Zcu = @import("../Zcu.zig");
3const Type = @import("../Type.zig");
4const Value = @import("../Value.zig");
5const InternPool = @import("../InternPool.zig");
6
7/// Given a body of AIR instructions, returns whether all type resolution necessary for codegen is complete.
8/// If `false`, then type resolution must have failed, so codegen cannot proceed.
9pub fn typesFullyResolved(air: Air, zcu: *Zcu) bool {
10 return checkBody(air, air.getMainBody(), zcu);
11}
12
13fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool {
14 const tags = air.instructions.items(.tag);
15 const datas = air.instructions.items(.data);
16
17 for (body) |inst| {
18 const data = datas[@intFromEnum(inst)];
19 switch (tags[@intFromEnum(inst)]) {
20 .inferred_alloc, .inferred_alloc_comptime => unreachable,
21
22 .arg => {
23 if (!checkType(data.arg.ty.toType(), zcu)) return false;
24 },
25
26 .add,
27 .add_safe,
28 .add_optimized,
29 .add_wrap,
30 .add_sat,
31 .sub,
32 .sub_safe,
33 .sub_optimized,
34 .sub_wrap,
35 .sub_sat,
36 .mul,
37 .mul_safe,
38 .mul_optimized,
39 .mul_wrap,
40 .mul_sat,
41 .div_float,
42 .div_float_optimized,
43 .div_trunc,
44 .div_trunc_optimized,
45 .div_floor,
46 .div_floor_optimized,
47 .div_exact,
48 .div_exact_optimized,
49 .rem,
50 .rem_optimized,
51 .mod,
52 .mod_optimized,
53 .max,
54 .min,
55 .bit_and,
56 .bit_or,
57 .shr,
58 .shr_exact,
59 .shl,
60 .shl_exact,
61 .shl_sat,
62 .xor,
63 .cmp_lt,
64 .cmp_lt_optimized,
65 .cmp_lte,
66 .cmp_lte_optimized,
67 .cmp_eq,
68 .cmp_eq_optimized,
69 .cmp_gte,
70 .cmp_gte_optimized,
71 .cmp_gt,
72 .cmp_gt_optimized,
73 .cmp_neq,
74 .cmp_neq_optimized,
75 .bool_and,
76 .bool_or,
77 .store,
78 .store_safe,
79 .set_union_tag,
80 .array_elem_val,
81 .slice_elem_val,
82 .ptr_elem_val,
83 .memset,
84 .memset_safe,
85 .memcpy,
86 .atomic_store_unordered,
87 .atomic_store_monotonic,
88 .atomic_store_release,
89 .atomic_store_seq_cst,
90 => {
91 if (!checkRef(data.bin_op.lhs, zcu)) return false;
92 if (!checkRef(data.bin_op.rhs, zcu)) return false;
93 },
94
95 .not,
96 .bitcast,
97 .clz,
98 .ctz,
99 .popcount,
100 .byte_swap,
101 .bit_reverse,
102 .abs,
103 .load,
104 .fptrunc,
105 .fpext,
106 .intcast,
107 .trunc,
108 .optional_payload,
109 .optional_payload_ptr,
110 .optional_payload_ptr_set,
111 .wrap_optional,
112 .unwrap_errunion_payload,
113 .unwrap_errunion_err,
114 .unwrap_errunion_payload_ptr,
115 .unwrap_errunion_err_ptr,
116 .errunion_payload_ptr_set,
117 .wrap_errunion_payload,
118 .wrap_errunion_err,
119 .struct_field_ptr_index_0,
120 .struct_field_ptr_index_1,
121 .struct_field_ptr_index_2,
122 .struct_field_ptr_index_3,
123 .get_union_tag,
124 .slice_len,
125 .slice_ptr,
126 .ptr_slice_len_ptr,
127 .ptr_slice_ptr_ptr,
128 .array_to_slice,
129 .int_from_float,
130 .int_from_float_optimized,
131 .float_from_int,
132 .splat,
133 .error_set_has_value,
134 .addrspace_cast,
135 .c_va_arg,
136 .c_va_copy,
137 => {
138 if (!checkType(data.ty_op.ty.toType(), zcu)) return false;
139 if (!checkRef(data.ty_op.operand, zcu)) return false;
140 },
141
142 .alloc,
143 .ret_ptr,
144 .c_va_start,
145 => {
146 if (!checkType(data.ty, zcu)) return false;
147 },
148
149 .ptr_add,
150 .ptr_sub,
151 .add_with_overflow,
152 .sub_with_overflow,
153 .mul_with_overflow,
154 .shl_with_overflow,
155 .slice,
156 .slice_elem_ptr,
157 .ptr_elem_ptr,
158 => {
159 const bin = air.extraData(Air.Bin, data.ty_pl.payload).data;
160 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
161 if (!checkRef(bin.lhs, zcu)) return false;
162 if (!checkRef(bin.rhs, zcu)) return false;
163 },
164
165 .block,
166 .loop,
167 => {
168 const extra = air.extraData(Air.Block, data.ty_pl.payload);
169 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
170 if (!checkBody(
171 air,
172 @ptrCast(air.extra[extra.end..][0..extra.data.body_len]),
173 zcu,
174 )) return false;
175 },
176
177 .dbg_inline_block => {
178 const extra = air.extraData(Air.DbgInlineBlock, data.ty_pl.payload);
179 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
180 if (!checkBody(
181 air,
182 @ptrCast(air.extra[extra.end..][0..extra.data.body_len]),
183 zcu,
184 )) return false;
185 },
186
187 .sqrt,
188 .sin,
189 .cos,
190 .tan,
191 .exp,
192 .exp2,
193 .log,
194 .log2,
195 .log10,
196 .floor,
197 .ceil,
198 .round,
199 .trunc_float,
200 .neg,
201 .neg_optimized,
202 .is_null,
203 .is_non_null,
204 .is_null_ptr,
205 .is_non_null_ptr,
206 .is_err,
207 .is_non_err,
208 .is_err_ptr,
209 .is_non_err_ptr,
210 .int_from_ptr,
211 .int_from_bool,
212 .ret,
213 .ret_safe,
214 .ret_load,
215 .is_named_enum_value,
216 .tag_name,
217 .error_name,
218 .cmp_lt_errors_len,
219 .c_va_end,
220 .set_err_return_trace,
221 => {
222 if (!checkRef(data.un_op, zcu)) return false;
223 },
224
225 .br => {
226 if (!checkRef(data.br.operand, zcu)) return false;
227 },
228
229 .cmp_vector,
230 .cmp_vector_optimized,
231 => {
232 const extra = air.extraData(Air.VectorCmp, data.ty_pl.payload).data;
233 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
234 if (!checkRef(extra.lhs, zcu)) return false;
235 if (!checkRef(extra.rhs, zcu)) return false;
236 },
237
238 .reduce,
239 .reduce_optimized,
240 => {
241 if (!checkRef(data.reduce.operand, zcu)) return false;
242 },
243
244 .struct_field_ptr,
245 .struct_field_val,
246 => {
247 const extra = air.extraData(Air.StructField, data.ty_pl.payload).data;
248 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
249 if (!checkRef(extra.struct_operand, zcu)) return false;
250 },
251
252 .shuffle => {
253 const extra = air.extraData(Air.Shuffle, data.ty_pl.payload).data;
254 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
255 if (!checkRef(extra.a, zcu)) return false;
256 if (!checkRef(extra.b, zcu)) return false;
257 if (!checkVal(Value.fromInterned(extra.mask), zcu)) return false;
258 },
259
260 .cmpxchg_weak,
261 .cmpxchg_strong,
262 => {
263 const extra = air.extraData(Air.Cmpxchg, data.ty_pl.payload).data;
264 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
265 if (!checkRef(extra.ptr, zcu)) return false;
266 if (!checkRef(extra.expected_value, zcu)) return false;
267 if (!checkRef(extra.new_value, zcu)) return false;
268 },
269
270 .aggregate_init => {
271 const ty = data.ty_pl.ty.toType();
272 const elems_len: usize = @intCast(ty.arrayLen(zcu));
273 const elems: []const Air.Inst.Ref = @ptrCast(air.extra[data.ty_pl.payload..][0..elems_len]);
274 if (!checkType(ty, zcu)) return false;
275 if (ty.zigTypeTag(zcu) == .Struct) {
276 for (elems, 0..) |elem, elem_idx| {
277 if (ty.structFieldIsComptime(elem_idx, zcu)) continue;
278 if (!checkRef(elem, zcu)) return false;
279 }
280 } else {
281 for (elems) |elem| {
282 if (!checkRef(elem, zcu)) return false;
283 }
284 }
285 },
286
287 .union_init => {
288 const extra = air.extraData(Air.UnionInit, data.ty_pl.payload).data;
289 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
290 if (!checkRef(extra.init, zcu)) return false;
291 },
292
293 .field_parent_ptr => {
294 const extra = air.extraData(Air.FieldParentPtr, data.ty_pl.payload).data;
295 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
296 if (!checkRef(extra.field_ptr, zcu)) return false;
297 },
298
299 .atomic_load => {
300 if (!checkRef(data.atomic_load.ptr, zcu)) return false;
301 },
302
303 .prefetch => {
304 if (!checkRef(data.prefetch.ptr, zcu)) return false;
305 },
306
307 .vector_store_elem => {
308 const bin = air.extraData(Air.Bin, data.vector_store_elem.payload).data;
309 if (!checkRef(data.vector_store_elem.vector_ptr, zcu)) return false;
310 if (!checkRef(bin.lhs, zcu)) return false;
311 if (!checkRef(bin.rhs, zcu)) return false;
312 },
313
314 .select,
315 .mul_add,
316 => {
317 const bin = air.extraData(Air.Bin, data.pl_op.payload).data;
318 if (!checkRef(data.pl_op.operand, zcu)) return false;
319 if (!checkRef(bin.lhs, zcu)) return false;
320 if (!checkRef(bin.rhs, zcu)) return false;
321 },
322
323 .atomic_rmw => {
324 const extra = air.extraData(Air.AtomicRmw, data.pl_op.payload).data;
325 if (!checkRef(data.pl_op.operand, zcu)) return false;
326 if (!checkRef(extra.operand, zcu)) return false;
327 },
328
329 .call,
330 .call_always_tail,
331 .call_never_tail,
332 .call_never_inline,
333 => {
334 const extra = air.extraData(Air.Call, data.pl_op.payload);
335 const args: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end..][0..extra.data.args_len]);
336 if (!checkRef(data.pl_op.operand, zcu)) return false;
337 for (args) |arg| if (!checkRef(arg, zcu)) return false;
338 },
339
340 .dbg_var_ptr,
341 .dbg_var_val,
342 => {
343 if (!checkRef(data.pl_op.operand, zcu)) return false;
344 },
345
346 .@"try" => {
347 const extra = air.extraData(Air.Try, data.pl_op.payload);
348 if (!checkRef(data.pl_op.operand, zcu)) return false;
349 if (!checkBody(
350 air,
351 @ptrCast(air.extra[extra.end..][0..extra.data.body_len]),
352 zcu,
353 )) return false;
354 },
355
356 .try_ptr => {
357 const extra = air.extraData(Air.TryPtr, data.ty_pl.payload);
358 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
359 if (!checkRef(extra.data.ptr, zcu)) return false;
360 if (!checkBody(
361 air,
362 @ptrCast(air.extra[extra.end..][0..extra.data.body_len]),
363 zcu,
364 )) return false;
365 },
366
367 .cond_br => {
368 const extra = air.extraData(Air.CondBr, data.pl_op.payload);
369 if (!checkRef(data.pl_op.operand, zcu)) return false;
370 if (!checkBody(
371 air,
372 @ptrCast(air.extra[extra.end..][0..extra.data.then_body_len]),
373 zcu,
374 )) return false;
375 if (!checkBody(
376 air,
377 @ptrCast(air.extra[extra.end + extra.data.then_body_len ..][0..extra.data.else_body_len]),
378 zcu,
379 )) return false;
380 },
381
382 .switch_br => {
383 const extra = air.extraData(Air.SwitchBr, data.pl_op.payload);
384 if (!checkRef(data.pl_op.operand, zcu)) return false;
385 var extra_index = extra.end;
386 for (0..extra.data.cases_len) |_| {
387 const case = air.extraData(Air.SwitchBr.Case, extra_index);
388 extra_index = case.end;
389 const items: []const Air.Inst.Ref = @ptrCast(air.extra[extra_index..][0..case.data.items_len]);
390 extra_index += case.data.items_len;
391 for (items) |item| if (!checkRef(item, zcu)) return false;
392 if (!checkBody(
393 air,
394 @ptrCast(air.extra[extra_index..][0..case.data.body_len]),
395 zcu,
396 )) return false;
397 extra_index += case.data.body_len;
398 }
399 if (!checkBody(
400 air,
401 @ptrCast(air.extra[extra_index..][0..extra.data.else_body_len]),
402 zcu,
403 )) return false;
404 },
405
406 .assembly => {
407 const extra = air.extraData(Air.Asm, data.ty_pl.payload);
408 if (!checkType(data.ty_pl.ty.toType(), zcu)) return false;
409 // Luckily, we only care about the inputs and outputs, so we don't have to do
410 // the whole null-terminated string dance.
411 const outputs: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end..][0..extra.data.outputs_len]);
412 const inputs: []const Air.Inst.Ref = @ptrCast(air.extra[extra.end + extra.data.outputs_len ..][0..extra.data.inputs_len]);
413 for (outputs) |output| if (output != .none and !checkRef(output, zcu)) return false;
414 for (inputs) |input| if (input != .none and !checkRef(input, zcu)) return false;
415 },
416
417 .trap,
418 .breakpoint,
419 .ret_addr,
420 .frame_addr,
421 .unreach,
422 .wasm_memory_size,
423 .wasm_memory_grow,
424 .work_item_id,
425 .work_group_size,
426 .work_group_id,
427 .fence,
428 .dbg_stmt,
429 .err_return_trace,
430 .save_err_return_trace_index,
431 => {},
432 }
433 }
434 return true;
435}
436
437fn checkRef(ref: Air.Inst.Ref, zcu: *Zcu) bool {
438 const ip_index = ref.toInterned() orelse {
439 // This operand refers back to a previous instruction.
440 // We have already checked that instruction's type.
441 // So, there's no need to check this operand's type.
442 return true;
443 };
444 return checkVal(Value.fromInterned(ip_index), zcu);
445}
446
447fn checkVal(val: Value, zcu: *Zcu) bool {
448 if (!checkType(val.typeOf(zcu), zcu)) return false;
449 // Check for lazy values
450 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
451 .int => |int| switch (int.storage) {
452 .u64, .i64, .big_int => return true,
453 .lazy_align, .lazy_size => |ty_index| {
454 return checkType(Type.fromInterned(ty_index), zcu);
455 },
456 },
457 else => return true,
458 }
459}
460
461fn checkType(ty: Type, zcu: *Zcu) bool {
462 const ip = &zcu.intern_pool;
463 return switch (ty.zigTypeTag(zcu)) {
464 .Type,
465 .Void,
466 .Bool,
467 .NoReturn,
468 .Int,
469 .Float,
470 .ErrorSet,
471 .Enum,
472 .Opaque,
473 .Vector,
474 // These types can appear due to some dummy instructions Sema introduces and expects to be omitted by Liveness.
475 // It's a little silly -- but fine, we'll return `true`.
476 .ComptimeFloat,
477 .ComptimeInt,
478 .Undefined,
479 .Null,
480 .EnumLiteral,
481 => true,
482
483 .Frame,
484 .AnyFrame,
485 => @panic("TODO Air.types_resolved.checkType async frames"),
486
487 .Optional => checkType(ty.childType(zcu), zcu),
488 .ErrorUnion => checkType(ty.errorUnionPayload(zcu), zcu),
489 .Pointer => checkType(ty.childType(zcu), zcu),
490 .Array => checkType(ty.childType(zcu), zcu),
491
492 .Fn => {
493 const info = zcu.typeToFunc(ty).?;
494 for (0..info.param_types.len) |i| {
495 const param_ty = info.param_types.get(ip)[i];
496 if (!checkType(Type.fromInterned(param_ty), zcu)) return false;
497 }
498 return checkType(Type.fromInterned(info.return_type), zcu);
499 },
500 .Struct => switch (ip.indexToKey(ty.toIntern())) {
501 .struct_type => {
502 const struct_obj = zcu.typeToStruct(ty).?;
503 return switch (struct_obj.layout) {
504 .@"packed" => struct_obj.backingIntType(ip).* != .none,
505 .auto, .@"extern" => struct_obj.flagsPtr(ip).fully_resolved,
506 };
507 },
508 .anon_struct_type => |tuple| {
509 for (0..tuple.types.len) |i| {
510 const field_is_comptime = tuple.values.get(ip)[i] != .none;
511 if (field_is_comptime) continue;
512 const field_ty = tuple.types.get(ip)[i];
513 if (!checkType(Type.fromInterned(field_ty), zcu)) return false;
514 }
515 return true;
516 },
517 else => unreachable,
518 },
519 .Union => return zcu.typeToUnion(ty).?.flagsPtr(ip).status == .fully_resolved,
520 };
521}
src/Compilation.zig+32-2
...@@ -37,6 +37,7 @@ const Cache = std.Build.Cache;...@@ -37,6 +37,7 @@ const Cache = std.Build.Cache;
37const c_codegen = @import("codegen/c.zig");37const c_codegen = @import("codegen/c.zig");
38const libtsan = @import("libtsan.zig");38const libtsan = @import("libtsan.zig");
39const Zir = std.zig.Zir;39const Zir = std.zig.Zir;
40const Air = @import("Air.zig");
40const Builtin = @import("Builtin.zig");41const Builtin = @import("Builtin.zig");
41const LlvmObject = @import("codegen/llvm.zig").Object;42const LlvmObject = @import("codegen/llvm.zig").Object;
4243
...@@ -316,18 +317,29 @@ const Job = union(enum) {...@@ -316,18 +317,29 @@ const Job = union(enum) {
316 codegen_decl: InternPool.DeclIndex,317 codegen_decl: InternPool.DeclIndex,
317 /// Write the machine code for a function to the output file.318 /// Write the machine code for a function to the output file.
318 /// This will either be a non-generic `func_decl` or a `func_instance`.319 /// This will either be a non-generic `func_decl` or a `func_instance`.
319 codegen_func: InternPool.Index,320 codegen_func: struct {
321 func: InternPool.Index,
322 /// This `Air` is owned by the `Job` and allocated with `gpa`.
323 /// It must be deinited when the job is processed.
324 air: Air,
325 },
320 /// Render the .h file snippet for the Decl.326 /// Render the .h file snippet for the Decl.
321 emit_h_decl: InternPool.DeclIndex,327 emit_h_decl: InternPool.DeclIndex,
322 /// The Decl needs to be analyzed and possibly export itself.328 /// The Decl needs to be analyzed and possibly export itself.
323 /// It may have already be analyzed, or it may have been determined329 /// It may have already be analyzed, or it may have been determined
324 /// to be outdated; in this case perform semantic analysis again.330 /// to be outdated; in this case perform semantic analysis again.
325 analyze_decl: InternPool.DeclIndex,331 analyze_decl: InternPool.DeclIndex,
332 /// Analyze the body of a runtime function.
333 /// After analysis, a `codegen_func` job will be queued.
334 /// These must be separate jobs to ensure any needed type resolution occurs *before* codegen.
335 analyze_func: InternPool.Index,
326 /// The source file containing the Decl has been updated, and so the336 /// The source file containing the Decl has been updated, and so the
327 /// Decl may need its line number information updated in the debug info.337 /// Decl may need its line number information updated in the debug info.
328 update_line_number: InternPool.DeclIndex,338 update_line_number: InternPool.DeclIndex,
329 /// The main source file for the module needs to be analyzed.339 /// The main source file for the module needs to be analyzed.
330 analyze_mod: *Package.Module,340 analyze_mod: *Package.Module,
341 /// Fully resolve the given `struct` or `union` type.
342 resolve_type_fully: InternPool.Index,
331343
332 /// one of the glibc static objects344 /// one of the glibc static objects
333 glibc_crt_file: glibc.CRTFile,345 glibc_crt_file: glibc.CRTFile,
...@@ -3389,7 +3401,7 @@ pub fn performAllTheWork(...@@ -3389,7 +3401,7 @@ pub fn performAllTheWork(
3389 if (try zcu.findOutdatedToAnalyze()) |outdated| {3401 if (try zcu.findOutdatedToAnalyze()) |outdated| {
3390 switch (outdated.unwrap()) {3402 switch (outdated.unwrap()) {
3391 .decl => |decl| try comp.work_queue.writeItem(.{ .analyze_decl = decl }),3403 .decl => |decl| try comp.work_queue.writeItem(.{ .analyze_decl = decl }),
3392 .func => |func| try comp.work_queue.writeItem(.{ .codegen_func = func }),3404 .func => |func| try comp.work_queue.writeItem(.{ .analyze_func = func }),
3393 }3405 }
3394 continue;3406 continue;
3395 }3407 }
...@@ -3439,6 +3451,14 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3439,6 +3451,14 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3439 const named_frame = tracy.namedFrame("codegen_func");3451 const named_frame = tracy.namedFrame("codegen_func");
3440 defer named_frame.end();3452 defer named_frame.end();
34413453
3454 const module = comp.module.?;
3455 // This call takes ownership of `func.air`.
3456 try module.linkerUpdateFunc(func.func, func.air);
3457 },
3458 .analyze_func => |func| {
3459 const named_frame = tracy.namedFrame("analyze_func");
3460 defer named_frame.end();
3461
3442 const module = comp.module.?;3462 const module = comp.module.?;
3443 module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {3463 module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
3444 error.OutOfMemory => return error.OutOfMemory,3464 error.OutOfMemory => return error.OutOfMemory,
...@@ -3518,6 +3538,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo...@@ -3518,6 +3538,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
3518 try module.ensureFuncBodyAnalysisQueued(decl.val.toIntern());3538 try module.ensureFuncBodyAnalysisQueued(decl.val.toIntern());
3519 }3539 }
3520 },3540 },
3541 .resolve_type_fully => |ty| {
3542 const named_frame = tracy.namedFrame("resolve_type_fully");
3543 defer named_frame.end();
3544
3545 const zcu = comp.module.?;
3546 Type.fromInterned(ty).resolveFully(zcu) catch |err| switch (err) {
3547 error.OutOfMemory => return error.OutOfMemory,
3548 error.AnalysisFail => return,
3549 };
3550 },
3521 .update_line_number => |decl_index| {3551 .update_line_number => |decl_index| {
3522 const named_frame = tracy.namedFrame("update_line_number");3552 const named_frame = tracy.namedFrame("update_line_number");
3523 defer named_frame.end();3553 defer named_frame.end();
src/Sema.zig+430-1028
...@@ -64,14 +64,6 @@ generic_owner: InternPool.Index = .none,...@@ -64,14 +64,6 @@ generic_owner: InternPool.Index = .none,
64/// instantiation can point back to the instantiation site in addition to the64/// instantiation can point back to the instantiation site in addition to the
65/// declaration site.65/// declaration site.
66generic_call_src: LazySrcLoc = LazySrcLoc.unneeded,66generic_call_src: LazySrcLoc = LazySrcLoc.unneeded,
67/// The key is types that must be fully resolved prior to machine code
68/// generation pass. Types are added to this set when resolving them
69/// immediately could cause a dependency loop, but they do need to be resolved
70/// before machine code generation passes process the AIR.
71/// It would work fine if this were an array list instead of an array hash map.
72/// I chose array hash map with the intention to save time by omitting
73/// duplicates.
74types_to_resolve: std.AutoArrayHashMapUnmanaged(InternPool.Index, void) = .{},
75/// These are lazily created runtime blocks from block_inline instructions.67/// These are lazily created runtime blocks from block_inline instructions.
76/// They are created when an break_inline passes through a runtime condition, because68/// They are created when an break_inline passes through a runtime condition, because
77/// Sema must convert comptime control flow to runtime control flow, which means69/// Sema must convert comptime control flow to runtime control flow, which means
...@@ -872,7 +864,6 @@ pub fn deinit(sema: *Sema) void {...@@ -872,7 +864,6 @@ pub fn deinit(sema: *Sema) void {
872 sema.air_extra.deinit(gpa);864 sema.air_extra.deinit(gpa);
873 sema.inst_map.deinit(gpa);865 sema.inst_map.deinit(gpa);
874 sema.decl_val_table.deinit(gpa);866 sema.decl_val_table.deinit(gpa);
875 sema.types_to_resolve.deinit(gpa);
876 {867 {
877 var it = sema.post_hoc_blocks.iterator();868 var it = sema.post_hoc_blocks.iterator();
878 while (it.next()) |entry| {869 while (it.next()) |entry| {
...@@ -2078,8 +2069,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)...@@ -2078,8 +2069,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
2078 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));2069 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));
20792070
2080 // var st: StackTrace = undefined;2071 // var st: StackTrace = undefined;
2081 const stack_trace_ty = try sema.getBuiltinType("StackTrace");2072 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
2082 try sema.resolveTypeFields(stack_trace_ty);2073 try stack_trace_ty.resolveFields(mod);
2083 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));2074 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));
20842075
2085 // st.instruction_addresses = &addrs;2076 // st.instruction_addresses = &addrs;
...@@ -2628,7 +2619,7 @@ fn analyzeAsInt(...@@ -2628,7 +2619,7 @@ fn analyzeAsInt(
2628 const mod = sema.mod;2619 const mod = sema.mod;
2629 const coerced = try sema.coerce(block, dest_ty, air_ref, src);2620 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
2630 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);2621 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
2631 return (try val.getUnsignedIntAdvanced(mod, sema)).?;2622 return (try val.getUnsignedIntAdvanced(mod, .sema)).?;
2632}2623}
26332624
2634/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,2625/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
...@@ -2832,6 +2823,7 @@ fn zirStructDecl(...@@ -2832,6 +2823,7 @@ fn zirStructDecl(
2832 }2823 }
28332824
2834 try mod.finalizeAnonDecl(new_decl_index);2825 try mod.finalizeAnonDecl(new_decl_index);
2826 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
2835 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));2827 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
2836}2828}
28372829
...@@ -3332,7 +3324,7 @@ fn zirUnionDecl(...@@ -3332,7 +3324,7 @@ fn zirUnionDecl(
3332 }3324 }
33333325
3334 try mod.finalizeAnonDecl(new_decl_index);3326 try mod.finalizeAnonDecl(new_decl_index);
33353327 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
3336 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));3328 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
3337}3329}
33383330
...@@ -3457,12 +3449,12 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -3457,12 +3449,12 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
3457 defer tracy.end();3449 defer tracy.end();
34583450
3459 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {3451 if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) {
3460 try sema.resolveTypeFields(sema.fn_ret_ty);3452 try sema.fn_ret_ty.resolveFields(sema.mod);
3461 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);3453 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);
3462 }3454 }
34633455
3464 const target = sema.mod.getTarget();3456 const target = sema.mod.getTarget();
3465 const ptr_type = try sema.ptrType(.{3457 const ptr_type = try sema.mod.ptrTypeSema(.{
3466 .child = sema.fn_ret_ty.toIntern(),3458 .child = sema.fn_ret_ty.toIntern(),
3467 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },3459 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
3468 });3460 });
...@@ -3471,7 +3463,6 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -3471,7 +3463,6 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
3471 // We are inlining a function call; this should be emitted as an alloc, not a ret_ptr.3463 // We are inlining a function call; this should be emitted as an alloc, not a ret_ptr.
3472 // TODO when functions gain result location support, the inlining struct in3464 // TODO when functions gain result location support, the inlining struct in
3473 // Block should contain the return pointer, and we would pass that through here.3465 // Block should contain the return pointer, and we would pass that through here.
3474 try sema.queueFullTypeResolution(sema.fn_ret_ty);
3475 return block.addTy(.alloc, ptr_type);3466 return block.addTy(.alloc, ptr_type);
3476 }3467 }
34773468
...@@ -3667,8 +3658,8 @@ fn zirAllocExtended(...@@ -3667,8 +3658,8 @@ fn zirAllocExtended(
3667 try sema.validateVarType(block, ty_src, var_ty, false);3658 try sema.validateVarType(block, ty_src, var_ty, false);
3668 }3659 }
3669 const target = sema.mod.getTarget();3660 const target = sema.mod.getTarget();
3670 try sema.resolveTypeLayout(var_ty);3661 try var_ty.resolveLayout(sema.mod);
3671 const ptr_type = try sema.ptrType(.{3662 const ptr_type = try sema.mod.ptrTypeSema(.{
3672 .child = var_ty.toIntern(),3663 .child = var_ty.toIntern(),
3673 .flags = .{3664 .flags = .{
3674 .alignment = alignment,3665 .alignment = alignment,
...@@ -3902,7 +3893,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3902,7 +3893,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3902 const idx_val = (try sema.resolveValue(data.rhs)).?;3893 const idx_val = (try sema.resolveValue(data.rhs)).?;
3903 break :blk .{3894 break :blk .{
3904 data.lhs,3895 data.lhs,
3905 .{ .elem = try idx_val.toUnsignedIntAdvanced(sema) },3896 .{ .elem = try idx_val.toUnsignedIntSema(zcu) },
3906 };3897 };
3907 },3898 },
3908 .bitcast => .{3899 .bitcast => .{
...@@ -3940,7 +3931,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3940,7 +3931,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3940 .val = payload_val.toIntern(),3931 .val = payload_val.toIntern(),
3941 } });3932 } });
3942 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty);3933 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(opt_val), opt_ty);
3943 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(sema)).toIntern();3934 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrOptPayload(zcu)).toIntern();
3944 },3935 },
3945 .eu_payload => ptr: {3936 .eu_payload => ptr: {
3946 // Set the error union to non-error at comptime.3937 // Set the error union to non-error at comptime.
...@@ -3953,7 +3944,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3953,7 +3944,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3953 .val = .{ .payload = payload_val.toIntern() },3944 .val = .{ .payload = payload_val.toIntern() },
3954 } });3945 } });
3955 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty);3946 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), Value.fromInterned(eu_val), eu_ty);
3956 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(sema)).toIntern();3947 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrEuPayload(zcu)).toIntern();
3957 },3948 },
3958 .field => |idx| ptr: {3949 .field => |idx| ptr: {
3959 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);3950 const maybe_union_ty = Value.fromInterned(decl_parent_ptr).typeOf(zcu).childType(zcu);
...@@ -3967,9 +3958,9 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,...@@ -3967,9 +3958,9 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
3967 const store_val = try zcu.unionValue(maybe_union_ty, tag_val, payload_val);3958 const store_val = try zcu.unionValue(maybe_union_ty, tag_val, payload_val);
3968 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);3959 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
3969 }3960 }
3970 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, sema)).toIntern();3961 break :ptr (try Value.fromInterned(decl_parent_ptr).ptrField(idx, zcu)).toIntern();
3971 },3962 },
3972 .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, sema)).toIntern(),3963 .elem => |idx| (try Value.fromInterned(decl_parent_ptr).ptrElem(idx, zcu)).toIntern(),
3973 };3964 };
3974 try ptr_mapping.put(air_ptr, new_ptr);3965 try ptr_mapping.put(air_ptr, new_ptr);
3975 }3966 }
...@@ -4060,7 +4051,7 @@ fn finishResolveComptimeKnownAllocPtr(...@@ -4060,7 +4051,7 @@ fn finishResolveComptimeKnownAllocPtr(
4060fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {4051fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
4061 var ptr_info = ptr_ty.ptrInfo(sema.mod);4052 var ptr_info = ptr_ty.ptrInfo(sema.mod);
4062 ptr_info.flags.is_const = true;4053 ptr_info.flags.is_const = true;
4063 return sema.ptrType(ptr_info);4054 return sema.mod.ptrTypeSema(ptr_info);
4064}4055}
40654056
4066fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {4057fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref {
...@@ -4103,11 +4094,10 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I...@@ -4103,11 +4094,10 @@ fn zirAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
4103 return sema.analyzeComptimeAlloc(block, var_ty, .none);4094 return sema.analyzeComptimeAlloc(block, var_ty, .none);
4104 }4095 }
4105 const target = sema.mod.getTarget();4096 const target = sema.mod.getTarget();
4106 const ptr_type = try sema.ptrType(.{4097 const ptr_type = try sema.mod.ptrTypeSema(.{
4107 .child = var_ty.toIntern(),4098 .child = var_ty.toIntern(),
4108 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },4099 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4109 });4100 });
4110 try sema.queueFullTypeResolution(var_ty);
4111 const ptr = try block.addTy(.alloc, ptr_type);4101 const ptr = try block.addTy(.alloc, ptr_type);
4112 const ptr_inst = ptr.toIndex().?;4102 const ptr_inst = ptr.toIndex().?;
4113 try sema.maybe_comptime_allocs.put(sema.gpa, ptr_inst, .{ .runtime_index = block.runtime_index });4103 try sema.maybe_comptime_allocs.put(sema.gpa, ptr_inst, .{ .runtime_index = block.runtime_index });
...@@ -4127,11 +4117,10 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -4127,11 +4117,10 @@ fn zirAllocMut(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
4127 }4117 }
4128 try sema.validateVarType(block, ty_src, var_ty, false);4118 try sema.validateVarType(block, ty_src, var_ty, false);
4129 const target = sema.mod.getTarget();4119 const target = sema.mod.getTarget();
4130 const ptr_type = try sema.ptrType(.{4120 const ptr_type = try sema.mod.ptrTypeSema(.{
4131 .child = var_ty.toIntern(),4121 .child = var_ty.toIntern(),
4132 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },4122 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
4133 });4123 });
4134 try sema.queueFullTypeResolution(var_ty);
4135 return block.addTy(.alloc, ptr_type);4124 return block.addTy(.alloc, ptr_type);
4136}4125}
41374126
...@@ -4227,7 +4216,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4227,7 +4216,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4227 }4216 }
4228 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);4217 const final_elem_ty = try sema.resolvePeerTypes(block, ty_src, peer_vals, .none);
42294218
4230 const final_ptr_ty = try sema.ptrType(.{4219 const final_ptr_ty = try mod.ptrTypeSema(.{
4231 .child = final_elem_ty.toIntern(),4220 .child = final_elem_ty.toIntern(),
4232 .flags = .{4221 .flags = .{
4233 .alignment = ia1.alignment,4222 .alignment = ia1.alignment,
...@@ -4247,7 +4236,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4247,7 +4236,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4247 // Unless the block is comptime, `alloc_inferred` always produces4236 // Unless the block is comptime, `alloc_inferred` always produces
4248 // a runtime constant. The final inferred type needs to be4237 // a runtime constant. The final inferred type needs to be
4249 // fully resolved so it can be lowered in codegen.4238 // fully resolved so it can be lowered in codegen.
4250 try sema.resolveTypeFully(final_elem_ty);4239 try final_elem_ty.resolveFully(mod);
42514240
4252 return;4241 return;
4253 }4242 }
...@@ -4259,8 +4248,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com...@@ -4259,8 +4248,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
4259 return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(mod)});4248 return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(mod)});
4260 }4249 }
42614250
4262 try sema.queueFullTypeResolution(final_elem_ty);
4263
4264 // Change it to a normal alloc.4251 // Change it to a normal alloc.
4265 sema.air_instructions.set(@intFromEnum(ptr_inst), .{4252 sema.air_instructions.set(@intFromEnum(ptr_inst), .{
4266 .tag = .alloc,4253 .tag = .alloc,
...@@ -4633,7 +4620,7 @@ fn validateArrayInitTy(...@@ -4633,7 +4620,7 @@ fn validateArrayInitTy(
4633 return;4620 return;
4634 },4621 },
4635 .Struct => if (ty.isTuple(mod)) {4622 .Struct => if (ty.isTuple(mod)) {
4636 try sema.resolveTypeFields(ty);4623 try ty.resolveFields(mod);
4637 const array_len = ty.arrayLen(mod);4624 const array_len = ty.arrayLen(mod);
4638 if (init_count > array_len) {4625 if (init_count > array_len) {
4639 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{4626 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{
...@@ -4911,7 +4898,7 @@ fn validateStructInit(...@@ -4911,7 +4898,7 @@ fn validateStructInit(
4911 if (block.is_comptime and4898 if (block.is_comptime and
4912 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)4899 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)
4913 {4900 {
4914 try sema.resolveStructLayout(struct_ty);4901 try struct_ty.resolveLayout(mod);
4915 // In this case the only thing we need to do is evaluate the implicit4902 // In this case the only thing we need to do is evaluate the implicit
4916 // store instructions for default field values, and report any missing fields.4903 // store instructions for default field values, and report any missing fields.
4917 // Avoid the cost of the extra machinery for detecting a comptime struct init value.4904 // Avoid the cost of the extra machinery for detecting a comptime struct init value.
...@@ -4919,7 +4906,7 @@ fn validateStructInit(...@@ -4919,7 +4906,7 @@ fn validateStructInit(
4919 const i: u32 = @intCast(i_usize);4906 const i: u32 = @intCast(i_usize);
4920 if (field_ptr != .none) continue;4907 if (field_ptr != .none) continue;
49214908
4922 try sema.resolveStructFieldInits(struct_ty);4909 try struct_ty.resolveStructFieldInits(mod);
4923 const default_val = struct_ty.structFieldDefaultValue(i, mod);4910 const default_val = struct_ty.structFieldDefaultValue(i, mod);
4924 if (default_val.toIntern() == .unreachable_value) {4911 if (default_val.toIntern() == .unreachable_value) {
4925 const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {4912 const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {
...@@ -4968,7 +4955,7 @@ fn validateStructInit(...@@ -4968,7 +4955,7 @@ fn validateStructInit(
4968 const air_tags = sema.air_instructions.items(.tag);4955 const air_tags = sema.air_instructions.items(.tag);
4969 const air_datas = sema.air_instructions.items(.data);4956 const air_datas = sema.air_instructions.items(.data);
49704957
4971 try sema.resolveStructFieldInits(struct_ty);4958 try struct_ty.resolveStructFieldInits(mod);
49724959
4973 // We collect the comptime field values in case the struct initialization4960 // We collect the comptime field values in case the struct initialization
4974 // ends up being comptime-known.4961 // ends up being comptime-known.
...@@ -5127,7 +5114,7 @@ fn validateStructInit(...@@ -5127,7 +5114,7 @@ fn validateStructInit(
5127 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);5114 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
5128 return;5115 return;
5129 }5116 }
5130 try sema.resolveStructLayout(struct_ty);5117 try struct_ty.resolveLayout(mod);
51315118
5132 // Our task is to insert `store` instructions for all the default field values.5119 // Our task is to insert `store` instructions for all the default field values.
5133 for (found_fields, 0..) |field_ptr, i| {5120 for (found_fields, 0..) |field_ptr, i| {
...@@ -5172,7 +5159,7 @@ fn zirValidatePtrArrayInit(...@@ -5172,7 +5159,7 @@ fn zirValidatePtrArrayInit(
5172 var root_msg: ?*Module.ErrorMsg = null;5159 var root_msg: ?*Module.ErrorMsg = null;
5173 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);5160 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
51745161
5175 try sema.resolveStructFieldInits(array_ty);5162 try array_ty.resolveStructFieldInits(mod);
5176 var i = instrs.len;5163 var i = instrs.len;
5177 while (i < array_len) : (i += 1) {5164 while (i < array_len) : (i += 1) {
5178 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();5165 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();
...@@ -5241,7 +5228,7 @@ fn zirValidatePtrArrayInit(...@@ -5241,7 +5228,7 @@ fn zirValidatePtrArrayInit(
52415228
5242 if (array_ty.isTuple(mod)) {5229 if (array_ty.isTuple(mod)) {
5243 if (array_ty.structFieldIsComptime(i, mod))5230 if (array_ty.structFieldIsComptime(i, mod))
5244 try sema.resolveStructFieldInits(array_ty);5231 try array_ty.resolveStructFieldInits(mod);
5245 if (try array_ty.structFieldValueComptime(mod, i)) |opv| {5232 if (try array_ty.structFieldValueComptime(mod, i)) |opv| {
5246 element_vals[i] = opv.toIntern();5233 element_vals[i] = opv.toIntern();
5247 continue;5234 continue;
...@@ -5581,7 +5568,7 @@ fn storeToInferredAllocComptime(...@@ -5581,7 +5568,7 @@ fn storeToInferredAllocComptime(
5581 .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known",5568 .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known",
5582 });5569 });
5583 };5570 };
5584 const alloc_ty = try sema.ptrType(.{5571 const alloc_ty = try zcu.ptrTypeSema(.{
5585 .child = operand_ty.toIntern(),5572 .child = operand_ty.toIntern(),
5586 .flags = .{5573 .flags = .{
5587 .alignment = iac.alignment,5574 .alignment = iac.alignment,
...@@ -5688,7 +5675,7 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {...@@ -5688,7 +5675,7 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
56885675
5689fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {5676fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
5690 const mod = sema.mod;5677 const mod = sema.mod;
5691 const ptr_ty = (try sema.ptrType(.{5678 const ptr_ty = (try mod.ptrTypeSema(.{
5692 .child = mod.intern_pool.typeOf(val),5679 .child = mod.intern_pool.typeOf(val),
5693 .flags = .{5680 .flags = .{
5694 .alignment = .none,5681 .alignment = .none,
...@@ -6645,8 +6632,6 @@ fn addDbgVar(...@@ -6645,8 +6632,6 @@ fn addDbgVar(
6645 // real `block` instruction.6632 // real `block` instruction.
6646 if (block.need_debug_scope) |ptr| ptr.* = true;6633 if (block.need_debug_scope) |ptr| ptr.* = true;
66476634
6648 try sema.queueFullTypeResolution(operand_ty);
6649
6650 // Add the name to the AIR.6635 // Add the name to the AIR.
6651 const name_extra_index: u32 = @intCast(sema.air_extra.items.len);6636 const name_extra_index: u32 = @intCast(sema.air_extra.items.len);
6652 const elements_used = name.len / 4 + 1;6637 const elements_used = name.len / 4 + 1;
...@@ -6832,14 +6817,8 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref...@@ -6832,14 +6817,8 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
68326817
6833 if (!block.ownerModule().error_tracing) return .none;6818 if (!block.ownerModule().error_tracing) return .none;
68346819
6835 const stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) {6820 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
6836 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,6821 try stack_trace_ty.resolveFields(mod);
6837 else => |e| return e,
6838 };
6839 sema.resolveTypeFields(stack_trace_ty) catch |err| switch (err) {
6840 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
6841 else => |e| return e,
6842 };
6843 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);6822 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
6844 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {6823 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
6845 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),6824 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
...@@ -6879,8 +6858,8 @@ fn popErrorReturnTrace(...@@ -6879,8 +6858,8 @@ fn popErrorReturnTrace(
6879 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or6858 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
6880 // the result is comptime-known to be a non-error. Either way, pop unconditionally.6859 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
68816860
6882 const stack_trace_ty = try sema.getBuiltinType("StackTrace");6861 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
6883 try sema.resolveTypeFields(stack_trace_ty);6862 try stack_trace_ty.resolveFields(mod);
6884 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6863 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
6885 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);6864 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
6886 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);6865 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
...@@ -6905,8 +6884,8 @@ fn popErrorReturnTrace(...@@ -6905,8 +6884,8 @@ fn popErrorReturnTrace(
6905 defer then_block.instructions.deinit(gpa);6884 defer then_block.instructions.deinit(gpa);
69066885
6907 // If non-error, then pop the error return trace by restoring the index.6886 // If non-error, then pop the error return trace by restoring the index.
6908 const stack_trace_ty = try sema.getBuiltinType("StackTrace");6887 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
6909 try sema.resolveTypeFields(stack_trace_ty);6888 try stack_trace_ty.resolveFields(mod);
6910 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);6889 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
6911 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);6890 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
6912 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);6891 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
...@@ -7032,8 +7011,8 @@ fn zirCall(...@@ -7032,8 +7011,8 @@ fn zirCall(
7032 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only7011 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
7033 // need to clean-up our own trace if we were passed to a non-error-handling expression.7012 // need to clean-up our own trace if we were passed to a non-error-handling expression.
7034 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {7013 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {
7035 const stack_trace_ty = try sema.getBuiltinType("StackTrace");7014 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
7036 try sema.resolveTypeFields(stack_trace_ty);7015 try stack_trace_ty.resolveFields(mod);
7037 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls);7016 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls);
7038 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);7017 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
70397018
...@@ -7264,10 +7243,6 @@ const CallArgsInfo = union(enum) {...@@ -7264,10 +7243,6 @@ const CallArgsInfo = union(enum) {
7264 ) CompileError!Air.Inst.Ref {7243 ) CompileError!Air.Inst.Ref {
7265 const mod = sema.mod;7244 const mod = sema.mod;
7266 const param_count = func_ty_info.param_types.len;7245 const param_count = func_ty_info.param_types.len;
7267 if (maybe_param_ty) |param_ty| switch (param_ty.toIntern()) {
7268 .generic_poison_type => {},
7269 else => try sema.queueFullTypeResolution(param_ty),
7270 };
7271 const uncoerced_arg: Air.Inst.Ref = switch (cai) {7246 const uncoerced_arg: Air.Inst.Ref = switch (cai) {
7272 inline .resolved, .call_builtin => |resolved| resolved.args[arg_index],7247 inline .resolved, .call_builtin => |resolved| resolved.args[arg_index],
7273 .zir_call => |zir_call| arg_val: {7248 .zir_call => |zir_call| arg_val: {
...@@ -7494,24 +7469,19 @@ fn analyzeCall(...@@ -7494,24 +7469,19 @@ fn analyzeCall(
74947469
7495 const gpa = sema.gpa;7470 const gpa = sema.gpa;
74967471
7497 var is_generic_call = func_ty_info.is_generic;7472 const is_generic_call = func_ty_info.is_generic;
7498 var is_comptime_call = block.is_comptime or modifier == .compile_time;7473 var is_comptime_call = block.is_comptime or modifier == .compile_time;
7499 var is_inline_call = is_comptime_call or modifier == .always_inline or func_ty_info.cc == .Inline;7474 var is_inline_call = is_comptime_call or modifier == .always_inline or func_ty_info.cc == .Inline;
7500 var comptime_reason: ?*const Block.ComptimeReason = null;7475 var comptime_reason: ?*const Block.ComptimeReason = null;
7501 if (!is_inline_call and !is_comptime_call) {7476 if (!is_inline_call and !is_comptime_call) {
7502 if (sema.typeRequiresComptime(Type.fromInterned(func_ty_info.return_type))) |ct| {7477 if (try sema.typeRequiresComptime(Type.fromInterned(func_ty_info.return_type))) {
7503 is_comptime_call = ct;7478 is_comptime_call = true;
7504 is_inline_call = ct;7479 is_inline_call = true;
7505 if (ct) {7480 comptime_reason = &.{ .comptime_ret_ty = .{
7506 comptime_reason = &.{ .comptime_ret_ty = .{7481 .func = func,
7507 .func = func,7482 .func_src = func_src,
7508 .func_src = func_src,7483 .return_ty = Type.fromInterned(func_ty_info.return_type),
7509 .return_ty = Type.fromInterned(func_ty_info.return_type),7484 } };
7510 } };
7511 }
7512 } else |err| switch (err) {
7513 error.GenericPoison => is_generic_call = true,
7514 else => |e| return e,
7515 }7485 }
7516 }7486 }
75177487
...@@ -7871,7 +7841,6 @@ fn analyzeCall(...@@ -7871,7 +7841,6 @@ fn analyzeCall(
78717841
7872 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);7842 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
78737843
7874 try sema.queueFullTypeResolution(Type.fromInterned(func_ty_info.return_type));
7875 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {7844 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {
7876 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true;7845 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true;
7877 }7846 }
...@@ -8281,7 +8250,6 @@ fn instantiateGenericCall(...@@ -8281,7 +8250,6 @@ fn instantiateGenericCall(
8281 }8250 }
8282 } else {8251 } else {
8283 // The parameter is runtime-known.8252 // The parameter is runtime-known.
8284 try sema.queueFullTypeResolution(arg_ty);
8285 child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{8253 child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
8286 .tag = .arg,8254 .tag = .arg,
8287 .data = .{ .arg = .{8255 .data = .{ .arg = .{
...@@ -8330,8 +8298,6 @@ fn instantiateGenericCall(...@@ -8330,8 +8298,6 @@ fn instantiateGenericCall(
8330 return error.GenericPoison;8298 return error.GenericPoison;
8331 }8299 }
83328300
8333 try sema.queueFullTypeResolution(Type.fromInterned(func_ty_info.return_type));
8334
8335 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);8301 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
83368302
8337 if (sema.owner_func_index != .none and8303 if (sema.owner_func_index != .none and
...@@ -8423,7 +8389,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil...@@ -8423,7 +8389,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
8423 else => |e| return e,8389 else => |e| return e,
8424 };8390 };
8425 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod);8391 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod);
8426 try sema.resolveTypeFields(indexable_ty);8392 try indexable_ty.resolveFields(mod);
8427 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction8393 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
8428 if (indexable_ty.zigTypeTag(mod) == .Struct) {8394 if (indexable_ty.zigTypeTag(mod) == .Struct) {
8429 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);8395 const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod);
...@@ -8687,7 +8653,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8687,7 +8653,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8687 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);8653 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
86888654
8689 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8655 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8690 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntAdvanced(sema));8656 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(mod));
8691 if (int > mod.global_error_set.count() or int == 0)8657 if (int > mod.global_error_set.count() or int == 0)
8692 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8658 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8693 return Air.internedToRef((try mod.intern(.{ .err = .{8659 return Air.internedToRef((try mod.intern(.{ .err = .{
...@@ -8791,7 +8757,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -8791,7 +8757,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
8791 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {8757 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {
8792 .Enum => operand,8758 .Enum => operand,
8793 .Union => blk: {8759 .Union => blk: {
8794 try sema.resolveTypeFields(operand_ty);8760 try operand_ty.resolveFields(mod);
8795 const tag_ty = operand_ty.unionTagType(mod) orelse {8761 const tag_ty = operand_ty.unionTagType(mod) orelse {
8796 return sema.fail(8762 return sema.fail(
8797 block,8763 block,
...@@ -8933,7 +8899,7 @@ fn analyzeOptionalPayloadPtr(...@@ -8933,7 +8899,7 @@ fn analyzeOptionalPayloadPtr(
8933 }8899 }
89348900
8935 const child_type = opt_type.optionalChild(zcu);8901 const child_type = opt_type.optionalChild(zcu);
8936 const child_pointer = try sema.ptrType(.{8902 const child_pointer = try zcu.ptrTypeSema(.{
8937 .child = child_type.toIntern(),8903 .child = child_type.toIntern(),
8938 .flags = .{8904 .flags = .{
8939 .is_const = optional_ptr_ty.isConstPtr(zcu),8905 .is_const = optional_ptr_ty.isConstPtr(zcu),
...@@ -8957,13 +8923,13 @@ fn analyzeOptionalPayloadPtr(...@@ -8957,13 +8923,13 @@ fn analyzeOptionalPayloadPtr(
8957 const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);8923 const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);
8958 try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr);8924 try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr);
8959 }8925 }
8960 return Air.internedToRef((try ptr_val.ptrOptPayload(sema)).toIntern());8926 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());
8961 }8927 }
8962 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {8928 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
8963 if (val.isNull(zcu)) {8929 if (val.isNull(zcu)) {
8964 return sema.fail(block, src, "unable to unwrap null", .{});8930 return sema.fail(block, src, "unable to unwrap null", .{});
8965 }8931 }
8966 return Air.internedToRef((try ptr_val.ptrOptPayload(sema)).toIntern());8932 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());
8967 }8933 }
8968 }8934 }
89698935
...@@ -9006,7 +8972,7 @@ fn zirOptionalPayload(...@@ -9006,7 +8972,7 @@ fn zirOptionalPayload(
9006 // TODO https://github.com/ziglang/zig/issues/65978972 // TODO https://github.com/ziglang/zig/issues/6597
9007 if (true) break :t operand_ty;8973 if (true) break :t operand_ty;
9008 const ptr_info = operand_ty.ptrInfo(mod);8974 const ptr_info = operand_ty.ptrInfo(mod);
9009 break :t try sema.ptrType(.{8975 break :t try mod.ptrTypeSema(.{
9010 .child = ptr_info.child,8976 .child = ptr_info.child,
9011 .flags = .{8977 .flags = .{
9012 .alignment = ptr_info.flags.alignment,8978 .alignment = ptr_info.flags.alignment,
...@@ -9124,7 +9090,7 @@ fn analyzeErrUnionPayloadPtr(...@@ -9124,7 +9090,7 @@ fn analyzeErrUnionPayloadPtr(
91249090
9125 const err_union_ty = operand_ty.childType(zcu);9091 const err_union_ty = operand_ty.childType(zcu);
9126 const payload_ty = err_union_ty.errorUnionPayload(zcu);9092 const payload_ty = err_union_ty.errorUnionPayload(zcu);
9127 const operand_pointer_ty = try sema.ptrType(.{9093 const operand_pointer_ty = try zcu.ptrTypeSema(.{
9128 .child = payload_ty.toIntern(),9094 .child = payload_ty.toIntern(),
9129 .flags = .{9095 .flags = .{
9130 .is_const = operand_ty.isConstPtr(zcu),9096 .is_const = operand_ty.isConstPtr(zcu),
...@@ -9149,13 +9115,13 @@ fn analyzeErrUnionPayloadPtr(...@@ -9149,13 +9115,13 @@ fn analyzeErrUnionPayloadPtr(
9149 const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);9115 const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);
9150 try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr);9116 try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr);
9151 }9117 }
9152 return Air.internedToRef((try ptr_val.ptrEuPayload(sema)).toIntern());9118 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());
9153 }9119 }
9154 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {9120 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
9155 if (val.getErrorName(zcu).unwrap()) |name| {9121 if (val.getErrorName(zcu).unwrap()) |name| {
9156 return sema.failWithComptimeErrorRetTrace(block, src, name);9122 return sema.failWithComptimeErrorRetTrace(block, src, name);
9157 }9123 }
9158 return Air.internedToRef((try ptr_val.ptrEuPayload(sema)).toIntern());9124 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());
9159 }9125 }
9160 }9126 }
91619127
...@@ -9603,17 +9569,8 @@ fn funcCommon(...@@ -9603,17 +9569,8 @@ fn funcCommon(
9603 }9569 }
9604 }9570 }
96059571
9606 var ret_ty_requires_comptime = false;9572 const ret_ty_requires_comptime = try sema.typeRequiresComptime(bare_return_type);
9607 const ret_poison = if (sema.typeRequiresComptime(bare_return_type)) |ret_comptime| rp: {9573 const ret_poison = bare_return_type.isGenericPoison();
9608 ret_ty_requires_comptime = ret_comptime;
9609 break :rp bare_return_type.isGenericPoison();
9610 } else |err| switch (err) {
9611 error.GenericPoison => rp: {
9612 is_generic = true;
9613 break :rp true;
9614 },
9615 else => |e| return e,
9616 };
9617 const final_is_generic = is_generic or comptime_bits != 0 or ret_ty_requires_comptime;9574 const final_is_generic = is_generic or comptime_bits != 0 or ret_ty_requires_comptime;
96189575
9619 const param_types = block.params.items(.ty);9576 const param_types = block.params.items(.ty);
...@@ -9961,8 +9918,8 @@ fn finishFunc(...@@ -9961,8 +9918,8 @@ fn finishFunc(
9961 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {9918 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {
9962 // Make sure that StackTrace's fields are resolved so that the backend can9919 // Make sure that StackTrace's fields are resolved so that the backend can
9963 // lower this fn type.9920 // lower this fn type.
9964 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");9921 const unresolved_stack_trace_ty = try mod.getBuiltinType("StackTrace");
9965 try sema.resolveTypeFields(unresolved_stack_trace_ty);9922 try unresolved_stack_trace_ty.resolveFields(mod);
9966 }9923 }
99679924
9968 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);9925 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
...@@ -10021,21 +9978,7 @@ fn zirParam(...@@ -10021,21 +9978,7 @@ fn zirParam(
10021 }9978 }
10022 };9979 };
100239980
10024 const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) {9981 const is_comptime = try sema.typeRequiresComptime(param_ty) or comptime_syntax;
10025 error.GenericPoison => {
10026 // The type is not available until the generic instantiation.
10027 // We result the param instruction with a poison value and
10028 // insert an anytype parameter.
10029 try block.params.append(sema.arena, .{
10030 .ty = .generic_poison_type,
10031 .is_comptime = comptime_syntax,
10032 .name = param_name,
10033 });
10034 sema.inst_map.putAssumeCapacity(inst, .generic_poison);
10035 return;
10036 },
10037 else => |e| return e,
10038 } or comptime_syntax;
100399982
10040 try block.params.append(sema.arena, .{9983 try block.params.append(sema.arena, .{
10041 .ty = param_ty.toIntern(),9984 .ty = param_ty.toIntern(),
...@@ -10162,7 +10105,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10162,7 +10105,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10162 }10105 }
10163 return Air.internedToRef((try zcu.intValue(10106 return Air.internedToRef((try zcu.intValue(
10164 Type.usize,10107 Type.usize,
10165 (try operand_val.getUnsignedIntAdvanced(zcu, sema)).?,10108 (try operand_val.getUnsignedIntAdvanced(zcu, .sema)).?,
10166 )).toIntern());10109 )).toIntern());
10167 }10110 }
10168 const len = operand_ty.vectorLen(zcu);10111 const len = operand_ty.vectorLen(zcu);
...@@ -10174,7 +10117,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -10174,7 +10117,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
10174 new_elem.* = (try zcu.undefValue(Type.usize)).toIntern();10117 new_elem.* = (try zcu.undefValue(Type.usize)).toIntern();
10175 continue;10118 continue;
10176 }10119 }
10177 const addr = try ptr_val.getUnsignedIntAdvanced(zcu, sema) orelse {10120 const addr = try ptr_val.getUnsignedIntAdvanced(zcu, .sema) orelse {
10178 // A vector element wasn't an integer pointer. This is a runtime operation.10121 // A vector element wasn't an integer pointer. This is a runtime operation.
10179 break :ct;10122 break :ct;
10180 };10123 };
...@@ -11047,7 +10990,7 @@ const SwitchProngAnalysis = struct {...@@ -11047,7 +10990,7 @@ const SwitchProngAnalysis = struct {
11047 const union_obj = zcu.typeToUnion(operand_ty).?;10990 const union_obj = zcu.typeToUnion(operand_ty).?;
11048 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);10991 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
11049 if (capture_byref) {10992 if (capture_byref) {
11050 const ptr_field_ty = try sema.ptrType(.{10993 const ptr_field_ty = try zcu.ptrTypeSema(.{
11051 .child = field_ty.toIntern(),10994 .child = field_ty.toIntern(),
11052 .flags = .{10995 .flags = .{
11053 .is_const = !operand_ptr_ty.ptrIsMutable(zcu),10996 .is_const = !operand_ptr_ty.ptrIsMutable(zcu),
...@@ -11056,7 +10999,7 @@ const SwitchProngAnalysis = struct {...@@ -11056,7 +10999,7 @@ const SwitchProngAnalysis = struct {
11056 },10999 },
11057 });11000 });
11058 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| {11001 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |union_ptr| {
11059 return Air.internedToRef((try union_ptr.ptrField(field_index, sema)).toIntern());11002 return Air.internedToRef((try union_ptr.ptrField(field_index, zcu)).toIntern());
11060 }11003 }
11061 return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty);11004 return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty);
11062 } else {11005 } else {
...@@ -11150,7 +11093,7 @@ const SwitchProngAnalysis = struct {...@@ -11150,7 +11093,7 @@ const SwitchProngAnalysis = struct {
11150 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);11093 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
11151 for (field_indices, dummy_captures) |field_idx, *dummy| {11094 for (field_indices, dummy_captures) |field_idx, *dummy| {
11152 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);11095 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
11153 const field_ptr_ty = try sema.ptrType(.{11096 const field_ptr_ty = try zcu.ptrTypeSema(.{
11154 .child = field_ty.toIntern(),11097 .child = field_ty.toIntern(),
11155 .flags = .{11098 .flags = .{
11156 .is_const = operand_ptr_info.flags.is_const,11099 .is_const = operand_ptr_info.flags.is_const,
...@@ -11186,7 +11129,7 @@ const SwitchProngAnalysis = struct {...@@ -11186,7 +11129,7 @@ const SwitchProngAnalysis = struct {
1118611129
11187 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| {11130 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| {
11188 if (op_ptr_val.isUndef(zcu)) return zcu.undefRef(capture_ptr_ty);11131 if (op_ptr_val.isUndef(zcu)) return zcu.undefRef(capture_ptr_ty);
11189 const field_ptr_val = try op_ptr_val.ptrField(first_field_index, sema);11132 const field_ptr_val = try op_ptr_val.ptrField(first_field_index, zcu);
11190 return Air.internedToRef((try zcu.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern());11133 return Air.internedToRef((try zcu.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern());
11191 }11134 }
1119211135
...@@ -11399,7 +11342,7 @@ fn switchCond(...@@ -11399,7 +11342,7 @@ fn switchCond(
11399 },11342 },
1140011343
11401 .Union => {11344 .Union => {
11402 try sema.resolveTypeFields(operand_ty);11345 try operand_ty.resolveFields(mod);
11403 const enum_ty = operand_ty.unionTagType(mod) orelse {11346 const enum_ty = operand_ty.unionTagType(mod) orelse {
11404 const msg = msg: {11347 const msg = msg: {
11405 const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});11348 const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});
...@@ -13691,7 +13634,7 @@ fn maybeErrorUnwrap(...@@ -13691,7 +13634,7 @@ fn maybeErrorUnwrap(
13691 return true;13634 return true;
13692 }13635 }
1369313636
13694 const panic_fn = try sema.getBuiltin("panicUnwrapError");13637 const panic_fn = try mod.getBuiltin("panicUnwrapError");
13695 const err_return_trace = try sema.getErrorReturnTrace(block);13638 const err_return_trace = try sema.getErrorReturnTrace(block);
13696 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };13639 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
13697 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");13640 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
...@@ -13701,7 +13644,7 @@ fn maybeErrorUnwrap(...@@ -13701,7 +13644,7 @@ fn maybeErrorUnwrap(
13701 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;13644 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
13702 const msg_inst = try sema.resolveInst(inst_data.operand);13645 const msg_inst = try sema.resolveInst(inst_data.operand);
1370313646
13704 const panic_fn = try sema.getBuiltin("panic");13647 const panic_fn = try mod.getBuiltin("panic");
13705 const err_return_trace = try sema.getErrorReturnTrace(block);13648 const err_return_trace = try sema.getErrorReturnTrace(block);
13706 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };13649 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
13707 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");13650 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
...@@ -13766,7 +13709,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -13766,7 +13709,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
13766 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{13709 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{
13767 .needed_comptime_reason = "field name must be comptime-known",13710 .needed_comptime_reason = "field name must be comptime-known",
13768 });13711 });
13769 try sema.resolveTypeFields(ty);13712 try ty.resolveFields(mod);
13770 const ip = &mod.intern_pool;13713 const ip = &mod.intern_pool;
1377113714
13772 const has_field = hf: {13715 const has_field = hf: {
...@@ -13946,7 +13889,7 @@ fn zirShl(...@@ -13946,7 +13889,7 @@ fn zirShl(
13946 return mod.undefRef(sema.typeOf(lhs));13889 return mod.undefRef(sema.typeOf(lhs));
13947 }13890 }
13948 // If rhs is 0, return lhs without doing any calculations.13891 // If rhs is 0, return lhs without doing any calculations.
13949 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {13892 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
13950 return lhs;13893 return lhs;
13951 }13894 }
13952 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {13895 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {
...@@ -14111,7 +14054,7 @@ fn zirShr(...@@ -14111,7 +14054,7 @@ fn zirShr(
14111 return mod.undefRef(lhs_ty);14054 return mod.undefRef(lhs_ty);
14112 }14055 }
14113 // If rhs is 0, return lhs without doing any calculations.14056 // If rhs is 0, return lhs without doing any calculations.
14114 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {14057 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
14115 return lhs;14058 return lhs;
14116 }14059 }
14117 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {14060 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
...@@ -14158,7 +14101,7 @@ fn zirShr(...@@ -14158,7 +14101,7 @@ fn zirShr(
14158 if (air_tag == .shr_exact) {14101 if (air_tag == .shr_exact) {
14159 // Detect if any ones would be shifted out.14102 // Detect if any ones would be shifted out.
14160 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, mod);14103 const truncated = try lhs_val.intTruncBitsAsValue(lhs_ty, sema.arena, .unsigned, rhs_val, mod);
14161 if (!(try truncated.compareAllWithZeroAdvanced(.eq, sema))) {14104 if (!(try truncated.compareAllWithZeroSema(.eq, mod))) {
14162 return sema.fail(block, src, "exact shift shifted out 1 bits", .{});14105 return sema.fail(block, src, "exact shift shifted out 1 bits", .{});
14163 }14106 }
14164 }14107 }
...@@ -14582,12 +14525,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14582,12 +14525,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14582 try sema.requireRuntimeBlock(block, src, runtime_src);14525 try sema.requireRuntimeBlock(block, src, runtime_src);
1458314526
14584 if (ptr_addrspace) |ptr_as| {14527 if (ptr_addrspace) |ptr_as| {
14585 const alloc_ty = try sema.ptrType(.{14528 const alloc_ty = try mod.ptrTypeSema(.{
14586 .child = result_ty.toIntern(),14529 .child = result_ty.toIntern(),
14587 .flags = .{ .address_space = ptr_as },14530 .flags = .{ .address_space = ptr_as },
14588 });14531 });
14589 const alloc = try block.addTy(.alloc, alloc_ty);14532 const alloc = try block.addTy(.alloc, alloc_ty);
14590 const elem_ptr_ty = try sema.ptrType(.{14533 const elem_ptr_ty = try mod.ptrTypeSema(.{
14591 .child = resolved_elem_ty.toIntern(),14534 .child = resolved_elem_ty.toIntern(),
14592 .flags = .{ .address_space = ptr_as },14535 .flags = .{ .address_space = ptr_as },
14593 });14536 });
...@@ -14670,7 +14613,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins...@@ -14670,7 +14613,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
14670 .none => null,14613 .none => null,
14671 else => Value.fromInterned(ptr_info.sentinel),14614 else => Value.fromInterned(ptr_info.sentinel),
14672 },14615 },
14673 .len = try val.sliceLen(sema),14616 .len = try val.sliceLen(mod),
14674 };14617 };
14675 },14618 },
14676 .One => {14619 .One => {
...@@ -14912,12 +14855,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -14912,12 +14855,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
14912 }14855 }
1491314856
14914 if (ptr_addrspace) |ptr_as| {14857 if (ptr_addrspace) |ptr_as| {
14915 const alloc_ty = try sema.ptrType(.{14858 const alloc_ty = try mod.ptrTypeSema(.{
14916 .child = result_ty.toIntern(),14859 .child = result_ty.toIntern(),
14917 .flags = .{ .address_space = ptr_as },14860 .flags = .{ .address_space = ptr_as },
14918 });14861 });
14919 const alloc = try block.addTy(.alloc, alloc_ty);14862 const alloc = try block.addTy(.alloc, alloc_ty);
14920 const elem_ptr_ty = try sema.ptrType(.{14863 const elem_ptr_ty = try mod.ptrTypeSema(.{
14921 .child = lhs_info.elem_type.toIntern(),14864 .child = lhs_info.elem_type.toIntern(),
14922 .flags = .{ .address_space = ptr_as },14865 .flags = .{ .address_space = ptr_as },
14923 });14866 });
...@@ -15105,7 +15048,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15105,7 +15048,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15105 .Int, .ComptimeInt, .ComptimeFloat => {15048 .Int, .ComptimeInt, .ComptimeFloat => {
15106 if (maybe_lhs_val) |lhs_val| {15049 if (maybe_lhs_val) |lhs_val| {
15107 if (!lhs_val.isUndef(mod)) {15050 if (!lhs_val.isUndef(mod)) {
15108 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {15051 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
15109 const scalar_zero = switch (scalar_tag) {15052 const scalar_zero = switch (scalar_tag) {
15110 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15053 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
15111 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15054 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
...@@ -15120,7 +15063,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15120,7 +15063,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15120 if (rhs_val.isUndef(mod)) {15063 if (rhs_val.isUndef(mod)) {
15121 return sema.failWithUseOfUndef(block, rhs_src);15064 return sema.failWithUseOfUndef(block, rhs_src);
15122 }15065 }
15123 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15066 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15124 return sema.failWithDivideByZero(block, rhs_src);15067 return sema.failWithDivideByZero(block, rhs_src);
15125 }15068 }
15126 // TODO: if the RHS is one, return the LHS directly15069 // TODO: if the RHS is one, return the LHS directly
...@@ -15241,7 +15184,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15241,7 +15184,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15241 if (lhs_val.isUndef(mod)) {15184 if (lhs_val.isUndef(mod)) {
15242 return sema.failWithUseOfUndef(block, rhs_src);15185 return sema.failWithUseOfUndef(block, rhs_src);
15243 } else {15186 } else {
15244 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {15187 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
15245 const scalar_zero = switch (scalar_tag) {15188 const scalar_zero = switch (scalar_tag) {
15246 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15189 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
15247 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15190 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
...@@ -15256,7 +15199,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15256,7 +15199,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15256 if (rhs_val.isUndef(mod)) {15199 if (rhs_val.isUndef(mod)) {
15257 return sema.failWithUseOfUndef(block, rhs_src);15200 return sema.failWithUseOfUndef(block, rhs_src);
15258 }15201 }
15259 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15202 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15260 return sema.failWithDivideByZero(block, rhs_src);15203 return sema.failWithDivideByZero(block, rhs_src);
15261 }15204 }
15262 // TODO: if the RHS is one, return the LHS directly15205 // TODO: if the RHS is one, return the LHS directly
...@@ -15408,7 +15351,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15408,7 +15351,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15408 // If the lhs is undefined, result is undefined.15351 // If the lhs is undefined, result is undefined.
15409 if (maybe_lhs_val) |lhs_val| {15352 if (maybe_lhs_val) |lhs_val| {
15410 if (!lhs_val.isUndef(mod)) {15353 if (!lhs_val.isUndef(mod)) {
15411 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {15354 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
15412 const scalar_zero = switch (scalar_tag) {15355 const scalar_zero = switch (scalar_tag) {
15413 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15356 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
15414 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15357 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
...@@ -15423,7 +15366,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15423,7 +15366,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15423 if (rhs_val.isUndef(mod)) {15366 if (rhs_val.isUndef(mod)) {
15424 return sema.failWithUseOfUndef(block, rhs_src);15367 return sema.failWithUseOfUndef(block, rhs_src);
15425 }15368 }
15426 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15369 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15427 return sema.failWithDivideByZero(block, rhs_src);15370 return sema.failWithDivideByZero(block, rhs_src);
15428 }15371 }
15429 // TODO: if the RHS is one, return the LHS directly15372 // TODO: if the RHS is one, return the LHS directly
...@@ -15518,7 +15461,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15518,7 +15461,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15518 // If the lhs is undefined, result is undefined.15461 // If the lhs is undefined, result is undefined.
15519 if (maybe_lhs_val) |lhs_val| {15462 if (maybe_lhs_val) |lhs_val| {
15520 if (!lhs_val.isUndef(mod)) {15463 if (!lhs_val.isUndef(mod)) {
15521 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {15464 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
15522 const scalar_zero = switch (scalar_tag) {15465 const scalar_zero = switch (scalar_tag) {
15523 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15466 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
15524 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15467 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
...@@ -15533,7 +15476,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -15533,7 +15476,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
15533 if (rhs_val.isUndef(mod)) {15476 if (rhs_val.isUndef(mod)) {
15534 return sema.failWithUseOfUndef(block, rhs_src);15477 return sema.failWithUseOfUndef(block, rhs_src);
15535 }15478 }
15536 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15479 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15537 return sema.failWithDivideByZero(block, rhs_src);15480 return sema.failWithDivideByZero(block, rhs_src);
15538 }15481 }
15539 }15482 }
...@@ -15758,7 +15701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15758,7 +15701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15758 if (lhs_val.isUndef(mod)) {15701 if (lhs_val.isUndef(mod)) {
15759 return sema.failWithUseOfUndef(block, lhs_src);15702 return sema.failWithUseOfUndef(block, lhs_src);
15760 }15703 }
15761 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {15704 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
15762 const scalar_zero = switch (scalar_tag) {15705 const scalar_zero = switch (scalar_tag) {
15763 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),15706 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
15764 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),15707 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
...@@ -15777,18 +15720,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15777,18 +15720,18 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15777 if (rhs_val.isUndef(mod)) {15720 if (rhs_val.isUndef(mod)) {
15778 return sema.failWithUseOfUndef(block, rhs_src);15721 return sema.failWithUseOfUndef(block, rhs_src);
15779 }15722 }
15780 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15723 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15781 return sema.failWithDivideByZero(block, rhs_src);15724 return sema.failWithDivideByZero(block, rhs_src);
15782 }15725 }
15783 if (!(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))) {15726 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {
15784 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);15727 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
15785 }15728 }
15786 if (maybe_lhs_val) |lhs_val| {15729 if (maybe_lhs_val) |lhs_val| {
15787 const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val);15730 const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val);
15788 // If this answer could possibly be different by doing `intMod`,15731 // If this answer could possibly be different by doing `intMod`,
15789 // we must emit a compile error. Otherwise, it's OK.15732 // we must emit a compile error. Otherwise, it's OK.
15790 if (!(try lhs_val.compareAllWithZeroAdvanced(.gte, sema)) and15733 if (!(try lhs_val.compareAllWithZeroSema(.gte, mod)) and
15791 !(try rem_result.compareAllWithZeroAdvanced(.eq, sema)))15734 !(try rem_result.compareAllWithZeroSema(.eq, mod)))
15792 {15735 {
15793 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15736 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15794 }15737 }
...@@ -15806,14 +15749,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -15806,14 +15749,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
15806 if (rhs_val.isUndef(mod)) {15749 if (rhs_val.isUndef(mod)) {
15807 return sema.failWithUseOfUndef(block, rhs_src);15750 return sema.failWithUseOfUndef(block, rhs_src);
15808 }15751 }
15809 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15752 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15810 return sema.failWithDivideByZero(block, rhs_src);15753 return sema.failWithDivideByZero(block, rhs_src);
15811 }15754 }
15812 if (!(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))) {15755 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {
15813 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);15756 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
15814 }15757 }
15815 if (maybe_lhs_val) |lhs_val| {15758 if (maybe_lhs_val) |lhs_val| {
15816 if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroAdvanced(.gte, sema))) {15759 if (lhs_val.isUndef(mod) or !(try lhs_val.compareAllWithZeroSema(.gte, mod))) {
15817 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);15760 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
15818 }15761 }
15819 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern());15762 return Air.internedToRef((try lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod)).toIntern());
...@@ -15864,8 +15807,8 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr...@@ -15864,8 +15807,8 @@ fn intRemScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) CompileErr
15864 // resorting to BigInt first.15807 // resorting to BigInt first.
15865 var lhs_space: Value.BigIntSpace = undefined;15808 var lhs_space: Value.BigIntSpace = undefined;
15866 var rhs_space: Value.BigIntSpace = undefined;15809 var rhs_space: Value.BigIntSpace = undefined;
15867 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);15810 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
15868 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);15811 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
15869 const limbs_q = try sema.arena.alloc(15812 const limbs_q = try sema.arena.alloc(
15870 math.big.Limb,15813 math.big.Limb,
15871 lhs_bigint.limbs.len,15814 lhs_bigint.limbs.len,
...@@ -15941,7 +15884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15941,7 +15884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15941 if (rhs_val.isUndef(mod)) {15884 if (rhs_val.isUndef(mod)) {
15942 return sema.failWithUseOfUndef(block, rhs_src);15885 return sema.failWithUseOfUndef(block, rhs_src);
15943 }15886 }
15944 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15887 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15945 return sema.failWithDivideByZero(block, rhs_src);15888 return sema.failWithDivideByZero(block, rhs_src);
15946 }15889 }
15947 if (maybe_lhs_val) |lhs_val| {15890 if (maybe_lhs_val) |lhs_val| {
...@@ -15957,7 +15900,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -15957,7 +15900,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
15957 if (rhs_val.isUndef(mod)) {15900 if (rhs_val.isUndef(mod)) {
15958 return sema.failWithUseOfUndef(block, rhs_src);15901 return sema.failWithUseOfUndef(block, rhs_src);
15959 }15902 }
15960 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15903 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
15961 return sema.failWithDivideByZero(block, rhs_src);15904 return sema.failWithDivideByZero(block, rhs_src);
15962 }15905 }
15963 }15906 }
...@@ -16036,7 +15979,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -16036,7 +15979,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
16036 if (rhs_val.isUndef(mod)) {15979 if (rhs_val.isUndef(mod)) {
16037 return sema.failWithUseOfUndef(block, rhs_src);15980 return sema.failWithUseOfUndef(block, rhs_src);
16038 }15981 }
16039 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15982 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
16040 return sema.failWithDivideByZero(block, rhs_src);15983 return sema.failWithDivideByZero(block, rhs_src);
16041 }15984 }
16042 if (maybe_lhs_val) |lhs_val| {15985 if (maybe_lhs_val) |lhs_val| {
...@@ -16052,7 +15995,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins...@@ -16052,7 +15995,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
16052 if (rhs_val.isUndef(mod)) {15995 if (rhs_val.isUndef(mod)) {
16053 return sema.failWithUseOfUndef(block, rhs_src);15996 return sema.failWithUseOfUndef(block, rhs_src);
16054 }15997 }
16055 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {15998 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
16056 return sema.failWithDivideByZero(block, rhs_src);15999 return sema.failWithDivideByZero(block, rhs_src);
16057 }16000 }
16058 }16001 }
...@@ -16139,12 +16082,12 @@ fn zirOverflowArithmetic(...@@ -16139,12 +16082,12 @@ fn zirOverflowArithmetic(
16139 // to the result, even if it is undefined..16082 // to the result, even if it is undefined..
16140 // Otherwise, if either of the argument is undefined, undefined is returned.16083 // Otherwise, if either of the argument is undefined, undefined is returned.
16141 if (maybe_lhs_val) |lhs_val| {16084 if (maybe_lhs_val) |lhs_val| {
16142 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {16085 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {
16143 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };16086 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
16144 }16087 }
16145 }16088 }
16146 if (maybe_rhs_val) |rhs_val| {16089 if (maybe_rhs_val) |rhs_val| {
16147 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {16090 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) {
16148 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16091 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16149 }16092 }
16150 }16093 }
...@@ -16165,7 +16108,7 @@ fn zirOverflowArithmetic(...@@ -16165,7 +16108,7 @@ fn zirOverflowArithmetic(
16165 if (maybe_rhs_val) |rhs_val| {16108 if (maybe_rhs_val) |rhs_val| {
16166 if (rhs_val.isUndef(mod)) {16109 if (rhs_val.isUndef(mod)) {
16167 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };16110 break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef };
16168 } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16111 } else if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16169 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16112 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16170 } else if (maybe_lhs_val) |lhs_val| {16113 } else if (maybe_lhs_val) |lhs_val| {
16171 if (lhs_val.isUndef(mod)) {16114 if (lhs_val.isUndef(mod)) {
...@@ -16184,7 +16127,7 @@ fn zirOverflowArithmetic(...@@ -16184,7 +16127,7 @@ fn zirOverflowArithmetic(
16184 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);16127 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);
16185 if (maybe_lhs_val) |lhs_val| {16128 if (maybe_lhs_val) |lhs_val| {
16186 if (!lhs_val.isUndef(mod)) {16129 if (!lhs_val.isUndef(mod)) {
16187 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16130 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
16188 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16131 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16189 } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {16132 } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
16190 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };16133 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
...@@ -16194,7 +16137,7 @@ fn zirOverflowArithmetic(...@@ -16194,7 +16137,7 @@ fn zirOverflowArithmetic(
1619416137
16195 if (maybe_rhs_val) |rhs_val| {16138 if (maybe_rhs_val) |rhs_val| {
16196 if (!rhs_val.isUndef(mod)) {16139 if (!rhs_val.isUndef(mod)) {
16197 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16140 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16198 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };16141 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
16199 } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {16142 } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
16200 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16143 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
...@@ -16218,12 +16161,12 @@ fn zirOverflowArithmetic(...@@ -16218,12 +16161,12 @@ fn zirOverflowArithmetic(
16218 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.16161 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.
16219 // Oterhwise if either of the arguments is undefined, both results are undefined.16162 // Oterhwise if either of the arguments is undefined, both results are undefined.
16220 if (maybe_lhs_val) |lhs_val| {16163 if (maybe_lhs_val) |lhs_val| {
16221 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {16164 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {
16222 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16165 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16223 }16166 }
16224 }16167 }
16225 if (maybe_rhs_val) |rhs_val| {16168 if (maybe_rhs_val) |rhs_val| {
16226 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) {16169 if (!rhs_val.isUndef(mod) and (try rhs_val.compareAllWithZeroSema(.eq, mod))) {
16227 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };16170 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
16228 }16171 }
16229 }16172 }
...@@ -16374,7 +16317,7 @@ fn analyzeArithmetic(...@@ -16374,7 +16317,7 @@ fn analyzeArithmetic(
16374 // overflow (max_int), causing illegal behavior.16317 // overflow (max_int), causing illegal behavior.
16375 // For floats: either operand being undef makes the result undef.16318 // For floats: either operand being undef makes the result undef.
16376 if (maybe_lhs_val) |lhs_val| {16319 if (maybe_lhs_val) |lhs_val| {
16377 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {16320 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {
16378 return casted_rhs;16321 return casted_rhs;
16379 }16322 }
16380 }16323 }
...@@ -16386,7 +16329,7 @@ fn analyzeArithmetic(...@@ -16386,7 +16329,7 @@ fn analyzeArithmetic(
16386 return mod.undefRef(resolved_type);16329 return mod.undefRef(resolved_type);
16387 }16330 }
16388 }16331 }
16389 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16332 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16390 return casted_lhs;16333 return casted_lhs;
16391 }16334 }
16392 }16335 }
...@@ -16418,7 +16361,7 @@ fn analyzeArithmetic(...@@ -16418,7 +16361,7 @@ fn analyzeArithmetic(
16418 // If either of the operands are zero, the other operand is returned.16361 // If either of the operands are zero, the other operand is returned.
16419 // If either of the operands are undefined, the result is undefined.16362 // If either of the operands are undefined, the result is undefined.
16420 if (maybe_lhs_val) |lhs_val| {16363 if (maybe_lhs_val) |lhs_val| {
16421 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {16364 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {
16422 return casted_rhs;16365 return casted_rhs;
16423 }16366 }
16424 }16367 }
...@@ -16426,7 +16369,7 @@ fn analyzeArithmetic(...@@ -16426,7 +16369,7 @@ fn analyzeArithmetic(
16426 if (rhs_val.isUndef(mod)) {16369 if (rhs_val.isUndef(mod)) {
16427 return mod.undefRef(resolved_type);16370 return mod.undefRef(resolved_type);
16428 }16371 }
16429 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16372 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16430 return casted_lhs;16373 return casted_lhs;
16431 }16374 }
16432 if (maybe_lhs_val) |lhs_val| {16375 if (maybe_lhs_val) |lhs_val| {
...@@ -16439,7 +16382,7 @@ fn analyzeArithmetic(...@@ -16439,7 +16382,7 @@ fn analyzeArithmetic(
16439 // If either of the operands are zero, then the other operand is returned.16382 // If either of the operands are zero, then the other operand is returned.
16440 // If either of the operands are undefined, the result is undefined.16383 // If either of the operands are undefined, the result is undefined.
16441 if (maybe_lhs_val) |lhs_val| {16384 if (maybe_lhs_val) |lhs_val| {
16442 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) {16385 if (!lhs_val.isUndef(mod) and (try lhs_val.compareAllWithZeroSema(.eq, mod))) {
16443 return casted_rhs;16386 return casted_rhs;
16444 }16387 }
16445 }16388 }
...@@ -16447,7 +16390,7 @@ fn analyzeArithmetic(...@@ -16447,7 +16390,7 @@ fn analyzeArithmetic(
16447 if (rhs_val.isUndef(mod)) {16390 if (rhs_val.isUndef(mod)) {
16448 return mod.undefRef(resolved_type);16391 return mod.undefRef(resolved_type);
16449 }16392 }
16450 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16393 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16451 return casted_lhs;16394 return casted_lhs;
16452 }16395 }
16453 if (maybe_lhs_val) |lhs_val| {16396 if (maybe_lhs_val) |lhs_val| {
...@@ -16488,7 +16431,7 @@ fn analyzeArithmetic(...@@ -16488,7 +16431,7 @@ fn analyzeArithmetic(
16488 return mod.undefRef(resolved_type);16431 return mod.undefRef(resolved_type);
16489 }16432 }
16490 }16433 }
16491 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16434 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16492 return casted_lhs;16435 return casted_lhs;
16493 }16436 }
16494 }16437 }
...@@ -16523,7 +16466,7 @@ fn analyzeArithmetic(...@@ -16523,7 +16466,7 @@ fn analyzeArithmetic(
16523 if (rhs_val.isUndef(mod)) {16466 if (rhs_val.isUndef(mod)) {
16524 return mod.undefRef(resolved_type);16467 return mod.undefRef(resolved_type);
16525 }16468 }
16526 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16469 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16527 return casted_lhs;16470 return casted_lhs;
16528 }16471 }
16529 }16472 }
...@@ -16544,7 +16487,7 @@ fn analyzeArithmetic(...@@ -16544,7 +16487,7 @@ fn analyzeArithmetic(
16544 if (rhs_val.isUndef(mod)) {16487 if (rhs_val.isUndef(mod)) {
16545 return mod.undefRef(resolved_type);16488 return mod.undefRef(resolved_type);
16546 }16489 }
16547 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16490 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16548 return casted_lhs;16491 return casted_lhs;
16549 }16492 }
16550 }16493 }
...@@ -16591,7 +16534,7 @@ fn analyzeArithmetic(...@@ -16591,7 +16534,7 @@ fn analyzeArithmetic(
16591 if (lhs_val.isNan(mod)) {16534 if (lhs_val.isNan(mod)) {
16592 return Air.internedToRef(lhs_val.toIntern());16535 return Air.internedToRef(lhs_val.toIntern());
16593 }16536 }
16594 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) lz: {16537 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) lz: {
16595 if (maybe_rhs_val) |rhs_val| {16538 if (maybe_rhs_val) |rhs_val| {
16596 if (rhs_val.isNan(mod)) {16539 if (rhs_val.isNan(mod)) {
16597 return Air.internedToRef(rhs_val.toIntern());16540 return Air.internedToRef(rhs_val.toIntern());
...@@ -16622,7 +16565,7 @@ fn analyzeArithmetic(...@@ -16622,7 +16565,7 @@ fn analyzeArithmetic(
16622 if (rhs_val.isNan(mod)) {16565 if (rhs_val.isNan(mod)) {
16623 return Air.internedToRef(rhs_val.toIntern());16566 return Air.internedToRef(rhs_val.toIntern());
16624 }16567 }
16625 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) rz: {16568 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) rz: {
16626 if (maybe_lhs_val) |lhs_val| {16569 if (maybe_lhs_val) |lhs_val| {
16627 if (lhs_val.isInf(mod)) {16570 if (lhs_val.isInf(mod)) {
16628 return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern());16571 return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern());
...@@ -16674,7 +16617,7 @@ fn analyzeArithmetic(...@@ -16674,7 +16617,7 @@ fn analyzeArithmetic(
16674 };16617 };
16675 if (maybe_lhs_val) |lhs_val| {16618 if (maybe_lhs_val) |lhs_val| {
16676 if (!lhs_val.isUndef(mod)) {16619 if (!lhs_val.isUndef(mod)) {
16677 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16620 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
16678 const zero_val = try sema.splat(resolved_type, scalar_zero);16621 const zero_val = try sema.splat(resolved_type, scalar_zero);
16679 return Air.internedToRef(zero_val.toIntern());16622 return Air.internedToRef(zero_val.toIntern());
16680 }16623 }
...@@ -16687,7 +16630,7 @@ fn analyzeArithmetic(...@@ -16687,7 +16630,7 @@ fn analyzeArithmetic(
16687 if (rhs_val.isUndef(mod)) {16630 if (rhs_val.isUndef(mod)) {
16688 return mod.undefRef(resolved_type);16631 return mod.undefRef(resolved_type);
16689 }16632 }
16690 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16633 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16691 const zero_val = try sema.splat(resolved_type, scalar_zero);16634 const zero_val = try sema.splat(resolved_type, scalar_zero);
16692 return Air.internedToRef(zero_val.toIntern());16635 return Air.internedToRef(zero_val.toIntern());
16693 }16636 }
...@@ -16719,7 +16662,7 @@ fn analyzeArithmetic(...@@ -16719,7 +16662,7 @@ fn analyzeArithmetic(
16719 };16662 };
16720 if (maybe_lhs_val) |lhs_val| {16663 if (maybe_lhs_val) |lhs_val| {
16721 if (!lhs_val.isUndef(mod)) {16664 if (!lhs_val.isUndef(mod)) {
16722 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16665 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
16723 const zero_val = try sema.splat(resolved_type, scalar_zero);16666 const zero_val = try sema.splat(resolved_type, scalar_zero);
16724 return Air.internedToRef(zero_val.toIntern());16667 return Air.internedToRef(zero_val.toIntern());
16725 }16668 }
...@@ -16732,7 +16675,7 @@ fn analyzeArithmetic(...@@ -16732,7 +16675,7 @@ fn analyzeArithmetic(
16732 if (rhs_val.isUndef(mod)) {16675 if (rhs_val.isUndef(mod)) {
16733 return mod.undefRef(resolved_type);16676 return mod.undefRef(resolved_type);
16734 }16677 }
16735 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {16678 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
16736 const zero_val = try sema.splat(resolved_type, scalar_zero);16679 const zero_val = try sema.splat(resolved_type, scalar_zero);
16737 return Air.internedToRef(zero_val.toIntern());16680 return Air.internedToRef(zero_val.toIntern());
16738 }16681 }
...@@ -16828,7 +16771,7 @@ fn analyzePtrArithmetic(...@@ -16828,7 +16771,7 @@ fn analyzePtrArithmetic(
1682816771
16829 const new_ptr_ty = t: {16772 const new_ptr_ty = t: {
16830 // Calculate the new pointer alignment.16773 // Calculate the new pointer alignment.
16831 // This code is duplicated in `elemPtrType`.16774 // This code is duplicated in `Type.elemPtrType`.
16832 if (ptr_info.flags.alignment == .none) {16775 if (ptr_info.flags.alignment == .none) {
16833 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.16776 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
16834 break :t ptr_ty;16777 break :t ptr_ty;
...@@ -16837,7 +16780,7 @@ fn analyzePtrArithmetic(...@@ -16837,7 +16780,7 @@ fn analyzePtrArithmetic(
16837 // it being a multiple of the type size.16780 // it being a multiple of the type size.
16838 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));16781 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));
16839 const addend = if (opt_off_val) |off_val| a: {16782 const addend = if (opt_off_val) |off_val| a: {
16840 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntAdvanced(sema));16783 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntSema(mod));
16841 break :a elem_size * off_int;16784 break :a elem_size * off_int;
16842 } else elem_size;16785 } else elem_size;
1684316786
...@@ -16850,7 +16793,7 @@ fn analyzePtrArithmetic(...@@ -16850,7 +16793,7 @@ fn analyzePtrArithmetic(
16850 ));16793 ));
16851 assert(new_align != .none);16794 assert(new_align != .none);
1685216795
16853 break :t try sema.ptrType(.{16796 break :t try mod.ptrTypeSema(.{
16854 .child = ptr_info.child,16797 .child = ptr_info.child,
16855 .sentinel = ptr_info.sentinel,16798 .sentinel = ptr_info.sentinel,
16856 .flags = .{16799 .flags = .{
...@@ -16869,14 +16812,14 @@ fn analyzePtrArithmetic(...@@ -16869,14 +16812,14 @@ fn analyzePtrArithmetic(
16869 if (opt_off_val) |offset_val| {16812 if (opt_off_val) |offset_val| {
16870 if (ptr_val.isUndef(mod)) return mod.undefRef(new_ptr_ty);16813 if (ptr_val.isUndef(mod)) return mod.undefRef(new_ptr_ty);
1687116814
16872 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntAdvanced(sema));16815 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntSema(mod));
16873 if (offset_int == 0) return ptr;16816 if (offset_int == 0) return ptr;
16874 if (air_tag == .ptr_sub) {16817 if (air_tag == .ptr_sub) {
16875 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));16818 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));
16876 const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty);16819 const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty);
16877 return Air.internedToRef(new_ptr_val.toIntern());16820 return Air.internedToRef(new_ptr_val.toIntern());
16878 } else {16821 } else {
16879 const new_ptr_val = try mod.getCoerced(try ptr_val.ptrElem(offset_int, sema), new_ptr_ty);16822 const new_ptr_val = try mod.getCoerced(try ptr_val.ptrElem(offset_int, mod), new_ptr_ty);
16880 return Air.internedToRef(new_ptr_val.toIntern());16823 return Air.internedToRef(new_ptr_val.toIntern());
16881 }16824 }
16882 } else break :rs offset_src;16825 } else break :rs offset_src;
...@@ -16975,7 +16918,6 @@ fn zirAsm(...@@ -16975,7 +16918,6 @@ fn zirAsm(
16975 // Indicate the output is the asm instruction return value.16918 // Indicate the output is the asm instruction return value.
16976 arg.* = .none;16919 arg.* = .none;
16977 const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);16920 const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
16978 try sema.queueFullTypeResolution(out_ty);
16979 expr_ty = Air.internedToRef(out_ty.toIntern());16921 expr_ty = Air.internedToRef(out_ty.toIntern());
16980 } else {16922 } else {
16981 arg.* = try sema.resolveInst(output.data.operand);16923 arg.* = try sema.resolveInst(output.data.operand);
...@@ -17010,7 +16952,6 @@ fn zirAsm(...@@ -17010,7 +16952,6 @@ fn zirAsm(
17010 .ComptimeFloat => arg.* = try sema.coerce(block, Type.f64, uncasted_arg, src),16952 .ComptimeFloat => arg.* = try sema.coerce(block, Type.f64, uncasted_arg, src),
17011 else => {16953 else => {
17012 arg.* = uncasted_arg;16954 arg.* = uncasted_arg;
17013 try sema.queueFullTypeResolution(uncasted_arg_ty);
17014 },16955 },
17015 }16956 }
1701616957
...@@ -17169,7 +17110,7 @@ fn analyzeCmpUnionTag(...@@ -17169,7 +17110,7 @@ fn analyzeCmpUnionTag(
17169) CompileError!Air.Inst.Ref {17110) CompileError!Air.Inst.Ref {
17170 const mod = sema.mod;17111 const mod = sema.mod;
17171 const union_ty = sema.typeOf(un);17112 const union_ty = sema.typeOf(un);
17172 try sema.resolveTypeFields(union_ty);17113 try union_ty.resolveFields(mod);
17173 const union_tag_ty = union_ty.unionTagType(mod) orelse {17114 const union_tag_ty = union_ty.unionTagType(mod) orelse {
17174 const msg = msg: {17115 const msg = msg: {
17175 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});17116 const msg = try sema.errMsg(un_src, "comparison of union and enum literal is only valid for tagged union types", .{});
...@@ -17385,9 +17326,6 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -17385,9 +17326,6 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
17385 => {},17326 => {},
17386 }17327 }
17387 const val = try ty.lazyAbiSize(mod);17328 const val = try ty.lazyAbiSize(mod);
17388 if (val.isLazySize(mod)) {
17389 try sema.queueFullTypeResolution(ty);
17390 }
17391 return Air.internedToRef(val.toIntern());17329 return Air.internedToRef(val.toIntern());
17392}17330}
1739317331
...@@ -17427,7 +17365,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -17427,7 +17365,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
17427 .AnyFrame,17365 .AnyFrame,
17428 => {},17366 => {},
17429 }17367 }
17430 const bit_size = try operand_ty.bitSizeAdvanced(mod, sema);17368 const bit_size = try operand_ty.bitSizeAdvanced(mod, .sema);
17431 return mod.intRef(Type.comptime_int, bit_size);17369 return mod.intRef(Type.comptime_int, bit_size);
17432}17370}
1743317371
...@@ -17613,7 +17551,7 @@ fn zirBuiltinSrc(...@@ -17613,7 +17551,7 @@ fn zirBuiltinSrc(
17613 } });17551 } });
17614 };17552 };
1761517553
17616 const src_loc_ty = try sema.getBuiltinType("SourceLocation");17554 const src_loc_ty = try mod.getBuiltinType("SourceLocation");
17617 const fields = .{17555 const fields = .{
17618 // file: [:0]const u8,17556 // file: [:0]const u8,
17619 file_name_val,17557 file_name_val,
...@@ -17637,7 +17575,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17637,7 +17575,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17637 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;17575 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
17638 const src = block.nodeOffset(inst_data.src_node);17576 const src = block.nodeOffset(inst_data.src_node);
17639 const ty = try sema.resolveType(block, src, inst_data.operand);17577 const ty = try sema.resolveType(block, src, inst_data.operand);
17640 const type_info_ty = try sema.getBuiltinType("Type");17578 const type_info_ty = try mod.getBuiltinType("Type");
17641 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;17579 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;
1764217580
17643 if (ty.typeDeclInst(mod)) |type_decl_inst| {17581 if (ty.typeDeclInst(mod)) |type_decl_inst| {
...@@ -17718,7 +17656,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17718,7 +17656,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17718 .ty = new_decl_ty.toIntern(),17656 .ty = new_decl_ty.toIntern(),
17719 .storage = .{ .elems = param_vals },17657 .storage = .{ .elems = param_vals },
17720 } });17658 } });
17721 const slice_ty = (try sema.ptrType(.{17659 const slice_ty = (try mod.ptrTypeSema(.{
17722 .child = param_info_ty.toIntern(),17660 .child = param_info_ty.toIntern(),
17723 .flags = .{17661 .flags = .{
17724 .size = .Slice,17662 .size = .Slice,
...@@ -17748,7 +17686,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17748,7 +17686,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17748 func_ty_info.return_type,17686 func_ty_info.return_type,
17749 } });17687 } });
1775017688
17751 const callconv_ty = try sema.getBuiltinType("CallingConvention");17689 const callconv_ty = try mod.getBuiltinType("CallingConvention");
1775217690
17753 const field_values = .{17691 const field_values = .{
17754 // calling_convention: CallingConvention,17692 // calling_convention: CallingConvention,
...@@ -17782,7 +17720,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17782,7 +17720,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17782 const int_info_decl = mod.declPtr(int_info_decl_index);17720 const int_info_decl = mod.declPtr(int_info_decl_index);
17783 const int_info_ty = int_info_decl.val.toType();17721 const int_info_ty = int_info_decl.val.toType();
1778417722
17785 const signedness_ty = try sema.getBuiltinType("Signedness");17723 const signedness_ty = try mod.getBuiltinType("Signedness");
17786 const info = ty.intInfo(mod);17724 const info = ty.intInfo(mod);
17787 const field_values = .{17725 const field_values = .{
17788 // signedness: Signedness,17726 // signedness: Signedness,
...@@ -17830,12 +17768,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17830,12 +17768,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17830 else17768 else
17831 try Type.fromInterned(info.child).lazyAbiAlignment(mod);17769 try Type.fromInterned(info.child).lazyAbiAlignment(mod);
1783217770
17833 const addrspace_ty = try sema.getBuiltinType("AddressSpace");17771 const addrspace_ty = try mod.getBuiltinType("AddressSpace");
17834 const pointer_ty = t: {17772 const pointer_ty = t: {
17835 const decl_index = (try sema.namespaceLookup(17773 const decl_index = (try sema.namespaceLookup(
17836 block,17774 block,
17837 src,17775 src,
17838 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod),17776 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),
17839 try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls),17777 try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls),
17840 )).?;17778 )).?;
17841 try sema.ensureDeclAnalyzed(decl_index);17779 try sema.ensureDeclAnalyzed(decl_index);
...@@ -17984,8 +17922,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17984,8 +17922,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17984 break :t set_field_ty_decl.val.toType();17922 break :t set_field_ty_decl.val.toType();
17985 };17923 };
1798617924
17987 try sema.queueFullTypeResolution(error_field_ty);
17988
17989 // Build our list of Error values17925 // Build our list of Error values
17990 // Optional value is only null if anyerror17926 // Optional value is only null if anyerror
17991 // Value can be zero-length slice otherwise17927 // Value can be zero-length slice otherwise
...@@ -18036,7 +17972,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18036,7 +17972,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18036 };17972 };
1803717973
18038 // Build our ?[]const Error value17974 // Build our ?[]const Error value
18039 const slice_errors_ty = try sema.ptrType(.{17975 const slice_errors_ty = try mod.ptrTypeSema(.{
18040 .child = error_field_ty.toIntern(),17976 .child = error_field_ty.toIntern(),
18041 .flags = .{17977 .flags = .{
18042 .size = .Slice,17978 .size = .Slice,
...@@ -18182,7 +18118,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18182,7 +18118,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18182 .ty = fields_array_ty.toIntern(),18118 .ty = fields_array_ty.toIntern(),
18183 .storage = .{ .elems = enum_field_vals },18119 .storage = .{ .elems = enum_field_vals },
18184 } });18120 } });
18185 const slice_ty = (try sema.ptrType(.{18121 const slice_ty = (try mod.ptrTypeSema(.{
18186 .child = enum_field_ty.toIntern(),18122 .child = enum_field_ty.toIntern(),
18187 .flags = .{18123 .flags = .{
18188 .size = .Slice,18124 .size = .Slice,
...@@ -18262,7 +18198,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18262,7 +18198,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18262 break :t union_field_ty_decl.val.toType();18198 break :t union_field_ty_decl.val.toType();
18263 };18199 };
1826418200
18265 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout18201 try ty.resolveLayout(mod); // Getting alignment requires type layout
18266 const union_obj = mod.typeToUnion(ty).?;18202 const union_obj = mod.typeToUnion(ty).?;
18267 const tag_type = union_obj.loadTagType(ip);18203 const tag_type = union_obj.loadTagType(ip);
18268 const layout = union_obj.getLayout(ip);18204 const layout = union_obj.getLayout(ip);
...@@ -18298,7 +18234,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18298,7 +18234,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18298 };18234 };
1829918235
18300 const alignment = switch (layout) {18236 const alignment = switch (layout) {
18301 .auto, .@"extern" => try sema.unionFieldAlignment(union_obj, @intCast(field_index)),18237 .auto, .@"extern" => try mod.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(field_index), .sema),
18302 .@"packed" => .none,18238 .@"packed" => .none,
18303 };18239 };
1830418240
...@@ -18326,7 +18262,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18326,7 +18262,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18326 .ty = array_fields_ty.toIntern(),18262 .ty = array_fields_ty.toIntern(),
18327 .storage = .{ .elems = union_field_vals },18263 .storage = .{ .elems = union_field_vals },
18328 } });18264 } });
18329 const slice_ty = (try sema.ptrType(.{18265 const slice_ty = (try mod.ptrTypeSema(.{
18330 .child = union_field_ty.toIntern(),18266 .child = union_field_ty.toIntern(),
18331 .flags = .{18267 .flags = .{
18332 .size = .Slice,18268 .size = .Slice,
...@@ -18359,7 +18295,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18359,7 +18295,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18359 const decl_index = (try sema.namespaceLookup(18295 const decl_index = (try sema.namespaceLookup(
18360 block,18296 block,
18361 src,18297 src,
18362 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod),18298 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),
18363 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),18299 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
18364 )).?;18300 )).?;
18365 try sema.ensureDeclAnalyzed(decl_index);18301 try sema.ensureDeclAnalyzed(decl_index);
...@@ -18412,7 +18348,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18412,7 +18348,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18412 break :t struct_field_ty_decl.val.toType();18348 break :t struct_field_ty_decl.val.toType();
18413 };18349 };
1841418350
18415 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout18351 try ty.resolveLayout(mod); // Getting alignment requires type layout
1841618352
18417 var struct_field_vals: []InternPool.Index = &.{};18353 var struct_field_vals: []InternPool.Index = &.{};
18418 defer gpa.free(struct_field_vals);18354 defer gpa.free(struct_field_vals);
...@@ -18452,7 +18388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18452,7 +18388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18452 } });18388 } });
18453 };18389 };
1845418390
18455 try sema.resolveTypeLayout(Type.fromInterned(field_ty));18391 try Type.fromInterned(field_ty).resolveLayout(mod);
1845618392
18457 const is_comptime = field_val != .none;18393 const is_comptime = field_val != .none;
18458 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;18394 const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null;
...@@ -18481,7 +18417,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18481,7 +18417,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18481 };18417 };
18482 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);18418 struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len);
1848318419
18484 try sema.resolveStructFieldInits(ty);18420 try ty.resolveStructFieldInits(mod);
1848518421
18486 for (struct_field_vals, 0..) |*field_val, field_index| {18422 for (struct_field_vals, 0..) |*field_val, field_index| {
18487 const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name|18423 const field_name = if (struct_type.fieldName(ip, field_index).unwrap()) |field_name|
...@@ -18520,10 +18456,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18520,10 +18456,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18520 const default_val_ptr = try sema.optRefValue(opt_default_val);18456 const default_val_ptr = try sema.optRefValue(opt_default_val);
18521 const alignment = switch (struct_type.layout) {18457 const alignment = switch (struct_type.layout) {
18522 .@"packed" => .none,18458 .@"packed" => .none,
18523 else => try sema.structFieldAlignment(18459 else => try mod.structFieldAlignmentAdvanced(
18524 struct_type.fieldAlign(ip, field_index),18460 struct_type.fieldAlign(ip, field_index),
18525 field_ty,18461 field_ty,
18526 struct_type.layout,18462 struct_type.layout,
18463 .sema,
18527 ),18464 ),
18528 };18465 };
1852918466
...@@ -18555,7 +18492,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18555,7 +18492,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18555 .ty = array_fields_ty.toIntern(),18492 .ty = array_fields_ty.toIntern(),
18556 .storage = .{ .elems = struct_field_vals },18493 .storage = .{ .elems = struct_field_vals },
18557 } });18494 } });
18558 const slice_ty = (try sema.ptrType(.{18495 const slice_ty = (try mod.ptrTypeSema(.{
18559 .child = struct_field_ty.toIntern(),18496 .child = struct_field_ty.toIntern(),
18560 .flags = .{18497 .flags = .{
18561 .size = .Slice,18498 .size = .Slice,
...@@ -18591,7 +18528,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18591,7 +18528,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18591 const decl_index = (try sema.namespaceLookup(18528 const decl_index = (try sema.namespaceLookup(
18592 block,18529 block,
18593 src,18530 src,
18594 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod),18531 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),
18595 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),18532 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
18596 )).?;18533 )).?;
18597 try sema.ensureDeclAnalyzed(decl_index);18534 try sema.ensureDeclAnalyzed(decl_index);
...@@ -18635,7 +18572,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18635,7 +18572,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18635 break :t type_opaque_ty_decl.val.toType();18572 break :t type_opaque_ty_decl.val.toType();
18636 };18573 };
1863718574
18638 try sema.resolveTypeFields(ty);18575 try ty.resolveFields(mod);
18639 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));18576 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1864018577
18641 const field_values = .{18578 const field_values = .{
...@@ -18677,7 +18614,6 @@ fn typeInfoDecls(...@@ -18677,7 +18614,6 @@ fn typeInfoDecls(
18677 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);18614 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
18678 break :t declaration_ty_decl.val.toType();18615 break :t declaration_ty_decl.val.toType();
18679 };18616 };
18680 try sema.queueFullTypeResolution(declaration_ty);
1868118617
18682 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);18618 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
18683 defer decl_vals.deinit();18619 defer decl_vals.deinit();
...@@ -18695,7 +18631,7 @@ fn typeInfoDecls(...@@ -18695,7 +18631,7 @@ fn typeInfoDecls(
18695 .ty = array_decl_ty.toIntern(),18631 .ty = array_decl_ty.toIntern(),
18696 .storage = .{ .elems = decl_vals.items },18632 .storage = .{ .elems = decl_vals.items },
18697 } });18633 } });
18698 const slice_ty = (try sema.ptrType(.{18634 const slice_ty = (try mod.ptrTypeSema(.{
18699 .child = declaration_ty.toIntern(),18635 .child = declaration_ty.toIntern(),
18700 .flags = .{18636 .flags = .{
18701 .size = .Slice,18637 .size = .Slice,
...@@ -19295,7 +19231,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -19295,7 +19231,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1929519231
19296 const operand_ty = sema.typeOf(operand);19232 const operand_ty = sema.typeOf(operand);
19297 const ptr_info = operand_ty.ptrInfo(mod);19233 const ptr_info = operand_ty.ptrInfo(mod);
19298 const res_ty = try sema.ptrType(.{19234 const res_ty = try mod.ptrTypeSema(.{
19299 .child = err_union_ty.errorUnionPayload(mod).toIntern(),19235 .child = err_union_ty.errorUnionPayload(mod).toIntern(),
19300 .flags = .{19236 .flags = .{
19301 .is_const = ptr_info.flags.is_const,19237 .is_const = ptr_info.flags.is_const,
...@@ -19528,11 +19464,11 @@ fn retWithErrTracing(...@@ -19528,11 +19464,11 @@ fn retWithErrTracing(
19528 else => true,19464 else => true,
19529 };19465 };
19530 const gpa = sema.gpa;19466 const gpa = sema.gpa;
19531 const stack_trace_ty = try sema.getBuiltinType("StackTrace");19467 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
19532 try sema.resolveTypeFields(stack_trace_ty);19468 try stack_trace_ty.resolveFields(mod);
19533 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);19469 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
19534 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);19470 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
19535 const return_err_fn = try sema.getBuiltin("returnError");19471 const return_err_fn = try mod.getBuiltin("returnError");
19536 const args: [1]Air.Inst.Ref = .{err_return_trace};19472 const args: [1]Air.Inst.Ref = .{err_return_trace};
1953719473
19538 if (!need_check) {19474 if (!need_check) {
...@@ -19735,7 +19671,7 @@ fn analyzeRet(...@@ -19735,7 +19671,7 @@ fn analyzeRet(
19735 return sema.failWithOwnedErrorMsg(block, msg);19671 return sema.failWithOwnedErrorMsg(block, msg);
19736 }19672 }
1973719673
19738 try sema.resolveTypeLayout(sema.fn_ret_ty);19674 try sema.fn_ret_ty.resolveLayout(mod);
1973919675
19740 try sema.validateRuntimeValue(block, operand_src, operand);19676 try sema.validateRuntimeValue(block, operand_src, operand);
1974119677
...@@ -19817,7 +19753,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19817,7 +19753,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19817 },19753 },
19818 else => {},19754 else => {},
19819 }19755 }
19820 const align_bytes = (try val.getUnsignedIntAdvanced(mod, sema)).?;19756 const align_bytes = (try val.getUnsignedIntAdvanced(mod, .sema)).?;
19821 break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes);19757 break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes);
19822 } else .none;19758 } else .none;
1982319759
...@@ -19851,7 +19787,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19851,7 +19787,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19851 elem_ty.fmt(mod), bit_offset, bit_offset - host_size * 8, host_size,19787 elem_ty.fmt(mod), bit_offset, bit_offset - host_size * 8, host_size,
19852 });19788 });
19853 }19789 }
19854 const elem_bit_size = try elem_ty.bitSizeAdvanced(mod, sema);19790 const elem_bit_size = try elem_ty.bitSizeAdvanced(mod, .sema);
19855 if (elem_bit_size > host_size * 8 - bit_offset) {19791 if (elem_bit_size > host_size * 8 - bit_offset) {
19856 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{19792 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{
19857 elem_ty.fmt(mod), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,19793 elem_ty.fmt(mod), bit_offset, elem_bit_size - (host_size * 8 - bit_offset), host_size,
...@@ -19892,7 +19828,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -19892,7 +19828,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
19892 });19828 });
19893 }19829 }
1989419830
19895 const ty = try sema.ptrType(.{19831 const ty = try mod.ptrTypeSema(.{
19896 .child = elem_ty.toIntern(),19832 .child = elem_ty.toIntern(),
19897 .sentinel = sentinel,19833 .sentinel = sentinel,
19898 .flags = .{19834 .flags = .{
...@@ -19983,7 +19919,7 @@ fn structInitEmpty(...@@ -19983,7 +19919,7 @@ fn structInitEmpty(
19983 const mod = sema.mod;19919 const mod = sema.mod;
19984 const gpa = sema.gpa;19920 const gpa = sema.gpa;
19985 // This logic must be synchronized with that in `zirStructInit`.19921 // This logic must be synchronized with that in `zirStructInit`.
19986 try sema.resolveTypeFields(struct_ty);19922 try struct_ty.resolveFields(mod);
1998719923
19988 // The init values to use for the struct instance.19924 // The init values to use for the struct instance.
19989 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));19925 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));
...@@ -20054,7 +19990,6 @@ fn unionInit(...@@ -20054,7 +19990,6 @@ fn unionInit(
2005419990
20055 try sema.requireRuntimeBlock(block, init_src, null);19991 try sema.requireRuntimeBlock(block, init_src, null);
20056 _ = union_ty_src;19992 _ = union_ty_src;
20057 try sema.queueFullTypeResolution(union_ty);
20058 return block.addUnionInit(union_ty, field_index, init);19993 return block.addUnionInit(union_ty, field_index, init);
20059}19994}
2006019995
...@@ -20083,7 +20018,7 @@ fn zirStructInit(...@@ -20083,7 +20018,7 @@ fn zirStructInit(
20083 else => |e| return e,20018 else => |e| return e,
20084 };20019 };
20085 const resolved_ty = result_ty.optEuBaseType(mod);20020 const resolved_ty = result_ty.optEuBaseType(mod);
20086 try sema.resolveTypeLayout(resolved_ty);20021 try resolved_ty.resolveLayout(mod);
2008720022
20088 if (resolved_ty.zigTypeTag(mod) == .Struct) {20023 if (resolved_ty.zigTypeTag(mod) == .Struct) {
20089 // This logic must be synchronized with that in `zirStructInitEmpty`.20024 // This logic must be synchronized with that in `zirStructInitEmpty`.
...@@ -20124,7 +20059,7 @@ fn zirStructInit(...@@ -20124,7 +20059,7 @@ fn zirStructInit(
20124 const field_ty = resolved_ty.structFieldType(field_index, mod);20059 const field_ty = resolved_ty.structFieldType(field_index, mod);
20125 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);20060 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
20126 if (!is_packed) {20061 if (!is_packed) {
20127 try sema.resolveStructFieldInits(resolved_ty);20062 try resolved_ty.resolveStructFieldInits(mod);
20128 if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {20063 if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {
20129 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {20064 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {
20130 return sema.failWithNeededComptime(block, field_src, .{20065 return sema.failWithNeededComptime(block, field_src, .{
...@@ -20197,7 +20132,7 @@ fn zirStructInit(...@@ -20197,7 +20132,7 @@ fn zirStructInit(
2019720132
20198 if (is_ref) {20133 if (is_ref) {
20199 const target = mod.getTarget();20134 const target = mod.getTarget();
20200 const alloc_ty = try sema.ptrType(.{20135 const alloc_ty = try mod.ptrTypeSema(.{
20201 .child = result_ty.toIntern(),20136 .child = result_ty.toIntern(),
20202 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20137 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20203 });20138 });
...@@ -20211,7 +20146,6 @@ fn zirStructInit(...@@ -20211,7 +20146,6 @@ fn zirStructInit(
20211 }20146 }
2021220147
20213 try sema.requireRuntimeBlock(block, src, null);20148 try sema.requireRuntimeBlock(block, src, null);
20214 try sema.queueFullTypeResolution(resolved_ty);
20215 const union_val = try block.addUnionInit(resolved_ty, field_index, init_inst);20149 const union_val = try block.addUnionInit(resolved_ty, field_index, init_inst);
20216 return sema.coerce(block, result_ty, union_val, src);20150 return sema.coerce(block, result_ty, union_val, src);
20217 }20151 }
...@@ -20288,7 +20222,7 @@ fn finishStructInit(...@@ -20288,7 +20222,7 @@ fn finishStructInit(
20288 continue;20222 continue;
20289 }20223 }
2029020224
20291 try sema.resolveStructFieldInits(struct_ty);20225 try struct_ty.resolveStructFieldInits(mod);
2029220226
20293 const field_init = struct_type.fieldInit(ip, i);20227 const field_init = struct_type.fieldInit(ip, i);
20294 if (field_init == .none) {20228 if (field_init == .none) {
...@@ -20358,9 +20292,9 @@ fn finishStructInit(...@@ -20358,9 +20292,9 @@ fn finishStructInit(
20358 }20292 }
2035920293
20360 if (is_ref) {20294 if (is_ref) {
20361 try sema.resolveStructLayout(struct_ty);20295 try struct_ty.resolveLayout(mod);
20362 const target = sema.mod.getTarget();20296 const target = sema.mod.getTarget();
20363 const alloc_ty = try sema.ptrType(.{20297 const alloc_ty = try mod.ptrTypeSema(.{
20364 .child = result_ty.toIntern(),20298 .child = result_ty.toIntern(),
20365 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20299 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20366 });20300 });
...@@ -20380,8 +20314,7 @@ fn finishStructInit(...@@ -20380,8 +20314,7 @@ fn finishStructInit(
20380 .init_node_offset = init_src.offset.node_offset.x,20314 .init_node_offset = init_src.offset.node_offset.x,
20381 .elem_index = @intCast(runtime_index),20315 .elem_index = @intCast(runtime_index),
20382 } }));20316 } }));
20383 try sema.resolveStructFieldInits(struct_ty);20317 try struct_ty.resolveStructFieldInits(mod);
20384 try sema.queueFullTypeResolution(struct_ty);
20385 const struct_val = try block.addAggregateInit(struct_ty, field_inits);20318 const struct_val = try block.addAggregateInit(struct_ty, field_inits);
20386 return sema.coerce(block, result_ty, struct_val, init_src);20319 return sema.coerce(block, result_ty, struct_val, init_src);
20387}20320}
...@@ -20490,7 +20423,7 @@ fn structInitAnon(...@@ -20490,7 +20423,7 @@ fn structInitAnon(
2049020423
20491 if (is_ref) {20424 if (is_ref) {
20492 const target = mod.getTarget();20425 const target = mod.getTarget();
20493 const alloc_ty = try sema.ptrType(.{20426 const alloc_ty = try mod.ptrTypeSema(.{
20494 .child = tuple_ty,20427 .child = tuple_ty,
20495 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20428 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20496 });20429 });
...@@ -20504,7 +20437,7 @@ fn structInitAnon(...@@ -20504,7 +20437,7 @@ fn structInitAnon(
20504 };20437 };
20505 extra_index = item.end;20438 extra_index = item.end;
2050620439
20507 const field_ptr_ty = try sema.ptrType(.{20440 const field_ptr_ty = try mod.ptrTypeSema(.{
20508 .child = field_ty,20441 .child = field_ty,
20509 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20442 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20510 });20443 });
...@@ -20597,7 +20530,7 @@ fn zirArrayInit(...@@ -20597,7 +20530,7 @@ fn zirArrayInit(
20597 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);20530 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
20598 if (is_tuple) {20531 if (is_tuple) {
20599 if (array_ty.structFieldIsComptime(i, mod))20532 if (array_ty.structFieldIsComptime(i, mod))
20600 try sema.resolveStructFieldInits(array_ty);20533 try array_ty.resolveStructFieldInits(mod);
20601 if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {20534 if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
20602 const init_val = try sema.resolveValue(dest.*) orelse {20535 const init_val = try sema.resolveValue(dest.*) orelse {
20603 return sema.failWithNeededComptime(block, elem_src, .{20536 return sema.failWithNeededComptime(block, elem_src, .{
...@@ -20641,11 +20574,10 @@ fn zirArrayInit(...@@ -20641,11 +20574,10 @@ fn zirArrayInit(
20641 .init_node_offset = src.offset.node_offset.x,20574 .init_node_offset = src.offset.node_offset.x,
20642 .elem_index = runtime_index,20575 .elem_index = runtime_index,
20643 } }));20576 } }));
20644 try sema.queueFullTypeResolution(array_ty);
2064520577
20646 if (is_ref) {20578 if (is_ref) {
20647 const target = mod.getTarget();20579 const target = mod.getTarget();
20648 const alloc_ty = try sema.ptrType(.{20580 const alloc_ty = try mod.ptrTypeSema(.{
20649 .child = result_ty.toIntern(),20581 .child = result_ty.toIntern(),
20650 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20582 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20651 });20583 });
...@@ -20654,7 +20586,7 @@ fn zirArrayInit(...@@ -20654,7 +20586,7 @@ fn zirArrayInit(
2065420586
20655 if (is_tuple) {20587 if (is_tuple) {
20656 for (resolved_args, 0..) |arg, i| {20588 for (resolved_args, 0..) |arg, i| {
20657 const elem_ptr_ty = try sema.ptrType(.{20589 const elem_ptr_ty = try mod.ptrTypeSema(.{
20658 .child = array_ty.structFieldType(i, mod).toIntern(),20590 .child = array_ty.structFieldType(i, mod).toIntern(),
20659 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20591 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20660 });20592 });
...@@ -20667,7 +20599,7 @@ fn zirArrayInit(...@@ -20667,7 +20599,7 @@ fn zirArrayInit(
20667 return sema.makePtrConst(block, alloc);20599 return sema.makePtrConst(block, alloc);
20668 }20600 }
2066920601
20670 const elem_ptr_ty = try sema.ptrType(.{20602 const elem_ptr_ty = try mod.ptrTypeSema(.{
20671 .child = array_ty.elemType2(mod).toIntern(),20603 .child = array_ty.elemType2(mod).toIntern(),
20672 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20604 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20673 });20605 });
...@@ -20755,14 +20687,14 @@ fn arrayInitAnon(...@@ -20755,14 +20687,14 @@ fn arrayInitAnon(
2075520687
20756 if (is_ref) {20688 if (is_ref) {
20757 const target = sema.mod.getTarget();20689 const target = sema.mod.getTarget();
20758 const alloc_ty = try sema.ptrType(.{20690 const alloc_ty = try mod.ptrTypeSema(.{
20759 .child = tuple_ty,20691 .child = tuple_ty,
20760 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20692 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20761 });20693 });
20762 const alloc = try block.addTy(.alloc, alloc_ty);20694 const alloc = try block.addTy(.alloc, alloc_ty);
20763 for (operands, 0..) |operand, i_usize| {20695 for (operands, 0..) |operand, i_usize| {
20764 const i: u32 = @intCast(i_usize);20696 const i: u32 = @intCast(i_usize);
20765 const field_ptr_ty = try sema.ptrType(.{20697 const field_ptr_ty = try mod.ptrTypeSema(.{
20766 .child = types[i],20698 .child = types[i],
20767 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },20699 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
20768 });20700 });
...@@ -20832,7 +20764,7 @@ fn fieldType(...@@ -20832,7 +20764,7 @@ fn fieldType(
20832 const ip = &mod.intern_pool;20764 const ip = &mod.intern_pool;
20833 var cur_ty = aggregate_ty;20765 var cur_ty = aggregate_ty;
20834 while (true) {20766 while (true) {
20835 try sema.resolveTypeFields(cur_ty);20767 try cur_ty.resolveFields(mod);
20836 switch (cur_ty.zigTypeTag(mod)) {20768 switch (cur_ty.zigTypeTag(mod)) {
20837 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {20769 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {
20838 .anon_struct_type => |anon_struct| {20770 .anon_struct_type => |anon_struct| {
...@@ -20883,8 +20815,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {...@@ -20883,8 +20815,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20883fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {20815fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
20884 const mod = sema.mod;20816 const mod = sema.mod;
20885 const ip = &mod.intern_pool;20817 const ip = &mod.intern_pool;
20886 const stack_trace_ty = try sema.getBuiltinType("StackTrace");20818 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
20887 try sema.resolveTypeFields(stack_trace_ty);20819 try stack_trace_ty.resolveFields(mod);
20888 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);20820 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
20889 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());20821 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());
2089020822
...@@ -20918,9 +20850,6 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -20918,9 +20850,6 @@ fn zirAlignOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
20918 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});20850 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});
20919 }20851 }
20920 const val = try ty.lazyAbiAlignment(mod);20852 const val = try ty.lazyAbiAlignment(mod);
20921 if (val.isLazyAlign(mod)) {
20922 try sema.queueFullTypeResolution(ty);
20923 }
20924 return Air.internedToRef(val.toIntern());20853 return Air.internedToRef(val.toIntern());
20925}20854}
2092620855
...@@ -21095,7 +21024,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -21095,7 +21024,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
21095 const mod = sema.mod;21024 const mod = sema.mod;
21096 const ip = &mod.intern_pool;21025 const ip = &mod.intern_pool;
2109721026
21098 try sema.resolveTypeLayout(operand_ty);21027 try operand_ty.resolveLayout(mod);
21099 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {21028 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
21100 .EnumLiteral => {21029 .EnumLiteral => {
21101 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);21030 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
...@@ -21171,7 +21100,7 @@ fn zirReify(...@@ -21171,7 +21100,7 @@ fn zirReify(
21171 },21100 },
21172 },21101 },
21173 };21102 };
21174 const type_info_ty = try sema.getBuiltinType("Type");21103 const type_info_ty = try mod.getBuiltinType("Type");
21175 const uncasted_operand = try sema.resolveInst(extra.operand);21104 const uncasted_operand = try sema.resolveInst(extra.operand);
21176 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);21105 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
21177 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{21106 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{
...@@ -21205,7 +21134,7 @@ fn zirReify(...@@ -21205,7 +21134,7 @@ fn zirReify(
21205 );21134 );
2120621135
21207 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);21136 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
21208 const bits: u16 = @intCast(try bits_val.toUnsignedIntAdvanced(sema));21137 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod));
21209 const ty = try mod.intType(signedness, bits);21138 const ty = try mod.intType(signedness, bits);
21210 return Air.internedToRef(ty.toIntern());21139 return Air.internedToRef(ty.toIntern());
21211 },21140 },
...@@ -21220,7 +21149,7 @@ fn zirReify(...@@ -21220,7 +21149,7 @@ fn zirReify(
21220 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),21149 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
21221 ).?);21150 ).?);
2122221151
21223 const len: u32 = @intCast(try len_val.toUnsignedIntAdvanced(sema));21152 const len: u32 = @intCast(try len_val.toUnsignedIntSema(mod));
21224 const child_ty = child_val.toType();21153 const child_ty = child_val.toType();
2122521154
21226 try sema.checkVectorElemType(block, src, child_ty);21155 try sema.checkVectorElemType(block, src, child_ty);
...@@ -21238,7 +21167,7 @@ fn zirReify(...@@ -21238,7 +21167,7 @@ fn zirReify(
21238 try ip.getOrPutString(gpa, "bits", .no_embedded_nulls),21167 try ip.getOrPutString(gpa, "bits", .no_embedded_nulls),
21239 ).?);21168 ).?);
2124021169
21241 const bits: u16 = @intCast(try bits_val.toUnsignedIntAdvanced(sema));21170 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod));
21242 const ty = switch (bits) {21171 const ty = switch (bits) {
21243 16 => Type.f16,21172 16 => Type.f16,
21244 32 => Type.f32,21173 32 => Type.f32,
...@@ -21288,7 +21217,7 @@ fn zirReify(...@@ -21288,7 +21217,7 @@ fn zirReify(
21288 return sema.fail(block, src, "alignment must fit in 'u32'", .{});21217 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
21289 }21218 }
2129021219
21291 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;21220 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, .sema)).?;
21292 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {21221 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
21293 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});21222 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
21294 }21223 }
...@@ -21296,7 +21225,7 @@ fn zirReify(...@@ -21296,7 +21225,7 @@ fn zirReify(
2129621225
21297 const elem_ty = child_val.toType();21226 const elem_ty = child_val.toType();
21298 if (abi_align != .none) {21227 if (abi_align != .none) {
21299 try sema.resolveTypeLayout(elem_ty);21228 try elem_ty.resolveLayout(mod);
21300 }21229 }
2130121230
21302 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);21231 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
...@@ -21340,7 +21269,7 @@ fn zirReify(...@@ -21340,7 +21269,7 @@ fn zirReify(
21340 }21269 }
21341 }21270 }
2134221271
21343 const ty = try sema.ptrType(.{21272 const ty = try mod.ptrTypeSema(.{
21344 .child = elem_ty.toIntern(),21273 .child = elem_ty.toIntern(),
21345 .sentinel = actual_sentinel,21274 .sentinel = actual_sentinel,
21346 .flags = .{21275 .flags = .{
...@@ -21369,7 +21298,7 @@ fn zirReify(...@@ -21369,7 +21298,7 @@ fn zirReify(
21369 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),21298 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),
21370 ).?);21299 ).?);
2137121300
21372 const len = try len_val.toUnsignedIntAdvanced(sema);21301 const len = try len_val.toUnsignedIntSema(mod);
21373 const child_ty = child_val.toType();21302 const child_ty = child_val.toType();
21374 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {21303 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
21375 const ptr_ty = try mod.singleMutPtrType(child_ty);21304 const ptr_ty = try mod.singleMutPtrType(child_ty);
...@@ -21476,7 +21405,7 @@ fn zirReify(...@@ -21476,7 +21405,7 @@ fn zirReify(
21476 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);21405 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
2147721406
21478 // Decls21407 // Decls
21479 if (try decls_val.sliceLen(sema) > 0) {21408 if (try decls_val.sliceLen(mod) > 0) {
21480 return sema.fail(block, src, "reified structs must have no decls", .{});21409 return sema.fail(block, src, "reified structs must have no decls", .{});
21481 }21410 }
2148221411
...@@ -21509,7 +21438,7 @@ fn zirReify(...@@ -21509,7 +21438,7 @@ fn zirReify(
21509 try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls),21438 try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls),
21510 ).?);21439 ).?);
2151121440
21512 if (try decls_val.sliceLen(sema) > 0) {21441 if (try decls_val.sliceLen(mod) > 0) {
21513 return sema.fail(block, src, "reified enums must have no decls", .{});21442 return sema.fail(block, src, "reified enums must have no decls", .{});
21514 }21443 }
2151521444
...@@ -21527,7 +21456,7 @@ fn zirReify(...@@ -21527,7 +21456,7 @@ fn zirReify(
21527 ).?);21456 ).?);
2152821457
21529 // Decls21458 // Decls
21530 if (try decls_val.sliceLen(sema) > 0) {21459 if (try decls_val.sliceLen(mod) > 0) {
21531 return sema.fail(block, src, "reified opaque must have no decls", .{});21460 return sema.fail(block, src, "reified opaque must have no decls", .{});
21532 }21461 }
2153321462
...@@ -21575,7 +21504,7 @@ fn zirReify(...@@ -21575,7 +21504,7 @@ fn zirReify(
21575 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),21504 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
21576 ).?);21505 ).?);
2157721506
21578 if (try decls_val.sliceLen(sema) > 0) {21507 if (try decls_val.sliceLen(mod) > 0) {
21579 return sema.fail(block, src, "reified unions must have no decls", .{});21508 return sema.fail(block, src, "reified unions must have no decls", .{});
21580 }21509 }
21581 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);21510 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
...@@ -21934,7 +21863,7 @@ fn reifyUnion(...@@ -21934,7 +21863,7 @@ fn reifyUnion(
2193421863
21935 field_ty.* = field_type_val.toIntern();21864 field_ty.* = field_type_val.toIntern();
21936 if (any_aligns) {21865 if (any_aligns) {
21937 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntAdvanced(sema);21866 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod);
21938 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {21867 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21939 // TODO: better source location21868 // TODO: better source location
21940 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});21869 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
...@@ -21979,7 +21908,7 @@ fn reifyUnion(...@@ -21979,7 +21908,7 @@ fn reifyUnion(
2197921908
21980 field_ty.* = field_type_val.toIntern();21909 field_ty.* = field_type_val.toIntern();
21981 if (any_aligns) {21910 if (any_aligns) {
21982 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntAdvanced(sema);21911 const byte_align = try (try field_info.fieldValue(mod, 2)).toUnsignedIntSema(mod);
21983 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {21912 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
21984 // TODO: better source location21913 // TODO: better source location
21985 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});21914 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
...@@ -22036,6 +21965,7 @@ fn reifyUnion(...@@ -22036,6 +21965,7 @@ fn reifyUnion(
22036 loaded_union.flagsPtr(ip).status = .have_field_types;21965 loaded_union.flagsPtr(ip).status = .have_field_types;
2203721966
22038 try mod.finalizeAnonDecl(new_decl_index);21967 try mod.finalizeAnonDecl(new_decl_index);
21968 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
22039 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));21969 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22040}21970}
2204121971
...@@ -22109,7 +22039,7 @@ fn reifyStruct(...@@ -22109,7 +22039,7 @@ fn reifyStruct(
2210922039
22110 if (field_is_comptime) any_comptime_fields = true;22040 if (field_is_comptime) any_comptime_fields = true;
22111 if (field_default_value != .none) any_default_inits = true;22041 if (field_default_value != .none) any_default_inits = true;
22112 switch (try field_alignment_val.orderAgainstZeroAdvanced(mod, sema)) {22042 switch (try field_alignment_val.orderAgainstZeroAdvanced(mod, .sema)) {
22113 .eq => {},22043 .eq => {},
22114 .gt => any_aligned_fields = true,22044 .gt => any_aligned_fields = true,
22115 .lt => unreachable,22045 .lt => unreachable,
...@@ -22192,7 +22122,7 @@ fn reifyStruct(...@@ -22192,7 +22122,7 @@ fn reifyStruct(
22192 return sema.fail(block, src, "alignment must fit in 'u32'", .{});22122 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
22193 }22123 }
2219422124
22195 const byte_align = try field_alignment_val.toUnsignedIntAdvanced(sema);22125 const byte_align = try field_alignment_val.toUnsignedIntSema(mod);
22196 if (byte_align == 0) {22126 if (byte_align == 0) {
22197 if (layout != .@"packed") {22127 if (layout != .@"packed") {
22198 struct_type.field_aligns.get(ip)[field_idx] = .none;22128 struct_type.field_aligns.get(ip)[field_idx] = .none;
...@@ -22278,7 +22208,7 @@ fn reifyStruct(...@@ -22278,7 +22208,7 @@ fn reifyStruct(
22278 var fields_bit_sum: u64 = 0;22208 var fields_bit_sum: u64 = 0;
22279 for (0..struct_type.field_types.len) |field_idx| {22209 for (0..struct_type.field_types.len) |field_idx| {
22280 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]);22210 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_idx]);
22281 sema.resolveTypeLayout(field_ty) catch |err| switch (err) {22211 field_ty.resolveLayout(mod) catch |err| switch (err) {
22282 error.AnalysisFail => {22212 error.AnalysisFail => {
22283 const msg = sema.err orelse return err;22213 const msg = sema.err orelse return err;
22284 try sema.errNote(src, msg, "while checking a field of this struct", .{});22214 try sema.errNote(src, msg, "while checking a field of this struct", .{});
...@@ -22300,11 +22230,12 @@ fn reifyStruct(...@@ -22300,11 +22230,12 @@ fn reifyStruct(
22300 }22230 }
2230122231
22302 try mod.finalizeAnonDecl(new_decl_index);22232 try mod.finalizeAnonDecl(new_decl_index);
22233 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
22303 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));22234 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
22304}22235}
2230522236
22306fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {22237fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
22307 const va_list_ty = try sema.getBuiltinType("VaList");22238 const va_list_ty = try sema.mod.getBuiltinType("VaList");
22308 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);22239 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);
2230922240
22310 const inst = try sema.resolveInst(zir_ref);22241 const inst = try sema.resolveInst(zir_ref);
...@@ -22343,7 +22274,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)...@@ -22343,7 +22274,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
22343 const va_list_src = block.builtinCallArgSrc(extra.node, 0);22274 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2234422275
22345 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);22276 const va_list_ref = try sema.resolveVaListRef(block, va_list_src, extra.operand);
22346 const va_list_ty = try sema.getBuiltinType("VaList");22277 const va_list_ty = try sema.mod.getBuiltinType("VaList");
2234722278
22348 try sema.requireRuntimeBlock(block, src, null);22279 try sema.requireRuntimeBlock(block, src, null);
22349 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);22280 return block.addTyOp(.c_va_copy, va_list_ty, va_list_ref);
...@@ -22363,7 +22294,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C...@@ -22363,7 +22294,7 @@ fn zirCVaEnd(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C
22363fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {22294fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
22364 const src = block.nodeOffset(@bitCast(extended.operand));22295 const src = block.nodeOffset(@bitCast(extended.operand));
2236522296
22366 const va_list_ty = try sema.getBuiltinType("VaList");22297 const va_list_ty = try sema.mod.getBuiltinType("VaList");
22367 try sema.requireRuntimeBlock(block, src, null);22298 try sema.requireRuntimeBlock(block, src, null);
22368 return block.addInst(.{22299 return block.addInst(.{
22369 .tag = .c_va_start,22300 .tag = .c_va_start,
...@@ -22497,7 +22428,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro...@@ -22497,7 +22428,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
22497 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);22428 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);
2249822429
22499 if (try sema.resolveValue(operand)) |operand_val| {22430 if (try sema.resolveValue(operand)) |operand_val| {
22500 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, mod, sema);22431 const result_val = try operand_val.floatFromIntAdvanced(sema.arena, operand_ty, dest_ty, mod, .sema);
22501 return Air.internedToRef(result_val.toIntern());22432 return Air.internedToRef(result_val.toIntern());
22502 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) {22433 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) {
22503 return sema.failWithNeededComptime(block, operand_src, .{22434 return sema.failWithNeededComptime(block, operand_src, .{
...@@ -22545,7 +22476,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -22545,7 +22476,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
22545 try sema.checkPtrType(block, src, ptr_ty, true);22476 try sema.checkPtrType(block, src, ptr_ty, true);
2254622477
22547 const elem_ty = ptr_ty.elemType2(mod);22478 const elem_ty = ptr_ty.elemType2(mod);
22548 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, sema);22479 const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, .sema);
2254922480
22550 if (ptr_ty.isSlice(mod)) {22481 if (ptr_ty.isSlice(mod)) {
22551 const msg = msg: {22482 const msg = msg: {
...@@ -22644,7 +22575,7 @@ fn ptrFromIntVal(...@@ -22644,7 +22575,7 @@ fn ptrFromIntVal(
22644 }22575 }
22645 return sema.failWithUseOfUndef(block, operand_src);22576 return sema.failWithUseOfUndef(block, operand_src);
22646 }22577 }
22647 const addr = try operand_val.toUnsignedIntAdvanced(sema);22578 const addr = try operand_val.toUnsignedIntSema(zcu);
22648 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)22579 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)
22649 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(zcu)});22580 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(zcu)});
22650 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))22581 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))
...@@ -22842,8 +22773,8 @@ fn ptrCastFull(...@@ -22842,8 +22773,8 @@ fn ptrCastFull(
22842 const src_info = operand_ty.ptrInfo(mod);22773 const src_info = operand_ty.ptrInfo(mod);
22843 const dest_info = dest_ty.ptrInfo(mod);22774 const dest_info = dest_ty.ptrInfo(mod);
2284422775
22845 try sema.resolveTypeLayout(Type.fromInterned(src_info.child));22776 try Type.fromInterned(src_info.child).resolveLayout(mod);
22846 try sema.resolveTypeLayout(Type.fromInterned(dest_info.child));22777 try Type.fromInterned(dest_info.child).resolveLayout(mod);
2284722778
22848 const src_slice_like = src_info.flags.size == .Slice or22779 const src_slice_like = src_info.flags.size == .Slice or
22849 (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array);22780 (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array);
...@@ -23091,7 +23022,7 @@ fn ptrCastFull(...@@ -23091,7 +23022,7 @@ fn ptrCastFull(
23091 // Only convert to a many-pointer at first23022 // Only convert to a many-pointer at first
23092 var info = dest_info;23023 var info = dest_info;
23093 info.flags.size = .Many;23024 info.flags.size = .Many;
23094 const ty = try sema.ptrType(info);23025 const ty = try mod.ptrTypeSema(info);
23095 if (dest_ty.zigTypeTag(mod) == .Optional) {23026 if (dest_ty.zigTypeTag(mod) == .Optional) {
23096 break :blk try mod.optionalType(ty.toIntern());23027 break :blk try mod.optionalType(ty.toIntern());
23097 } else {23028 } else {
...@@ -23109,7 +23040,7 @@ fn ptrCastFull(...@@ -23109,7 +23040,7 @@ fn ptrCastFull(
23109 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)});23040 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)});
23110 }23041 }
23111 if (dest_align.compare(.gt, src_align)) {23042 if (dest_align.compare(.gt, src_align)) {
23112 if (try ptr_val.getUnsignedIntAdvanced(mod, null)) |addr| {23043 if (try ptr_val.getUnsignedIntAdvanced(mod, .sema)) |addr| {
23113 if (!dest_align.check(addr)) {23044 if (!dest_align.check(addr)) {
23114 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{23045 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{
23115 addr,23046 addr,
...@@ -23176,7 +23107,7 @@ fn ptrCastFull(...@@ -23176,7 +23107,7 @@ fn ptrCastFull(
23176 // We can't change address spaces with a bitcast, so this requires two instructions23107 // We can't change address spaces with a bitcast, so this requires two instructions
23177 var intermediate_info = src_info;23108 var intermediate_info = src_info;
23178 intermediate_info.flags.address_space = dest_info.flags.address_space;23109 intermediate_info.flags.address_space = dest_info.flags.address_space;
23179 const intermediate_ptr_ty = try sema.ptrType(intermediate_info);23110 const intermediate_ptr_ty = try mod.ptrTypeSema(intermediate_info);
23180 const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: {23111 const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: {
23181 break :blk try mod.optionalType(intermediate_ptr_ty.toIntern());23112 break :blk try mod.optionalType(intermediate_ptr_ty.toIntern());
23182 } else intermediate_ptr_ty;23113 } else intermediate_ptr_ty;
...@@ -23233,7 +23164,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst...@@ -23233,7 +23164,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
23233 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;23164 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;
2323423165
23235 const dest_ty = blk: {23166 const dest_ty = blk: {
23236 const dest_ty = try sema.ptrType(ptr_info);23167 const dest_ty = try mod.ptrTypeSema(ptr_info);
23237 if (operand_ty.zigTypeTag(mod) == .Optional) {23168 if (operand_ty.zigTypeTag(mod) == .Optional) {
23238 break :blk try mod.optionalType(dest_ty.toIntern());23169 break :blk try mod.optionalType(dest_ty.toIntern());
23239 }23170 }
...@@ -23523,7 +23454,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6...@@ -23523,7 +23454,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2352323454
23524 const mod = sema.mod;23455 const mod = sema.mod;
23525 const ip = &mod.intern_pool;23456 const ip = &mod.intern_pool;
23526 try sema.resolveTypeLayout(ty);23457 try ty.resolveLayout(mod);
23527 switch (ty.zigTypeTag(mod)) {23458 switch (ty.zigTypeTag(mod)) {
23528 .Struct => {},23459 .Struct => {},
23529 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}),23460 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}),
...@@ -23766,7 +23697,7 @@ fn checkAtomicPtrOperand(...@@ -23766,7 +23697,7 @@ fn checkAtomicPtrOperand(
23766 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {23697 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
23767 .Pointer => ptr_ty.ptrInfo(mod),23698 .Pointer => ptr_ty.ptrInfo(mod),
23768 else => {23699 else => {
23769 const wanted_ptr_ty = try sema.ptrType(wanted_ptr_data);23700 const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data);
23770 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);23701 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
23771 unreachable;23702 unreachable;
23772 },23703 },
...@@ -23776,7 +23707,7 @@ fn checkAtomicPtrOperand(...@@ -23776,7 +23707,7 @@ fn checkAtomicPtrOperand(
23776 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;23707 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
23777 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;23708 wanted_ptr_data.flags.is_volatile = ptr_data.flags.is_volatile;
2377823709
23779 const wanted_ptr_ty = try sema.ptrType(wanted_ptr_data);23710 const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data);
23780 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);23711 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2378123712
23782 return casted_ptr;23713 return casted_ptr;
...@@ -23953,7 +23884,7 @@ fn resolveExportOptions(...@@ -23953,7 +23884,7 @@ fn resolveExportOptions(
23953 const mod = sema.mod;23884 const mod = sema.mod;
23954 const gpa = sema.gpa;23885 const gpa = sema.gpa;
23955 const ip = &mod.intern_pool;23886 const ip = &mod.intern_pool;
23956 const export_options_ty = try sema.getBuiltinType("ExportOptions");23887 const export_options_ty = try mod.getBuiltinType("ExportOptions");
23957 const air_ref = try sema.resolveInst(zir_ref);23888 const air_ref = try sema.resolveInst(zir_ref);
23958 const options = try sema.coerce(block, export_options_ty, air_ref, src);23889 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2395923890
...@@ -24017,7 +23948,7 @@ fn resolveBuiltinEnum(...@@ -24017,7 +23948,7 @@ fn resolveBuiltinEnum(
24017 reason: NeededComptimeReason,23948 reason: NeededComptimeReason,
24018) CompileError!@field(std.builtin, name) {23949) CompileError!@field(std.builtin, name) {
24019 const mod = sema.mod;23950 const mod = sema.mod;
24020 const ty = try sema.getBuiltinType(name);23951 const ty = try mod.getBuiltinType(name);
24021 const air_ref = try sema.resolveInst(zir_ref);23952 const air_ref = try sema.resolveInst(zir_ref);
24022 const coerced = try sema.coerce(block, ty, air_ref, src);23953 const coerced = try sema.coerce(block, ty, air_ref, src);
24023 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);23954 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
...@@ -24777,7 +24708,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -24777,7 +24708,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
24777 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;24708 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
24778 const func = try sema.resolveInst(extra.callee);24709 const func = try sema.resolveInst(extra.callee);
2477924710
24780 const modifier_ty = try sema.getBuiltinType("CallModifier");24711 const modifier_ty = try mod.getBuiltinType("CallModifier");
24781 const air_ref = try sema.resolveInst(extra.modifier);24712 const air_ref = try sema.resolveInst(extra.modifier);
24782 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);24713 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
24783 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{24714 const modifier_val = try sema.resolveConstDefinedValue(block, modifier_src, modifier_ref, .{
...@@ -24881,7 +24812,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24881,7 +24812,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24881 .Struct, .Union => {},24812 .Struct, .Union => {},
24882 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(zcu)}),24813 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(zcu)}),
24883 }24814 }
24884 try sema.resolveTypeLayout(parent_ty);24815 try parent_ty.resolveLayout(zcu);
2488524816
24886 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{24817 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{
24887 .needed_comptime_reason = "field name must be comptime-known",24818 .needed_comptime_reason = "field name must be comptime-known",
...@@ -24912,7 +24843,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24912,7 +24843,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24912 var actual_parent_ptr_info: InternPool.Key.PtrType = .{24843 var actual_parent_ptr_info: InternPool.Key.PtrType = .{
24913 .child = parent_ty.toIntern(),24844 .child = parent_ty.toIntern(),
24914 .flags = .{24845 .flags = .{
24915 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(zcu, sema),24846 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),
24916 .is_const = field_ptr_info.flags.is_const,24847 .is_const = field_ptr_info.flags.is_const,
24917 .is_volatile = field_ptr_info.flags.is_volatile,24848 .is_volatile = field_ptr_info.flags.is_volatile,
24918 .is_allowzero = field_ptr_info.flags.is_allowzero,24849 .is_allowzero = field_ptr_info.flags.is_allowzero,
...@@ -24924,7 +24855,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24924,7 +24855,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24924 var actual_field_ptr_info: InternPool.Key.PtrType = .{24855 var actual_field_ptr_info: InternPool.Key.PtrType = .{
24925 .child = field_ty.toIntern(),24856 .child = field_ty.toIntern(),
24926 .flags = .{24857 .flags = .{
24927 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(zcu, sema),24858 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),
24928 .is_const = field_ptr_info.flags.is_const,24859 .is_const = field_ptr_info.flags.is_const,
24929 .is_volatile = field_ptr_info.flags.is_volatile,24860 .is_volatile = field_ptr_info.flags.is_volatile,
24930 .is_allowzero = field_ptr_info.flags.is_allowzero,24861 .is_allowzero = field_ptr_info.flags.is_allowzero,
...@@ -24935,12 +24866,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24935,12 +24866,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24935 switch (parent_ty.containerLayout(zcu)) {24866 switch (parent_ty.containerLayout(zcu)) {
24936 .auto => {24867 .auto => {
24937 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(24868 actual_parent_ptr_info.flags.alignment = actual_field_ptr_info.flags.alignment.minStrict(
24938 if (zcu.typeToStruct(parent_ty)) |struct_obj| try sema.structFieldAlignment(24869 if (zcu.typeToStruct(parent_ty)) |struct_obj| try zcu.structFieldAlignmentAdvanced(
24939 struct_obj.fieldAlign(ip, field_index),24870 struct_obj.fieldAlign(ip, field_index),
24940 field_ty,24871 field_ty,
24941 struct_obj.layout,24872 struct_obj.layout,
24873 .sema,
24942 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|24874 ) else if (zcu.typeToUnion(parent_ty)) |union_obj|
24943 try sema.unionFieldAlignment(union_obj, field_index)24875 try zcu.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema)
24944 else24876 else
24945 actual_field_ptr_info.flags.alignment,24877 actual_field_ptr_info.flags.alignment,
24946 );24878 );
...@@ -24970,9 +24902,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -24970,9 +24902,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
24970 },24902 },
24971 }24903 }
2497224904
24973 const actual_field_ptr_ty = try sema.ptrType(actual_field_ptr_info);24905 const actual_field_ptr_ty = try zcu.ptrTypeSema(actual_field_ptr_info);
24974 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src);24906 const casted_field_ptr = try sema.coerce(block, actual_field_ptr_ty, field_ptr, field_ptr_src);
24975 const actual_parent_ptr_ty = try sema.ptrType(actual_parent_ptr_info);24907 const actual_parent_ptr_ty = try zcu.ptrTypeSema(actual_parent_ptr_info);
2497624908
24977 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {24909 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {
24978 switch (parent_ty.zigTypeTag(zcu)) {24910 switch (parent_ty.zigTypeTag(zcu)) {
...@@ -25032,7 +24964,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins...@@ -25032,7 +24964,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
25032 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);24964 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);
25033 } else result: {24965 } else result: {
25034 try sema.requireRuntimeBlock(block, inst_src, field_ptr_src);24966 try sema.requireRuntimeBlock(block, inst_src, field_ptr_src);
25035 try sema.queueFullTypeResolution(parent_ty);
25036 break :result try block.addInst(.{24967 break :result try block.addInst(.{
25037 .tag = .field_parent_ptr,24968 .tag = .field_parent_ptr,
25038 .data = .{ .ty_pl = .{24969 .data = .{ .ty_pl = .{
...@@ -25345,7 +25276,7 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A...@@ -25345,7 +25276,7 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A
25345 // Already an array pointer.25276 // Already an array pointer.
25346 return ptr;25277 return ptr;
25347 }25278 }
25348 const new_ty = try sema.ptrType(.{25279 const new_ty = try mod.ptrTypeSema(.{
25349 .child = (try mod.arrayType(.{25280 .child = (try mod.arrayType(.{
25350 .len = len,25281 .len = len,
25351 .sentinel = info.sentinel,25282 .sentinel = info.sentinel,
...@@ -25444,7 +25375,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25444,7 +25375,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25444 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {25375 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {
25445 if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src;25376 if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src;
25446 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {25377 if (try sema.resolveDefinedValue(block, src_src, src_ptr)) |_| {
25447 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(mod, sema)).?;25378 const len_u64 = (try len_val.?.getUnsignedIntAdvanced(mod, .sema)).?;
25448 const len = try sema.usizeCast(block, dest_src, len_u64);25379 const len = try sema.usizeCast(block, dest_src, len_u64);
25449 for (0..len) |i| {25380 for (0..len) |i| {
25450 const elem_index = try mod.intRef(Type.usize, i);25381 const elem_index = try mod.intRef(Type.usize, i);
...@@ -25503,7 +25434,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25503,7 +25434,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25503 var new_dest_ptr = dest_ptr;25434 var new_dest_ptr = dest_ptr;
25504 var new_src_ptr = src_ptr;25435 var new_src_ptr = src_ptr;
25505 if (len_val) |val| {25436 if (len_val) |val| {
25506 const len = try val.toUnsignedIntAdvanced(sema);25437 const len = try val.toUnsignedIntSema(mod);
25507 if (len == 0) {25438 if (len == 0) {
25508 // This AIR instruction guarantees length > 0 if it is comptime-known.25439 // This AIR instruction guarantees length > 0 if it is comptime-known.
25509 return;25440 return;
...@@ -25550,7 +25481,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25550,7 +25481,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25550 assert(dest_manyptr_ty_key.flags.size == .One);25481 assert(dest_manyptr_ty_key.flags.size == .One);
25551 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();25482 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();
25552 dest_manyptr_ty_key.flags.size = .Many;25483 dest_manyptr_ty_key.flags.size = .Many;
25553 break :ptr try sema.coerceCompatiblePtrs(block, try sema.ptrType(dest_manyptr_ty_key), new_dest_ptr, dest_src);25484 break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(dest_manyptr_ty_key), new_dest_ptr, dest_src);
25554 } else new_dest_ptr;25485 } else new_dest_ptr;
2555525486
25556 const new_src_ptr_ty = sema.typeOf(new_src_ptr);25487 const new_src_ptr_ty = sema.typeOf(new_src_ptr);
...@@ -25561,7 +25492,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25561,7 +25492,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25561 assert(src_manyptr_ty_key.flags.size == .One);25492 assert(src_manyptr_ty_key.flags.size == .One);
25562 src_manyptr_ty_key.child = src_elem_ty.toIntern();25493 src_manyptr_ty_key.child = src_elem_ty.toIntern();
25563 src_manyptr_ty_key.flags.size = .Many;25494 src_manyptr_ty_key.flags.size = .Many;
25564 break :ptr try sema.coerceCompatiblePtrs(block, try sema.ptrType(src_manyptr_ty_key), new_src_ptr, src_src);25495 break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(src_manyptr_ty_key), new_src_ptr, src_src);
25565 } else new_src_ptr;25496 } else new_src_ptr;
2556625497
25567 // ok1: dest >= src + len25498 // ok1: dest >= src + len
...@@ -25628,7 +25559,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25628,7 +25559,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
25628 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;25559 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;
25629 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src);25560 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src);
25630 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;25561 const len_val = (try sema.resolveDefinedValue(block, dest_src, len_air_ref)) orelse break :rs dest_src;
25631 const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, sema)).?;25562 const len_u64 = (try len_val.getUnsignedIntAdvanced(mod, .sema)).?;
25632 const len = try sema.usizeCast(block, dest_src, len_u64);25563 const len = try sema.usizeCast(block, dest_src, len_u64);
25633 if (len == 0) {25564 if (len == 0) {
25634 // This AIR instruction guarantees length > 0 if it is comptime-known.25565 // This AIR instruction guarantees length > 0 if it is comptime-known.
...@@ -25808,7 +25739,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25808,7 +25739,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25808 if (val.isGenericPoison()) {25739 if (val.isGenericPoison()) {
25809 break :blk null;25740 break :blk null;
25810 }25741 }
25811 const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntAdvanced(sema));25742 const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntSema(mod));
25812 const default = target_util.defaultFunctionAlignment(target);25743 const default = target_util.defaultFunctionAlignment(target);
25813 break :blk if (alignment == default) .none else alignment;25744 break :blk if (alignment == default) .none else alignment;
25814 } else if (extra.data.bits.has_align_ref) blk: {25745 } else if (extra.data.bits.has_align_ref) blk: {
...@@ -25828,7 +25759,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25828,7 +25759,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25828 error.GenericPoison => break :blk null,25759 error.GenericPoison => break :blk null,
25829 else => |e| return e,25760 else => |e| return e,
25830 };25761 };
25831 const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntAdvanced(sema));25762 const alignment = try sema.validateAlignAllowZero(block, align_src, try align_val.toUnsignedIntSema(mod));
25832 const default = target_util.defaultFunctionAlignment(target);25763 const default = target_util.defaultFunctionAlignment(target);
25833 break :blk if (alignment == default) .none else alignment;25764 break :blk if (alignment == default) .none else alignment;
25834 } else .none;25765 } else .none;
...@@ -25904,7 +25835,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25904,7 +25835,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25904 const body = sema.code.bodySlice(extra_index, body_len);25835 const body = sema.code.bodySlice(extra_index, body_len);
25905 extra_index += body.len;25836 extra_index += body.len;
2590625837
25907 const cc_ty = try sema.getBuiltinType("CallingConvention");25838 const cc_ty = try mod.getBuiltinType("CallingConvention");
25908 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{25839 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{
25909 .needed_comptime_reason = "calling convention must be comptime-known",25840 .needed_comptime_reason = "calling convention must be comptime-known",
25910 });25841 });
...@@ -26117,7 +26048,7 @@ fn resolvePrefetchOptions(...@@ -26117,7 +26048,7 @@ fn resolvePrefetchOptions(
26117 const mod = sema.mod;26048 const mod = sema.mod;
26118 const gpa = sema.gpa;26049 const gpa = sema.gpa;
26119 const ip = &mod.intern_pool;26050 const ip = &mod.intern_pool;
26120 const options_ty = try sema.getBuiltinType("PrefetchOptions");26051 const options_ty = try mod.getBuiltinType("PrefetchOptions");
26121 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);26052 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2612226053
26123 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });26054 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -26141,7 +26072,7 @@ fn resolvePrefetchOptions(...@@ -26141,7 +26072,7 @@ fn resolvePrefetchOptions(
2614126072
26142 return std.builtin.PrefetchOptions{26073 return std.builtin.PrefetchOptions{
26143 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),26074 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),
26144 .locality = @intCast(try locality_val.toUnsignedIntAdvanced(sema)),26075 .locality = @intCast(try locality_val.toUnsignedIntSema(mod)),
26145 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),26076 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),
26146 };26077 };
26147}26078}
...@@ -26189,7 +26120,7 @@ fn resolveExternOptions(...@@ -26189,7 +26120,7 @@ fn resolveExternOptions(
26189 const gpa = sema.gpa;26120 const gpa = sema.gpa;
26190 const ip = &mod.intern_pool;26121 const ip = &mod.intern_pool;
26191 const options_inst = try sema.resolveInst(zir_ref);26122 const options_inst = try sema.resolveInst(zir_ref);
26192 const extern_options_ty = try sema.getBuiltinType("ExternOptions");26123 const extern_options_ty = try mod.getBuiltinType("ExternOptions");
26193 const options = try sema.coerce(block, extern_options_ty, options_inst, src);26124 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2619426125
26195 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });26126 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
...@@ -26440,7 +26371,7 @@ fn explainWhyTypeIsComptime(...@@ -26440,7 +26371,7 @@ fn explainWhyTypeIsComptime(
26440 var type_set = TypeSet{};26371 var type_set = TypeSet{};
26441 defer type_set.deinit(sema.gpa);26372 defer type_set.deinit(sema.gpa);
2644226373
26443 try sema.resolveTypeFully(ty);26374 try ty.resolveFully(sema.mod);
26444 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);26375 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);
26445}26376}
2644626377
...@@ -26567,7 +26498,7 @@ const ExternPosition = enum {...@@ -26567,7 +26498,7 @@ const ExternPosition = enum {
2656726498
26568/// Returns true if `ty` is allowed in extern types.26499/// Returns true if `ty` is allowed in extern types.
26569/// Does *NOT* require `ty` to be resolved in any way.26500/// Does *NOT* require `ty` to be resolved in any way.
26570/// Calls `resolveTypeLayout` for packed containers.26501/// Calls `resolveLayout` for packed containers.
26571fn validateExternType(26502fn validateExternType(
26572 sema: *Sema,26503 sema: *Sema,
26573 ty: Type,26504 ty: Type,
...@@ -26618,7 +26549,7 @@ fn validateExternType(...@@ -26618,7 +26549,7 @@ fn validateExternType(
26618 .Struct, .Union => switch (ty.containerLayout(mod)) {26549 .Struct, .Union => switch (ty.containerLayout(mod)) {
26619 .@"extern" => return true,26550 .@"extern" => return true,
26620 .@"packed" => {26551 .@"packed" => {
26621 const bit_size = try ty.bitSizeAdvanced(mod, sema);26552 const bit_size = try ty.bitSizeAdvanced(mod, .sema);
26622 switch (bit_size) {26553 switch (bit_size) {
26623 0, 8, 16, 32, 64, 128 => return true,26554 0, 8, 16, 32, 64, 128 => return true,
26624 else => return false,26555 else => return false,
...@@ -26796,11 +26727,11 @@ fn explainWhyTypeIsNotPacked(...@@ -26796,11 +26727,11 @@ fn explainWhyTypeIsNotPacked(
26796 }26727 }
26797}26728}
2679826729
26799fn prepareSimplePanic(sema: *Sema, block: *Block) !void {26730fn prepareSimplePanic(sema: *Sema) !void {
26800 const mod = sema.mod;26731 const mod = sema.mod;
2680126732
26802 if (mod.panic_func_index == .none) {26733 if (mod.panic_func_index == .none) {
26803 const decl_index = (try sema.getBuiltinDecl(block, "panic"));26734 const decl_index = (try mod.getBuiltinDecl("panic"));
26804 // decl_index may be an alias; we must find the decl that actually26735 // decl_index may be an alias; we must find the decl that actually
26805 // owns the function.26736 // owns the function.
26806 try sema.ensureDeclAnalyzed(decl_index);26737 try sema.ensureDeclAnalyzed(decl_index);
...@@ -26813,10 +26744,10 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {...@@ -26813,10 +26744,10 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {
26813 }26744 }
2681426745
26815 if (mod.null_stack_trace == .none) {26746 if (mod.null_stack_trace == .none) {
26816 const stack_trace_ty = try sema.getBuiltinType("StackTrace");26747 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
26817 try sema.resolveTypeFields(stack_trace_ty);26748 try stack_trace_ty.resolveFields(mod);
26818 const target = mod.getTarget();26749 const target = mod.getTarget();
26819 const ptr_stack_trace_ty = try sema.ptrType(.{26750 const ptr_stack_trace_ty = try mod.ptrTypeSema(.{
26820 .child = stack_trace_ty.toIntern(),26751 .child = stack_trace_ty.toIntern(),
26821 .flags = .{26752 .flags = .{
26822 .address_space = target_util.defaultAddressSpace(target, .global_constant),26753 .address_space = target_util.defaultAddressSpace(target, .global_constant),
...@@ -26838,9 +26769,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP...@@ -26838,9 +26769,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
26838 const gpa = sema.gpa;26769 const gpa = sema.gpa;
26839 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;26770 if (mod.panic_messages[@intFromEnum(panic_id)].unwrap()) |x| return x;
2684026771
26841 try sema.prepareSimplePanic(block);26772 try sema.prepareSimplePanic();
2684226773
26843 const panic_messages_ty = try sema.getBuiltinType("panic_messages");26774 const panic_messages_ty = try mod.getBuiltinType("panic_messages");
26844 const msg_decl_index = (sema.namespaceLookup(26775 const msg_decl_index = (sema.namespaceLookup(
26845 block,26776 block,
26846 LazySrcLoc.unneeded,26777 LazySrcLoc.unneeded,
...@@ -26946,7 +26877,7 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst....@@ -26946,7 +26877,7 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
26946 return;26877 return;
26947 }26878 }
2694826879
26949 try sema.prepareSimplePanic(block);26880 try sema.prepareSimplePanic();
2695026881
26951 const panic_func = mod.funcInfo(mod.panic_func_index);26882 const panic_func = mod.funcInfo(mod.panic_func_index);
26952 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);26883 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);
...@@ -26992,7 +26923,7 @@ fn panicUnwrapError(...@@ -26992,7 +26923,7 @@ fn panicUnwrapError(
26992 if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) {26923 if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) {
26993 _ = try fail_block.addNoOp(.trap);26924 _ = try fail_block.addNoOp(.trap);
26994 } else {26925 } else {
26995 const panic_fn = try sema.getBuiltin("panicUnwrapError");26926 const panic_fn = try sema.mod.getBuiltin("panicUnwrapError");
26996 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);26927 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
26997 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);26928 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
26998 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };26929 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
...@@ -27051,7 +26982,7 @@ fn panicSentinelMismatch(...@@ -27051,7 +26982,7 @@ fn panicSentinelMismatch(
27051 const actual_sentinel = if (ptr_ty.isSlice(mod))26982 const actual_sentinel = if (ptr_ty.isSlice(mod))
27052 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)26983 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)
27053 else blk: {26984 else blk: {
27054 const elem_ptr_ty = try sema.elemPtrType(ptr_ty, null);26985 const elem_ptr_ty = try ptr_ty.elemPtrType(null, mod);
27055 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);26986 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);
27056 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);26987 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);
27057 };26988 };
...@@ -27069,7 +27000,7 @@ fn panicSentinelMismatch(...@@ -27069,7 +27000,7 @@ fn panicSentinelMismatch(
27069 } else if (sentinel_ty.isSelfComparable(mod, true))27000 } else if (sentinel_ty.isSelfComparable(mod, true))
27070 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)27001 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)
27071 else {27002 else {
27072 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");27003 const panic_fn = try mod.getBuiltin("checkNonScalarSentinel");
27073 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };27004 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
27074 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");27005 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");
27075 return;27006 return;
...@@ -27108,7 +27039,7 @@ fn safetyCheckFormatted(...@@ -27108,7 +27039,7 @@ fn safetyCheckFormatted(
27108 if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) {27039 if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) {
27109 _ = try fail_block.addNoOp(.trap);27040 _ = try fail_block.addNoOp(.trap);
27110 } else {27041 } else {
27111 const panic_fn = try sema.getBuiltin(func);27042 const panic_fn = try sema.mod.getBuiltin(func);
27112 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");27043 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");
27113 }27044 }
27114 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);27045 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
...@@ -27170,7 +27101,7 @@ fn fieldVal(...@@ -27170,7 +27101,7 @@ fn fieldVal(
27170 return Air.internedToRef((try mod.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern());27101 return Air.internedToRef((try mod.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern());
27171 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {27102 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27172 const ptr_info = object_ty.ptrInfo(mod);27103 const ptr_info = object_ty.ptrInfo(mod);
27173 const result_ty = try sema.ptrType(.{27104 const result_ty = try mod.ptrTypeSema(.{
27174 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),27105 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
27175 .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none,27106 .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none,
27176 .flags = .{27107 .flags = .{
...@@ -27267,7 +27198,7 @@ fn fieldVal(...@@ -27267,7 +27198,7 @@ fn fieldVal(
27267 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27198 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27268 return inst;27199 return inst;
27269 }27200 }
27270 try sema.resolveTypeFields(child_type);27201 try child_type.resolveFields(mod);
27271 if (child_type.unionTagType(mod)) |enum_ty| {27202 if (child_type.unionTagType(mod)) |enum_ty| {
27272 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {27203 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {
27273 const field_index: u32 = @intCast(field_index_usize);27204 const field_index: u32 = @intCast(field_index_usize);
...@@ -27361,7 +27292,7 @@ fn fieldPtr(...@@ -27361,7 +27292,7 @@ fn fieldPtr(
27361 return anonDeclRef(sema, int_val.toIntern());27292 return anonDeclRef(sema, int_val.toIntern());
27362 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {27293 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
27363 const ptr_info = object_ty.ptrInfo(mod);27294 const ptr_info = object_ty.ptrInfo(mod);
27364 const new_ptr_ty = try sema.ptrType(.{27295 const new_ptr_ty = try mod.ptrTypeSema(.{
27365 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),27296 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
27366 .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,27297 .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,
27367 .flags = .{27298 .flags = .{
...@@ -27376,7 +27307,7 @@ fn fieldPtr(...@@ -27376,7 +27307,7 @@ fn fieldPtr(
27376 .packed_offset = ptr_info.packed_offset,27307 .packed_offset = ptr_info.packed_offset,
27377 });27308 });
27378 const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);27309 const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);
27379 const result_ty = try sema.ptrType(.{27310 const result_ty = try mod.ptrTypeSema(.{
27380 .child = new_ptr_ty.toIntern(),27311 .child = new_ptr_ty.toIntern(),
27381 .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,27312 .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
27382 .flags = .{27313 .flags = .{
...@@ -27410,7 +27341,7 @@ fn fieldPtr(...@@ -27410,7 +27341,7 @@ fn fieldPtr(
27410 if (field_name.eqlSlice("ptr", ip)) {27341 if (field_name.eqlSlice("ptr", ip)) {
27411 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);27342 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2741227343
27413 const result_ty = try sema.ptrType(.{27344 const result_ty = try mod.ptrTypeSema(.{
27414 .child = slice_ptr_ty.toIntern(),27345 .child = slice_ptr_ty.toIntern(),
27415 .flags = .{27346 .flags = .{
27416 .is_const = !attr_ptr_ty.ptrIsMutable(mod),27347 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
...@@ -27420,7 +27351,7 @@ fn fieldPtr(...@@ -27420,7 +27351,7 @@ fn fieldPtr(
27420 });27351 });
2742127352
27422 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {27353 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
27423 return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, sema)).toIntern());27354 return Air.internedToRef((try val.ptrField(Value.slice_ptr_index, mod)).toIntern());
27424 }27355 }
27425 try sema.requireRuntimeBlock(block, src, null);27356 try sema.requireRuntimeBlock(block, src, null);
2742627357
...@@ -27428,7 +27359,7 @@ fn fieldPtr(...@@ -27428,7 +27359,7 @@ fn fieldPtr(
27428 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);27359 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
27429 return field_ptr;27360 return field_ptr;
27430 } else if (field_name.eqlSlice("len", ip)) {27361 } else if (field_name.eqlSlice("len", ip)) {
27431 const result_ty = try sema.ptrType(.{27362 const result_ty = try mod.ptrTypeSema(.{
27432 .child = .usize_type,27363 .child = .usize_type,
27433 .flags = .{27364 .flags = .{
27434 .is_const = !attr_ptr_ty.ptrIsMutable(mod),27365 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
...@@ -27438,7 +27369,7 @@ fn fieldPtr(...@@ -27438,7 +27369,7 @@ fn fieldPtr(
27438 });27369 });
2743927370
27440 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {27371 if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| {
27441 return Air.internedToRef((try val.ptrField(Value.slice_len_index, sema)).toIntern());27372 return Air.internedToRef((try val.ptrField(Value.slice_len_index, mod)).toIntern());
27442 }27373 }
27443 try sema.requireRuntimeBlock(block, src, null);27374 try sema.requireRuntimeBlock(block, src, null);
2744427375
...@@ -27506,7 +27437,7 @@ fn fieldPtr(...@@ -27506,7 +27437,7 @@ fn fieldPtr(
27506 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {27437 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
27507 return inst;27438 return inst;
27508 }27439 }
27509 try sema.resolveTypeFields(child_type);27440 try child_type.resolveFields(mod);
27510 if (child_type.unionTagType(mod)) |enum_ty| {27441 if (child_type.unionTagType(mod)) |enum_ty| {
27511 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {27442 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
27512 const field_index_u32: u32 = @intCast(field_index);27443 const field_index_u32: u32 = @intCast(field_index);
...@@ -27601,7 +27532,7 @@ fn fieldCallBind(...@@ -27601,7 +27532,7 @@ fn fieldCallBind(
27601 find_field: {27532 find_field: {
27602 switch (concrete_ty.zigTypeTag(mod)) {27533 switch (concrete_ty.zigTypeTag(mod)) {
27603 .Struct => {27534 .Struct => {
27604 try sema.resolveTypeFields(concrete_ty);27535 try concrete_ty.resolveFields(mod);
27605 if (mod.typeToStruct(concrete_ty)) |struct_type| {27536 if (mod.typeToStruct(concrete_ty)) |struct_type| {
27606 const field_index = struct_type.nameIndex(ip, field_name) orelse27537 const field_index = struct_type.nameIndex(ip, field_name) orelse
27607 break :find_field;27538 break :find_field;
...@@ -27627,7 +27558,7 @@ fn fieldCallBind(...@@ -27627,7 +27558,7 @@ fn fieldCallBind(
27627 }27558 }
27628 },27559 },
27629 .Union => {27560 .Union => {
27630 try sema.resolveTypeFields(concrete_ty);27561 try concrete_ty.resolveFields(mod);
27631 const union_obj = mod.typeToUnion(concrete_ty).?;27562 const union_obj = mod.typeToUnion(concrete_ty).?;
27632 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;27563 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;
27633 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);27564 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
...@@ -27737,7 +27668,7 @@ fn finishFieldCallBind(...@@ -27737,7 +27668,7 @@ fn finishFieldCallBind(
27737 object_ptr: Air.Inst.Ref,27668 object_ptr: Air.Inst.Ref,
27738) CompileError!ResolvedFieldCallee {27669) CompileError!ResolvedFieldCallee {
27739 const mod = sema.mod;27670 const mod = sema.mod;
27740 const ptr_field_ty = try sema.ptrType(.{27671 const ptr_field_ty = try mod.ptrTypeSema(.{
27741 .child = field_ty.toIntern(),27672 .child = field_ty.toIntern(),
27742 .flags = .{27673 .flags = .{
27743 .is_const = !ptr_ty.ptrIsMutable(mod),27674 .is_const = !ptr_ty.ptrIsMutable(mod),
...@@ -27748,14 +27679,14 @@ fn finishFieldCallBind(...@@ -27748,14 +27679,14 @@ fn finishFieldCallBind(
27748 const container_ty = ptr_ty.childType(mod);27679 const container_ty = ptr_ty.childType(mod);
27749 if (container_ty.zigTypeTag(mod) == .Struct) {27680 if (container_ty.zigTypeTag(mod) == .Struct) {
27750 if (container_ty.structFieldIsComptime(field_index, mod)) {27681 if (container_ty.structFieldIsComptime(field_index, mod)) {
27751 try sema.resolveStructFieldInits(container_ty);27682 try container_ty.resolveStructFieldInits(mod);
27752 const default_val = (try container_ty.structFieldValueComptime(mod, field_index)).?;27683 const default_val = (try container_ty.structFieldValueComptime(mod, field_index)).?;
27753 return .{ .direct = Air.internedToRef(default_val.toIntern()) };27684 return .{ .direct = Air.internedToRef(default_val.toIntern()) };
27754 }27685 }
27755 }27686 }
2775627687
27757 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {27688 if (try sema.resolveDefinedValue(block, src, object_ptr)) |struct_ptr_val| {
27758 const ptr_val = try struct_ptr_val.ptrField(field_index, sema);27689 const ptr_val = try struct_ptr_val.ptrField(field_index, mod);
27759 const pointer = Air.internedToRef(ptr_val.toIntern());27690 const pointer = Air.internedToRef(ptr_val.toIntern());
27760 return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) };27691 return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) };
27761 }27692 }
...@@ -27831,8 +27762,8 @@ fn structFieldPtr(...@@ -27831,8 +27762,8 @@ fn structFieldPtr(
27831 const ip = &mod.intern_pool;27762 const ip = &mod.intern_pool;
27832 assert(struct_ty.zigTypeTag(mod) == .Struct);27763 assert(struct_ty.zigTypeTag(mod) == .Struct);
2783327764
27834 try sema.resolveTypeFields(struct_ty);27765 try struct_ty.resolveFields(mod);
27835 try sema.resolveStructLayout(struct_ty);27766 try struct_ty.resolveLayout(mod);
2783627767
27837 if (struct_ty.isTuple(mod)) {27768 if (struct_ty.isTuple(mod)) {
27838 if (field_name.eqlSlice("len", ip)) {27769 if (field_name.eqlSlice("len", ip)) {
...@@ -27871,7 +27802,7 @@ fn structFieldPtrByIndex(...@@ -27871,7 +27802,7 @@ fn structFieldPtrByIndex(
27871 }27802 }
2787227803
27873 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {27804 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
27874 const val = try struct_ptr_val.ptrField(field_index, sema);27805 const val = try struct_ptr_val.ptrField(field_index, mod);
27875 return Air.internedToRef(val.toIntern());27806 return Air.internedToRef(val.toIntern());
27876 }27807 }
2787727808
...@@ -27915,10 +27846,11 @@ fn structFieldPtrByIndex(...@@ -27915,10 +27846,11 @@ fn structFieldPtrByIndex(
27915 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));27846 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));
27916 } else {27847 } else {
27917 // Our alignment is capped at the field alignment.27848 // Our alignment is capped at the field alignment.
27918 const field_align = try sema.structFieldAlignment(27849 const field_align = try mod.structFieldAlignmentAdvanced(
27919 struct_type.fieldAlign(ip, field_index),27850 struct_type.fieldAlign(ip, field_index),
27920 Type.fromInterned(field_ty),27851 Type.fromInterned(field_ty),
27921 struct_type.layout,27852 struct_type.layout,
27853 .sema,
27922 );27854 );
27923 ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none)27855 ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none)
27924 field_align27856 field_align
...@@ -27926,10 +27858,10 @@ fn structFieldPtrByIndex(...@@ -27926,10 +27858,10 @@ fn structFieldPtrByIndex(
27926 field_align.min(parent_align);27858 field_align.min(parent_align);
27927 }27859 }
2792827860
27929 const ptr_field_ty = try sema.ptrType(ptr_ty_data);27861 const ptr_field_ty = try mod.ptrTypeSema(ptr_ty_data);
2793027862
27931 if (struct_type.fieldIsComptime(ip, field_index)) {27863 if (struct_type.fieldIsComptime(ip, field_index)) {
27932 try sema.resolveStructFieldInits(struct_ty);27864 try struct_ty.resolveStructFieldInits(mod);
27933 const val = try mod.intern(.{ .ptr = .{27865 const val = try mod.intern(.{ .ptr = .{
27934 .ty = ptr_field_ty.toIntern(),27866 .ty = ptr_field_ty.toIntern(),
27935 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },27867 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },
...@@ -27955,7 +27887,7 @@ fn structFieldVal(...@@ -27955,7 +27887,7 @@ fn structFieldVal(
27955 const ip = &mod.intern_pool;27887 const ip = &mod.intern_pool;
27956 assert(struct_ty.zigTypeTag(mod) == .Struct);27888 assert(struct_ty.zigTypeTag(mod) == .Struct);
2795727889
27958 try sema.resolveTypeFields(struct_ty);27890 try struct_ty.resolveFields(mod);
2795927891
27960 switch (ip.indexToKey(struct_ty.toIntern())) {27892 switch (ip.indexToKey(struct_ty.toIntern())) {
27961 .struct_type => {27893 .struct_type => {
...@@ -27966,7 +27898,7 @@ fn structFieldVal(...@@ -27966,7 +27898,7 @@ fn structFieldVal(
27966 const field_index = struct_type.nameIndex(ip, field_name) orelse27898 const field_index = struct_type.nameIndex(ip, field_name) orelse
27967 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);27899 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
27968 if (struct_type.fieldIsComptime(ip, field_index)) {27900 if (struct_type.fieldIsComptime(ip, field_index)) {
27969 try sema.resolveStructFieldInits(struct_ty);27901 try struct_ty.resolveStructFieldInits(mod);
27970 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);27902 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
27971 }27903 }
2797227904
...@@ -27983,7 +27915,7 @@ fn structFieldVal(...@@ -27983,7 +27915,7 @@ fn structFieldVal(
27983 }27915 }
2798427916
27985 try sema.requireRuntimeBlock(block, src, null);27917 try sema.requireRuntimeBlock(block, src, null);
27986 try sema.resolveTypeLayout(field_ty);27918 try field_ty.resolveLayout(mod);
27987 return block.addStructFieldVal(struct_byval, field_index, field_ty);27919 return block.addStructFieldVal(struct_byval, field_index, field_ty);
27988 },27920 },
27989 .anon_struct_type => |anon_struct| {27921 .anon_struct_type => |anon_struct| {
...@@ -28050,7 +27982,7 @@ fn tupleFieldValByIndex(...@@ -28050,7 +27982,7 @@ fn tupleFieldValByIndex(
28050 const field_ty = tuple_ty.structFieldType(field_index, mod);27982 const field_ty = tuple_ty.structFieldType(field_index, mod);
2805127983
28052 if (tuple_ty.structFieldIsComptime(field_index, mod))27984 if (tuple_ty.structFieldIsComptime(field_index, mod))
28053 try sema.resolveStructFieldInits(tuple_ty);27985 try tuple_ty.resolveStructFieldInits(mod);
28054 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {27986 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
28055 return Air.internedToRef(default_value.toIntern());27987 return Air.internedToRef(default_value.toIntern());
28056 }27988 }
...@@ -28071,7 +28003,7 @@ fn tupleFieldValByIndex(...@@ -28071,7 +28003,7 @@ fn tupleFieldValByIndex(
28071 }28003 }
2807228004
28073 try sema.requireRuntimeBlock(block, src, null);28005 try sema.requireRuntimeBlock(block, src, null);
28074 try sema.resolveTypeLayout(field_ty);28006 try field_ty.resolveLayout(mod);
28075 return block.addStructFieldVal(tuple_byval, field_index, field_ty);28007 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
28076}28008}
2807728009
...@@ -28092,11 +28024,11 @@ fn unionFieldPtr(...@@ -28092,11 +28024,11 @@ fn unionFieldPtr(
2809228024
28093 const union_ptr_ty = sema.typeOf(union_ptr);28025 const union_ptr_ty = sema.typeOf(union_ptr);
28094 const union_ptr_info = union_ptr_ty.ptrInfo(mod);28026 const union_ptr_info = union_ptr_ty.ptrInfo(mod);
28095 try sema.resolveTypeFields(union_ty);28027 try union_ty.resolveFields(mod);
28096 const union_obj = mod.typeToUnion(union_ty).?;28028 const union_obj = mod.typeToUnion(union_ty).?;
28097 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);28029 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
28098 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);28030 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
28099 const ptr_field_ty = try sema.ptrType(.{28031 const ptr_field_ty = try mod.ptrTypeSema(.{
28100 .child = field_ty.toIntern(),28032 .child = field_ty.toIntern(),
28101 .flags = .{28033 .flags = .{
28102 .is_const = union_ptr_info.flags.is_const,28034 .is_const = union_ptr_info.flags.is_const,
...@@ -28107,7 +28039,7 @@ fn unionFieldPtr(...@@ -28107,7 +28039,7 @@ fn unionFieldPtr(
28107 union_ptr_info.flags.alignment28039 union_ptr_info.flags.alignment
28108 else28040 else
28109 try sema.typeAbiAlignment(union_ty);28041 try sema.typeAbiAlignment(union_ty);
28110 const field_align = try sema.unionFieldAlignment(union_obj, field_index);28042 const field_align = try mod.unionFieldNormalAlignmentAdvanced(union_obj, field_index, .sema);
28111 break :blk union_align.min(field_align);28043 break :blk union_align.min(field_align);
28112 } else union_ptr_info.flags.alignment,28044 } else union_ptr_info.flags.alignment,
28113 },28045 },
...@@ -28163,7 +28095,7 @@ fn unionFieldPtr(...@@ -28163,7 +28095,7 @@ fn unionFieldPtr(
28163 },28095 },
28164 .@"packed", .@"extern" => {},28096 .@"packed", .@"extern" => {},
28165 }28097 }
28166 const field_ptr_val = try union_ptr_val.ptrField(field_index, sema);28098 const field_ptr_val = try union_ptr_val.ptrField(field_index, mod);
28167 return Air.internedToRef(field_ptr_val.toIntern());28099 return Air.internedToRef(field_ptr_val.toIntern());
28168 }28100 }
2816928101
...@@ -28198,7 +28130,7 @@ fn unionFieldVal(...@@ -28198,7 +28130,7 @@ fn unionFieldVal(
28198 const ip = &zcu.intern_pool;28130 const ip = &zcu.intern_pool;
28199 assert(union_ty.zigTypeTag(zcu) == .Union);28131 assert(union_ty.zigTypeTag(zcu) == .Union);
2820028132
28201 try sema.resolveTypeFields(union_ty);28133 try union_ty.resolveFields(zcu);
28202 const union_obj = zcu.typeToUnion(union_ty).?;28134 const union_obj = zcu.typeToUnion(union_ty).?;
28203 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);28135 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
28204 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);28136 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
...@@ -28237,7 +28169,7 @@ fn unionFieldVal(...@@ -28237,7 +28169,7 @@ fn unionFieldVal(
28237 .@"packed" => if (tag_matches) {28169 .@"packed" => if (tag_matches) {
28238 // Fast path - no need to use bitcast logic.28170 // Fast path - no need to use bitcast logic.
28239 return Air.internedToRef(un.val);28171 return Air.internedToRef(un.val);
28240 } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeAdvanced(zcu, sema), 0)) |field_val| {28172 } else if (try sema.bitCastVal(union_val, field_ty, 0, try union_ty.bitSizeAdvanced(zcu, .sema), 0)) |field_val| {
28241 return Air.internedToRef(field_val.toIntern());28173 return Air.internedToRef(field_val.toIntern());
28242 },28174 },
28243 }28175 }
...@@ -28256,7 +28188,7 @@ fn unionFieldVal(...@@ -28256,7 +28188,7 @@ fn unionFieldVal(
28256 _ = try block.addNoOp(.unreach);28188 _ = try block.addNoOp(.unreach);
28257 return .unreachable_value;28189 return .unreachable_value;
28258 }28190 }
28259 try sema.resolveTypeLayout(field_ty);28191 try field_ty.resolveLayout(zcu);
28260 return block.addStructFieldVal(union_byval, field_index, field_ty);28192 return block.addStructFieldVal(union_byval, field_index, field_ty);
28261}28193}
2826228194
...@@ -28287,7 +28219,7 @@ fn elemPtr(...@@ -28287,7 +28219,7 @@ fn elemPtr(
28287 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28219 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28288 .needed_comptime_reason = "tuple field access index must be comptime-known",28220 .needed_comptime_reason = "tuple field access index must be comptime-known",
28289 });28221 });
28290 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));28222 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));
28291 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);28223 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
28292 },28224 },
28293 else => {28225 else => {
...@@ -28325,11 +28257,11 @@ fn elemPtrOneLayerOnly(...@@ -28325,11 +28257,11 @@ fn elemPtrOneLayerOnly(
28325 const runtime_src = rs: {28257 const runtime_src = rs: {
28326 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;28258 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;
28327 const index_val = maybe_index_val orelse break :rs elem_index_src;28259 const index_val = maybe_index_val orelse break :rs elem_index_src;
28328 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));28260 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));
28329 const elem_ptr = try ptr_val.ptrElem(index, sema);28261 const elem_ptr = try ptr_val.ptrElem(index, mod);
28330 return Air.internedToRef(elem_ptr.toIntern());28262 return Air.internedToRef(elem_ptr.toIntern());
28331 };28263 };
28332 const result_ty = try sema.elemPtrType(indexable_ty, null);28264 const result_ty = try indexable_ty.elemPtrType(null, mod);
2833328265
28334 try sema.requireRuntimeBlock(block, src, runtime_src);28266 try sema.requireRuntimeBlock(block, src, runtime_src);
28335 return block.addPtrElemPtr(indexable, elem_index, result_ty);28267 return block.addPtrElemPtr(indexable, elem_index, result_ty);
...@@ -28343,7 +28275,7 @@ fn elemPtrOneLayerOnly(...@@ -28343,7 +28275,7 @@ fn elemPtrOneLayerOnly(
28343 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28275 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28344 .needed_comptime_reason = "tuple field access index must be comptime-known",28276 .needed_comptime_reason = "tuple field access index must be comptime-known",
28345 });28277 });
28346 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));28278 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));
28347 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);28279 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);
28348 },28280 },
28349 else => unreachable, // Guaranteed by checkIndexable28281 else => unreachable, // Guaranteed by checkIndexable
...@@ -28383,12 +28315,12 @@ fn elemVal(...@@ -28383,12 +28315,12 @@ fn elemVal(
28383 const runtime_src = rs: {28315 const runtime_src = rs: {
28384 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;28316 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
28385 const index_val = maybe_index_val orelse break :rs elem_index_src;28317 const index_val = maybe_index_val orelse break :rs elem_index_src;
28386 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));28318 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));
28387 const elem_ty = indexable_ty.elemType2(mod);28319 const elem_ty = indexable_ty.elemType2(mod);
28388 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);28320 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);
28389 const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty);28321 const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty);
28390 const elem_ptr_ty = try mod.singleConstPtrType(elem_ty);28322 const elem_ptr_ty = try mod.singleConstPtrType(elem_ty);
28391 const elem_ptr_val = try many_ptr_val.ptrElem(index, sema);28323 const elem_ptr_val = try many_ptr_val.ptrElem(index, mod);
28392 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {28324 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
28393 return Air.internedToRef((try mod.getCoerced(elem_val, elem_ty)).toIntern());28325 return Air.internedToRef((try mod.getCoerced(elem_val, elem_ty)).toIntern());
28394 }28326 }
...@@ -28404,7 +28336,7 @@ fn elemVal(...@@ -28404,7 +28336,7 @@ fn elemVal(
28404 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;28336 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;
28405 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;28337 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;
28406 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;28338 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;
28407 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntAdvanced(sema));28339 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntSema(mod));
28408 if (index != inner_ty.arrayLen(mod)) break :arr_sent;28340 if (index != inner_ty.arrayLen(mod)) break :arr_sent;
28409 return Air.internedToRef(sentinel.toIntern());28341 return Air.internedToRef(sentinel.toIntern());
28410 }28342 }
...@@ -28422,7 +28354,7 @@ fn elemVal(...@@ -28422,7 +28354,7 @@ fn elemVal(
28422 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{28354 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
28423 .needed_comptime_reason = "tuple field access index must be comptime-known",28355 .needed_comptime_reason = "tuple field access index must be comptime-known",
28424 });28356 });
28425 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));28357 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));
28426 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);28358 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
28427 },28359 },
28428 else => unreachable,28360 else => unreachable,
...@@ -28467,7 +28399,7 @@ fn tupleFieldPtr(...@@ -28467,7 +28399,7 @@ fn tupleFieldPtr(
28467 const mod = sema.mod;28399 const mod = sema.mod;
28468 const tuple_ptr_ty = sema.typeOf(tuple_ptr);28400 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
28469 const tuple_ty = tuple_ptr_ty.childType(mod);28401 const tuple_ty = tuple_ptr_ty.childType(mod);
28470 try sema.resolveTypeFields(tuple_ty);28402 try tuple_ty.resolveFields(mod);
28471 const field_count = tuple_ty.structFieldCount(mod);28403 const field_count = tuple_ty.structFieldCount(mod);
2847228404
28473 if (field_count == 0) {28405 if (field_count == 0) {
...@@ -28481,7 +28413,7 @@ fn tupleFieldPtr(...@@ -28481,7 +28413,7 @@ fn tupleFieldPtr(
28481 }28413 }
2848228414
28483 const field_ty = tuple_ty.structFieldType(field_index, mod);28415 const field_ty = tuple_ty.structFieldType(field_index, mod);
28484 const ptr_field_ty = try sema.ptrType(.{28416 const ptr_field_ty = try mod.ptrTypeSema(.{
28485 .child = field_ty.toIntern(),28417 .child = field_ty.toIntern(),
28486 .flags = .{28418 .flags = .{
28487 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),28419 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),
...@@ -28491,7 +28423,7 @@ fn tupleFieldPtr(...@@ -28491,7 +28423,7 @@ fn tupleFieldPtr(
28491 });28423 });
2849228424
28493 if (tuple_ty.structFieldIsComptime(field_index, mod))28425 if (tuple_ty.structFieldIsComptime(field_index, mod))
28494 try sema.resolveStructFieldInits(tuple_ty);28426 try tuple_ty.resolveStructFieldInits(mod);
2849528427
28496 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {28428 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
28497 return Air.internedToRef((try mod.intern(.{ .ptr = .{28429 return Air.internedToRef((try mod.intern(.{ .ptr = .{
...@@ -28502,7 +28434,7 @@ fn tupleFieldPtr(...@@ -28502,7 +28434,7 @@ fn tupleFieldPtr(
28502 }28434 }
2850328435
28504 if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| {28436 if (try sema.resolveValue(tuple_ptr)) |tuple_ptr_val| {
28505 const field_ptr_val = try tuple_ptr_val.ptrField(field_index, sema);28437 const field_ptr_val = try tuple_ptr_val.ptrField(field_index, mod);
28506 return Air.internedToRef(field_ptr_val.toIntern());28438 return Air.internedToRef(field_ptr_val.toIntern());
28507 }28439 }
2850828440
...@@ -28524,7 +28456,7 @@ fn tupleField(...@@ -28524,7 +28456,7 @@ fn tupleField(
28524) CompileError!Air.Inst.Ref {28456) CompileError!Air.Inst.Ref {
28525 const mod = sema.mod;28457 const mod = sema.mod;
28526 const tuple_ty = sema.typeOf(tuple);28458 const tuple_ty = sema.typeOf(tuple);
28527 try sema.resolveTypeFields(tuple_ty);28459 try tuple_ty.resolveFields(mod);
28528 const field_count = tuple_ty.structFieldCount(mod);28460 const field_count = tuple_ty.structFieldCount(mod);
2852928461
28530 if (field_count == 0) {28462 if (field_count == 0) {
...@@ -28540,7 +28472,7 @@ fn tupleField(...@@ -28540,7 +28472,7 @@ fn tupleField(
28540 const field_ty = tuple_ty.structFieldType(field_index, mod);28472 const field_ty = tuple_ty.structFieldType(field_index, mod);
2854128473
28542 if (tuple_ty.structFieldIsComptime(field_index, mod))28474 if (tuple_ty.structFieldIsComptime(field_index, mod))
28543 try sema.resolveStructFieldInits(tuple_ty);28475 try tuple_ty.resolveStructFieldInits(mod);
28544 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {28476 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
28545 return Air.internedToRef(default_value.toIntern()); // comptime field28477 return Air.internedToRef(default_value.toIntern()); // comptime field
28546 }28478 }
...@@ -28553,7 +28485,7 @@ fn tupleField(...@@ -28553,7 +28485,7 @@ fn tupleField(
28553 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);28485 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
2855428486
28555 try sema.requireRuntimeBlock(block, tuple_src, null);28487 try sema.requireRuntimeBlock(block, tuple_src, null);
28556 try sema.resolveTypeLayout(field_ty);28488 try field_ty.resolveLayout(mod);
28557 return block.addStructFieldVal(tuple, field_index, field_ty);28489 return block.addStructFieldVal(tuple, field_index, field_ty);
28558}28490}
2855928491
...@@ -28583,7 +28515,7 @@ fn elemValArray(...@@ -28583,7 +28515,7 @@ fn elemValArray(
28583 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);28515 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2858428516
28585 if (maybe_index_val) |index_val| {28517 if (maybe_index_val) |index_val| {
28586 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));28518 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));
28587 if (array_sent) |s| {28519 if (array_sent) |s| {
28588 if (index == array_len) {28520 if (index == array_len) {
28589 return Air.internedToRef(s.toIntern());28521 return Air.internedToRef(s.toIntern());
...@@ -28599,7 +28531,7 @@ fn elemValArray(...@@ -28599,7 +28531,7 @@ fn elemValArray(
28599 return mod.undefRef(elem_ty);28531 return mod.undefRef(elem_ty);
28600 }28532 }
28601 if (maybe_index_val) |index_val| {28533 if (maybe_index_val) |index_val| {
28602 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));28534 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));
28603 const elem_val = try array_val.elemValue(mod, index);28535 const elem_val = try array_val.elemValue(mod, index);
28604 return Air.internedToRef(elem_val.toIntern());28536 return Air.internedToRef(elem_val.toIntern());
28605 }28537 }
...@@ -28621,7 +28553,6 @@ fn elemValArray(...@@ -28621,7 +28553,6 @@ fn elemValArray(
28621 return Air.internedToRef(elem_val.toIntern());28553 return Air.internedToRef(elem_val.toIntern());
2862228554
28623 try sema.requireRuntimeBlock(block, src, runtime_src);28555 try sema.requireRuntimeBlock(block, src, runtime_src);
28624 try sema.queueFullTypeResolution(array_ty);
28625 return block.addBinOp(.array_elem_val, array, elem_index);28556 return block.addBinOp(.array_elem_val, array, elem_index);
28626}28557}
2862728558
...@@ -28650,7 +28581,7 @@ fn elemPtrArray(...@@ -28650,7 +28581,7 @@ fn elemPtrArray(
28650 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);28581 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);
28651 // The index must not be undefined since it can be out of bounds.28582 // The index must not be undefined since it can be out of bounds.
28652 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {28583 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28653 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntAdvanced(sema));28584 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(mod));
28654 if (index >= array_len_s) {28585 if (index >= array_len_s) {
28655 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";28586 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
28656 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });28587 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -28658,14 +28589,14 @@ fn elemPtrArray(...@@ -28658,14 +28589,14 @@ fn elemPtrArray(
28658 break :o index;28589 break :o index;
28659 } else null;28590 } else null;
2866028591
28661 const elem_ptr_ty = try sema.elemPtrType(array_ptr_ty, offset);28592 const elem_ptr_ty = try array_ptr_ty.elemPtrType(offset, mod);
2866228593
28663 if (maybe_undef_array_ptr_val) |array_ptr_val| {28594 if (maybe_undef_array_ptr_val) |array_ptr_val| {
28664 if (array_ptr_val.isUndef(mod)) {28595 if (array_ptr_val.isUndef(mod)) {
28665 return mod.undefRef(elem_ptr_ty);28596 return mod.undefRef(elem_ptr_ty);
28666 }28597 }
28667 if (offset) |index| {28598 if (offset) |index| {
28668 const elem_ptr = try array_ptr_val.ptrElem(index, sema);28599 const elem_ptr = try array_ptr_val.ptrElem(index, mod);
28669 return Air.internedToRef(elem_ptr.toIntern());28600 return Air.internedToRef(elem_ptr.toIntern());
28670 }28601 }
28671 }28602 }
...@@ -28710,19 +28641,19 @@ fn elemValSlice(...@@ -28710,19 +28641,19 @@ fn elemValSlice(
2871028641
28711 if (maybe_slice_val) |slice_val| {28642 if (maybe_slice_val) |slice_val| {
28712 runtime_src = elem_index_src;28643 runtime_src = elem_index_src;
28713 const slice_len = try slice_val.sliceLen(sema);28644 const slice_len = try slice_val.sliceLen(mod);
28714 const slice_len_s = slice_len + @intFromBool(slice_sent);28645 const slice_len_s = slice_len + @intFromBool(slice_sent);
28715 if (slice_len_s == 0) {28646 if (slice_len_s == 0) {
28716 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});28647 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
28717 }28648 }
28718 if (maybe_index_val) |index_val| {28649 if (maybe_index_val) |index_val| {
28719 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));28650 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));
28720 if (index >= slice_len_s) {28651 if (index >= slice_len_s) {
28721 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";28652 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
28722 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });28653 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28723 }28654 }
28724 const elem_ptr_ty = try sema.elemPtrType(slice_ty, index);28655 const elem_ptr_ty = try slice_ty.elemPtrType(index, mod);
28725 const elem_ptr_val = try slice_val.ptrElem(index, sema);28656 const elem_ptr_val = try slice_val.ptrElem(index, mod);
28726 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {28657 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
28727 return Air.internedToRef(elem_val.toIntern());28658 return Air.internedToRef(elem_val.toIntern());
28728 }28659 }
...@@ -28735,13 +28666,12 @@ fn elemValSlice(...@@ -28735,13 +28666,12 @@ fn elemValSlice(
28735 try sema.requireRuntimeBlock(block, src, runtime_src);28666 try sema.requireRuntimeBlock(block, src, runtime_src);
28736 if (oob_safety and block.wantSafety()) {28667 if (oob_safety and block.wantSafety()) {
28737 const len_inst = if (maybe_slice_val) |slice_val|28668 const len_inst = if (maybe_slice_val) |slice_val|
28738 try mod.intRef(Type.usize, try slice_val.sliceLen(sema))28669 try mod.intRef(Type.usize, try slice_val.sliceLen(mod))
28739 else28670 else
28740 try block.addTyOp(.slice_len, Type.usize, slice);28671 try block.addTyOp(.slice_len, Type.usize, slice);
28741 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;28672 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
28742 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);28673 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
28743 }28674 }
28744 try sema.queueFullTypeResolution(sema.typeOf(slice));
28745 return block.addBinOp(.slice_elem_val, slice, elem_index);28675 return block.addBinOp(.slice_elem_val, slice, elem_index);
28746}28676}
2874728677
...@@ -28762,17 +28692,17 @@ fn elemPtrSlice(...@@ -28762,17 +28692,17 @@ fn elemPtrSlice(
28762 const maybe_undef_slice_val = try sema.resolveValue(slice);28692 const maybe_undef_slice_val = try sema.resolveValue(slice);
28763 // The index must not be undefined since it can be out of bounds.28693 // The index must not be undefined since it can be out of bounds.
28764 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {28694 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28765 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntAdvanced(sema));28695 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntSema(mod));
28766 break :o index;28696 break :o index;
28767 } else null;28697 } else null;
2876828698
28769 const elem_ptr_ty = try sema.elemPtrType(slice_ty, offset);28699 const elem_ptr_ty = try slice_ty.elemPtrType(offset, mod);
2877028700
28771 if (maybe_undef_slice_val) |slice_val| {28701 if (maybe_undef_slice_val) |slice_val| {
28772 if (slice_val.isUndef(mod)) {28702 if (slice_val.isUndef(mod)) {
28773 return mod.undefRef(elem_ptr_ty);28703 return mod.undefRef(elem_ptr_ty);
28774 }28704 }
28775 const slice_len = try slice_val.sliceLen(sema);28705 const slice_len = try slice_val.sliceLen(mod);
28776 const slice_len_s = slice_len + @intFromBool(slice_sent);28706 const slice_len_s = slice_len + @intFromBool(slice_sent);
28777 if (slice_len_s == 0) {28707 if (slice_len_s == 0) {
28778 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});28708 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
...@@ -28782,7 +28712,7 @@ fn elemPtrSlice(...@@ -28782,7 +28712,7 @@ fn elemPtrSlice(
28782 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";28712 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
28783 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });28713 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
28784 }28714 }
28785 const elem_ptr_val = try slice_val.ptrElem(index, sema);28715 const elem_ptr_val = try slice_val.ptrElem(index, mod);
28786 return Air.internedToRef(elem_ptr_val.toIntern());28716 return Air.internedToRef(elem_ptr_val.toIntern());
28787 }28717 }
28788 }28718 }
...@@ -28795,7 +28725,7 @@ fn elemPtrSlice(...@@ -28795,7 +28725,7 @@ fn elemPtrSlice(
28795 const len_inst = len: {28725 const len_inst = len: {
28796 if (maybe_undef_slice_val) |slice_val|28726 if (maybe_undef_slice_val) |slice_val|
28797 if (!slice_val.isUndef(mod))28727 if (!slice_val.isUndef(mod))
28798 break :len try mod.intRef(Type.usize, try slice_val.sliceLen(sema));28728 break :len try mod.intRef(Type.usize, try slice_val.sliceLen(mod));
28799 break :len try block.addTyOp(.slice_len, Type.usize, slice);28729 break :len try block.addTyOp(.slice_len, Type.usize, slice);
28800 };28730 };
28801 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;28731 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
...@@ -28860,9 +28790,9 @@ fn coerceExtra(...@@ -28860,9 +28790,9 @@ fn coerceExtra(
28860 if (dest_ty.isGenericPoison()) return inst;28790 if (dest_ty.isGenericPoison()) return inst;
28861 const zcu = sema.mod;28791 const zcu = sema.mod;
28862 const dest_ty_src = inst_src; // TODO better source location28792 const dest_ty_src = inst_src; // TODO better source location
28863 try sema.resolveTypeFields(dest_ty);28793 try dest_ty.resolveFields(zcu);
28864 const inst_ty = sema.typeOf(inst);28794 const inst_ty = sema.typeOf(inst);
28865 try sema.resolveTypeFields(inst_ty);28795 try inst_ty.resolveFields(zcu);
28866 const target = zcu.getTarget();28796 const target = zcu.getTarget();
28867 // If the types are the same, we can return the operand.28797 // If the types are the same, we can return the operand.
28868 if (dest_ty.eql(inst_ty, zcu))28798 if (dest_ty.eql(inst_ty, zcu))
...@@ -28876,7 +28806,6 @@ fn coerceExtra(...@@ -28876,7 +28806,6 @@ fn coerceExtra(
28876 return sema.coerceInMemory(val, dest_ty);28806 return sema.coerceInMemory(val, dest_ty);
28877 }28807 }
28878 try sema.requireRuntimeBlock(block, inst_src, null);28808 try sema.requireRuntimeBlock(block, inst_src, null);
28879 try sema.queueFullTypeResolution(dest_ty);
28880 const new_val = try block.addBitCast(dest_ty, inst);28809 const new_val = try block.addBitCast(dest_ty, inst);
28881 try sema.checkKnownAllocPtr(block, inst, new_val);28810 try sema.checkKnownAllocPtr(block, inst, new_val);
28882 return new_val;28811 return new_val;
...@@ -29172,7 +29101,7 @@ fn coerceExtra(...@@ -29172,7 +29101,7 @@ fn coerceExtra(
29172 // empty tuple to zero-length slice29101 // empty tuple to zero-length slice
29173 // note that this allows coercing to a mutable slice.29102 // note that this allows coercing to a mutable slice.
29174 if (inst_child_ty.structFieldCount(zcu) == 0) {29103 if (inst_child_ty.structFieldCount(zcu) == 0) {
29175 const align_val = try dest_ty.ptrAlignmentAdvanced(zcu, sema);29104 const align_val = try dest_ty.ptrAlignmentAdvanced(zcu, .sema);
29176 return Air.internedToRef(try zcu.intern(.{ .slice = .{29105 return Air.internedToRef(try zcu.intern(.{ .slice = .{
29177 .ty = dest_ty.toIntern(),29106 .ty = dest_ty.toIntern(),
29178 .ptr = try zcu.intern(.{ .ptr = .{29107 .ptr = try zcu.intern(.{ .ptr = .{
...@@ -29317,7 +29246,7 @@ fn coerceExtra(...@@ -29317,7 +29246,7 @@ fn coerceExtra(
29317 }29246 }
29318 break :int;29247 break :int;
29319 };29248 };
29320 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, zcu, sema);29249 const result_val = try val.floatFromIntAdvanced(sema.arena, inst_ty, dest_ty, zcu, .sema);
29321 // TODO implement this compile error29250 // TODO implement this compile error
29322 //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);29251 //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);
29323 //if (!int_again_val.eql(val, inst_ty, zcu)) {29252 //if (!int_again_val.eql(val, inst_ty, zcu)) {
...@@ -30649,7 +30578,6 @@ fn storePtr2(...@@ -30649,7 +30578,6 @@ fn storePtr2(
30649 }30578 }
3065030579
30651 try sema.requireRuntimeBlock(block, src, runtime_src);30580 try sema.requireRuntimeBlock(block, src, runtime_src);
30652 try sema.queueFullTypeResolution(elem_ty);
3065330581
30654 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {30582 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
30655 const ptr_inst = ptr.toIndex().?;30583 const ptr_inst = ptr.toIndex().?;
...@@ -30871,10 +30799,10 @@ fn bitCast(...@@ -30871,10 +30799,10 @@ fn bitCast(
30871 operand_src: ?LazySrcLoc,30799 operand_src: ?LazySrcLoc,
30872) CompileError!Air.Inst.Ref {30800) CompileError!Air.Inst.Ref {
30873 const zcu = sema.mod;30801 const zcu = sema.mod;
30874 try sema.resolveTypeLayout(dest_ty);30802 try dest_ty.resolveLayout(zcu);
3087530803
30876 const old_ty = sema.typeOf(inst);30804 const old_ty = sema.typeOf(inst);
30877 try sema.resolveTypeLayout(old_ty);30805 try old_ty.resolveLayout(zcu);
3087830806
30879 const dest_bits = dest_ty.bitSize(zcu);30807 const dest_bits = dest_ty.bitSize(zcu);
30880 const old_bits = old_ty.bitSize(zcu);30808 const old_bits = old_ty.bitSize(zcu);
...@@ -31056,7 +30984,7 @@ fn coerceEnumToUnion(...@@ -31056,7 +30984,7 @@ fn coerceEnumToUnion(
3105630984
31057 const union_obj = mod.typeToUnion(union_ty).?;30985 const union_obj = mod.typeToUnion(union_ty).?;
31058 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);30986 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
31059 try sema.resolveTypeFields(field_ty);30987 try field_ty.resolveFields(mod);
31060 if (field_ty.zigTypeTag(mod) == .NoReturn) {30988 if (field_ty.zigTypeTag(mod) == .NoReturn) {
31061 const msg = msg: {30989 const msg = msg: {
31062 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});30990 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});
...@@ -31469,8 +31397,8 @@ fn coerceTupleToStruct(...@@ -31469,8 +31397,8 @@ fn coerceTupleToStruct(
31469) !Air.Inst.Ref {31397) !Air.Inst.Ref {
31470 const mod = sema.mod;31398 const mod = sema.mod;
31471 const ip = &mod.intern_pool;31399 const ip = &mod.intern_pool;
31472 try sema.resolveTypeFields(struct_ty);31400 try struct_ty.resolveFields(mod);
31473 try sema.resolveStructFieldInits(struct_ty);31401 try struct_ty.resolveStructFieldInits(mod);
3147431402
31475 if (struct_ty.isTupleOrAnonStruct(mod)) {31403 if (struct_ty.isTupleOrAnonStruct(mod)) {
31476 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);31404 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
...@@ -31817,7 +31745,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl...@@ -31817,7 +31745,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
31817 });31745 });
31818 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type31746 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type
31819 try sema.declareDependency(.{ .decl_val = decl_index });31747 try sema.declareDependency(.{ .decl_val = decl_index });
31820 const ptr_ty = try sema.ptrType(.{31748 const ptr_ty = try mod.ptrTypeSema(.{
31821 .child = decl_val.typeOf(mod).toIntern(),31749 .child = decl_val.typeOf(mod).toIntern(),
31822 .flags = .{31750 .flags = .{
31823 .alignment = owner_decl.alignment,31751 .alignment = owner_decl.alignment,
...@@ -31864,14 +31792,14 @@ fn analyzeRef(...@@ -31864,14 +31792,14 @@ fn analyzeRef(
3186431792
31865 try sema.requireRuntimeBlock(block, src, null);31793 try sema.requireRuntimeBlock(block, src, null);
31866 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);31794 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);
31867 const ptr_type = try sema.ptrType(.{31795 const ptr_type = try mod.ptrTypeSema(.{
31868 .child = operand_ty.toIntern(),31796 .child = operand_ty.toIntern(),
31869 .flags = .{31797 .flags = .{
31870 .is_const = true,31798 .is_const = true,
31871 .address_space = address_space,31799 .address_space = address_space,
31872 },31800 },
31873 });31801 });
31874 const mut_ptr_type = try sema.ptrType(.{31802 const mut_ptr_type = try mod.ptrTypeSema(.{
31875 .child = operand_ty.toIntern(),31803 .child = operand_ty.toIntern(),
31876 .flags = .{ .address_space = address_space },31804 .flags = .{ .address_space = address_space },
31877 });31805 });
...@@ -31979,7 +31907,7 @@ fn analyzeSliceLen(...@@ -31979,7 +31907,7 @@ fn analyzeSliceLen(
31979 if (slice_val.isUndef(mod)) {31907 if (slice_val.isUndef(mod)) {
31980 return mod.undefRef(Type.usize);31908 return mod.undefRef(Type.usize);
31981 }31909 }
31982 return mod.intRef(Type.usize, try slice_val.sliceLen(sema));31910 return mod.intRef(Type.usize, try slice_val.sliceLen(mod));
31983 }31911 }
31984 try sema.requireRuntimeBlock(block, src, null);31912 try sema.requireRuntimeBlock(block, src, null);
31985 return block.addTyOp(.slice_len, Type.usize, slice_inst);31913 return block.addTyOp(.slice_len, Type.usize, slice_inst);
...@@ -32347,7 +32275,7 @@ fn analyzeSlice(...@@ -32347,7 +32275,7 @@ fn analyzeSlice(
32347 assert(manyptr_ty_key.flags.size == .One);32275 assert(manyptr_ty_key.flags.size == .One);
32348 manyptr_ty_key.child = elem_ty.toIntern();32276 manyptr_ty_key.child = elem_ty.toIntern();
32349 manyptr_ty_key.flags.size = .Many;32277 manyptr_ty_key.flags.size = .Many;
32350 break :ptr try sema.coerceCompatiblePtrs(block, try sema.ptrType(manyptr_ty_key), ptr_or_slice, ptr_src);32278 break :ptr try sema.coerceCompatiblePtrs(block, try mod.ptrTypeSema(manyptr_ty_key), ptr_or_slice, ptr_src);
32351 } else ptr_or_slice;32279 } else ptr_or_slice;
3235232280
32353 const start = try sema.coerce(block, Type.usize, uncasted_start, start_src);32281 const start = try sema.coerce(block, Type.usize, uncasted_start, start_src);
...@@ -32416,7 +32344,7 @@ fn analyzeSlice(...@@ -32416,7 +32344,7 @@ fn analyzeSlice(
32416 return sema.fail(block, src, "slice of undefined", .{});32344 return sema.fail(block, src, "slice of undefined", .{});
32417 }32345 }
32418 const has_sentinel = slice_ty.sentinel(mod) != null;32346 const has_sentinel = slice_ty.sentinel(mod) != null;
32419 const slice_len = try slice_val.sliceLen(sema);32347 const slice_len = try slice_val.sliceLen(mod);
32420 const len_plus_sent = slice_len + @intFromBool(has_sentinel);32348 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
32421 const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent);32349 const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent);
32422 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {32350 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {
...@@ -32431,7 +32359,7 @@ fn analyzeSlice(...@@ -32431,7 +32359,7 @@ fn analyzeSlice(
32431 "end index {} out of bounds for slice of length {d}{s}",32359 "end index {} out of bounds for slice of length {d}{s}",
32432 .{32360 .{
32433 end_val.fmtValue(mod, sema),32361 end_val.fmtValue(mod, sema),
32434 try slice_val.sliceLen(sema),32362 try slice_val.sliceLen(mod),
32435 sentinel_label,32363 sentinel_label,
32436 },32364 },
32437 );32365 );
...@@ -32504,7 +32432,7 @@ fn analyzeSlice(...@@ -32504,7 +32432,7 @@ fn analyzeSlice(
3250432432
32505 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);32433 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);
32506 const many_ptr_val = try mod.getCoerced(ptr_val, many_ptr_ty);32434 const many_ptr_val = try mod.getCoerced(ptr_val, many_ptr_ty);
32507 const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, sema);32435 const elem_ptr = try many_ptr_val.ptrElem(sentinel_index, mod);
32508 const res = try sema.pointerDerefExtra(block, src, elem_ptr);32436 const res = try sema.pointerDerefExtra(block, src, elem_ptr);
32509 const actual_sentinel = switch (res) {32437 const actual_sentinel = switch (res) {
32510 .runtime_load => break :sentinel_check,32438 .runtime_load => break :sentinel_check,
...@@ -32567,9 +32495,9 @@ fn analyzeSlice(...@@ -32567,9 +32495,9 @@ fn analyzeSlice(
32567 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;32495 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;
3256832496
32569 if (opt_new_len_val) |new_len_val| {32497 if (opt_new_len_val) |new_len_val| {
32570 const new_len_int = try new_len_val.toUnsignedIntAdvanced(sema);32498 const new_len_int = try new_len_val.toUnsignedIntSema(mod);
3257132499
32572 const return_ty = try sema.ptrType(.{32500 const return_ty = try mod.ptrTypeSema(.{
32573 .child = (try mod.arrayType(.{32501 .child = (try mod.arrayType(.{
32574 .len = new_len_int,32502 .len = new_len_int,
32575 .sentinel = if (sentinel) |s| s.toIntern() else .none,32503 .sentinel = if (sentinel) |s| s.toIntern() else .none,
...@@ -32631,7 +32559,7 @@ fn analyzeSlice(...@@ -32631,7 +32559,7 @@ fn analyzeSlice(
32631 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});32559 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
32632 }32560 }
3263332561
32634 const return_ty = try sema.ptrType(.{32562 const return_ty = try mod.ptrTypeSema(.{
32635 .child = elem_ty.toIntern(),32563 .child = elem_ty.toIntern(),
32636 .sentinel = if (sentinel) |s| s.toIntern() else .none,32564 .sentinel = if (sentinel) |s| s.toIntern() else .none,
32637 .flags = .{32565 .flags = .{
...@@ -32659,7 +32587,7 @@ fn analyzeSlice(...@@ -32659,7 +32587,7 @@ fn analyzeSlice(
32659 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {32587 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
32660 // we don't need to add one for sentinels because the32588 // we don't need to add one for sentinels because the
32661 // underlying value data includes the sentinel32589 // underlying value data includes the sentinel
32662 break :blk try mod.intRef(Type.usize, try slice_val.sliceLen(sema));32590 break :blk try mod.intRef(Type.usize, try slice_val.sliceLen(mod));
32663 }32591 }
3266432592
32665 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);32593 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
...@@ -32751,7 +32679,7 @@ fn cmpNumeric(...@@ -32751,7 +32679,7 @@ fn cmpNumeric(
32751 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {32679 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {
32752 return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false;32680 return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false;
32753 }32681 }
32754 return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, mod, sema))32682 return if (try Value.compareHeteroAdvanced(lhs_val, op, rhs_val, mod, .sema))
32755 .bool_true32683 .bool_true
32756 else32684 else
32757 .bool_false;32685 .bool_false;
...@@ -32820,11 +32748,11 @@ fn cmpNumeric(...@@ -32820,11 +32748,11 @@ fn cmpNumeric(
32820 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,32748 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,
32821 // add/subtract 1.32749 // add/subtract 1.
32822 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|32750 const lhs_is_signed = if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val|
32823 !(try lhs_val.compareAllWithZeroAdvanced(.gte, sema))32751 !(try lhs_val.compareAllWithZeroSema(.gte, mod))
32824 else32752 else
32825 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));32753 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));
32826 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|32754 const rhs_is_signed = if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val|
32827 !(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))32755 !(try rhs_val.compareAllWithZeroSema(.gte, mod))
32828 else32756 else
32829 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));32757 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));
32830 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;32758 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
...@@ -32972,7 +32900,7 @@ fn compareIntsOnlyPossibleResult(...@@ -32972,7 +32900,7 @@ fn compareIntsOnlyPossibleResult(
32972) Allocator.Error!?bool {32900) Allocator.Error!?bool {
32973 const mod = sema.mod;32901 const mod = sema.mod;
32974 const rhs_info = rhs_ty.intInfo(mod);32902 const rhs_info = rhs_ty.intInfo(mod);
32975 const vs_zero = lhs_val.orderAgainstZeroAdvanced(mod, sema) catch unreachable;32903 const vs_zero = lhs_val.orderAgainstZeroAdvanced(mod, .sema) catch unreachable;
32976 const is_zero = vs_zero == .eq;32904 const is_zero = vs_zero == .eq;
32977 const is_negative = vs_zero == .lt;32905 const is_negative = vs_zero == .lt;
32978 const is_positive = vs_zero == .gt;32906 const is_positive = vs_zero == .gt;
...@@ -33136,7 +33064,6 @@ fn wrapErrorUnionPayload(...@@ -33136,7 +33064,6 @@ fn wrapErrorUnionPayload(
33136 } })));33064 } })));
33137 }33065 }
33138 try sema.requireRuntimeBlock(block, inst_src, null);33066 try sema.requireRuntimeBlock(block, inst_src, null);
33139 try sema.queueFullTypeResolution(dest_payload_ty);
33140 return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced);33067 return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced);
33141}33068}
3314233069
...@@ -33939,7 +33866,7 @@ fn resolvePeerTypesInner(...@@ -33939,7 +33866,7 @@ fn resolvePeerTypesInner(
3393933866
33940 opt_ptr_info = ptr_info;33867 opt_ptr_info = ptr_info;
33941 }33868 }
33942 return .{ .success = try sema.ptrType(opt_ptr_info.?) };33869 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };
33943 },33870 },
3394433871
33945 .ptr => {33872 .ptr => {
...@@ -34249,7 +34176,7 @@ fn resolvePeerTypesInner(...@@ -34249,7 +34176,7 @@ fn resolvePeerTypesInner(
34249 },34176 },
34250 }34177 }
3425134178
34252 return .{ .success = try sema.ptrType(opt_ptr_info.?) };34179 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };
34253 },34180 },
3425434181
34255 .func => {34182 .func => {
...@@ -34606,7 +34533,7 @@ fn resolvePeerTypesInner(...@@ -34606,7 +34533,7 @@ fn resolvePeerTypesInner(
34606 var comptime_val: ?Value = null;34533 var comptime_val: ?Value = null;
34607 for (peer_tys) |opt_ty| {34534 for (peer_tys) |opt_ty| {
34608 const struct_ty = opt_ty orelse continue;34535 const struct_ty = opt_ty orelse continue;
34609 try sema.resolveStructFieldInits(struct_ty);34536 try struct_ty.resolveStructFieldInits(mod);
3461034537
34611 const uncoerced_field_val = try struct_ty.structFieldValueComptime(mod, field_index) orelse {34538 const uncoerced_field_val = try struct_ty.structFieldValueComptime(mod, field_index) orelse {
34612 comptime_val = null;34539 comptime_val = null;
...@@ -34742,181 +34669,22 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {...@@ -34742,181 +34669,22 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
34742 const ip = &mod.intern_pool;34669 const ip = &mod.intern_pool;
34743 const fn_ty_info = mod.typeToFunc(fn_ty).?;34670 const fn_ty_info = mod.typeToFunc(fn_ty).?;
3474434671
34745 try sema.resolveTypeFully(Type.fromInterned(fn_ty_info.return_type));34672 try Type.fromInterned(fn_ty_info.return_type).resolveFully(mod);
3474634673
34747 if (mod.comp.config.any_error_tracing and34674 if (mod.comp.config.any_error_tracing and
34748 Type.fromInterned(fn_ty_info.return_type).isError(mod))34675 Type.fromInterned(fn_ty_info.return_type).isError(mod))
34749 {34676 {
34750 // Ensure the type exists so that backends can assume that.34677 // Ensure the type exists so that backends can assume that.
34751 _ = try sema.getBuiltinType("StackTrace");34678 _ = try mod.getBuiltinType("StackTrace");
34752 }34679 }
3475334680
34754 for (0..fn_ty_info.param_types.len) |i| {34681 for (0..fn_ty_info.param_types.len) |i| {
34755 try sema.resolveTypeFully(Type.fromInterned(fn_ty_info.param_types.get(ip)[i]));34682 try Type.fromInterned(fn_ty_info.param_types.get(ip)[i]).resolveFully(mod);
34756 }34683 }
34757}34684}
3475834685
34759/// Make it so that calling hash() and eql() on `val` will not assert due
34760/// to a type not having its layout resolved.
34761fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {34686fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
34762 const mod = sema.mod;34687 return val.resolveLazy(sema.arena, sema.mod);
34763 switch (mod.intern_pool.indexToKey(val.toIntern())) {
34764 .int => |int| switch (int.storage) {
34765 .u64, .i64, .big_int => return val,
34766 .lazy_align, .lazy_size => return mod.intValue(
34767 Type.fromInterned(int.ty),
34768 (try val.getUnsignedIntAdvanced(mod, sema)).?,
34769 ),
34770 },
34771 .slice => |slice| {
34772 const ptr = try sema.resolveLazyValue(Value.fromInterned(slice.ptr));
34773 const len = try sema.resolveLazyValue(Value.fromInterned(slice.len));
34774 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;
34775 return Value.fromInterned(try mod.intern(.{ .slice = .{
34776 .ty = slice.ty,
34777 .ptr = ptr.toIntern(),
34778 .len = len.toIntern(),
34779 } }));
34780 },
34781 .ptr => |ptr| {
34782 switch (ptr.base_addr) {
34783 .decl, .comptime_alloc, .anon_decl, .int => return val,
34784 .comptime_field => |field_val| {
34785 const resolved_field_val =
34786 (try sema.resolveLazyValue(Value.fromInterned(field_val))).toIntern();
34787 return if (resolved_field_val == field_val)
34788 val
34789 else
34790 Value.fromInterned((try mod.intern(.{ .ptr = .{
34791 .ty = ptr.ty,
34792 .base_addr = .{ .comptime_field = resolved_field_val },
34793 .byte_offset = ptr.byte_offset,
34794 } })));
34795 },
34796 .eu_payload, .opt_payload => |base| {
34797 const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base))).toIntern();
34798 return if (resolved_base == base)
34799 val
34800 else
34801 Value.fromInterned((try mod.intern(.{ .ptr = .{
34802 .ty = ptr.ty,
34803 .base_addr = switch (ptr.base_addr) {
34804 .eu_payload => .{ .eu_payload = resolved_base },
34805 .opt_payload => .{ .opt_payload = resolved_base },
34806 else => unreachable,
34807 },
34808 .byte_offset = ptr.byte_offset,
34809 } })));
34810 },
34811 .arr_elem, .field => |base_index| {
34812 const resolved_base = (try sema.resolveLazyValue(Value.fromInterned(base_index.base))).toIntern();
34813 return if (resolved_base == base_index.base)
34814 val
34815 else
34816 Value.fromInterned((try mod.intern(.{ .ptr = .{
34817 .ty = ptr.ty,
34818 .base_addr = switch (ptr.base_addr) {
34819 .arr_elem => .{ .arr_elem = .{
34820 .base = resolved_base,
34821 .index = base_index.index,
34822 } },
34823 .field => .{ .field = .{
34824 .base = resolved_base,
34825 .index = base_index.index,
34826 } },
34827 else => unreachable,
34828 },
34829 .byte_offset = ptr.byte_offset,
34830 } })));
34831 },
34832 }
34833 },
34834 .aggregate => |aggregate| switch (aggregate.storage) {
34835 .bytes => return val,
34836 .elems => |elems| {
34837 var resolved_elems: []InternPool.Index = &.{};
34838 for (elems, 0..) |elem, i| {
34839 const resolved_elem = (try sema.resolveLazyValue(Value.fromInterned(elem))).toIntern();
34840 if (resolved_elems.len == 0 and resolved_elem != elem) {
34841 resolved_elems = try sema.arena.alloc(InternPool.Index, elems.len);
34842 @memcpy(resolved_elems[0..i], elems[0..i]);
34843 }
34844 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;
34845 }
34846 return if (resolved_elems.len == 0) val else Value.fromInterned((try mod.intern(.{ .aggregate = .{
34847 .ty = aggregate.ty,
34848 .storage = .{ .elems = resolved_elems },
34849 } })));
34850 },
34851 .repeated_elem => |elem| {
34852 const resolved_elem = (try sema.resolveLazyValue(Value.fromInterned(elem))).toIntern();
34853 return if (resolved_elem == elem) val else Value.fromInterned((try mod.intern(.{ .aggregate = .{
34854 .ty = aggregate.ty,
34855 .storage = .{ .repeated_elem = resolved_elem },
34856 } })));
34857 },
34858 },
34859 .un => |un| {
34860 const resolved_tag = if (un.tag == .none)
34861 .none
34862 else
34863 (try sema.resolveLazyValue(Value.fromInterned(un.tag))).toIntern();
34864 const resolved_val = (try sema.resolveLazyValue(Value.fromInterned(un.val))).toIntern();
34865 return if (resolved_tag == un.tag and resolved_val == un.val)
34866 val
34867 else
34868 Value.fromInterned((try mod.intern(.{ .un = .{
34869 .ty = un.ty,
34870 .tag = resolved_tag,
34871 .val = resolved_val,
34872 } })));
34873 },
34874 else => return val,
34875 }
34876}
34877
34878pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void {
34879 const mod = sema.mod;
34880 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
34881 .simple_type => |simple_type| return sema.resolveSimpleType(simple_type),
34882 else => {},
34883 }
34884 switch (ty.zigTypeTag(mod)) {
34885 .Struct => return sema.resolveStructLayout(ty),
34886 .Union => return sema.resolveUnionLayout(ty),
34887 .Array => {
34888 if (ty.arrayLenIncludingSentinel(mod) == 0) return;
34889 const elem_ty = ty.childType(mod);
34890 return sema.resolveTypeLayout(elem_ty);
34891 },
34892 .Optional => {
34893 const payload_ty = ty.optionalChild(mod);
34894 // In case of querying the ABI alignment of this optional, we will ask
34895 // for hasRuntimeBits() of the payload type, so we need "requires comptime"
34896 // to be known already before this function returns.
34897 _ = try sema.typeRequiresComptime(payload_ty);
34898 return sema.resolveTypeLayout(payload_ty);
34899 },
34900 .ErrorUnion => {
34901 const payload_ty = ty.errorUnionPayload(mod);
34902 return sema.resolveTypeLayout(payload_ty);
34903 },
34904 .Fn => {
34905 const info = mod.typeToFunc(ty).?;
34906 if (info.is_generic) {
34907 // Resolving of generic function types is deferred to when
34908 // the function is instantiated.
34909 return;
34910 }
34911 const ip = &mod.intern_pool;
34912 for (0..info.param_types.len) |i| {
34913 const param_ty = info.param_types.get(ip)[i];
34914 try sema.resolveTypeLayout(Type.fromInterned(param_ty));
34915 }
34916 try sema.resolveTypeLayout(Type.fromInterned(info.return_type));
34917 },
34918 else => {},
34919 }
34920}34688}
3492134689
34922/// Resolve a struct's alignment only without triggering resolution of its layout.34690/// Resolve a struct's alignment only without triggering resolution of its layout.
...@@ -34925,11 +34693,13 @@ pub fn resolveStructAlignment(...@@ -34925,11 +34693,13 @@ pub fn resolveStructAlignment(
34925 sema: *Sema,34693 sema: *Sema,
34926 ty: InternPool.Index,34694 ty: InternPool.Index,
34927 struct_type: InternPool.LoadedStructType,34695 struct_type: InternPool.LoadedStructType,
34928) CompileError!Alignment {34696) SemaError!void {
34929 const mod = sema.mod;34697 const mod = sema.mod;
34930 const ip = &mod.intern_pool;34698 const ip = &mod.intern_pool;
34931 const target = mod.getTarget();34699 const target = mod.getTarget();
3493234700
34701 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
34702
34933 assert(struct_type.flagsPtr(ip).alignment == .none);34703 assert(struct_type.flagsPtr(ip).alignment == .none);
34934 assert(struct_type.layout != .@"packed");34704 assert(struct_type.layout != .@"packed");
3493534705
...@@ -34940,7 +34710,7 @@ pub fn resolveStructAlignment(...@@ -34940,7 +34710,7 @@ pub fn resolveStructAlignment(
34940 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;34710 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
34941 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));34711 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
34942 struct_type.flagsPtr(ip).alignment = result;34712 struct_type.flagsPtr(ip).alignment = result;
34943 return result;34713 return;
34944 }34714 }
3494534715
34946 try sema.resolveTypeFieldsStruct(ty, struct_type);34716 try sema.resolveTypeFieldsStruct(ty, struct_type);
...@@ -34952,7 +34722,7 @@ pub fn resolveStructAlignment(...@@ -34952,7 +34722,7 @@ pub fn resolveStructAlignment(
34952 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;34722 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
34953 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));34723 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
34954 struct_type.flagsPtr(ip).alignment = result;34724 struct_type.flagsPtr(ip).alignment = result;
34955 return result;34725 return;
34956 }34726 }
34957 defer struct_type.clearAlignmentWip(ip);34727 defer struct_type.clearAlignmentWip(ip);
3495834728
...@@ -34962,30 +34732,35 @@ pub fn resolveStructAlignment(...@@ -34962,30 +34732,35 @@ pub fn resolveStructAlignment(
34962 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);34732 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
34963 if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty))34733 if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty))
34964 continue;34734 continue;
34965 const field_align = try sema.structFieldAlignment(34735 const field_align = try mod.structFieldAlignmentAdvanced(
34966 struct_type.fieldAlign(ip, i),34736 struct_type.fieldAlign(ip, i),
34967 field_ty,34737 field_ty,
34968 struct_type.layout,34738 struct_type.layout,
34739 .sema,
34969 );34740 );
34970 result = result.maxStrict(field_align);34741 result = result.maxStrict(field_align);
34971 }34742 }
3497234743
34973 struct_type.flagsPtr(ip).alignment = result;34744 struct_type.flagsPtr(ip).alignment = result;
34974 return result;
34975}34745}
3497634746
34977fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {34747pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
34978 const zcu = sema.mod;34748 const zcu = sema.mod;
34979 const ip = &zcu.intern_pool;34749 const ip = &zcu.intern_pool;
34980 const struct_type = zcu.typeToStruct(ty) orelse return;34750 const struct_type = zcu.typeToStruct(ty) orelse return;
3498134751
34752 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
34753
34982 if (struct_type.haveLayout(ip))34754 if (struct_type.haveLayout(ip))
34983 return;34755 return;
3498434756
34985 try sema.resolveTypeFields(ty);34757 try ty.resolveFields(zcu);
3498634758
34987 if (struct_type.layout == .@"packed") {34759 if (struct_type.layout == .@"packed") {
34988 try semaBackingIntType(zcu, struct_type);34760 semaBackingIntType(zcu, struct_type) catch |err| switch (err) {
34761 error.OutOfMemory, error.AnalysisFail => |e| return e,
34762 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
34763 };
34989 return;34764 return;
34990 }34765 }
3499134766
...@@ -35021,10 +34796,11 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -35021,10 +34796,11 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
35021 },34796 },
35022 else => return err,34797 else => return err,
35023 };34798 };
35024 field_align.* = try sema.structFieldAlignment(34799 field_align.* = try zcu.structFieldAlignmentAdvanced(
35025 struct_type.fieldAlign(ip, i),34800 struct_type.fieldAlign(ip, i),
35026 field_ty,34801 field_ty,
35027 struct_type.layout,34802 struct_type.layout,
34803 .sema,
35028 );34804 );
35029 big_align = big_align.maxStrict(field_align.*);34805 big_align = big_align.maxStrict(field_align.*);
35030 }34806 }
...@@ -35160,7 +34936,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co...@@ -35160,7 +34936,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co
35160 var accumulator: u64 = 0;34936 var accumulator: u64 = 0;
35161 for (0..struct_type.field_types.len) |i| {34937 for (0..struct_type.field_types.len) |i| {
35162 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);34938 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
35163 accumulator += try field_ty.bitSizeAdvanced(mod, &sema);34939 accumulator += try field_ty.bitSizeAdvanced(mod, .sema);
35164 }34940 }
35165 break :blk accumulator;34941 break :blk accumulator;
35166 };34942 };
...@@ -35270,11 +35046,13 @@ pub fn resolveUnionAlignment(...@@ -35270,11 +35046,13 @@ pub fn resolveUnionAlignment(
35270 sema: *Sema,35046 sema: *Sema,
35271 ty: Type,35047 ty: Type,
35272 union_type: InternPool.LoadedUnionType,35048 union_type: InternPool.LoadedUnionType,
35273) CompileError!Alignment {35049) SemaError!void {
35274 const mod = sema.mod;35050 const mod = sema.mod;
35275 const ip = &mod.intern_pool;35051 const ip = &mod.intern_pool;
35276 const target = mod.getTarget();35052 const target = mod.getTarget();
3527735053
35054 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35055
35278 assert(!union_type.haveLayout(ip));35056 assert(!union_type.haveLayout(ip));
3527935057
35280 if (union_type.flagsPtr(ip).status == .field_types_wip) {35058 if (union_type.flagsPtr(ip).status == .field_types_wip) {
...@@ -35284,7 +35062,7 @@ pub fn resolveUnionAlignment(...@@ -35284,7 +35062,7 @@ pub fn resolveUnionAlignment(
35284 union_type.flagsPtr(ip).assumed_pointer_aligned = true;35062 union_type.flagsPtr(ip).assumed_pointer_aligned = true;
35285 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));35063 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
35286 union_type.flagsPtr(ip).alignment = result;35064 union_type.flagsPtr(ip).alignment = result;
35287 return result;35065 return;
35288 }35066 }
3528935067
35290 try sema.resolveTypeFieldsUnion(ty, union_type);35068 try sema.resolveTypeFieldsUnion(ty, union_type);
...@@ -35304,11 +35082,10 @@ pub fn resolveUnionAlignment(...@@ -35304,11 +35082,10 @@ pub fn resolveUnionAlignment(
35304 }35082 }
3530535083
35306 union_type.flagsPtr(ip).alignment = max_align;35084 union_type.flagsPtr(ip).alignment = max_align;
35307 return max_align;
35308}35085}
3530935086
35310/// This logic must be kept in sync with `Module.getUnionLayout`.35087/// This logic must be kept in sync with `Module.getUnionLayout`.
35311fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {35088pub fn resolveUnionLayout(sema: *Sema, ty: Type) SemaError!void {
35312 const zcu = sema.mod;35089 const zcu = sema.mod;
35313 const ip = &zcu.intern_pool;35090 const ip = &zcu.intern_pool;
3531435091
...@@ -35317,6 +35094,8 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -35317,6 +35094,8 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
35317 // Load again, since the tag type might have changed due to resolution.35094 // Load again, since the tag type might have changed due to resolution.
35318 const union_type = ip.loadUnionType(ty.ip_index);35095 const union_type = ip.loadUnionType(ty.ip_index);
3531935096
35097 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35098
35320 switch (union_type.flagsPtr(ip).status) {35099 switch (union_type.flagsPtr(ip).status) {
35321 .none, .have_field_types => {},35100 .none, .have_field_types => {},
35322 .field_types_wip, .layout_wip => {35101 .field_types_wip, .layout_wip => {
...@@ -35425,53 +35204,15 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {...@@ -35425,53 +35204,15 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3542535204
35426/// Returns `error.AnalysisFail` if any of the types (recursively) failed to35205/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
35427/// be resolved.35206/// be resolved.
35428pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {35207pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
35429 const mod = sema.mod;
35430 const ip = &mod.intern_pool;
35431 switch (ty.zigTypeTag(mod)) {
35432 .Pointer => {
35433 return sema.resolveTypeFully(ty.childType(mod));
35434 },
35435 .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
35436 .struct_type => try sema.resolveStructFully(ty),
35437 .anon_struct_type => |tuple| {
35438 for (tuple.types.get(ip)) |field_ty| {
35439 try sema.resolveTypeFully(Type.fromInterned(field_ty));
35440 }
35441 },
35442 .simple_type => |simple_type| try sema.resolveSimpleType(simple_type),
35443 else => {},
35444 },
35445 .Union => return sema.resolveUnionFully(ty),
35446 .Array => return sema.resolveTypeFully(ty.childType(mod)),
35447 .Optional => {
35448 return sema.resolveTypeFully(ty.optionalChild(mod));
35449 },
35450 .ErrorUnion => return sema.resolveTypeFully(ty.errorUnionPayload(mod)),
35451 .Fn => {
35452 const info = mod.typeToFunc(ty).?;
35453 if (info.is_generic) {
35454 // Resolving of generic function types is deferred to when
35455 // the function is instantiated.
35456 return;
35457 }
35458 for (0..info.param_types.len) |i| {
35459 const param_ty = info.param_types.get(ip)[i];
35460 try sema.resolveTypeFully(Type.fromInterned(param_ty));
35461 }
35462 try sema.resolveTypeFully(Type.fromInterned(info.return_type));
35463 },
35464 else => {},
35465 }
35466}
35467
35468fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {
35469 try sema.resolveStructLayout(ty);35208 try sema.resolveStructLayout(ty);
3547035209
35471 const mod = sema.mod;35210 const mod = sema.mod;
35472 const ip = &mod.intern_pool;35211 const ip = &mod.intern_pool;
35473 const struct_type = mod.typeToStruct(ty).?;35212 const struct_type = mod.typeToStruct(ty).?;
3547435213
35214 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35215
35475 if (struct_type.setFullyResolved(ip)) return;35216 if (struct_type.setFullyResolved(ip)) return;
35476 errdefer struct_type.clearFullyResolved(ip);35217 errdefer struct_type.clearFullyResolved(ip);
3547735218
...@@ -35481,16 +35222,19 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {...@@ -35481,16 +35222,19 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {
3548135222
35482 for (0..struct_type.field_types.len) |i| {35223 for (0..struct_type.field_types.len) |i| {
35483 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);35224 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
35484 try sema.resolveTypeFully(field_ty);35225 try field_ty.resolveFully(mod);
35485 }35226 }
35486}35227}
3548735228
35488fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {35229pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
35489 try sema.resolveUnionLayout(ty);35230 try sema.resolveUnionLayout(ty);
3549035231
35491 const mod = sema.mod;35232 const mod = sema.mod;
35492 const ip = &mod.intern_pool;35233 const ip = &mod.intern_pool;
35493 const union_obj = mod.typeToUnion(ty).?;35234 const union_obj = mod.typeToUnion(ty).?;
35235
35236 assert(sema.ownerUnit().unwrap().decl == union_obj.decl);
35237
35494 switch (union_obj.flagsPtr(ip).status) {35238 switch (union_obj.flagsPtr(ip).status) {
35495 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},35239 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
35496 .fully_resolved_wip, .fully_resolved => return,35240 .fully_resolved_wip, .fully_resolved => return,
...@@ -35506,7 +35250,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {...@@ -35506,7 +35250,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
35506 union_obj.flagsPtr(ip).status = .fully_resolved_wip;35250 union_obj.flagsPtr(ip).status = .fully_resolved_wip;
35507 for (0..union_obj.field_types.len) |field_index| {35251 for (0..union_obj.field_types.len) |field_index| {
35508 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);35252 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
35509 try sema.resolveTypeFully(field_ty);35253 try field_ty.resolveFully(mod);
35510 }35254 }
35511 union_obj.flagsPtr(ip).status = .fully_resolved;35255 union_obj.flagsPtr(ip).status = .fully_resolved;
35512 }35256 }
...@@ -35515,135 +35259,18 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {...@@ -35515,135 +35259,18 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
35515 _ = try sema.typeRequiresComptime(ty);35259 _ = try sema.typeRequiresComptime(ty);
35516}35260}
3551735261
35518pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!void {
35519 const mod = sema.mod;
35520 const ip = &mod.intern_pool;
35521 const ty_ip = ty.toIntern();
35522
35523 switch (ty_ip) {
35524 .none => unreachable,
35525
35526 .u0_type,
35527 .i0_type,
35528 .u1_type,
35529 .u8_type,
35530 .i8_type,
35531 .u16_type,
35532 .i16_type,
35533 .u29_type,
35534 .u32_type,
35535 .i32_type,
35536 .u64_type,
35537 .i64_type,
35538 .u80_type,
35539 .u128_type,
35540 .i128_type,
35541 .usize_type,
35542 .isize_type,
35543 .c_char_type,
35544 .c_short_type,
35545 .c_ushort_type,
35546 .c_int_type,
35547 .c_uint_type,
35548 .c_long_type,
35549 .c_ulong_type,
35550 .c_longlong_type,
35551 .c_ulonglong_type,
35552 .c_longdouble_type,
35553 .f16_type,
35554 .f32_type,
35555 .f64_type,
35556 .f80_type,
35557 .f128_type,
35558 .anyopaque_type,
35559 .bool_type,
35560 .void_type,
35561 .type_type,
35562 .anyerror_type,
35563 .adhoc_inferred_error_set_type,
35564 .comptime_int_type,
35565 .comptime_float_type,
35566 .noreturn_type,
35567 .anyframe_type,
35568 .null_type,
35569 .undefined_type,
35570 .enum_literal_type,
35571 .manyptr_u8_type,
35572 .manyptr_const_u8_type,
35573 .manyptr_const_u8_sentinel_0_type,
35574 .single_const_pointer_to_comptime_int_type,
35575 .slice_const_u8_type,
35576 .slice_const_u8_sentinel_0_type,
35577 .optional_noreturn_type,
35578 .anyerror_void_error_union_type,
35579 .generic_poison_type,
35580 .empty_struct_type,
35581 => {},
35582
35583 .undef => unreachable,
35584 .zero => unreachable,
35585 .zero_usize => unreachable,
35586 .zero_u8 => unreachable,
35587 .one => unreachable,
35588 .one_usize => unreachable,
35589 .one_u8 => unreachable,
35590 .four_u8 => unreachable,
35591 .negative_one => unreachable,
35592 .calling_convention_c => unreachable,
35593 .calling_convention_inline => unreachable,
35594 .void_value => unreachable,
35595 .unreachable_value => unreachable,
35596 .null_value => unreachable,
35597 .bool_true => unreachable,
35598 .bool_false => unreachable,
35599 .empty_struct => unreachable,
35600 .generic_poison => unreachable,
35601
35602 else => switch (ip.items.items(.tag)[@intFromEnum(ty_ip)]) {
35603 .type_struct,
35604 .type_struct_packed,
35605 .type_struct_packed_inits,
35606 => try sema.resolveTypeFieldsStruct(ty_ip, ip.loadStructType(ty_ip)),
35607
35608 .type_union => try sema.resolveTypeFieldsUnion(Type.fromInterned(ty_ip), ip.loadUnionType(ty_ip)),
35609 .simple_type => try sema.resolveSimpleType(ip.indexToKey(ty_ip).simple_type),
35610 else => {},
35611 },
35612 }
35613}
35614
35615/// Fully resolves a simple type. This is usually a nop, but for builtin types with
35616/// special InternPool indices (such as std.builtin.Type) it will analyze and fully
35617/// resolve the container type.
35618fn resolveSimpleType(sema: *Sema, simple_type: InternPool.SimpleType) CompileError!void {
35619 const builtin_type_name: []const u8 = switch (simple_type) {
35620 .atomic_order => "AtomicOrder",
35621 .atomic_rmw_op => "AtomicRmwOp",
35622 .calling_convention => "CallingConvention",
35623 .address_space => "AddressSpace",
35624 .float_mode => "FloatMode",
35625 .reduce_op => "ReduceOp",
35626 .call_modifier => "CallModifer",
35627 .prefetch_options => "PrefetchOptions",
35628 .export_options => "ExportOptions",
35629 .extern_options => "ExternOptions",
35630 .type_info => "Type",
35631 else => return,
35632 };
35633 // This will fully resolve the type.
35634 _ = try sema.getBuiltinType(builtin_type_name);
35635}
35636
35637pub fn resolveTypeFieldsStruct(35262pub fn resolveTypeFieldsStruct(
35638 sema: *Sema,35263 sema: *Sema,
35639 ty: InternPool.Index,35264 ty: InternPool.Index,
35640 struct_type: InternPool.LoadedStructType,35265 struct_type: InternPool.LoadedStructType,
35641) CompileError!void {35266) SemaError!void {
35642 const zcu = sema.mod;35267 const zcu = sema.mod;
35643 const ip = &zcu.intern_pool;35268 const ip = &zcu.intern_pool;
35644 // If there is no owner decl it means the struct has no fields.35269 // If there is no owner decl it means the struct has no fields.
35645 const owner_decl = struct_type.decl.unwrap() orelse return;35270 const owner_decl = struct_type.decl.unwrap() orelse return;
3564635271
35272 assert(sema.ownerUnit().unwrap().decl == owner_decl);
35273
35647 switch (zcu.declPtr(owner_decl).analysis) {35274 switch (zcu.declPtr(owner_decl).analysis) {
35648 .file_failure,35275 .file_failure,
35649 .dependency_failure,35276 .dependency_failure,
...@@ -35674,16 +35301,19 @@ pub fn resolveTypeFieldsStruct(...@@ -35674,16 +35301,19 @@ pub fn resolveTypeFieldsStruct(
35674 }35301 }
35675 return error.AnalysisFail;35302 return error.AnalysisFail;
35676 },35303 },
35677 else => |e| return e,35304 error.OutOfMemory => return error.OutOfMemory,
35305 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35678 };35306 };
35679}35307}
3568035308
35681pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {35309pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
35682 const zcu = sema.mod;35310 const zcu = sema.mod;
35683 const ip = &zcu.intern_pool;35311 const ip = &zcu.intern_pool;
35684 const struct_type = zcu.typeToStruct(ty) orelse return;35312 const struct_type = zcu.typeToStruct(ty) orelse return;
35685 const owner_decl = struct_type.decl.unwrap() orelse return;35313 const owner_decl = struct_type.decl.unwrap() orelse return;
3568635314
35315 assert(sema.ownerUnit().unwrap().decl == owner_decl);
35316
35687 // Inits can start as resolved35317 // Inits can start as resolved
35688 if (struct_type.haveFieldInits(ip)) return;35318 if (struct_type.haveFieldInits(ip)) return;
3568935319
...@@ -35706,15 +35336,19 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {...@@ -35706,15 +35336,19 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {
35706 }35336 }
35707 return error.AnalysisFail;35337 return error.AnalysisFail;
35708 },35338 },
35709 else => |e| return e,35339 error.OutOfMemory => return error.OutOfMemory,
35340 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35710 };35341 };
35711 struct_type.setHaveFieldInits(ip);35342 struct_type.setHaveFieldInits(ip);
35712}35343}
3571335344
35714pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) CompileError!void {35345pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.LoadedUnionType) SemaError!void {
35715 const zcu = sema.mod;35346 const zcu = sema.mod;
35716 const ip = &zcu.intern_pool;35347 const ip = &zcu.intern_pool;
35717 const owner_decl = zcu.declPtr(union_type.decl);35348 const owner_decl = zcu.declPtr(union_type.decl);
35349
35350 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35351
35718 switch (owner_decl.analysis) {35352 switch (owner_decl.analysis) {
35719 .file_failure,35353 .file_failure,
35720 .dependency_failure,35354 .dependency_failure,
...@@ -35752,7 +35386,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load...@@ -35752,7 +35386,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
35752 }35386 }
35753 return error.AnalysisFail;35387 return error.AnalysisFail;
35754 },35388 },
35755 else => |e| return e,35389 error.OutOfMemory => return error.OutOfMemory,
35390 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
35756 };35391 };
35757 union_type.flagsPtr(ip).status = .have_field_types;35392 union_type.flagsPtr(ip).status = .have_field_types;
35758}35393}
...@@ -36801,106 +36436,6 @@ fn generateUnionTagTypeSimple(...@@ -36801,106 +36436,6 @@ fn generateUnionTagTypeSimple(
36801 return enum_ty;36436 return enum_ty;
36802}36437}
3680336438
36804fn getBuiltin(sema: *Sema, name: []const u8) CompileError!Air.Inst.Ref {
36805 const zcu = sema.mod;
36806
36807 var block: Block = .{
36808 .parent = null,
36809 .sema = sema,
36810 .namespace = sema.owner_decl.src_namespace,
36811 .instructions = .{},
36812 .inlining = null,
36813 .is_comptime = true,
36814 .src_base_inst = sema.owner_decl.zir_decl_index.unwrap() orelse owner: {
36815 assert(sema.owner_decl.has_tv);
36816 assert(sema.owner_decl.owns_tv);
36817 switch (sema.owner_decl.typeOf(zcu).zigTypeTag(zcu)) {
36818 .Type => break :owner sema.owner_decl.val.toType().typeDeclInst(zcu).?,
36819 .Fn => {
36820 const owner = zcu.funcInfo(sema.owner_decl.val.toIntern()).generic_owner;
36821 const generic_owner_decl = zcu.declPtr(zcu.funcInfo(owner).owner_decl);
36822 break :owner generic_owner_decl.zir_decl_index.unwrap().?;
36823 },
36824 else => unreachable,
36825 }
36826 },
36827 .type_name_ctx = sema.owner_decl.name,
36828 };
36829 defer block.instructions.deinit(sema.gpa);
36830
36831 const src = block.nodeOffset(0);
36832
36833 const decl_index = try getBuiltinDecl(sema, &block, name);
36834 return sema.analyzeDeclVal(&block, src, decl_index);
36835}
36836
36837fn getBuiltinDecl(sema: *Sema, block: *Block, name: []const u8) CompileError!InternPool.DeclIndex {
36838 const gpa = sema.gpa;
36839
36840 const src = block.nodeOffset(0);
36841
36842 const mod = sema.mod;
36843 const ip = &mod.intern_pool;
36844 const std_mod = mod.std_mod;
36845 const std_file = (mod.importPkg(std_mod) catch unreachable).file;
36846 const opt_builtin_inst = (try sema.namespaceLookupRef(
36847 block,
36848 src,
36849 mod.declPtr(std_file.root_decl.unwrap().?).src_namespace.toOptional(),
36850 try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls),
36851 )) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
36852 const builtin_inst = try sema.analyzeLoad(block, src, opt_builtin_inst, src);
36853 const builtin_ty = sema.analyzeAsType(block, src, builtin_inst) catch |err| switch (err) {
36854 error.AnalysisFail => std.debug.panic("std.builtin is corrupt", .{}),
36855 else => |e| return e,
36856 };
36857 const decl_index = (try sema.namespaceLookup(
36858 block,
36859 src,
36860 builtin_ty.getNamespaceIndex(mod),
36861 try ip.getOrPutString(gpa, name, .no_embedded_nulls),
36862 )) orelse std.debug.panic("lib/std/builtin.zig is corrupt and missing '{s}'", .{name});
36863 return decl_index;
36864}
36865
36866fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
36867 const zcu = sema.mod;
36868 const ty_inst = try sema.getBuiltin(name);
36869
36870 var block: Block = .{
36871 .parent = null,
36872 .sema = sema,
36873 .namespace = sema.owner_decl.src_namespace,
36874 .instructions = .{},
36875 .inlining = null,
36876 .is_comptime = true,
36877 .src_base_inst = sema.owner_decl.zir_decl_index.unwrap() orelse owner: {
36878 assert(sema.owner_decl.has_tv);
36879 assert(sema.owner_decl.owns_tv);
36880 switch (sema.owner_decl.typeOf(zcu).zigTypeTag(zcu)) {
36881 .Type => break :owner sema.owner_decl.val.toType().typeDeclInst(zcu).?,
36882 .Fn => {
36883 const owner = zcu.funcInfo(sema.owner_decl.val.toIntern()).generic_owner;
36884 const generic_owner_decl = zcu.declPtr(zcu.funcInfo(owner).owner_decl);
36885 break :owner generic_owner_decl.zir_decl_index.unwrap().?;
36886 },
36887 else => unreachable,
36888 }
36889 },
36890 .type_name_ctx = sema.owner_decl.name,
36891 };
36892 defer block.instructions.deinit(sema.gpa);
36893
36894 const src = block.nodeOffset(0);
36895
36896 const result_ty = sema.analyzeAsType(&block, src, ty_inst) catch |err| switch (err) {
36897 error.AnalysisFail => std.debug.panic("std.builtin.{s} is corrupt", .{name}),
36898 else => |e| return e,
36899 };
36900 try sema.resolveTypeFully(result_ty); // Should not fail
36901 return result_ty;
36902}
36903
36904/// There is another implementation of this in `Type.onePossibleValue`. This one36439/// There is another implementation of this in `Type.onePossibleValue`. This one
36905/// in `Sema` is for calling during semantic analysis, and performs field resolution36440/// in `Sema` is for calling during semantic analysis, and performs field resolution
36906/// to get the answer. The one in `Type` is for calling during codegen and asserts36441/// to get the answer. The one in `Type` is for calling during codegen and asserts
...@@ -37104,8 +36639,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37104,8 +36639,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37104 },36639 },
3710536640
37106 .struct_type => {36641 .struct_type => {
36642 // Resolving the layout first helps to avoid loops.
36643 // If the type has a coherent layout, we can recurse through fields safely.
36644 try ty.resolveLayout(zcu);
36645
37107 const struct_type = ip.loadStructType(ty.toIntern());36646 const struct_type = ip.loadStructType(ty.toIntern());
37108 try sema.resolveTypeFieldsStruct(ty.toIntern(), struct_type);
3710936647
37110 if (struct_type.field_types.len == 0) {36648 if (struct_type.field_types.len == 0) {
37111 // In this case the struct has no fields at all and36649 // In this case the struct has no fields at all and
...@@ -37122,20 +36660,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37122,20 +36660,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37122 );36660 );
37123 for (field_vals, 0..) |*field_val, i| {36661 for (field_vals, 0..) |*field_val, i| {
37124 if (struct_type.fieldIsComptime(ip, i)) {36662 if (struct_type.fieldIsComptime(ip, i)) {
37125 try sema.resolveStructFieldInits(ty);36663 try ty.resolveStructFieldInits(zcu);
37126 field_val.* = struct_type.field_inits.get(ip)[i];36664 field_val.* = struct_type.field_inits.get(ip)[i];
37127 continue;36665 continue;
37128 }36666 }
37129 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);36667 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
37130 if (field_ty.eql(ty, zcu)) {
37131 const msg = try sema.errMsg(
37132 ty.srcLoc(zcu),
37133 "struct '{}' depends on itself",
37134 .{ty.fmt(zcu)},
37135 );
37136 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
37137 return sema.failWithOwnedErrorMsg(null, msg);
37138 }
37139 if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| {36668 if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| {
37140 field_val.* = field_opv.toIntern();36669 field_val.* = field_opv.toIntern();
37141 } else return null;36670 } else return null;
...@@ -37163,8 +36692,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37163,8 +36692,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37163 },36692 },
3716436693
37165 .union_type => {36694 .union_type => {
36695 // Resolving the layout first helps to avoid loops.
36696 // If the type has a coherent layout, we can recurse through fields safely.
36697 try ty.resolveLayout(zcu);
36698
37166 const union_obj = ip.loadUnionType(ty.toIntern());36699 const union_obj = ip.loadUnionType(ty.toIntern());
37167 try sema.resolveTypeFieldsUnion(ty, union_obj);
37168 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse36700 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse
37169 return null;36701 return null;
37170 if (union_obj.field_types.len == 0) {36702 if (union_obj.field_types.len == 0) {
...@@ -37172,15 +36704,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {...@@ -37172,15 +36704,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
37172 return Value.fromInterned(only);36704 return Value.fromInterned(only);
37173 }36705 }
37174 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);36706 const only_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[0]);
37175 if (only_field_ty.eql(ty, zcu)) {
37176 const msg = try sema.errMsg(
37177 ty.srcLoc(zcu),
37178 "union '{}' depends on itself",
37179 .{ty.fmt(zcu)},
37180 );
37181 try sema.addFieldErrNote(ty, 0, msg, "while checking this field", .{});
37182 return sema.failWithOwnedErrorMsg(null, msg);
37183 }
37184 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse36707 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
37185 return null;36708 return null;
37186 const only = try zcu.intern(.{ .un = .{36709 const only = try zcu.intern(.{ .un = .{
...@@ -37298,7 +36821,7 @@ fn analyzeComptimeAlloc(...@@ -37298,7 +36821,7 @@ fn analyzeComptimeAlloc(
37298 // Needed to make an anon decl with type `var_type` (the `finish()` call below).36821 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
37299 _ = try sema.typeHasOnePossibleValue(var_type);36822 _ = try sema.typeHasOnePossibleValue(var_type);
3730036823
37301 const ptr_type = try sema.ptrType(.{36824 const ptr_type = try mod.ptrTypeSema(.{
37302 .child = var_type.toIntern(),36825 .child = var_type.toIntern(),
37303 .flags = .{36826 .flags = .{
37304 .alignment = alignment,36827 .alignment = alignment,
...@@ -37485,64 +37008,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {...@@ -37485,64 +37008,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3748537008
37486/// `generic_poison` will return false.37009/// `generic_poison` will return false.
37487/// May return false negatives when structs and unions are having their field types resolved.37010/// May return false negatives when structs and unions are having their field types resolved.
37488pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {37011pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool {
37489 return ty.comptimeOnlyAdvanced(sema.mod, sema);37012 return ty.comptimeOnlyAdvanced(sema.mod, .sema);
37490}37013}
3749137014
37492pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {37015pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool {
37493 const mod = sema.mod;37016 return ty.hasRuntimeBitsAdvanced(sema.mod, false, .sema) catch |err| switch (err) {
37494 return ty.hasRuntimeBitsAdvanced(mod, false, .{ .sema = sema }) catch |err| switch (err) {
37495 error.NeedLazy => unreachable,37017 error.NeedLazy => unreachable,
37496 else => |e| return e,37018 else => |e| return e,
37497 };37019 };
37498}37020}
3749937021
37500pub fn typeAbiSize(sema: *Sema, ty: Type) !u64 {37022pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 {
37501 try sema.resolveTypeLayout(ty);37023 try ty.resolveLayout(sema.mod);
37502 return ty.abiSize(sema.mod);37024 return ty.abiSize(sema.mod);
37503}37025}
3750437026
37505pub fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!Alignment {37027pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment {
37506 return (try ty.abiAlignmentAdvanced(sema.mod, .{ .sema = sema })).scalar;37028 return (try ty.abiAlignmentAdvanced(sema.mod, .sema)).scalar;
37507}
37508
37509/// Not valid to call for packed unions.
37510/// Keep implementation in sync with `Module.unionFieldNormalAlignment`.
37511pub fn unionFieldAlignment(sema: *Sema, u: InternPool.LoadedUnionType, field_index: u32) !Alignment {
37512 const mod = sema.mod;
37513 const ip = &mod.intern_pool;
37514 const field_align = u.fieldAlign(ip, field_index);
37515 if (field_align != .none) return field_align;
37516 const field_ty = Type.fromInterned(u.field_types.get(ip)[field_index]);
37517 if (field_ty.isNoReturn(sema.mod)) return .none;
37518 return sema.typeAbiAlignment(field_ty);
37519}
37520
37521/// Keep implementation in sync with `Module.structFieldAlignment`.
37522pub fn structFieldAlignment(
37523 sema: *Sema,
37524 explicit_alignment: InternPool.Alignment,
37525 field_ty: Type,
37526 layout: std.builtin.Type.ContainerLayout,
37527) !Alignment {
37528 if (explicit_alignment != .none)
37529 return explicit_alignment;
37530 const mod = sema.mod;
37531 switch (layout) {
37532 .@"packed" => return .none,
37533 .auto => if (mod.getTarget().ofmt != .c) return sema.typeAbiAlignment(field_ty),
37534 .@"extern" => {},
37535 }
37536 // extern
37537 const ty_abi_align = try sema.typeAbiAlignment(field_ty);
37538 if (field_ty.isAbiInt(mod) and field_ty.intInfo(mod).bits >= 128) {
37539 return ty_abi_align.maxStrict(.@"16");
37540 }
37541 return ty_abi_align;
37542}37029}
3754337030
37544pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {37031pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
37545 return ty.fnHasRuntimeBitsAdvanced(sema.mod, sema);37032 return ty.fnHasRuntimeBitsAdvanced(sema.mod, .sema);
37546}37033}
3754737034
37548fn unionFieldIndex(37035fn unionFieldIndex(
...@@ -37554,7 +37041,7 @@ fn unionFieldIndex(...@@ -37554,7 +37041,7 @@ fn unionFieldIndex(
37554) !u32 {37041) !u32 {
37555 const mod = sema.mod;37042 const mod = sema.mod;
37556 const ip = &mod.intern_pool;37043 const ip = &mod.intern_pool;
37557 try sema.resolveTypeFields(union_ty);37044 try union_ty.resolveFields(mod);
37558 const union_obj = mod.typeToUnion(union_ty).?;37045 const union_obj = mod.typeToUnion(union_ty).?;
37559 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse37046 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse
37560 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);37047 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);
...@@ -37570,7 +37057,7 @@ fn structFieldIndex(...@@ -37570,7 +37057,7 @@ fn structFieldIndex(
37570) !u32 {37057) !u32 {
37571 const mod = sema.mod;37058 const mod = sema.mod;
37572 const ip = &mod.intern_pool;37059 const ip = &mod.intern_pool;
37573 try sema.resolveTypeFields(struct_ty);37060 try struct_ty.resolveFields(mod);
37574 if (struct_ty.isAnonStruct(mod)) {37061 if (struct_ty.isAnonStruct(mod)) {
37575 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);37062 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
37576 } else {37063 } else {
...@@ -37601,10 +37088,6 @@ fn anonStructFieldIndex(...@@ -37601,10 +37088,6 @@ fn anonStructFieldIndex(
37601 });37088 });
37602}37089}
3760337090
37604fn queueFullTypeResolution(sema: *Sema, ty: Type) !void {
37605 try sema.types_to_resolve.put(sema.gpa, ty.toIntern(), {});
37606}
37607
37608/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting37091/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting
37609/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).37092/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).
37610fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {37093fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type, overflow_idx: *?usize) !Value {
...@@ -37662,8 +37145,8 @@ fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {...@@ -37662,8 +37145,8 @@ fn intAddScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
37662 // resorting to BigInt first.37145 // resorting to BigInt first.
37663 var lhs_space: Value.BigIntSpace = undefined;37146 var lhs_space: Value.BigIntSpace = undefined;
37664 var rhs_space: Value.BigIntSpace = undefined;37147 var rhs_space: Value.BigIntSpace = undefined;
37665 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);37148 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
37666 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);37149 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
37667 const limbs = try sema.arena.alloc(37150 const limbs = try sema.arena.alloc(
37668 std.math.big.Limb,37151 std.math.big.Limb,
37669 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,37152 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -37752,8 +37235,8 @@ fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {...@@ -37752,8 +37235,8 @@ fn intSubScalar(sema: *Sema, lhs: Value, rhs: Value, scalar_ty: Type) !Value {
37752 // resorting to BigInt first.37235 // resorting to BigInt first.
37753 var lhs_space: Value.BigIntSpace = undefined;37236 var lhs_space: Value.BigIntSpace = undefined;
37754 var rhs_space: Value.BigIntSpace = undefined;37237 var rhs_space: Value.BigIntSpace = undefined;
37755 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);37238 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
37756 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);37239 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
37757 const limbs = try sema.arena.alloc(37240 const limbs = try sema.arena.alloc(
37758 std.math.big.Limb,37241 std.math.big.Limb,
37759 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,37242 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
...@@ -37836,8 +37319,8 @@ fn intSubWithOverflowScalar(...@@ -37836,8 +37319,8 @@ fn intSubWithOverflowScalar(
3783637319
37837 var lhs_space: Value.BigIntSpace = undefined;37320 var lhs_space: Value.BigIntSpace = undefined;
37838 var rhs_space: Value.BigIntSpace = undefined;37321 var rhs_space: Value.BigIntSpace = undefined;
37839 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);37322 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
37840 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);37323 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
37841 const limbs = try sema.arena.alloc(37324 const limbs = try sema.arena.alloc(
37842 std.math.big.Limb,37325 std.math.big.Limb,
37843 std.math.big.int.calcTwosCompLimbCount(info.bits),37326 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -38024,7 +37507,7 @@ fn intFitsInType(...@@ -38024,7 +37507,7 @@ fn intFitsInType(
3802437507
38025fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {37508fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {
38026 const mod = sema.mod;37509 const mod = sema.mod;
38027 if (!(try int_val.compareAllWithZeroAdvanced(.gte, sema))) return false;37510 if (!(try int_val.compareAllWithZeroSema(.gte, mod))) return false;
38028 const end_val = try mod.intValue(tag_ty, end);37511 const end_val = try mod.intValue(tag_ty, end);
38029 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;37512 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;
38030 return true;37513 return true;
...@@ -38094,8 +37577,8 @@ fn intAddWithOverflowScalar(...@@ -38094,8 +37577,8 @@ fn intAddWithOverflowScalar(
3809437577
38095 var lhs_space: Value.BigIntSpace = undefined;37578 var lhs_space: Value.BigIntSpace = undefined;
38096 var rhs_space: Value.BigIntSpace = undefined;37579 var rhs_space: Value.BigIntSpace = undefined;
38097 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);37580 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
38098 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);37581 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
38099 const limbs = try sema.arena.alloc(37582 const limbs = try sema.arena.alloc(
38100 std.math.big.Limb,37583 std.math.big.Limb,
38101 std.math.big.int.calcTwosCompLimbCount(info.bits),37584 std.math.big.int.calcTwosCompLimbCount(info.bits),
...@@ -38149,7 +37632,7 @@ fn compareScalar(...@@ -38149,7 +37632,7 @@ fn compareScalar(
38149 switch (op) {37632 switch (op) {
38150 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),37633 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),
38151 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),37634 .neq => return !(try sema.valuesEqual(coerced_lhs, coerced_rhs, ty)),
38152 else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, mod, sema),37635 else => return Value.compareHeteroAdvanced(coerced_lhs, op, coerced_rhs, mod, .sema),
38153 }37636 }
38154}37637}
3815537638
...@@ -38185,80 +37668,6 @@ fn compareVector(...@@ -38185,80 +37668,6 @@ fn compareVector(
38185 } })));37668 } })));
38186}37669}
3818737670
38188/// Returns the type of a pointer to an element.
38189/// Asserts that the type is a pointer, and that the element type is indexable.
38190/// If the element index is comptime-known, it must be passed in `offset`.
38191/// For *@Vector(n, T), return *align(a:b:h:v) T
38192/// For *[N]T, return *T
38193/// For [*]T, returns *T
38194/// For []T, returns *T
38195/// Handles const-ness and address spaces in particular.
38196/// This code is duplicated in `analyzePtrArithmetic`.
38197pub fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
38198 const mod = sema.mod;
38199 const ptr_info = ptr_ty.ptrInfo(mod);
38200 const elem_ty = ptr_ty.elemType2(mod);
38201 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;
38202 const parent_ty = ptr_ty.childType(mod);
38203
38204 const VI = InternPool.Key.PtrType.VectorIndex;
38205
38206 const vector_info: struct {
38207 host_size: u16 = 0,
38208 alignment: Alignment = .none,
38209 vector_index: VI = .none,
38210 } = if (parent_ty.isVector(mod) and ptr_info.flags.size == .One) blk: {
38211 const elem_bits = elem_ty.bitSize(mod);
38212 if (elem_bits == 0) break :blk .{};
38213 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
38214 if (!is_packed) break :blk .{};
38215
38216 break :blk .{
38217 .host_size = @intCast(parent_ty.arrayLen(mod)),
38218 .alignment = parent_ty.abiAlignment(mod),
38219 .vector_index = if (offset) |some| @enumFromInt(some) else .runtime,
38220 };
38221 } else .{};
38222
38223 const alignment: Alignment = a: {
38224 // Calculate the new pointer alignment.
38225 if (ptr_info.flags.alignment == .none) {
38226 // In case of an ABI-aligned pointer, any pointer arithmetic
38227 // maintains the same ABI-alignedness.
38228 break :a vector_info.alignment;
38229 }
38230 // If the addend is not a comptime-known value we can still count on
38231 // it being a multiple of the type size.
38232 const elem_size = try sema.typeAbiSize(elem_ty);
38233 const addend = if (offset) |off| elem_size * off else elem_size;
38234
38235 // The resulting pointer is aligned to the lcd between the offset (an
38236 // arbitrary number) and the alignment factor (always a power of two,
38237 // non zero).
38238 const new_align: Alignment = @enumFromInt(@min(
38239 @ctz(addend),
38240 ptr_info.flags.alignment.toLog2Units(),
38241 ));
38242 assert(new_align != .none);
38243 break :a new_align;
38244 };
38245 return sema.ptrType(.{
38246 .child = elem_ty.toIntern(),
38247 .flags = .{
38248 .alignment = alignment,
38249 .is_const = ptr_info.flags.is_const,
38250 .is_volatile = ptr_info.flags.is_volatile,
38251 .is_allowzero = is_allowzero,
38252 .address_space = ptr_info.flags.address_space,
38253 .vector_index = vector_info.vector_index,
38254 },
38255 .packed_offset = .{
38256 .host_size = vector_info.host_size,
38257 .bit_offset = 0,
38258 },
38259 });
38260}
38261
38262/// Merge lhs with rhs.37671/// Merge lhs with rhs.
38263/// Asserts that lhs and rhs are both error sets and are resolved.37672/// Asserts that lhs and rhs are both error sets and are resolved.
38264fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {37673fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
...@@ -38299,13 +37708,6 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool...@@ -38299,13 +37708,6 @@ fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool
38299 return sema.typeOf(ref).zigTypeTag(sema.mod) == tag;37708 return sema.typeOf(ref).zigTypeTag(sema.mod) == tag;
38300}37709}
3830137710
38302pub fn ptrType(sema: *Sema, info: InternPool.Key.PtrType) CompileError!Type {
38303 if (info.flags.alignment != .none) {
38304 _ = try sema.typeAbiAlignment(Type.fromInterned(info.child));
38305 }
38306 return sema.mod.ptrType(info);
38307}
38308
38309pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {37711pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
38310 if (!sema.mod.comp.debug_incremental) return;37712 if (!sema.mod.comp.debug_incremental) return;
3831137713
...@@ -38425,12 +37827,12 @@ fn maybeDerefSliceAsArray(...@@ -38425,12 +37827,12 @@ fn maybeDerefSliceAsArray(
38425 else => unreachable,37827 else => unreachable,
38426 };37828 };
38427 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);37829 const elem_ty = Type.fromInterned(slice.ty).childType(zcu);
38428 const len = try Value.fromInterned(slice.len).toUnsignedIntAdvanced(sema);37830 const len = try Value.fromInterned(slice.len).toUnsignedIntSema(zcu);
38429 const array_ty = try zcu.arrayType(.{37831 const array_ty = try zcu.arrayType(.{
38430 .child = elem_ty.toIntern(),37832 .child = elem_ty.toIntern(),
38431 .len = len,37833 .len = len,
38432 });37834 });
38433 const ptr_ty = try sema.ptrType(p: {37835 const ptr_ty = try zcu.ptrTypeSema(p: {
38434 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);37836 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);
38435 p.flags.size = .One;37837 p.flags.size = .One;
38436 p.child = array_ty.toIntern();37838 p.child = array_ty.toIntern();
src/Sema/bitcast.zig+4-4
...@@ -78,8 +78,8 @@ fn bitCastInner(...@@ -78,8 +78,8 @@ fn bitCastInner(
7878
79 const val_ty = val.typeOf(zcu);79 const val_ty = val.typeOf(zcu);
8080
81 try sema.resolveTypeLayout(val_ty);81 try val_ty.resolveLayout(zcu);
82 try sema.resolveTypeLayout(dest_ty);82 try dest_ty.resolveLayout(zcu);
8383
84 assert(val_ty.hasWellDefinedLayout(zcu));84 assert(val_ty.hasWellDefinedLayout(zcu));
8585
...@@ -136,8 +136,8 @@ fn bitCastSpliceInner(...@@ -136,8 +136,8 @@ fn bitCastSpliceInner(
136 const val_ty = val.typeOf(zcu);136 const val_ty = val.typeOf(zcu);
137 const splice_val_ty = splice_val.typeOf(zcu);137 const splice_val_ty = splice_val.typeOf(zcu);
138138
139 try sema.resolveTypeLayout(val_ty);139 try val_ty.resolveLayout(zcu);
140 try sema.resolveTypeLayout(splice_val_ty);140 try splice_val_ty.resolveLayout(zcu);
141141
142 const splice_bits = splice_val_ty.bitSize(zcu);142 const splice_bits = splice_val_ty.bitSize(zcu);
143143
src/Type.zig+508-116
...@@ -5,6 +5,7 @@...@@ -5,6 +5,7 @@
55
6const std = @import("std");6const std = @import("std");
7const builtin = @import("builtin");7const builtin = @import("builtin");
8const Allocator = std.mem.Allocator;
8const Value = @import("Value.zig");9const Value = @import("Value.zig");
9const assert = std.debug.assert;10const assert = std.debug.assert;
10const Target = std.Target;11const Target = std.Target;
...@@ -18,6 +19,7 @@ const InternPool = @import("InternPool.zig");...@@ -18,6 +19,7 @@ const InternPool = @import("InternPool.zig");
18const Alignment = InternPool.Alignment;19const Alignment = InternPool.Alignment;
19const Zir = std.zig.Zir;20const Zir = std.zig.Zir;
20const Type = @This();21const Type = @This();
22const SemaError = Zcu.SemaError;
2123
22ip_index: InternPool.Index,24ip_index: InternPool.Index,
2325
...@@ -458,7 +460,7 @@ pub fn toValue(self: Type) Value {...@@ -458,7 +460,7 @@ pub fn toValue(self: Type) Value {
458 return Value.fromInterned(self.toIntern());460 return Value.fromInterned(self.toIntern());
459}461}
460462
461const RuntimeBitsError = Module.CompileError || error{NeedLazy};463const RuntimeBitsError = SemaError || error{NeedLazy};
462464
463/// true if and only if the type takes up space in memory at runtime.465/// true if and only if the type takes up space in memory at runtime.
464/// There are two reasons a type will return false:466/// There are two reasons a type will return false:
...@@ -475,7 +477,7 @@ pub fn hasRuntimeBitsAdvanced(...@@ -475,7 +477,7 @@ pub fn hasRuntimeBitsAdvanced(
475 ty: Type,477 ty: Type,
476 mod: *Module,478 mod: *Module,
477 ignore_comptime_only: bool,479 ignore_comptime_only: bool,
478 strat: AbiAlignmentAdvancedStrat,480 strat: ResolveStratLazy,
479) RuntimeBitsError!bool {481) RuntimeBitsError!bool {
480 const ip = &mod.intern_pool;482 const ip = &mod.intern_pool;
481 return switch (ty.toIntern()) {483 return switch (ty.toIntern()) {
...@@ -488,8 +490,8 @@ pub fn hasRuntimeBitsAdvanced(...@@ -488,8 +490,8 @@ pub fn hasRuntimeBitsAdvanced(
488 // to comptime-only types do not, with the exception of function pointers.490 // to comptime-only types do not, with the exception of function pointers.
489 if (ignore_comptime_only) return true;491 if (ignore_comptime_only) return true;
490 return switch (strat) {492 return switch (strat) {
491 .sema => |sema| !(try sema.typeRequiresComptime(ty)),493 .sema => !try ty.comptimeOnlyAdvanced(mod, .sema),
492 .eager => !comptimeOnly(ty, mod),494 .eager => !ty.comptimeOnly(mod),
493 .lazy => error.NeedLazy,495 .lazy => error.NeedLazy,
494 };496 };
495 },497 },
...@@ -506,8 +508,8 @@ pub fn hasRuntimeBitsAdvanced(...@@ -506,8 +508,8 @@ pub fn hasRuntimeBitsAdvanced(
506 }508 }
507 if (ignore_comptime_only) return true;509 if (ignore_comptime_only) return true;
508 return switch (strat) {510 return switch (strat) {
509 .sema => |sema| !(try sema.typeRequiresComptime(child_ty)),511 .sema => !try child_ty.comptimeOnlyAdvanced(mod, .sema),
510 .eager => !comptimeOnly(child_ty, mod),512 .eager => !child_ty.comptimeOnly(mod),
511 .lazy => error.NeedLazy,513 .lazy => error.NeedLazy,
512 };514 };
513 },515 },
...@@ -578,7 +580,7 @@ pub fn hasRuntimeBitsAdvanced(...@@ -578,7 +580,7 @@ pub fn hasRuntimeBitsAdvanced(
578 return true;580 return true;
579 }581 }
580 switch (strat) {582 switch (strat) {
581 .sema => |sema| _ = try sema.resolveTypeFields(ty),583 .sema => try ty.resolveFields(mod),
582 .eager => assert(struct_type.haveFieldTypes(ip)),584 .eager => assert(struct_type.haveFieldTypes(ip)),
583 .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy,585 .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy,
584 }586 }
...@@ -622,7 +624,7 @@ pub fn hasRuntimeBitsAdvanced(...@@ -622,7 +624,7 @@ pub fn hasRuntimeBitsAdvanced(
622 },624 },
623 }625 }
624 switch (strat) {626 switch (strat) {
625 .sema => |sema| _ = try sema.resolveTypeFields(ty),627 .sema => try ty.resolveFields(mod),
626 .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()),628 .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()),
627 .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes())629 .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes())
628 return error.NeedLazy,630 return error.NeedLazy,
...@@ -784,19 +786,18 @@ pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool {...@@ -784,19 +786,18 @@ pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool {
784}786}
785787
786pub fn fnHasRuntimeBits(ty: Type, mod: *Module) bool {788pub fn fnHasRuntimeBits(ty: Type, mod: *Module) bool {
787 return ty.fnHasRuntimeBitsAdvanced(mod, null) catch unreachable;789 return ty.fnHasRuntimeBitsAdvanced(mod, .normal) catch unreachable;
788}790}
789791
790/// Determines whether a function type has runtime bits, i.e. whether a792/// Determines whether a function type has runtime bits, i.e. whether a
791/// function with this type can exist at runtime.793/// function with this type can exist at runtime.
792/// Asserts that `ty` is a function type.794/// Asserts that `ty` is a function type.
793/// If `opt_sema` is not provided, asserts that the return type is sufficiently resolved.795pub fn fnHasRuntimeBitsAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool {
794pub fn fnHasRuntimeBitsAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.CompileError!bool {
795 const fn_info = mod.typeToFunc(ty).?;796 const fn_info = mod.typeToFunc(ty).?;
796 if (fn_info.is_generic) return false;797 if (fn_info.is_generic) return false;
797 if (fn_info.is_var_args) return true;798 if (fn_info.is_var_args) return true;
798 if (fn_info.cc == .Inline) return false;799 if (fn_info.cc == .Inline) return false;
799 return !try Type.fromInterned(fn_info.return_type).comptimeOnlyAdvanced(mod, opt_sema);800 return !try Type.fromInterned(fn_info.return_type).comptimeOnlyAdvanced(mod, strat);
800}801}
801802
802pub fn isFnOrHasRuntimeBits(ty: Type, mod: *Module) bool {803pub fn isFnOrHasRuntimeBits(ty: Type, mod: *Module) bool {
...@@ -820,23 +821,23 @@ pub fn isNoReturn(ty: Type, mod: *Module) bool {...@@ -820,23 +821,23 @@ pub fn isNoReturn(ty: Type, mod: *Module) bool {
820821
821/// Returns `none` if the pointer is naturally aligned and the element type is 0-bit.822/// Returns `none` if the pointer is naturally aligned and the element type is 0-bit.
822pub fn ptrAlignment(ty: Type, mod: *Module) Alignment {823pub fn ptrAlignment(ty: Type, mod: *Module) Alignment {
823 return ptrAlignmentAdvanced(ty, mod, null) catch unreachable;824 return ptrAlignmentAdvanced(ty, mod, .normal) catch unreachable;
824}825}
825826
826pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !Alignment {827pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) !Alignment {
827 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {828 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
828 .ptr_type => |ptr_type| {829 .ptr_type => |ptr_type| {
829 if (ptr_type.flags.alignment != .none)830 if (ptr_type.flags.alignment != .none)
830 return ptr_type.flags.alignment;831 return ptr_type.flags.alignment;
831832
832 if (opt_sema) |sema| {833 if (strat == .sema) {
833 const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .{ .sema = sema });834 const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .sema);
834 return res.scalar;835 return res.scalar;
835 }836 }
836837
837 return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;838 return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
838 },839 },
839 .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(mod, opt_sema),840 .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(mod, strat),
840 else => unreachable,841 else => unreachable,
841 };842 };
842}843}
...@@ -868,10 +869,34 @@ pub const AbiAlignmentAdvanced = union(enum) {...@@ -868,10 +869,34 @@ pub const AbiAlignmentAdvanced = union(enum) {
868 val: Value,869 val: Value,
869};870};
870871
871pub const AbiAlignmentAdvancedStrat = union(enum) {872pub const ResolveStratLazy = enum {
872 eager,873 /// Return a `lazy_size` or `lazy_align` value if necessary.
874 /// This value can be resolved later using `Value.resolveLazy`.
873 lazy,875 lazy,
874 sema: *Sema,876 /// Return a scalar result, expecting all necessary type resolution to be completed.
877 /// Backends should typically use this, since they must not perform type resolution.
878 eager,
879 /// Return a scalar result, performing type resolution as necessary.
880 /// This should typically be used from semantic analysis.
881 sema,
882};
883
884/// The chosen strategy can be easily optimized away in release builds.
885/// However, in debug builds, it helps to avoid acceidentally resolving types in backends.
886pub const ResolveStrat = enum {
887 /// Assert that all necessary resolution is completed.
888 /// Backends should typically use this, since they must not perform type resolution.
889 normal,
890 /// Perform type resolution as necessary using `Zcu`.
891 /// This should typically be used from semantic analysis.
892 sema,
893
894 pub fn toLazy(strat: ResolveStrat) ResolveStratLazy {
895 return switch (strat) {
896 .normal => .eager,
897 .sema => .sema,
898 };
899 }
875};900};
876901
877/// If you pass `eager` you will get back `scalar` and assert the type is resolved.902/// If you pass `eager` you will get back `scalar` and assert the type is resolved.
...@@ -883,17 +908,12 @@ pub const AbiAlignmentAdvancedStrat = union(enum) {...@@ -883,17 +908,12 @@ pub const AbiAlignmentAdvancedStrat = union(enum) {
883pub fn abiAlignmentAdvanced(908pub fn abiAlignmentAdvanced(
884 ty: Type,909 ty: Type,
885 mod: *Module,910 mod: *Module,
886 strat: AbiAlignmentAdvancedStrat,911 strat: ResolveStratLazy,
887) Module.CompileError!AbiAlignmentAdvanced {912) SemaError!AbiAlignmentAdvanced {
888 const target = mod.getTarget();913 const target = mod.getTarget();
889 const use_llvm = mod.comp.config.use_llvm;914 const use_llvm = mod.comp.config.use_llvm;
890 const ip = &mod.intern_pool;915 const ip = &mod.intern_pool;
891916
892 const opt_sema = switch (strat) {
893 .sema => |sema| sema,
894 else => null,
895 };
896
897 switch (ty.toIntern()) {917 switch (ty.toIntern()) {
898 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = .@"1" },918 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = .@"1" },
899 else => switch (ip.indexToKey(ty.toIntern())) {919 else => switch (ip.indexToKey(ty.toIntern())) {
...@@ -911,7 +931,7 @@ pub fn abiAlignmentAdvanced(...@@ -911,7 +931,7 @@ pub fn abiAlignmentAdvanced(
911 if (vector_type.len == 0) return .{ .scalar = .@"1" };931 if (vector_type.len == 0) return .{ .scalar = .@"1" };
912 switch (mod.comp.getZigBackend()) {932 switch (mod.comp.getZigBackend()) {
913 else => {933 else => {
914 const elem_bits: u32 = @intCast(try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, opt_sema));934 const elem_bits: u32 = @intCast(try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, .sema));
915 if (elem_bits == 0) return .{ .scalar = .@"1" };935 if (elem_bits == 0) return .{ .scalar = .@"1" };
916 const bytes = ((elem_bits * vector_type.len) + 7) / 8;936 const bytes = ((elem_bits * vector_type.len) + 7) / 8;
917 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);937 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
...@@ -1024,7 +1044,7 @@ pub fn abiAlignmentAdvanced(...@@ -1024,7 +1044,7 @@ pub fn abiAlignmentAdvanced(
1024 const struct_type = ip.loadStructType(ty.toIntern());1044 const struct_type = ip.loadStructType(ty.toIntern());
1025 if (struct_type.layout == .@"packed") {1045 if (struct_type.layout == .@"packed") {
1026 switch (strat) {1046 switch (strat) {
1027 .sema => |sema| try sema.resolveTypeLayout(ty),1047 .sema => try ty.resolveLayout(mod),
1028 .lazy => if (struct_type.backingIntType(ip).* == .none) return .{1048 .lazy => if (struct_type.backingIntType(ip).* == .none) return .{
1029 .val = Value.fromInterned((try mod.intern(.{ .int = .{1049 .val = Value.fromInterned((try mod.intern(.{ .int = .{
1030 .ty = .comptime_int_type,1050 .ty = .comptime_int_type,
...@@ -1036,19 +1056,16 @@ pub fn abiAlignmentAdvanced(...@@ -1036,19 +1056,16 @@ pub fn abiAlignmentAdvanced(
1036 return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(mod) };1056 return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(mod) };
1037 }1057 }
10381058
1039 const flags = struct_type.flagsPtr(ip).*;1059 if (struct_type.flagsPtr(ip).alignment == .none) switch (strat) {
1040 if (flags.alignment != .none) return .{ .scalar = flags.alignment };
1041
1042 return switch (strat) {
1043 .eager => unreachable, // struct alignment not resolved1060 .eager => unreachable, // struct alignment not resolved
1044 .sema => |sema| .{1061 .sema => try ty.resolveStructAlignment(mod),
1045 .scalar = try sema.resolveStructAlignment(ty.toIntern(), struct_type),1062 .lazy => return .{ .val = Value.fromInterned(try mod.intern(.{ .int = .{
1046 },
1047 .lazy => .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{
1048 .ty = .comptime_int_type,1063 .ty = .comptime_int_type,
1049 .storage = .{ .lazy_align = ty.toIntern() },1064 .storage = .{ .lazy_align = ty.toIntern() },
1050 } }))) },1065 } })) },
1051 };1066 };
1067
1068 return .{ .scalar = struct_type.flagsPtr(ip).alignment };
1052 },1069 },
1053 .anon_struct_type => |tuple| {1070 .anon_struct_type => |tuple| {
1054 var big_align: Alignment = .@"1";1071 var big_align: Alignment = .@"1";
...@@ -1070,12 +1087,10 @@ pub fn abiAlignmentAdvanced(...@@ -1070,12 +1087,10 @@ pub fn abiAlignmentAdvanced(
1070 },1087 },
1071 .union_type => {1088 .union_type => {
1072 const union_type = ip.loadUnionType(ty.toIntern());1089 const union_type = ip.loadUnionType(ty.toIntern());
1073 const flags = union_type.flagsPtr(ip).*;
1074 if (flags.alignment != .none) return .{ .scalar = flags.alignment };
10751090
1076 if (!union_type.haveLayout(ip)) switch (strat) {1091 if (union_type.flagsPtr(ip).alignment == .none) switch (strat) {
1077 .eager => unreachable, // union layout not resolved1092 .eager => unreachable, // union layout not resolved
1078 .sema => |sema| return .{ .scalar = try sema.resolveUnionAlignment(ty, union_type) },1093 .sema => try ty.resolveUnionAlignment(mod),
1079 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1094 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{
1080 .ty = .comptime_int_type,1095 .ty = .comptime_int_type,
1081 .storage = .{ .lazy_align = ty.toIntern() },1096 .storage = .{ .lazy_align = ty.toIntern() },
...@@ -1117,9 +1132,9 @@ pub fn abiAlignmentAdvanced(...@@ -1117,9 +1132,9 @@ pub fn abiAlignmentAdvanced(
1117fn abiAlignmentAdvancedErrorUnion(1132fn abiAlignmentAdvancedErrorUnion(
1118 ty: Type,1133 ty: Type,
1119 mod: *Module,1134 mod: *Module,
1120 strat: AbiAlignmentAdvancedStrat,1135 strat: ResolveStratLazy,
1121 payload_ty: Type,1136 payload_ty: Type,
1122) Module.CompileError!AbiAlignmentAdvanced {1137) SemaError!AbiAlignmentAdvanced {
1123 // This code needs to be kept in sync with the equivalent switch prong1138 // This code needs to be kept in sync with the equivalent switch prong
1124 // in abiSizeAdvanced.1139 // in abiSizeAdvanced.
1125 const code_align = abiAlignment(Type.anyerror, mod);1140 const code_align = abiAlignment(Type.anyerror, mod);
...@@ -1154,8 +1169,8 @@ fn abiAlignmentAdvancedErrorUnion(...@@ -1154,8 +1169,8 @@ fn abiAlignmentAdvancedErrorUnion(
1154fn abiAlignmentAdvancedOptional(1169fn abiAlignmentAdvancedOptional(
1155 ty: Type,1170 ty: Type,
1156 mod: *Module,1171 mod: *Module,
1157 strat: AbiAlignmentAdvancedStrat,1172 strat: ResolveStratLazy,
1158) Module.CompileError!AbiAlignmentAdvanced {1173) SemaError!AbiAlignmentAdvanced {
1159 const target = mod.getTarget();1174 const target = mod.getTarget();
1160 const child_type = ty.optionalChild(mod);1175 const child_type = ty.optionalChild(mod);
11611176
...@@ -1217,8 +1232,8 @@ const AbiSizeAdvanced = union(enum) {...@@ -1217,8 +1232,8 @@ const AbiSizeAdvanced = union(enum) {
1217pub fn abiSizeAdvanced(1232pub fn abiSizeAdvanced(
1218 ty: Type,1233 ty: Type,
1219 mod: *Module,1234 mod: *Module,
1220 strat: AbiAlignmentAdvancedStrat,1235 strat: ResolveStratLazy,
1221) Module.CompileError!AbiSizeAdvanced {1236) SemaError!AbiSizeAdvanced {
1222 const target = mod.getTarget();1237 const target = mod.getTarget();
1223 const use_llvm = mod.comp.config.use_llvm;1238 const use_llvm = mod.comp.config.use_llvm;
1224 const ip = &mod.intern_pool;1239 const ip = &mod.intern_pool;
...@@ -1252,9 +1267,9 @@ pub fn abiSizeAdvanced(...@@ -1252,9 +1267,9 @@ pub fn abiSizeAdvanced(
1252 }1267 }
1253 },1268 },
1254 .vector_type => |vector_type| {1269 .vector_type => |vector_type| {
1255 const opt_sema = switch (strat) {1270 const sub_strat: ResolveStrat = switch (strat) {
1256 .sema => |sema| sema,1271 .sema => .sema,
1257 .eager => null,1272 .eager => .normal,
1258 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{1273 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{
1259 .ty = .comptime_int_type,1274 .ty = .comptime_int_type,
1260 .storage = .{ .lazy_size = ty.toIntern() },1275 .storage = .{ .lazy_size = ty.toIntern() },
...@@ -1269,7 +1284,7 @@ pub fn abiSizeAdvanced(...@@ -1269,7 +1284,7 @@ pub fn abiSizeAdvanced(
1269 };1284 };
1270 const total_bytes = switch (mod.comp.getZigBackend()) {1285 const total_bytes = switch (mod.comp.getZigBackend()) {
1271 else => total_bytes: {1286 else => total_bytes: {
1272 const elem_bits = try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, opt_sema);1287 const elem_bits = try Type.fromInterned(vector_type.child).bitSizeAdvanced(mod, sub_strat);
1273 const total_bits = elem_bits * vector_type.len;1288 const total_bits = elem_bits * vector_type.len;
1274 break :total_bytes (total_bits + 7) / 8;1289 break :total_bytes (total_bits + 7) / 8;
1275 },1290 },
...@@ -1403,7 +1418,7 @@ pub fn abiSizeAdvanced(...@@ -1403,7 +1418,7 @@ pub fn abiSizeAdvanced(
1403 .struct_type => {1418 .struct_type => {
1404 const struct_type = ip.loadStructType(ty.toIntern());1419 const struct_type = ip.loadStructType(ty.toIntern());
1405 switch (strat) {1420 switch (strat) {
1406 .sema => |sema| try sema.resolveTypeLayout(ty),1421 .sema => try ty.resolveLayout(mod),
1407 .lazy => switch (struct_type.layout) {1422 .lazy => switch (struct_type.layout) {
1408 .@"packed" => {1423 .@"packed" => {
1409 if (struct_type.backingIntType(ip).* == .none) return .{1424 if (struct_type.backingIntType(ip).* == .none) return .{
...@@ -1436,7 +1451,7 @@ pub fn abiSizeAdvanced(...@@ -1436,7 +1451,7 @@ pub fn abiSizeAdvanced(
1436 },1451 },
1437 .anon_struct_type => |tuple| {1452 .anon_struct_type => |tuple| {
1438 switch (strat) {1453 switch (strat) {
1439 .sema => |sema| try sema.resolveTypeLayout(ty),1454 .sema => try ty.resolveLayout(mod),
1440 .lazy, .eager => {},1455 .lazy, .eager => {},
1441 }1456 }
1442 const field_count = tuple.types.len;1457 const field_count = tuple.types.len;
...@@ -1449,7 +1464,7 @@ pub fn abiSizeAdvanced(...@@ -1449,7 +1464,7 @@ pub fn abiSizeAdvanced(
1449 .union_type => {1464 .union_type => {
1450 const union_type = ip.loadUnionType(ty.toIntern());1465 const union_type = ip.loadUnionType(ty.toIntern());
1451 switch (strat) {1466 switch (strat) {
1452 .sema => |sema| try sema.resolveTypeLayout(ty),1467 .sema => try ty.resolveLayout(mod),
1453 .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{1468 .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{
1454 .val = Value.fromInterned((try mod.intern(.{ .int = .{1469 .val = Value.fromInterned((try mod.intern(.{ .int = .{
1455 .ty = .comptime_int_type,1470 .ty = .comptime_int_type,
...@@ -1493,8 +1508,8 @@ pub fn abiSizeAdvanced(...@@ -1493,8 +1508,8 @@ pub fn abiSizeAdvanced(
1493fn abiSizeAdvancedOptional(1508fn abiSizeAdvancedOptional(
1494 ty: Type,1509 ty: Type,
1495 mod: *Module,1510 mod: *Module,
1496 strat: AbiAlignmentAdvancedStrat,1511 strat: ResolveStratLazy,
1497) Module.CompileError!AbiSizeAdvanced {1512) SemaError!AbiSizeAdvanced {
1498 const child_ty = ty.optionalChild(mod);1513 const child_ty = ty.optionalChild(mod);
14991514
1500 if (child_ty.isNoReturn(mod)) {1515 if (child_ty.isNoReturn(mod)) {
...@@ -1661,21 +1676,18 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 {...@@ -1661,21 +1676,18 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 {
1661}1676}
16621677
1663pub fn bitSize(ty: Type, mod: *Module) u64 {1678pub fn bitSize(ty: Type, mod: *Module) u64 {
1664 return bitSizeAdvanced(ty, mod, null) catch unreachable;1679 return bitSizeAdvanced(ty, mod, .normal) catch unreachable;
1665}1680}
16661681
1667/// If you pass `opt_sema`, any recursive type resolutions will happen if
1668/// necessary, possibly returning a CompileError. Passing `null` instead asserts
1669/// the type is fully resolved, and there will be no error, guaranteed.
1670pub fn bitSizeAdvanced(1682pub fn bitSizeAdvanced(
1671 ty: Type,1683 ty: Type,
1672 mod: *Module,1684 mod: *Module,
1673 opt_sema: ?*Sema,1685 strat: ResolveStrat,
1674) Module.CompileError!u64 {1686) SemaError!u64 {
1675 const target = mod.getTarget();1687 const target = mod.getTarget();
1676 const ip = &mod.intern_pool;1688 const ip = &mod.intern_pool;
16771689
1678 const strat: AbiAlignmentAdvancedStrat = if (opt_sema) |sema| .{ .sema = sema } else .eager;1690 const strat_lazy: ResolveStratLazy = strat.toLazy();
16791691
1680 switch (ip.indexToKey(ty.toIntern())) {1692 switch (ip.indexToKey(ty.toIntern())) {
1681 .int_type => |int_type| return int_type.bits,1693 .int_type => |int_type| return int_type.bits,
...@@ -1690,22 +1702,22 @@ pub fn bitSizeAdvanced(...@@ -1690,22 +1702,22 @@ pub fn bitSizeAdvanced(
1690 if (len == 0) return 0;1702 if (len == 0) return 0;
1691 const elem_ty = Type.fromInterned(array_type.child);1703 const elem_ty = Type.fromInterned(array_type.child);
1692 const elem_size = @max(1704 const elem_size = @max(
1693 (try elem_ty.abiAlignmentAdvanced(mod, strat)).scalar.toByteUnits() orelse 0,1705 (try elem_ty.abiAlignmentAdvanced(mod, strat_lazy)).scalar.toByteUnits() orelse 0,
1694 (try elem_ty.abiSizeAdvanced(mod, strat)).scalar,1706 (try elem_ty.abiSizeAdvanced(mod, strat_lazy)).scalar,
1695 );1707 );
1696 if (elem_size == 0) return 0;1708 if (elem_size == 0) return 0;
1697 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, opt_sema);1709 const elem_bit_size = try bitSizeAdvanced(elem_ty, mod, strat);
1698 return (len - 1) * 8 * elem_size + elem_bit_size;1710 return (len - 1) * 8 * elem_size + elem_bit_size;
1699 },1711 },
1700 .vector_type => |vector_type| {1712 .vector_type => |vector_type| {
1701 const child_ty = Type.fromInterned(vector_type.child);1713 const child_ty = Type.fromInterned(vector_type.child);
1702 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);1714 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, strat);
1703 return elem_bit_size * vector_type.len;1715 return elem_bit_size * vector_type.len;
1704 },1716 },
1705 .opt_type => {1717 .opt_type => {
1706 // Optionals and error unions are not packed so their bitsize1718 // Optionals and error unions are not packed so their bitsize
1707 // includes padding bits.1719 // includes padding bits.
1708 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;1720 return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8;
1709 },1721 },
17101722
1711 .error_set_type, .inferred_error_set_type => return mod.errorSetBits(),1723 .error_set_type, .inferred_error_set_type => return mod.errorSetBits(),
...@@ -1713,7 +1725,7 @@ pub fn bitSizeAdvanced(...@@ -1713,7 +1725,7 @@ pub fn bitSizeAdvanced(
1713 .error_union_type => {1725 .error_union_type => {
1714 // Optionals and error unions are not packed so their bitsize1726 // Optionals and error unions are not packed so their bitsize
1715 // includes padding bits.1727 // includes padding bits.
1716 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;1728 return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8;
1717 },1729 },
1718 .func_type => unreachable, // represents machine code; not a pointer1730 .func_type => unreachable, // represents machine code; not a pointer
1719 .simple_type => |t| switch (t) {1731 .simple_type => |t| switch (t) {
...@@ -1770,43 +1782,43 @@ pub fn bitSizeAdvanced(...@@ -1770,43 +1782,43 @@ pub fn bitSizeAdvanced(
1770 .struct_type => {1782 .struct_type => {
1771 const struct_type = ip.loadStructType(ty.toIntern());1783 const struct_type = ip.loadStructType(ty.toIntern());
1772 const is_packed = struct_type.layout == .@"packed";1784 const is_packed = struct_type.layout == .@"packed";
1773 if (opt_sema) |sema| {1785 if (strat == .sema) {
1774 try sema.resolveTypeFields(ty);1786 try ty.resolveFields(mod);
1775 if (is_packed) try sema.resolveTypeLayout(ty);1787 if (is_packed) try ty.resolveLayout(mod);
1776 }1788 }
1777 if (is_packed) {1789 if (is_packed) {
1778 return try Type.fromInterned(struct_type.backingIntType(ip).*).bitSizeAdvanced(mod, opt_sema);1790 return try Type.fromInterned(struct_type.backingIntType(ip).*).bitSizeAdvanced(mod, strat);
1779 }1791 }
1780 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1792 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;
1781 },1793 },
17821794
1783 .anon_struct_type => {1795 .anon_struct_type => {
1784 if (opt_sema) |sema| try sema.resolveTypeFields(ty);1796 if (strat == .sema) try ty.resolveFields(mod);
1785 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1797 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;
1786 },1798 },
17871799
1788 .union_type => {1800 .union_type => {
1789 const union_type = ip.loadUnionType(ty.toIntern());1801 const union_type = ip.loadUnionType(ty.toIntern());
1790 const is_packed = ty.containerLayout(mod) == .@"packed";1802 const is_packed = ty.containerLayout(mod) == .@"packed";
1791 if (opt_sema) |sema| {1803 if (strat == .sema) {
1792 try sema.resolveTypeFields(ty);1804 try ty.resolveFields(mod);
1793 if (is_packed) try sema.resolveTypeLayout(ty);1805 if (is_packed) try ty.resolveLayout(mod);
1794 }1806 }
1795 if (!is_packed) {1807 if (!is_packed) {
1796 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;1808 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;
1797 }1809 }
1798 assert(union_type.flagsPtr(ip).status.haveFieldTypes());1810 assert(union_type.flagsPtr(ip).status.haveFieldTypes());
17991811
1800 var size: u64 = 0;1812 var size: u64 = 0;
1801 for (0..union_type.field_types.len) |field_index| {1813 for (0..union_type.field_types.len) |field_index| {
1802 const field_ty = union_type.field_types.get(ip)[field_index];1814 const field_ty = union_type.field_types.get(ip)[field_index];
1803 size = @max(size, try bitSizeAdvanced(Type.fromInterned(field_ty), mod, opt_sema));1815 size = @max(size, try bitSizeAdvanced(Type.fromInterned(field_ty), mod, strat));
1804 }1816 }
18051817
1806 return size;1818 return size;
1807 },1819 },
1808 .opaque_type => unreachable,1820 .opaque_type => unreachable,
1809 .enum_type => return bitSizeAdvanced(Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), mod, opt_sema),1821 .enum_type => return bitSizeAdvanced(Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty), mod, strat),
18101822
1811 // values, not types1823 // values, not types
1812 .undef,1824 .undef,
...@@ -2722,13 +2734,12 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {...@@ -2722,13 +2734,12 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
2722/// During semantic analysis, instead call `Sema.typeRequiresComptime` which2734/// During semantic analysis, instead call `Sema.typeRequiresComptime` which
2723/// resolves field types rather than asserting they are already resolved.2735/// resolves field types rather than asserting they are already resolved.
2724pub fn comptimeOnly(ty: Type, mod: *Module) bool {2736pub fn comptimeOnly(ty: Type, mod: *Module) bool {
2725 return ty.comptimeOnlyAdvanced(mod, null) catch unreachable;2737 return ty.comptimeOnlyAdvanced(mod, .normal) catch unreachable;
2726}2738}
27272739
2728/// `generic_poison` will return false.2740/// `generic_poison` will return false.
2729/// May return false negatives when structs and unions are having their field types resolved.2741/// May return false negatives when structs and unions are having their field types resolved.
2730/// If `opt_sema` is not provided, asserts that the type is sufficiently resolved.2742pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool {
2731pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.CompileError!bool {
2732 const ip = &mod.intern_pool;2743 const ip = &mod.intern_pool;
2733 return switch (ty.toIntern()) {2744 return switch (ty.toIntern()) {
2734 .empty_struct_type => false,2745 .empty_struct_type => false,
...@@ -2738,19 +2749,19 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com...@@ -2738,19 +2749,19 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
2738 .ptr_type => |ptr_type| {2749 .ptr_type => |ptr_type| {
2739 const child_ty = Type.fromInterned(ptr_type.child);2750 const child_ty = Type.fromInterned(ptr_type.child);
2740 switch (child_ty.zigTypeTag(mod)) {2751 switch (child_ty.zigTypeTag(mod)) {
2741 .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(mod, opt_sema),2752 .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(mod, strat),
2742 .Opaque => return false,2753 .Opaque => return false,
2743 else => return child_ty.comptimeOnlyAdvanced(mod, opt_sema),2754 else => return child_ty.comptimeOnlyAdvanced(mod, strat),
2744 }2755 }
2745 },2756 },
2746 .anyframe_type => |child| {2757 .anyframe_type => |child| {
2747 if (child == .none) return false;2758 if (child == .none) return false;
2748 return Type.fromInterned(child).comptimeOnlyAdvanced(mod, opt_sema);2759 return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat);
2749 },2760 },
2750 .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(mod, opt_sema),2761 .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(mod, strat),
2751 .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(mod, opt_sema),2762 .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(mod, strat),
2752 .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(mod, opt_sema),2763 .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat),
2753 .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(mod, opt_sema),2764 .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(mod, strat),
27542765
2755 .error_set_type,2766 .error_set_type,
2756 .inferred_error_set_type,2767 .inferred_error_set_type,
...@@ -2817,8 +2828,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com...@@ -2817,8 +2828,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
2817 .no, .wip => false,2828 .no, .wip => false,
2818 .yes => true,2829 .yes => true,
2819 .unknown => {2830 .unknown => {
2820 // The type is not resolved; assert that we have a Sema.2831 assert(strat == .sema);
2821 const sema = opt_sema.?;
28222832
2823 if (struct_type.flagsPtr(ip).field_types_wip)2833 if (struct_type.flagsPtr(ip).field_types_wip)
2824 return false;2834 return false;
...@@ -2826,13 +2836,13 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com...@@ -2826,13 +2836,13 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
2826 struct_type.flagsPtr(ip).requires_comptime = .wip;2836 struct_type.flagsPtr(ip).requires_comptime = .wip;
2827 errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown;2837 errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown;
28282838
2829 try sema.resolveTypeFieldsStruct(ty.toIntern(), struct_type);2839 try ty.resolveFields(mod);
28302840
2831 for (0..struct_type.field_types.len) |i_usize| {2841 for (0..struct_type.field_types.len) |i_usize| {
2832 const i: u32 = @intCast(i_usize);2842 const i: u32 = @intCast(i_usize);
2833 if (struct_type.fieldIsComptime(ip, i)) continue;2843 if (struct_type.fieldIsComptime(ip, i)) continue;
2834 const field_ty = struct_type.field_types.get(ip)[i];2844 const field_ty = struct_type.field_types.get(ip)[i];
2835 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, opt_sema)) {2845 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) {
2836 // Note that this does not cause the layout to2846 // Note that this does not cause the layout to
2837 // be considered resolved. Comptime-only types2847 // be considered resolved. Comptime-only types
2838 // still maintain a layout of their2848 // still maintain a layout of their
...@@ -2851,7 +2861,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com...@@ -2851,7 +2861,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
2851 .anon_struct_type => |tuple| {2861 .anon_struct_type => |tuple| {
2852 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {2862 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
2853 const have_comptime_val = val != .none;2863 const have_comptime_val = val != .none;
2854 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, opt_sema)) return true;2864 if (!have_comptime_val and try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) return true;
2855 }2865 }
2856 return false;2866 return false;
2857 },2867 },
...@@ -2862,8 +2872,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com...@@ -2862,8 +2872,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
2862 .no, .wip => return false,2872 .no, .wip => return false,
2863 .yes => return true,2873 .yes => return true,
2864 .unknown => {2874 .unknown => {
2865 // The type is not resolved; assert that we have a Sema.2875 assert(strat == .sema);
2866 const sema = opt_sema.?;
28672876
2868 if (union_type.flagsPtr(ip).status == .field_types_wip)2877 if (union_type.flagsPtr(ip).status == .field_types_wip)
2869 return false;2878 return false;
...@@ -2871,11 +2880,11 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com...@@ -2871,11 +2880,11 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
2871 union_type.flagsPtr(ip).requires_comptime = .wip;2880 union_type.flagsPtr(ip).requires_comptime = .wip;
2872 errdefer union_type.flagsPtr(ip).requires_comptime = .unknown;2881 errdefer union_type.flagsPtr(ip).requires_comptime = .unknown;
28732882
2874 try sema.resolveTypeFieldsUnion(ty, union_type);2883 try ty.resolveFields(mod);
28752884
2876 for (0..union_type.field_types.len) |field_idx| {2885 for (0..union_type.field_types.len) |field_idx| {
2877 const field_ty = union_type.field_types.get(ip)[field_idx];2886 const field_ty = union_type.field_types.get(ip)[field_idx];
2878 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, opt_sema)) {2887 if (try Type.fromInterned(field_ty).comptimeOnlyAdvanced(mod, strat)) {
2879 union_type.flagsPtr(ip).requires_comptime = .yes;2888 union_type.flagsPtr(ip).requires_comptime = .yes;
2880 return true;2889 return true;
2881 }2890 }
...@@ -2889,7 +2898,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com...@@ -2889,7 +2898,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
28892898
2890 .opaque_type => false,2899 .opaque_type => false,
28912900
2892 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(mod, opt_sema),2901 .enum_type => return Type.fromInterned(ip.loadEnumType(ty.toIntern()).tag_ty).comptimeOnlyAdvanced(mod, strat),
28932902
2894 // values, not types2903 // values, not types
2895 .undef,2904 .undef,
...@@ -3180,10 +3189,10 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type {...@@ -3180,10 +3189,10 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type {
3180}3189}
31813190
3182pub fn structFieldAlign(ty: Type, index: usize, zcu: *Zcu) Alignment {3191pub fn structFieldAlign(ty: Type, index: usize, zcu: *Zcu) Alignment {
3183 return ty.structFieldAlignAdvanced(index, zcu, null) catch unreachable;3192 return ty.structFieldAlignAdvanced(index, zcu, .normal) catch unreachable;
3184}3193}
31853194
3186pub fn structFieldAlignAdvanced(ty: Type, index: usize, zcu: *Zcu, opt_sema: ?*Sema) !Alignment {3195pub fn structFieldAlignAdvanced(ty: Type, index: usize, zcu: *Zcu, strat: ResolveStrat) !Alignment {
3187 const ip = &zcu.intern_pool;3196 const ip = &zcu.intern_pool;
3188 switch (ip.indexToKey(ty.toIntern())) {3197 switch (ip.indexToKey(ty.toIntern())) {
3189 .struct_type => {3198 .struct_type => {
...@@ -3191,22 +3200,14 @@ pub fn structFieldAlignAdvanced(ty: Type, index: usize, zcu: *Zcu, opt_sema: ?*S...@@ -3191,22 +3200,14 @@ pub fn structFieldAlignAdvanced(ty: Type, index: usize, zcu: *Zcu, opt_sema: ?*S
3191 assert(struct_type.layout != .@"packed");3200 assert(struct_type.layout != .@"packed");
3192 const explicit_align = struct_type.fieldAlign(ip, index);3201 const explicit_align = struct_type.fieldAlign(ip, index);
3193 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);3202 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
3194 if (opt_sema) |sema| {3203 return zcu.structFieldAlignmentAdvanced(explicit_align, field_ty, struct_type.layout, strat);
3195 return sema.structFieldAlignment(explicit_align, field_ty, struct_type.layout);
3196 } else {
3197 return zcu.structFieldAlignment(explicit_align, field_ty, struct_type.layout);
3198 }
3199 },3204 },
3200 .anon_struct_type => |anon_struct| {3205 .anon_struct_type => |anon_struct| {
3201 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentAdvanced(zcu, if (opt_sema) |sema| .{ .sema = sema } else .eager)).scalar;3206 return (try Type.fromInterned(anon_struct.types.get(ip)[index]).abiAlignmentAdvanced(zcu, strat.toLazy())).scalar;
3202 },3207 },
3203 .union_type => {3208 .union_type => {
3204 const union_obj = ip.loadUnionType(ty.toIntern());3209 const union_obj = ip.loadUnionType(ty.toIntern());
3205 if (opt_sema) |sema| {3210 return zcu.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(index), strat);
3206 return sema.unionFieldAlignment(union_obj, @intCast(index));
3207 } else {
3208 return zcu.unionFieldNormalAlignment(union_obj, @intCast(index));
3209 }
3210 },3211 },
3211 else => unreachable,3212 else => unreachable,
3212 }3213 }
...@@ -3546,6 +3547,397 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:...@@ -3546,6 +3547,397 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
3546 } };3547 } };
3547}3548}
35483549
3550pub fn resolveLayout(ty: Type, zcu: *Zcu) SemaError!void {
3551 const ip = &zcu.intern_pool;
3552 switch (ip.indexToKey(ty.toIntern())) {
3553 .simple_type => |simple_type| return resolveSimpleType(simple_type, zcu),
3554 else => {},
3555 }
3556 switch (ty.zigTypeTag(zcu)) {
3557 .Struct => switch (ip.indexToKey(ty.toIntern())) {
3558 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {
3559 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);
3560 try field_ty.resolveLayout(zcu);
3561 },
3562 .struct_type => return ty.resolveStructInner(zcu, .layout),
3563 else => unreachable,
3564 },
3565 .Union => return ty.resolveUnionInner(zcu, .layout),
3566 .Array => {
3567 if (ty.arrayLenIncludingSentinel(zcu) == 0) return;
3568 const elem_ty = ty.childType(zcu);
3569 return elem_ty.resolveLayout(zcu);
3570 },
3571 .Optional => {
3572 const payload_ty = ty.optionalChild(zcu);
3573 return payload_ty.resolveLayout(zcu);
3574 },
3575 .ErrorUnion => {
3576 const payload_ty = ty.errorUnionPayload(zcu);
3577 return payload_ty.resolveLayout(zcu);
3578 },
3579 .Fn => {
3580 const info = zcu.typeToFunc(ty).?;
3581 if (info.is_generic) {
3582 // Resolving of generic function types is deferred to when
3583 // the function is instantiated.
3584 return;
3585 }
3586 for (0..info.param_types.len) |i| {
3587 const param_ty = info.param_types.get(ip)[i];
3588 try Type.fromInterned(param_ty).resolveLayout(zcu);
3589 }
3590 try Type.fromInterned(info.return_type).resolveLayout(zcu);
3591 },
3592 else => {},
3593 }
3594}
3595
3596pub fn resolveFields(ty: Type, zcu: *Zcu) SemaError!void {
3597 const ip = &zcu.intern_pool;
3598 const ty_ip = ty.toIntern();
3599
3600 switch (ty_ip) {
3601 .none => unreachable,
3602
3603 .u0_type,
3604 .i0_type,
3605 .u1_type,
3606 .u8_type,
3607 .i8_type,
3608 .u16_type,
3609 .i16_type,
3610 .u29_type,
3611 .u32_type,
3612 .i32_type,
3613 .u64_type,
3614 .i64_type,
3615 .u80_type,
3616 .u128_type,
3617 .i128_type,
3618 .usize_type,
3619 .isize_type,
3620 .c_char_type,
3621 .c_short_type,
3622 .c_ushort_type,
3623 .c_int_type,
3624 .c_uint_type,
3625 .c_long_type,
3626 .c_ulong_type,
3627 .c_longlong_type,
3628 .c_ulonglong_type,
3629 .c_longdouble_type,
3630 .f16_type,
3631 .f32_type,
3632 .f64_type,
3633 .f80_type,
3634 .f128_type,
3635 .anyopaque_type,
3636 .bool_type,
3637 .void_type,
3638 .type_type,
3639 .anyerror_type,
3640 .adhoc_inferred_error_set_type,
3641 .comptime_int_type,
3642 .comptime_float_type,
3643 .noreturn_type,
3644 .anyframe_type,
3645 .null_type,
3646 .undefined_type,
3647 .enum_literal_type,
3648 .manyptr_u8_type,
3649 .manyptr_const_u8_type,
3650 .manyptr_const_u8_sentinel_0_type,
3651 .single_const_pointer_to_comptime_int_type,
3652 .slice_const_u8_type,
3653 .slice_const_u8_sentinel_0_type,
3654 .optional_noreturn_type,
3655 .anyerror_void_error_union_type,
3656 .generic_poison_type,
3657 .empty_struct_type,
3658 => {},
3659
3660 .undef => unreachable,
3661 .zero => unreachable,
3662 .zero_usize => unreachable,
3663 .zero_u8 => unreachable,
3664 .one => unreachable,
3665 .one_usize => unreachable,
3666 .one_u8 => unreachable,
3667 .four_u8 => unreachable,
3668 .negative_one => unreachable,
3669 .calling_convention_c => unreachable,
3670 .calling_convention_inline => unreachable,
3671 .void_value => unreachable,
3672 .unreachable_value => unreachable,
3673 .null_value => unreachable,
3674 .bool_true => unreachable,
3675 .bool_false => unreachable,
3676 .empty_struct => unreachable,
3677 .generic_poison => unreachable,
3678
3679 else => switch (ip.items.items(.tag)[@intFromEnum(ty_ip)]) {
3680 .type_struct,
3681 .type_struct_packed,
3682 .type_struct_packed_inits,
3683 => return ty.resolveStructInner(zcu, .fields),
3684
3685 .type_union => return ty.resolveUnionInner(zcu, .fields),
3686
3687 .simple_type => return resolveSimpleType(ip.indexToKey(ty_ip).simple_type, zcu),
3688
3689 else => {},
3690 },
3691 }
3692}
3693
3694pub fn resolveFully(ty: Type, zcu: *Zcu) SemaError!void {
3695 const ip = &zcu.intern_pool;
3696
3697 switch (ip.indexToKey(ty.toIntern())) {
3698 .simple_type => |simple_type| return resolveSimpleType(simple_type, zcu),
3699 else => {},
3700 }
3701
3702 switch (ty.zigTypeTag(zcu)) {
3703 .Type,
3704 .Void,
3705 .Bool,
3706 .NoReturn,
3707 .Int,
3708 .Float,
3709 .ComptimeFloat,
3710 .ComptimeInt,
3711 .Undefined,
3712 .Null,
3713 .ErrorSet,
3714 .Enum,
3715 .Opaque,
3716 .Frame,
3717 .AnyFrame,
3718 .Vector,
3719 .EnumLiteral,
3720 => {},
3721
3722 .Pointer => return ty.childType(zcu).resolveFully(zcu),
3723 .Array => return ty.childType(zcu).resolveFully(zcu),
3724 .Optional => return ty.optionalChild(zcu).resolveFully(zcu),
3725 .ErrorUnion => return ty.errorUnionPayload(zcu).resolveFully(zcu),
3726 .Fn => {
3727 const info = zcu.typeToFunc(ty).?;
3728 if (info.is_generic) return;
3729 for (0..info.param_types.len) |i| {
3730 const param_ty = info.param_types.get(ip)[i];
3731 try Type.fromInterned(param_ty).resolveFully(zcu);
3732 }
3733 try Type.fromInterned(info.return_type).resolveFully(zcu);
3734 },
3735
3736 .Struct => switch (ip.indexToKey(ty.toIntern())) {
3737 .anon_struct_type => |anon_struct_type| for (0..anon_struct_type.types.len) |i| {
3738 const field_ty = Type.fromInterned(anon_struct_type.types.get(ip)[i]);
3739 try field_ty.resolveFully(zcu);
3740 },
3741 .struct_type => return ty.resolveStructInner(zcu, .full),
3742 else => unreachable,
3743 },
3744 .Union => return ty.resolveUnionInner(zcu, .full),
3745 }
3746}
3747
3748pub fn resolveStructFieldInits(ty: Type, zcu: *Zcu) SemaError!void {
3749 // TODO: stop calling this for tuples!
3750 _ = zcu.typeToStruct(ty) orelse return;
3751 return ty.resolveStructInner(zcu, .inits);
3752}
3753
3754pub fn resolveStructAlignment(ty: Type, zcu: *Zcu) SemaError!void {
3755 return ty.resolveStructInner(zcu, .alignment);
3756}
3757
3758pub fn resolveUnionAlignment(ty: Type, zcu: *Zcu) SemaError!void {
3759 return ty.resolveUnionInner(zcu, .alignment);
3760}
3761
3762/// `ty` must be a struct.
3763fn resolveStructInner(
3764 ty: Type,
3765 zcu: *Zcu,
3766 resolution: enum { fields, inits, alignment, layout, full },
3767) SemaError!void {
3768 const gpa = zcu.gpa;
3769
3770 const struct_obj = zcu.typeToStruct(ty).?;
3771 const owner_decl_index = struct_obj.decl.unwrap() orelse return;
3772
3773 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3774 defer analysis_arena.deinit();
3775
3776 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
3777 defer comptime_err_ret_trace.deinit();
3778
3779 var sema: Sema = .{
3780 .mod = zcu,
3781 .gpa = gpa,
3782 .arena = analysis_arena.allocator(),
3783 .code = undefined, // This ZIR will not be used.
3784 .owner_decl = zcu.declPtr(owner_decl_index),
3785 .owner_decl_index = owner_decl_index,
3786 .func_index = .none,
3787 .func_is_naked = false,
3788 .fn_ret_ty = Type.void,
3789 .fn_ret_ty_ies = null,
3790 .owner_func_index = .none,
3791 .comptime_err_ret_trace = &comptime_err_ret_trace,
3792 };
3793 defer sema.deinit();
3794
3795 switch (resolution) {
3796 .fields => return sema.resolveTypeFieldsStruct(ty.toIntern(), struct_obj),
3797 .inits => return sema.resolveStructFieldInits(ty),
3798 .alignment => return sema.resolveStructAlignment(ty.toIntern(), struct_obj),
3799 .layout => return sema.resolveStructLayout(ty),
3800 .full => return sema.resolveStructFully(ty),
3801 }
3802}
3803
3804/// `ty` must be a union.
3805fn resolveUnionInner(
3806 ty: Type,
3807 zcu: *Zcu,
3808 resolution: enum { fields, alignment, layout, full },
3809) SemaError!void {
3810 const gpa = zcu.gpa;
3811
3812 const union_obj = zcu.typeToUnion(ty).?;
3813 const owner_decl_index = union_obj.decl;
3814
3815 var analysis_arena = std.heap.ArenaAllocator.init(gpa);
3816 defer analysis_arena.deinit();
3817
3818 var comptime_err_ret_trace = std.ArrayList(Zcu.LazySrcLoc).init(gpa);
3819 defer comptime_err_ret_trace.deinit();
3820
3821 var sema: Sema = .{
3822 .mod = zcu,
3823 .gpa = gpa,
3824 .arena = analysis_arena.allocator(),
3825 .code = undefined, // This ZIR will not be used.
3826 .owner_decl = zcu.declPtr(owner_decl_index),
3827 .owner_decl_index = owner_decl_index,
3828 .func_index = .none,
3829 .func_is_naked = false,
3830 .fn_ret_ty = Type.void,
3831 .fn_ret_ty_ies = null,
3832 .owner_func_index = .none,
3833 .comptime_err_ret_trace = &comptime_err_ret_trace,
3834 };
3835 defer sema.deinit();
3836
3837 switch (resolution) {
3838 .fields => return sema.resolveTypeFieldsUnion(ty, union_obj),
3839 .alignment => return sema.resolveUnionAlignment(ty, union_obj),
3840 .layout => return sema.resolveUnionLayout(ty),
3841 .full => return sema.resolveUnionFully(ty),
3842 }
3843}
3844
3845/// Fully resolves a simple type. This is usually a nop, but for builtin types with
3846/// special InternPool indices (such as std.builtin.Type) it will analyze and fully
3847/// resolve the type.
3848fn resolveSimpleType(simple_type: InternPool.SimpleType, zcu: *Zcu) Allocator.Error!void {
3849 const builtin_type_name: []const u8 = switch (simple_type) {
3850 .atomic_order => "AtomicOrder",
3851 .atomic_rmw_op => "AtomicRmwOp",
3852 .calling_convention => "CallingConvention",
3853 .address_space => "AddressSpace",
3854 .float_mode => "FloatMode",
3855 .reduce_op => "ReduceOp",
3856 .call_modifier => "CallModifer",
3857 .prefetch_options => "PrefetchOptions",
3858 .export_options => "ExportOptions",
3859 .extern_options => "ExternOptions",
3860 .type_info => "Type",
3861 else => return,
3862 };
3863 // This will fully resolve the type.
3864 _ = try zcu.getBuiltinType(builtin_type_name);
3865}
3866
3867/// Returns the type of a pointer to an element.
3868/// Asserts that the type is a pointer, and that the element type is indexable.
3869/// If the element index is comptime-known, it must be passed in `offset`.
3870/// For *@Vector(n, T), return *align(a:b:h:v) T
3871/// For *[N]T, return *T
3872/// For [*]T, returns *T
3873/// For []T, returns *T
3874/// Handles const-ness and address spaces in particular.
3875/// This code is duplicated in `Sema.analyzePtrArithmetic`.
3876/// May perform type resolution and return a transitive `error.AnalysisFail`.
3877pub fn elemPtrType(ptr_ty: Type, offset: ?usize, zcu: *Zcu) !Type {
3878 const ptr_info = ptr_ty.ptrInfo(zcu);
3879 const elem_ty = ptr_ty.elemType2(zcu);
3880 const is_allowzero = ptr_info.flags.is_allowzero and (offset orelse 0) == 0;
3881 const parent_ty = ptr_ty.childType(zcu);
3882
3883 const VI = InternPool.Key.PtrType.VectorIndex;
3884
3885 const vector_info: struct {
3886 host_size: u16 = 0,
3887 alignment: Alignment = .none,
3888 vector_index: VI = .none,
3889 } = if (parent_ty.isVector(zcu) and ptr_info.flags.size == .One) blk: {
3890 const elem_bits = elem_ty.bitSize(zcu);
3891 if (elem_bits == 0) break :blk .{};
3892 const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits);
3893 if (!is_packed) break :blk .{};
3894
3895 break :blk .{
3896 .host_size = @intCast(parent_ty.arrayLen(zcu)),
3897 .alignment = parent_ty.abiAlignment(zcu),
3898 .vector_index = if (offset) |some| @enumFromInt(some) else .runtime,
3899 };
3900 } else .{};
3901
3902 const alignment: Alignment = a: {
3903 // Calculate the new pointer alignment.
3904 if (ptr_info.flags.alignment == .none) {
3905 // In case of an ABI-aligned pointer, any pointer arithmetic
3906 // maintains the same ABI-alignedness.
3907 break :a vector_info.alignment;
3908 }
3909 // If the addend is not a comptime-known value we can still count on
3910 // it being a multiple of the type size.
3911 const elem_size = (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar;
3912 const addend = if (offset) |off| elem_size * off else elem_size;
3913
3914 // The resulting pointer is aligned to the lcd between the offset (an
3915 // arbitrary number) and the alignment factor (always a power of two,
3916 // non zero).
3917 const new_align: Alignment = @enumFromInt(@min(
3918 @ctz(addend),
3919 ptr_info.flags.alignment.toLog2Units(),
3920 ));
3921 assert(new_align != .none);
3922 break :a new_align;
3923 };
3924 return zcu.ptrTypeSema(.{
3925 .child = elem_ty.toIntern(),
3926 .flags = .{
3927 .alignment = alignment,
3928 .is_const = ptr_info.flags.is_const,
3929 .is_volatile = ptr_info.flags.is_volatile,
3930 .is_allowzero = is_allowzero,
3931 .address_space = ptr_info.flags.address_space,
3932 .vector_index = vector_info.vector_index,
3933 },
3934 .packed_offset = .{
3935 .host_size = vector_info.host_size,
3936 .bit_offset = 0,
3937 },
3938 });
3939}
3940
3549pub const @"u1": Type = .{ .ip_index = .u1_type };3941pub const @"u1": Type = .{ .ip_index = .u1_type };
3550pub const @"u8": Type = .{ .ip_index = .u8_type };3942pub const @"u8": Type = .{ .ip_index = .u8_type };
3551pub const @"u16": Type = .{ .ip_index = .u16_type };3943pub const @"u16": Type = .{ .ip_index = .u16_type };
src/Value.zig+198-108
...@@ -161,9 +161,11 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {...@@ -161,9 +161,11 @@ pub fn intFromEnum(val: Value, ty: Type, mod: *Module) Allocator.Error!Value {
161 };161 };
162}162}
163163
164pub const ResolveStrat = Type.ResolveStrat;
165
164/// Asserts the value is an integer.166/// Asserts the value is an integer.
165pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst {167pub fn toBigInt(val: Value, space: *BigIntSpace, mod: *Module) BigIntConst {
166 return val.toBigIntAdvanced(space, mod, null) catch unreachable;168 return val.toBigIntAdvanced(space, mod, .normal) catch unreachable;
167}169}
168170
169/// Asserts the value is an integer.171/// Asserts the value is an integer.
...@@ -171,7 +173,7 @@ pub fn toBigIntAdvanced(...@@ -171,7 +173,7 @@ pub fn toBigIntAdvanced(
171 val: Value,173 val: Value,
172 space: *BigIntSpace,174 space: *BigIntSpace,
173 mod: *Module,175 mod: *Module,
174 opt_sema: ?*Sema,176 strat: ResolveStrat,
175) Module.CompileError!BigIntConst {177) Module.CompileError!BigIntConst {
176 return switch (val.toIntern()) {178 return switch (val.toIntern()) {
177 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),179 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),
...@@ -181,7 +183,7 @@ pub fn toBigIntAdvanced(...@@ -181,7 +183,7 @@ pub fn toBigIntAdvanced(
181 .int => |int| switch (int.storage) {183 .int => |int| switch (int.storage) {
182 .u64, .i64, .big_int => int.storage.toBigInt(space),184 .u64, .i64, .big_int => int.storage.toBigInt(space),
183 .lazy_align, .lazy_size => |ty| {185 .lazy_align, .lazy_size => |ty| {
184 if (opt_sema) |sema| try sema.resolveTypeLayout(Type.fromInterned(ty));186 if (strat == .sema) try Type.fromInterned(ty).resolveLayout(mod);
185 const x = switch (int.storage) {187 const x = switch (int.storage) {
186 else => unreachable,188 else => unreachable,
187 .lazy_align => Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0,189 .lazy_align => Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0,
...@@ -190,10 +192,10 @@ pub fn toBigIntAdvanced(...@@ -190,10 +192,10 @@ pub fn toBigIntAdvanced(
190 return BigIntMutable.init(&space.limbs, x).toConst();192 return BigIntMutable.init(&space.limbs, x).toConst();
191 },193 },
192 },194 },
193 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, mod, opt_sema),195 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).toBigIntAdvanced(space, mod, strat),
194 .opt, .ptr => BigIntMutable.init(196 .opt, .ptr => BigIntMutable.init(
195 &space.limbs,197 &space.limbs,
196 (try val.getUnsignedIntAdvanced(mod, opt_sema)).?,198 (try val.getUnsignedIntAdvanced(mod, strat)).?,
197 ).toConst(),199 ).toConst(),
198 else => unreachable,200 else => unreachable,
199 },201 },
...@@ -228,12 +230,12 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {...@@ -228,12 +230,12 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {
228/// If the value fits in a u64, return it, otherwise null.230/// If the value fits in a u64, return it, otherwise null.
229/// Asserts not undefined.231/// Asserts not undefined.
230pub fn getUnsignedInt(val: Value, mod: *Module) ?u64 {232pub fn getUnsignedInt(val: Value, mod: *Module) ?u64 {
231 return getUnsignedIntAdvanced(val, mod, null) catch unreachable;233 return getUnsignedIntAdvanced(val, mod, .normal) catch unreachable;
232}234}
233235
234/// If the value fits in a u64, return it, otherwise null.236/// If the value fits in a u64, return it, otherwise null.
235/// Asserts not undefined.237/// Asserts not undefined.
236pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64 {238pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u64 {
237 return switch (val.toIntern()) {239 return switch (val.toIntern()) {
238 .undef => unreachable,240 .undef => unreachable,
239 .bool_false => 0,241 .bool_false => 0,
...@@ -244,28 +246,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64...@@ -244,28 +246,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64
244 .big_int => |big_int| big_int.to(u64) catch null,246 .big_int => |big_int| big_int.to(u64) catch null,
245 .u64 => |x| x,247 .u64 => |x| x,
246 .i64 => |x| std.math.cast(u64, x),248 .i64 => |x| std.math.cast(u64, x),
247 .lazy_align => |ty| if (opt_sema) |sema|249 .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0,
248 (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar.toByteUnits() orelse 0250 .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(mod, strat.toLazy())).scalar,
249 else
250 Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0,
251 .lazy_size => |ty| if (opt_sema) |sema|
252 (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar
253 else
254 Type.fromInterned(ty).abiSize(mod),
255 },251 },
256 .ptr => |ptr| switch (ptr.base_addr) {252 .ptr => |ptr| switch (ptr.base_addr) {
257 .int => ptr.byte_offset,253 .int => ptr.byte_offset,
258 .field => |field| {254 .field => |field| {
259 const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, opt_sema)) orelse return null;255 const base_addr = (try Value.fromInterned(field.base).getUnsignedIntAdvanced(mod, strat)) orelse return null;
260 const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod);256 const struct_ty = Value.fromInterned(field.base).typeOf(mod).childType(mod);
261 if (opt_sema) |sema| try sema.resolveTypeLayout(struct_ty);257 if (strat == .sema) try struct_ty.resolveLayout(mod);
262 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), mod) + ptr.byte_offset;258 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), mod) + ptr.byte_offset;
263 },259 },
264 else => null,260 else => null,
265 },261 },
266 .opt => |opt| switch (opt.val) {262 .opt => |opt| switch (opt.val) {
267 .none => 0,263 .none => 0,
268 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(mod, opt_sema),264 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(mod, strat),
269 },265 },
270 else => null,266 else => null,
271 },267 },
...@@ -273,13 +269,13 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64...@@ -273,13 +269,13 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64
273}269}
274270
275/// Asserts the value is an integer and it fits in a u64271/// Asserts the value is an integer and it fits in a u64
276pub fn toUnsignedInt(val: Value, mod: *Module) u64 {272pub fn toUnsignedInt(val: Value, zcu: *Zcu) u64 {
277 return getUnsignedInt(val, mod).?;273 return getUnsignedInt(val, zcu).?;
278}274}
279275
280/// Asserts the value is an integer and it fits in a u64276/// Asserts the value is an integer and it fits in a u64
281pub fn toUnsignedIntAdvanced(val: Value, sema: *Sema) !u64 {277pub fn toUnsignedIntSema(val: Value, zcu: *Zcu) !u64 {
282 return (try getUnsignedIntAdvanced(val, sema.mod, sema)).?;278 return (try getUnsignedIntAdvanced(val, zcu, .sema)).?;
283}279}
284280
285/// Asserts the value is an integer and it fits in a i64281/// Asserts the value is an integer and it fits in a i64
...@@ -1028,13 +1024,13 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool {...@@ -1028,13 +1024,13 @@ pub fn floatHasFraction(self: Value, mod: *const Module) bool {
1028}1024}
10291025
1030pub fn orderAgainstZero(lhs: Value, mod: *Module) std.math.Order {1026pub fn orderAgainstZero(lhs: Value, mod: *Module) std.math.Order {
1031 return orderAgainstZeroAdvanced(lhs, mod, null) catch unreachable;1027 return orderAgainstZeroAdvanced(lhs, mod, .normal) catch unreachable;
1032}1028}
10331029
1034pub fn orderAgainstZeroAdvanced(1030pub fn orderAgainstZeroAdvanced(
1035 lhs: Value,1031 lhs: Value,
1036 mod: *Module,1032 mod: *Module,
1037 opt_sema: ?*Sema,1033 strat: ResolveStrat,
1038) Module.CompileError!std.math.Order {1034) Module.CompileError!std.math.Order {
1039 return switch (lhs.toIntern()) {1035 return switch (lhs.toIntern()) {
1040 .bool_false => .eq,1036 .bool_false => .eq,
...@@ -1052,13 +1048,13 @@ pub fn orderAgainstZeroAdvanced(...@@ -1052,13 +1048,13 @@ pub fn orderAgainstZeroAdvanced(
1052 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced(1048 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced(
1053 mod,1049 mod,
1054 false,1050 false,
1055 if (opt_sema) |sema| .{ .sema = sema } else .eager,1051 strat.toLazy(),
1056 ) catch |err| switch (err) {1052 ) catch |err| switch (err) {
1057 error.NeedLazy => unreachable,1053 error.NeedLazy => unreachable,
1058 else => |e| return e,1054 else => |e| return e,
1059 }) .gt else .eq,1055 }) .gt else .eq,
1060 },1056 },
1061 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(mod, opt_sema),1057 .enum_tag => |enum_tag| Value.fromInterned(enum_tag.int).orderAgainstZeroAdvanced(mod, strat),
1062 .float => |float| switch (float.storage) {1058 .float => |float| switch (float.storage) {
1063 inline else => |x| std.math.order(x, 0),1059 inline else => |x| std.math.order(x, 0),
1064 },1060 },
...@@ -1069,14 +1065,13 @@ pub fn orderAgainstZeroAdvanced(...@@ -1069,14 +1065,13 @@ pub fn orderAgainstZeroAdvanced(
10691065
1070/// Asserts the value is comparable.1066/// Asserts the value is comparable.
1071pub fn order(lhs: Value, rhs: Value, mod: *Module) std.math.Order {1067pub fn order(lhs: Value, rhs: Value, mod: *Module) std.math.Order {
1072 return orderAdvanced(lhs, rhs, mod, null) catch unreachable;1068 return orderAdvanced(lhs, rhs, mod, .normal) catch unreachable;
1073}1069}
10741070
1075/// Asserts the value is comparable.1071/// Asserts the value is comparable.
1076/// If opt_sema is null then this function asserts things are resolved and cannot fail.1072pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat) !std.math.Order {
1077pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, opt_sema: ?*Sema) !std.math.Order {1073 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, strat);
1078 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);1074 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, strat);
1079 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);
1080 switch (lhs_against_zero) {1075 switch (lhs_against_zero) {
1081 .lt => if (rhs_against_zero != .lt) return .lt,1076 .lt => if (rhs_against_zero != .lt) return .lt,
1082 .eq => return rhs_against_zero.invert(),1077 .eq => return rhs_against_zero.invert(),
...@@ -1096,15 +1091,15 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, opt_sema: ?*Sema) !st...@@ -1096,15 +1091,15 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, opt_sema: ?*Sema) !st
10961091
1097 var lhs_bigint_space: BigIntSpace = undefined;1092 var lhs_bigint_space: BigIntSpace = undefined;
1098 var rhs_bigint_space: BigIntSpace = undefined;1093 var rhs_bigint_space: BigIntSpace = undefined;
1099 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, opt_sema);1094 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, strat);
1100 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, opt_sema);1095 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, strat);
1101 return lhs_bigint.order(rhs_bigint);1096 return lhs_bigint.order(rhs_bigint);
1102}1097}
11031098
1104/// Asserts the value is comparable. Does not take a type parameter because it supports1099/// Asserts the value is comparable. Does not take a type parameter because it supports
1105/// comparisons between heterogeneous types.1100/// comparisons between heterogeneous types.
1106pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *Module) bool {1101pub fn compareHetero(lhs: Value, op: std.math.CompareOperator, rhs: Value, mod: *Module) bool {
1107 return compareHeteroAdvanced(lhs, op, rhs, mod, null) catch unreachable;1102 return compareHeteroAdvanced(lhs, op, rhs, mod, .normal) catch unreachable;
1108}1103}
11091104
1110pub fn compareHeteroAdvanced(1105pub fn compareHeteroAdvanced(
...@@ -1112,7 +1107,7 @@ pub fn compareHeteroAdvanced(...@@ -1112,7 +1107,7 @@ pub fn compareHeteroAdvanced(
1112 op: std.math.CompareOperator,1107 op: std.math.CompareOperator,
1113 rhs: Value,1108 rhs: Value,
1114 mod: *Module,1109 mod: *Module,
1115 opt_sema: ?*Sema,1110 strat: ResolveStrat,
1116) !bool {1111) !bool {
1117 if (lhs.pointerDecl(mod)) |lhs_decl| {1112 if (lhs.pointerDecl(mod)) |lhs_decl| {
1118 if (rhs.pointerDecl(mod)) |rhs_decl| {1113 if (rhs.pointerDecl(mod)) |rhs_decl| {
...@@ -1135,7 +1130,7 @@ pub fn compareHeteroAdvanced(...@@ -1135,7 +1130,7 @@ pub fn compareHeteroAdvanced(
1135 else => {},1130 else => {},
1136 }1131 }
1137 }1132 }
1138 return (try orderAdvanced(lhs, rhs, mod, opt_sema)).compare(op);1133 return (try orderAdvanced(lhs, rhs, mod, strat)).compare(op);
1139}1134}
11401135
1141/// Asserts the values are comparable. Both operands have type `ty`.1136/// Asserts the values are comparable. Both operands have type `ty`.
...@@ -1176,22 +1171,22 @@ pub fn compareScalar(...@@ -1176,22 +1171,22 @@ pub fn compareScalar(
1176///1171///
1177/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`1172/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
1178pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, mod: *Module) bool {1173pub fn compareAllWithZero(lhs: Value, op: std.math.CompareOperator, mod: *Module) bool {
1179 return compareAllWithZeroAdvancedExtra(lhs, op, mod, null) catch unreachable;1174 return compareAllWithZeroAdvancedExtra(lhs, op, mod, .normal) catch unreachable;
1180}1175}
11811176
1182pub fn compareAllWithZeroAdvanced(1177pub fn compareAllWithZeroSema(
1183 lhs: Value,1178 lhs: Value,
1184 op: std.math.CompareOperator,1179 op: std.math.CompareOperator,
1185 sema: *Sema,1180 zcu: *Zcu,
1186) Module.CompileError!bool {1181) Module.CompileError!bool {
1187 return compareAllWithZeroAdvancedExtra(lhs, op, sema.mod, sema);1182 return compareAllWithZeroAdvancedExtra(lhs, op, zcu, .sema);
1188}1183}
11891184
1190pub fn compareAllWithZeroAdvancedExtra(1185pub fn compareAllWithZeroAdvancedExtra(
1191 lhs: Value,1186 lhs: Value,
1192 op: std.math.CompareOperator,1187 op: std.math.CompareOperator,
1193 mod: *Module,1188 mod: *Module,
1194 opt_sema: ?*Sema,1189 strat: ResolveStrat,
1195) Module.CompileError!bool {1190) Module.CompileError!bool {
1196 if (lhs.isInf(mod)) {1191 if (lhs.isInf(mod)) {
1197 switch (op) {1192 switch (op) {
...@@ -1211,14 +1206,14 @@ pub fn compareAllWithZeroAdvancedExtra(...@@ -1211,14 +1206,14 @@ pub fn compareAllWithZeroAdvancedExtra(
1211 if (!std.math.order(byte, 0).compare(op)) break false;1206 if (!std.math.order(byte, 0).compare(op)) break false;
1212 } else true,1207 } else true,
1213 .elems => |elems| for (elems) |elem| {1208 .elems => |elems| for (elems) |elem| {
1214 if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, opt_sema)) break false;1209 if (!try Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat)) break false;
1215 } else true,1210 } else true,
1216 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, opt_sema),1211 .repeated_elem => |elem| Value.fromInterned(elem).compareAllWithZeroAdvancedExtra(op, mod, strat),
1217 },1212 },
1218 .undef => return false,1213 .undef => return false,
1219 else => {},1214 else => {},
1220 }1215 }
1221 return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op);1216 return (try orderAgainstZeroAdvanced(lhs, mod, strat)).compare(op);
1222}1217}
12231218
1224pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {1219pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
...@@ -1279,9 +1274,9 @@ pub fn slicePtr(val: Value, mod: *Module) Value {...@@ -1279,9 +1274,9 @@ pub fn slicePtr(val: Value, mod: *Module) Value {
1279}1274}
12801275
1281/// Gets the `len` field of a slice value as a `u64`.1276/// Gets the `len` field of a slice value as a `u64`.
1282/// Resolves the length using the provided `Sema` if necessary.1277/// Resolves the length using `Sema` if necessary.
1283pub fn sliceLen(val: Value, sema: *Sema) !u64 {1278pub fn sliceLen(val: Value, zcu: *Zcu) !u64 {
1284 return Value.fromInterned(sema.mod.intern_pool.sliceLen(val.toIntern())).toUnsignedIntAdvanced(sema);1279 return Value.fromInterned(zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(zcu);
1285}1280}
12861281
1287/// Asserts the value is an aggregate, and returns the element value at the given index.1282/// Asserts the value is an aggregate, and returns the element value at the given index.
...@@ -1482,29 +1477,29 @@ pub fn isFloat(self: Value, mod: *const Module) bool {...@@ -1482,29 +1477,29 @@ pub fn isFloat(self: Value, mod: *const Module) bool {
1482}1477}
14831478
1484pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module) !Value {1479pub fn floatFromInt(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module) !Value {
1485 return floatFromIntAdvanced(val, arena, int_ty, float_ty, mod, null) catch |err| switch (err) {1480 return floatFromIntAdvanced(val, arena, int_ty, float_ty, mod, .normal) catch |err| switch (err) {
1486 error.OutOfMemory => return error.OutOfMemory,1481 error.OutOfMemory => return error.OutOfMemory,
1487 else => unreachable,1482 else => unreachable,
1488 };1483 };
1489}1484}
14901485
1491pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {1486pub fn floatFromIntAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value {
1492 if (int_ty.zigTypeTag(mod) == .Vector) {1487 if (int_ty.zigTypeTag(mod) == .Vector) {
1493 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod));1488 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod));
1494 const scalar_ty = float_ty.scalarType(mod);1489 const scalar_ty = float_ty.scalarType(mod);
1495 for (result_data, 0..) |*scalar, i| {1490 for (result_data, 0..) |*scalar, i| {
1496 const elem_val = try val.elemValue(mod, i);1491 const elem_val = try val.elemValue(mod, i);
1497 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, opt_sema)).toIntern();1492 scalar.* = (try floatFromIntScalar(elem_val, scalar_ty, mod, strat)).toIntern();
1498 }1493 }
1499 return Value.fromInterned((try mod.intern(.{ .aggregate = .{1494 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
1500 .ty = float_ty.toIntern(),1495 .ty = float_ty.toIntern(),
1501 .storage = .{ .elems = result_data },1496 .storage = .{ .elems = result_data },
1502 } })));1497 } })));
1503 }1498 }
1504 return floatFromIntScalar(val, float_ty, mod, opt_sema);1499 return floatFromIntScalar(val, float_ty, mod, strat);
1505}1500}
15061501
1507pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value {1502pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, strat: ResolveStrat) !Value {
1508 return switch (mod.intern_pool.indexToKey(val.toIntern())) {1503 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1509 .undef => try mod.undefValue(float_ty),1504 .undef => try mod.undefValue(float_ty),
1510 .int => |int| switch (int.storage) {1505 .int => |int| switch (int.storage) {
...@@ -1513,16 +1508,8 @@ pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, opt_sema: ?*...@@ -1513,16 +1508,8 @@ pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, opt_sema: ?*
1513 return mod.floatValue(float_ty, float);1508 return mod.floatValue(float_ty, float);
1514 },1509 },
1515 inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, mod),1510 inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, mod),
1516 .lazy_align => |ty| if (opt_sema) |sema| {1511 .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0, float_ty, mod),
1517 return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar.toByteUnits() orelse 0, float_ty, mod);1512 .lazy_size => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(mod, strat.toLazy())).scalar, float_ty, mod),
1518 } else {
1519 return floatFromIntInner(Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0, float_ty, mod);
1520 },
1521 .lazy_size => |ty| if (opt_sema) |sema| {
1522 return floatFromIntInner((try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar, float_ty, mod);
1523 } else {
1524 return floatFromIntInner(Type.fromInterned(ty).abiSize(mod), float_ty, mod);
1525 },
1526 },1513 },
1527 else => unreachable,1514 else => unreachable,
1528 };1515 };
...@@ -3616,17 +3603,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex;...@@ -3616,17 +3603,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex;
36163603
3617/// `parent_ptr` must be a single-pointer to some optional.3604/// `parent_ptr` must be a single-pointer to some optional.
3618/// Returns a pointer to the payload of the optional.3605/// Returns a pointer to the payload of the optional.
3619/// This takes a `Sema` because it may need to perform type resolution.3606/// May perform type resolution.
3620pub fn ptrOptPayload(parent_ptr: Value, sema: *Sema) !Value {3607pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3621 const zcu = sema.mod;
3622
3623 const parent_ptr_ty = parent_ptr.typeOf(zcu);3608 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3624 const opt_ty = parent_ptr_ty.childType(zcu);3609 const opt_ty = parent_ptr_ty.childType(zcu);
36253610
3626 assert(parent_ptr_ty.ptrSize(zcu) == .One);3611 assert(parent_ptr_ty.ptrSize(zcu) == .One);
3627 assert(opt_ty.zigTypeTag(zcu) == .Optional);3612 assert(opt_ty.zigTypeTag(zcu) == .Optional);
36283613
3629 const result_ty = try sema.ptrType(info: {3614 const result_ty = try zcu.ptrTypeSema(info: {
3630 var new = parent_ptr_ty.ptrInfo(zcu);3615 var new = parent_ptr_ty.ptrInfo(zcu);
3631 // We can correctly preserve alignment `.none`, since an optional has the same3616 // We can correctly preserve alignment `.none`, since an optional has the same
3632 // natural alignment as its child type.3617 // natural alignment as its child type.
...@@ -3651,17 +3636,15 @@ pub fn ptrOptPayload(parent_ptr: Value, sema: *Sema) !Value {...@@ -3651,17 +3636,15 @@ pub fn ptrOptPayload(parent_ptr: Value, sema: *Sema) !Value {
36513636
3652/// `parent_ptr` must be a single-pointer to some error union.3637/// `parent_ptr` must be a single-pointer to some error union.
3653/// Returns a pointer to the payload of the error union.3638/// Returns a pointer to the payload of the error union.
3654/// This takes a `Sema` because it may need to perform type resolution.3639/// May perform type resolution.
3655pub fn ptrEuPayload(parent_ptr: Value, sema: *Sema) !Value {3640pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {
3656 const zcu = sema.mod;
3657
3658 const parent_ptr_ty = parent_ptr.typeOf(zcu);3641 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3659 const eu_ty = parent_ptr_ty.childType(zcu);3642 const eu_ty = parent_ptr_ty.childType(zcu);
36603643
3661 assert(parent_ptr_ty.ptrSize(zcu) == .One);3644 assert(parent_ptr_ty.ptrSize(zcu) == .One);
3662 assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion);3645 assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion);
36633646
3664 const result_ty = try sema.ptrType(info: {3647 const result_ty = try zcu.ptrTypeSema(info: {
3665 var new = parent_ptr_ty.ptrInfo(zcu);3648 var new = parent_ptr_ty.ptrInfo(zcu);
3666 // We can correctly preserve alignment `.none`, since an error union has a3649 // We can correctly preserve alignment `.none`, since an error union has a
3667 // natural alignment greater than or equal to that of its payload type.3650 // natural alignment greater than or equal to that of its payload type.
...@@ -3682,10 +3665,8 @@ pub fn ptrEuPayload(parent_ptr: Value, sema: *Sema) !Value {...@@ -3682,10 +3665,8 @@ pub fn ptrEuPayload(parent_ptr: Value, sema: *Sema) !Value {
3682/// `parent_ptr` must be a single-pointer to a struct, union, or slice.3665/// `parent_ptr` must be a single-pointer to a struct, union, or slice.
3683/// Returns a pointer to the aggregate field at the specified index.3666/// Returns a pointer to the aggregate field at the specified index.
3684/// For slices, uses `slice_ptr_index` and `slice_len_index`.3667/// For slices, uses `slice_ptr_index` and `slice_len_index`.
3685/// This takes a `Sema` because it may need to perform type resolution.3668/// May perform type resolution.
3686pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {3669pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
3687 const zcu = sema.mod;
3688
3689 const parent_ptr_ty = parent_ptr.typeOf(zcu);3670 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3690 const aggregate_ty = parent_ptr_ty.childType(zcu);3671 const aggregate_ty = parent_ptr_ty.childType(zcu);
36913672
...@@ -3698,17 +3679,17 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {...@@ -3698,17 +3679,17 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
3698 .Struct => field: {3679 .Struct => field: {
3699 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);3680 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);
3700 switch (aggregate_ty.containerLayout(zcu)) {3681 switch (aggregate_ty.containerLayout(zcu)) {
3701 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, sema) },3682 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) },
3702 .@"extern" => {3683 .@"extern" => {
3703 // Well-defined layout, so just offset the pointer appropriately.3684 // Well-defined layout, so just offset the pointer appropriately.
3704 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);3685 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);
3705 const field_align = a: {3686 const field_align = a: {
3706 const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {3687 const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {
3707 break :pa try sema.typeAbiAlignment(aggregate_ty);3688 break :pa (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;
3708 } else parent_ptr_info.flags.alignment;3689 } else parent_ptr_info.flags.alignment;
3709 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));3690 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));
3710 };3691 };
3711 const result_ty = try sema.ptrType(info: {3692 const result_ty = try zcu.ptrTypeSema(info: {
3712 var new = parent_ptr_info;3693 var new = parent_ptr_info;
3713 new.child = field_ty.toIntern();3694 new.child = field_ty.toIntern();
3714 new.flags.alignment = field_align;3695 new.flags.alignment = field_align;
...@@ -3723,14 +3704,14 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {...@@ -3723,14 +3704,14 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
3723 new.packed_offset = packed_offset;3704 new.packed_offset = packed_offset;
3724 new.child = field_ty.toIntern();3705 new.child = field_ty.toIntern();
3725 if (new.flags.alignment == .none) {3706 if (new.flags.alignment == .none) {
3726 new.flags.alignment = try sema.typeAbiAlignment(aggregate_ty);3707 new.flags.alignment = (try aggregate_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;
3727 }3708 }
3728 break :info new;3709 break :info new;
3729 });3710 });
3730 return zcu.getCoerced(parent_ptr, result_ty);3711 return zcu.getCoerced(parent_ptr, result_ty);
3731 },3712 },
3732 .byte_ptr => |ptr_info| {3713 .byte_ptr => |ptr_info| {
3733 const result_ty = try sema.ptrType(info: {3714 const result_ty = try zcu.ptrTypeSema(info: {
3734 var new = parent_ptr_info;3715 var new = parent_ptr_info;
3735 new.child = field_ty.toIntern();3716 new.child = field_ty.toIntern();
3736 new.packed_offset = .{3717 new.packed_offset = .{
...@@ -3749,10 +3730,10 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {...@@ -3749,10 +3730,10 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
3749 const union_obj = zcu.typeToUnion(aggregate_ty).?;3730 const union_obj = zcu.typeToUnion(aggregate_ty).?;
3750 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);3731 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);
3751 switch (aggregate_ty.containerLayout(zcu)) {3732 switch (aggregate_ty.containerLayout(zcu)) {
3752 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, sema) },3733 .auto => break :field .{ field_ty, try aggregate_ty.structFieldAlignAdvanced(@intCast(field_idx), zcu, .sema) },
3753 .@"extern" => {3734 .@"extern" => {
3754 // Point to the same address.3735 // Point to the same address.
3755 const result_ty = try sema.ptrType(info: {3736 const result_ty = try zcu.ptrTypeSema(info: {
3756 var new = parent_ptr_info;3737 var new = parent_ptr_info;
3757 new.child = field_ty.toIntern();3738 new.child = field_ty.toIntern();
3758 break :info new;3739 break :info new;
...@@ -3762,28 +3743,28 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {...@@ -3762,28 +3743,28 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
3762 .@"packed" => {3743 .@"packed" => {
3763 // If the field has an ABI size matching its bit size, then we can continue to use a3744 // If the field has an ABI size matching its bit size, then we can continue to use a
3764 // non-bit pointer if the parent pointer is also a non-bit pointer.3745 // non-bit pointer if the parent pointer is also a non-bit pointer.
3765 if (parent_ptr_info.packed_offset.host_size == 0 and try sema.typeAbiSize(field_ty) * 8 == try field_ty.bitSizeAdvanced(zcu, sema)) {3746 if (parent_ptr_info.packed_offset.host_size == 0 and (try field_ty.abiSizeAdvanced(zcu, .sema)).scalar * 8 == try field_ty.bitSizeAdvanced(zcu, .sema)) {
3766 // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely.3747 // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely.
3767 const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) {3748 const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) {
3768 .little => 0,3749 .little => 0,
3769 .big => try sema.typeAbiSize(aggregate_ty) - try sema.typeAbiSize(field_ty),3750 .big => (try aggregate_ty.abiSizeAdvanced(zcu, .sema)).scalar - (try field_ty.abiSizeAdvanced(zcu, .sema)).scalar,
3770 };3751 };
3771 const result_ty = try sema.ptrType(info: {3752 const result_ty = try zcu.ptrTypeSema(info: {
3772 var new = parent_ptr_info;3753 var new = parent_ptr_info;
3773 new.child = field_ty.toIntern();3754 new.child = field_ty.toIntern();
3774 new.flags.alignment = InternPool.Alignment.fromLog2Units(3755 new.flags.alignment = InternPool.Alignment.fromLog2Units(
3775 @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(zcu, sema)).toByteUnits().?),3756 @ctz(byte_offset | (try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema)).toByteUnits().?),
3776 );3757 );
3777 break :info new;3758 break :info new;
3778 });3759 });
3779 return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu);3760 return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu);
3780 } else {3761 } else {
3781 // The result must be a bit-pointer if it is not already.3762 // The result must be a bit-pointer if it is not already.
3782 const result_ty = try sema.ptrType(info: {3763 const result_ty = try zcu.ptrTypeSema(info: {
3783 var new = parent_ptr_info;3764 var new = parent_ptr_info;
3784 new.child = field_ty.toIntern();3765 new.child = field_ty.toIntern();
3785 if (new.packed_offset.host_size == 0) {3766 if (new.packed_offset.host_size == 0) {
3786 new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(zcu, sema)) + 7) / 8);3767 new.packed_offset.host_size = @intCast(((try aggregate_ty.bitSizeAdvanced(zcu, .sema)) + 7) / 8);
3787 assert(new.packed_offset.bit_offset == 0);3768 assert(new.packed_offset.bit_offset == 0);
3788 }3769 }
3789 break :info new;3770 break :info new;
...@@ -3805,14 +3786,14 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {...@@ -3805,14 +3786,14 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
3805 };3786 };
38063787
3807 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {3788 const new_align: InternPool.Alignment = if (parent_ptr_info.flags.alignment != .none) a: {
3808 const ty_align = try sema.typeAbiAlignment(field_ty);3789 const ty_align = (try field_ty.abiAlignmentAdvanced(zcu, .sema)).scalar;
3809 const true_field_align = if (field_align == .none) ty_align else field_align;3790 const true_field_align = if (field_align == .none) ty_align else field_align;
3810 const new_align = true_field_align.min(parent_ptr_info.flags.alignment);3791 const new_align = true_field_align.min(parent_ptr_info.flags.alignment);
3811 if (new_align == ty_align) break :a .none;3792 if (new_align == ty_align) break :a .none;
3812 break :a new_align;3793 break :a new_align;
3813 } else field_align;3794 } else field_align;
38143795
3815 const result_ty = try sema.ptrType(info: {3796 const result_ty = try zcu.ptrTypeSema(info: {
3816 var new = parent_ptr_info;3797 var new = parent_ptr_info;
3817 new.child = field_ty.toIntern();3798 new.child = field_ty.toIntern();
3818 new.flags.alignment = new_align;3799 new.flags.alignment = new_align;
...@@ -3834,10 +3815,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {...@@ -3834,10 +3815,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
38343815
3835/// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice.3816/// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice.
3836/// Returns a pointer to the element at the specified index.3817/// Returns a pointer to the element at the specified index.
3837/// This takes a `Sema` because it may need to perform type resolution.3818/// May perform type resolution.
3838pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, sema: *Sema) !Value {3819pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
3839 const zcu = sema.mod;
3840
3841 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {3820 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {
3842 .One, .Many, .C => orig_parent_ptr,3821 .One, .Many, .C => orig_parent_ptr,
3843 .Slice => orig_parent_ptr.slicePtr(zcu),3822 .Slice => orig_parent_ptr.slicePtr(zcu),
...@@ -3845,7 +3824,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, sema: *Sema) !Value {...@@ -3845,7 +3824,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, sema: *Sema) !Value {
38453824
3846 const parent_ptr_ty = parent_ptr.typeOf(zcu);3825 const parent_ptr_ty = parent_ptr.typeOf(zcu);
3847 const elem_ty = parent_ptr_ty.childType(zcu);3826 const elem_ty = parent_ptr_ty.childType(zcu);
3848 const result_ty = try sema.elemPtrType(parent_ptr_ty, @intCast(field_idx));3827 const result_ty = try parent_ptr_ty.elemPtrType(@intCast(field_idx), zcu);
38493828
3850 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);3829 if (parent_ptr.isUndef(zcu)) return zcu.undefValue(result_ty);
38513830
...@@ -3862,21 +3841,21 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, sema: *Sema) !Value {...@@ -3862,21 +3841,21 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, sema: *Sema) !Value {
38623841
3863 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {3842 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {
3864 .One => switch (elem_ty.zigTypeTag(zcu)) {3843 .One => switch (elem_ty.zigTypeTag(zcu)) {
3865 .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(zcu, sema), 8) },3844 .Vector => .{ .offset = field_idx * @divExact(try elem_ty.childType(zcu).bitSizeAdvanced(zcu, .sema), 8) },
3866 .Array => strat: {3845 .Array => strat: {
3867 const arr_elem_ty = elem_ty.childType(zcu);3846 const arr_elem_ty = elem_ty.childType(zcu);
3868 if (try sema.typeRequiresComptime(arr_elem_ty)) {3847 if (try arr_elem_ty.comptimeOnlyAdvanced(zcu, .sema)) {
3869 break :strat .{ .elem_ptr = arr_elem_ty };3848 break :strat .{ .elem_ptr = arr_elem_ty };
3870 }3849 }
3871 break :strat .{ .offset = field_idx * try sema.typeAbiSize(arr_elem_ty) };3850 break :strat .{ .offset = field_idx * (try arr_elem_ty.abiSizeAdvanced(zcu, .sema)).scalar };
3872 },3851 },
3873 else => unreachable,3852 else => unreachable,
3874 },3853 },
38753854
3876 .Many, .C => if (try sema.typeRequiresComptime(elem_ty))3855 .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(zcu, .sema))
3877 .{ .elem_ptr = elem_ty }3856 .{ .elem_ptr = elem_ty }
3878 else3857 else
3879 .{ .offset = field_idx * try sema.typeAbiSize(elem_ty) },3858 .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar },
38803859
3881 .Slice => unreachable,3860 .Slice => unreachable,
3882 };3861 };
...@@ -4014,11 +3993,7 @@ pub const PointerDeriveStep = union(enum) {...@@ -4014,11 +3993,7 @@ pub const PointerDeriveStep = union(enum) {
4014pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.Error!PointerDeriveStep {3993pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.Error!PointerDeriveStep {
4015 return ptr_val.pointerDerivationAdvanced(arena, zcu, null) catch |err| switch (err) {3994 return ptr_val.pointerDerivationAdvanced(arena, zcu, null) catch |err| switch (err) {
4016 error.OutOfMemory => |e| return e,3995 error.OutOfMemory => |e| return e,
4017 error.AnalysisFail,3996 error.AnalysisFail => unreachable,
4018 error.GenericPoison,
4019 error.ComptimeReturn,
4020 error.ComptimeBreak,
4021 => unreachable,
4022 };3997 };
4023}3998}
40243999
...@@ -4087,8 +4062,8 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4087,8 +4062,8 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4087 const base_ptr_ty = base_ptr.typeOf(zcu);4062 const base_ptr_ty = base_ptr.typeOf(zcu);
4088 const agg_ty = base_ptr_ty.childType(zcu);4063 const agg_ty = base_ptr_ty.childType(zcu);
4089 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {4064 const field_ty, const field_align = switch (agg_ty.zigTypeTag(zcu)) {
4090 .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, opt_sema) },4065 .Struct => .{ agg_ty.structFieldType(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, .sema) },
4091 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, opt_sema) },4066 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, .sema) },
4092 .Pointer => .{ switch (field.index) {4067 .Pointer => .{ switch (field.index) {
4093 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),4068 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),
4094 Value.slice_len_index => Type.usize,4069 Value.slice_len_index => Type.usize,
...@@ -4269,3 +4244,118 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op...@@ -4269,3 +4244,118 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
4269 .new_ptr_ty = Type.fromInterned(ptr.ty),4244 .new_ptr_ty = Type.fromInterned(ptr.ty),
4270 } };4245 } };
4271}4246}
4247
4248pub fn resolveLazy(val: Value, arena: Allocator, zcu: *Zcu) Zcu.SemaError!Value {
4249 switch (zcu.intern_pool.indexToKey(val.toIntern())) {
4250 .int => |int| switch (int.storage) {
4251 .u64, .i64, .big_int => return val,
4252 .lazy_align, .lazy_size => return zcu.intValue(
4253 Type.fromInterned(int.ty),
4254 (try val.getUnsignedIntAdvanced(zcu, .sema)).?,
4255 ),
4256 },
4257 .slice => |slice| {
4258 const ptr = try Value.fromInterned(slice.ptr).resolveLazy(arena, zcu);
4259 const len = try Value.fromInterned(slice.len).resolveLazy(arena, zcu);
4260 if (ptr.toIntern() == slice.ptr and len.toIntern() == slice.len) return val;
4261 return Value.fromInterned(try zcu.intern(.{ .slice = .{
4262 .ty = slice.ty,
4263 .ptr = ptr.toIntern(),
4264 .len = len.toIntern(),
4265 } }));
4266 },
4267 .ptr => |ptr| {
4268 switch (ptr.base_addr) {
4269 .decl, .comptime_alloc, .anon_decl, .int => return val,
4270 .comptime_field => |field_val| {
4271 const resolved_field_val = (try Value.fromInterned(field_val).resolveLazy(arena, zcu)).toIntern();
4272 return if (resolved_field_val == field_val)
4273 val
4274 else
4275 Value.fromInterned((try zcu.intern(.{ .ptr = .{
4276 .ty = ptr.ty,
4277 .base_addr = .{ .comptime_field = resolved_field_val },
4278 .byte_offset = ptr.byte_offset,
4279 } })));
4280 },
4281 .eu_payload, .opt_payload => |base| {
4282 const resolved_base = (try Value.fromInterned(base).resolveLazy(arena, zcu)).toIntern();
4283 return if (resolved_base == base)
4284 val
4285 else
4286 Value.fromInterned((try zcu.intern(.{ .ptr = .{
4287 .ty = ptr.ty,
4288 .base_addr = switch (ptr.base_addr) {
4289 .eu_payload => .{ .eu_payload = resolved_base },
4290 .opt_payload => .{ .opt_payload = resolved_base },
4291 else => unreachable,
4292 },
4293 .byte_offset = ptr.byte_offset,
4294 } })));
4295 },
4296 .arr_elem, .field => |base_index| {
4297 const resolved_base = (try Value.fromInterned(base_index.base).resolveLazy(arena, zcu)).toIntern();
4298 return if (resolved_base == base_index.base)
4299 val
4300 else
4301 Value.fromInterned((try zcu.intern(.{ .ptr = .{
4302 .ty = ptr.ty,
4303 .base_addr = switch (ptr.base_addr) {
4304 .arr_elem => .{ .arr_elem = .{
4305 .base = resolved_base,
4306 .index = base_index.index,
4307 } },
4308 .field => .{ .field = .{
4309 .base = resolved_base,
4310 .index = base_index.index,
4311 } },
4312 else => unreachable,
4313 },
4314 .byte_offset = ptr.byte_offset,
4315 } })));
4316 },
4317 }
4318 },
4319 .aggregate => |aggregate| switch (aggregate.storage) {
4320 .bytes => return val,
4321 .elems => |elems| {
4322 var resolved_elems: []InternPool.Index = &.{};
4323 for (elems, 0..) |elem, i| {
4324 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern();
4325 if (resolved_elems.len == 0 and resolved_elem != elem) {
4326 resolved_elems = try arena.alloc(InternPool.Index, elems.len);
4327 @memcpy(resolved_elems[0..i], elems[0..i]);
4328 }
4329 if (resolved_elems.len > 0) resolved_elems[i] = resolved_elem;
4330 }
4331 return if (resolved_elems.len == 0) val else Value.fromInterned((try zcu.intern(.{ .aggregate = .{
4332 .ty = aggregate.ty,
4333 .storage = .{ .elems = resolved_elems },
4334 } })));
4335 },
4336 .repeated_elem => |elem| {
4337 const resolved_elem = (try Value.fromInterned(elem).resolveLazy(arena, zcu)).toIntern();
4338 return if (resolved_elem == elem) val else Value.fromInterned((try zcu.intern(.{ .aggregate = .{
4339 .ty = aggregate.ty,
4340 .storage = .{ .repeated_elem = resolved_elem },
4341 } })));
4342 },
4343 },
4344 .un => |un| {
4345 const resolved_tag = if (un.tag == .none)
4346 .none
4347 else
4348 (try Value.fromInterned(un.tag).resolveLazy(arena, zcu)).toIntern();
4349 const resolved_val = (try Value.fromInterned(un.val).resolveLazy(arena, zcu)).toIntern();
4350 return if (resolved_tag == un.tag and resolved_val == un.val)
4351 val
4352 else
4353 Value.fromInterned((try zcu.intern(.{ .un = .{
4354 .ty = un.ty,
4355 .tag = resolved_tag,
4356 .val = resolved_val,
4357 } })));
4358 },
4359 else => return val,
4360 }
4361}
src/Zcu.zig+107-57
...@@ -3593,7 +3593,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In...@@ -3593,7 +3593,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
3593 },3593 },
3594 error.OutOfMemory => return error.OutOfMemory,3594 error.OutOfMemory => return error.OutOfMemory,
3595 };3595 };
3596 defer air.deinit(gpa);3596 errdefer air.deinit(gpa);
35973597
3598 const invalidate_ies_deps = i: {3598 const invalidate_ies_deps = i: {
3599 if (!was_outdated) break :i false;3599 if (!was_outdated) break :i false;
...@@ -3615,13 +3615,36 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In...@@ -3615,13 +3615,36 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
3615 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);3615 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
36163616
3617 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {3617 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {
3618 air.deinit(gpa);
3618 return;3619 return;
3619 }3620 }
36203621
3622 try comp.work_queue.writeItem(.{ .codegen_func = .{
3623 .func = func_index,
3624 .air = air,
3625 } });
3626}
3627
3628/// Takes ownership of `air`, even on error.
3629/// If any types referenced by `air` are unresolved, marks the codegen as failed.
3630pub fn linkerUpdateFunc(zcu: *Zcu, func_index: InternPool.Index, air: Air) Allocator.Error!void {
3631 const gpa = zcu.gpa;
3632 const ip = &zcu.intern_pool;
3633 const comp = zcu.comp;
3634
3635 defer {
3636 var air_mut = air;
3637 air_mut.deinit(gpa);
3638 }
3639
3640 const func = zcu.funcInfo(func_index);
3641 const decl_index = func.owner_decl;
3642 const decl = zcu.declPtr(decl_index);
3643
3621 var liveness = try Liveness.analyze(gpa, air, ip);3644 var liveness = try Liveness.analyze(gpa, air, ip);
3622 defer liveness.deinit(gpa);3645 defer liveness.deinit(gpa);
36233646
3624 if (dump_air) {3647 if (build_options.enable_debug_extensions and comp.verbose_air) {
3625 const fqn = try decl.fullyQualifiedName(zcu);3648 const fqn = try decl.fullyQualifiedName(zcu);
3626 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});3649 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
3627 @import("print_air.zig").dump(zcu, air, liveness);3650 @import("print_air.zig").dump(zcu, air, liveness);
...@@ -3629,7 +3652,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In...@@ -3629,7 +3652,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
3629 }3652 }
36303653
3631 if (std.debug.runtime_safety) {3654 if (std.debug.runtime_safety) {
3632 var verify = Liveness.Verify{3655 var verify: Liveness.Verify = .{
3633 .gpa = gpa,3656 .gpa = gpa,
3634 .air = air,3657 .air = air,
3635 .liveness = liveness,3658 .liveness = liveness,
...@@ -3642,7 +3665,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In...@@ -3642,7 +3665,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
3642 else => {3665 else => {
3643 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);3666 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
3644 zcu.failed_analysis.putAssumeCapacityNoClobber(3667 zcu.failed_analysis.putAssumeCapacityNoClobber(
3645 AnalUnit.wrap(.{ .decl = decl_index }),3668 AnalUnit.wrap(.{ .func = func_index }),
3646 try Module.ErrorMsg.create(3669 try Module.ErrorMsg.create(
3647 gpa,3670 gpa,
3648 decl.navSrcLoc(zcu),3671 decl.navSrcLoc(zcu),
...@@ -3659,7 +3682,13 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In...@@ -3659,7 +3682,13 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
3659 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0);3682 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0);
3660 defer codegen_prog_node.end();3683 defer codegen_prog_node.end();
36613684
3662 if (comp.bin_file) |lf| {3685 if (!air.typesFullyResolved(zcu)) {
3686 // A type we depend on failed to resolve. This is a transitive failure.
3687 // Correcting this failure will involve changing a type this function
3688 // depends on, hence triggering re-analysis of this function, so this
3689 // interacts correctly with incremental compilation.
3690 func.analysis(ip).state = .codegen_failure;
3691 } else if (comp.bin_file) |lf| {
3663 lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) {3692 lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) {
3664 error.OutOfMemory => return error.OutOfMemory,3693 error.OutOfMemory => return error.OutOfMemory,
3665 error.AnalysisFail => {3694 error.AnalysisFail => {
...@@ -3667,7 +3696,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In...@@ -3667,7 +3696,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
3667 },3696 },
3668 else => {3697 else => {
3669 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);3698 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
3670 zcu.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .decl = decl_index }), try Module.ErrorMsg.create(3699 zcu.failed_analysis.putAssumeCapacityNoClobber(AnalUnit.wrap(.{ .func = func_index }), try Module.ErrorMsg.create(
3671 gpa,3700 gpa,
3672 decl.navSrcLoc(zcu),3701 decl.navSrcLoc(zcu),
3673 "unable to codegen: {s}",3702 "unable to codegen: {s}",
...@@ -3735,7 +3764,7 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)...@@ -3735,7 +3764,7 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
37353764
3736 // Decl itself is safely analyzed, and body analysis is not yet queued3765 // Decl itself is safely analyzed, and body analysis is not yet queued
37373766
3738 try mod.comp.work_queue.writeItem(.{ .codegen_func = func_index });3767 try mod.comp.work_queue.writeItem(.{ .analyze_func = func_index });
3739 if (mod.emit_h != null) {3768 if (mod.emit_h != null) {
3740 // TODO: we ideally only want to do this if the function's type changed3769 // TODO: we ideally only want to do this if the function's type changed
3741 // since the last update3770 // since the last update
...@@ -3812,7 +3841,7 @@ fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespa...@@ -3812,7 +3841,7 @@ fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespa
3812 decl.analysis = .complete;3841 decl.analysis = .complete;
38133842
3814 try zcu.scanNamespace(namespace_index, decls, decl);3843 try zcu.scanNamespace(namespace_index, decls, decl);
38153844 try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
3816 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());3845 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
3817}3846}
38183847
...@@ -4103,7 +4132,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -4103,7 +4132,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
4103 // Note this resolves the type of the Decl, not the value; if this Decl4132 // Note this resolves the type of the Decl, not the value; if this Decl
4104 // is a struct, for example, this resolves `type` (which needs no resolution),4133 // is a struct, for example, this resolves `type` (which needs no resolution),
4105 // not the struct itself.4134 // not the struct itself.
4106 try sema.resolveTypeLayout(decl_ty);4135 try decl_ty.resolveLayout(mod);
41074136
4108 if (decl.kind == .@"usingnamespace") {4137 if (decl.kind == .@"usingnamespace") {
4109 if (!decl_ty.eql(Type.type, mod)) {4138 if (!decl_ty.eql(Type.type, mod)) {
...@@ -4220,7 +4249,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {...@@ -4220,7 +4249,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
4220 if (has_runtime_bits) {4249 if (has_runtime_bits) {
4221 // Needed for codegen_decl which will call updateDecl and then the4250 // Needed for codegen_decl which will call updateDecl and then the
4222 // codegen backend wants full access to the Decl Type.4251 // codegen backend wants full access to the Decl Type.
4223 try sema.resolveTypeFully(decl_ty);4252 try decl_ty.resolveFully(mod);
42244253
4225 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });4254 try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
42264255
...@@ -5212,23 +5241,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato...@@ -5212,23 +5241,6 @@ pub fn analyzeFnBody(mod: *Module, func_index: InternPool.Index, arena: Allocato
5212 else => |e| return e,5241 else => |e| return e,
5213 };5242 };
52145243
5215 // Similarly, resolve any queued up types that were requested to be resolved for
5216 // the backends.
5217 for (sema.types_to_resolve.keys()) |ty| {
5218 sema.resolveTypeFully(Type.fromInterned(ty)) catch |err| switch (err) {
5219 error.GenericPoison => unreachable,
5220 error.ComptimeReturn => unreachable,
5221 error.ComptimeBreak => unreachable,
5222 error.AnalysisFail => {
5223 // In this case our function depends on a type that had a compile error.
5224 // We should not try to lower this function.
5225 decl.analysis = .dependency_failure;
5226 return error.AnalysisFail;
5227 },
5228 else => |e| return e,
5229 };
5230 }
5231
5232 try sema.flushExports();5244 try sema.flushExports();
52335245
5234 return .{5246 return .{
...@@ -5793,6 +5805,16 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type...@@ -5793,6 +5805,16 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type
5793 return Type.fromInterned((try intern(mod, .{ .ptr_type = canon_info })));5805 return Type.fromInterned((try intern(mod, .{ .ptr_type = canon_info })));
5794}5806}
57955807
5808/// Like `ptrType`, but if `info` specifies an `alignment`, first ensures the pointer
5809/// child type's alignment is resolved so that an invalid alignment is not used.
5810/// In general, prefer this function during semantic analysis.
5811pub fn ptrTypeSema(zcu: *Zcu, info: InternPool.Key.PtrType) SemaError!Type {
5812 if (info.flags.alignment != .none) {
5813 _ = try Type.fromInterned(info.child).abiAlignmentAdvanced(zcu, .sema);
5814 }
5815 return zcu.ptrType(info);
5816}
5817
5796pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {5818pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
5797 return ptrType(mod, .{ .child = child_type.toIntern() });5819 return ptrType(mod, .{ .child = child_type.toIntern() });
5798}5820}
...@@ -6368,15 +6390,21 @@ pub fn unionAbiAlignment(mod: *Module, loaded_union: InternPool.LoadedUnionType)...@@ -6368,15 +6390,21 @@ pub fn unionAbiAlignment(mod: *Module, loaded_union: InternPool.LoadedUnionType)
6368 return max_align;6390 return max_align;
6369}6391}
63706392
6371/// Returns the field alignment, assuming the union is not packed.6393/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
6372/// Keep implementation in sync with `Sema.unionFieldAlignment`.6394pub fn unionFieldNormalAlignment(zcu: *Zcu, loaded_union: InternPool.LoadedUnionType, field_index: u32) Alignment {
6373/// Prefer to call that function instead of this one during Sema.6395 return zcu.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable;
6374pub fn unionFieldNormalAlignment(mod: *Module, loaded_union: InternPool.LoadedUnionType, field_index: u32) Alignment {6396}
6375 const ip = &mod.intern_pool;6397
6398/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
6399/// If `strat` is `.sema`, may perform type resolution.
6400pub fn unionFieldNormalAlignmentAdvanced(zcu: *Zcu, loaded_union: InternPool.LoadedUnionType, field_index: u32, strat: Type.ResolveStrat) SemaError!Alignment {
6401 const ip = &zcu.intern_pool;
6402 assert(loaded_union.flagsPtr(ip).layout != .@"packed");
6376 const field_align = loaded_union.fieldAlign(ip, field_index);6403 const field_align = loaded_union.fieldAlign(ip, field_index);
6377 if (field_align != .none) return field_align;6404 if (field_align != .none) return field_align;
6378 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);6405 const field_ty = Type.fromInterned(loaded_union.field_types.get(ip)[field_index]);
6379 return field_ty.abiAlignment(mod);6406 if (field_ty.isNoReturn(zcu)) return .none;
6407 return (try field_ty.abiAlignmentAdvanced(zcu, strat.toLazy())).scalar;
6380}6408}
63816409
6382/// Returns the index of the active field, given the current tag value6410/// Returns the index of the active field, given the current tag value
...@@ -6387,41 +6415,37 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType...@@ -6387,41 +6415,37 @@ pub fn unionTagFieldIndex(mod: *Module, loaded_union: InternPool.LoadedUnionType
6387 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());6415 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());
6388}6416}
63896417
6390/// Returns the field alignment of a non-packed struct in byte units.6418/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
6391/// Keep implementation in sync with `Sema.structFieldAlignment`.
6392/// asserts the layout is not packed.
6393pub fn structFieldAlignment(6419pub fn structFieldAlignment(
6394 mod: *Module,6420 zcu: *Zcu,
6395 explicit_alignment: InternPool.Alignment,6421 explicit_alignment: InternPool.Alignment,
6396 field_ty: Type,6422 field_ty: Type,
6397 layout: std.builtin.Type.ContainerLayout,6423 layout: std.builtin.Type.ContainerLayout,
6398) Alignment {6424) Alignment {
6425 return zcu.structFieldAlignmentAdvanced(explicit_alignment, field_ty, layout, .normal) catch unreachable;
6426}
6427
6428/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
6429/// If `strat` is `.sema`, may perform type resolution.
6430pub fn structFieldAlignmentAdvanced(
6431 zcu: *Zcu,
6432 explicit_alignment: InternPool.Alignment,
6433 field_ty: Type,
6434 layout: std.builtin.Type.ContainerLayout,
6435 strat: Type.ResolveStrat,
6436) SemaError!Alignment {
6399 assert(layout != .@"packed");6437 assert(layout != .@"packed");
6400 if (explicit_alignment != .none) return explicit_alignment;6438 if (explicit_alignment != .none) return explicit_alignment;
6439 const ty_abi_align = (try field_ty.abiAlignmentAdvanced(zcu, strat.toLazy())).scalar;
6401 switch (layout) {6440 switch (layout) {
6402 .@"packed" => unreachable,6441 .@"packed" => unreachable,
6403 .auto => {6442 .auto => if (zcu.getTarget().ofmt != .c) return ty_abi_align,
6404 if (mod.getTarget().ofmt == .c) {6443 .@"extern" => {},
6405 return structFieldAlignmentExtern(mod, field_ty);
6406 } else {
6407 return field_ty.abiAlignment(mod);
6408 }
6409 },
6410 .@"extern" => return structFieldAlignmentExtern(mod, field_ty),
6411 }6444 }
6412}6445 // extern
64136446 if (field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) {
6414/// Returns the field alignment of an extern struct in byte units.6447 return ty_abi_align.maxStrict(.@"16");
6415/// This logic is duplicated in Type.abiAlignmentAdvanced.
6416pub fn structFieldAlignmentExtern(mod: *Module, field_ty: Type) Alignment {
6417 const ty_abi_align = field_ty.abiAlignment(mod);
6418
6419 if (field_ty.isAbiInt(mod) and field_ty.intInfo(mod).bits >= 128) {
6420 // The C ABI requires 128 bit integer fields of structs
6421 // to be 16-bytes aligned.
6422 return ty_abi_align.max(.@"16");
6423 }6448 }
6424
6425 return ty_abi_align;6449 return ty_abi_align;
6426}6450}
64276451
...@@ -6480,3 +6504,29 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved...@@ -6480,3 +6504,29 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
64806504
6481 return result;6505 return result;
6482}6506}
6507
6508pub fn getBuiltin(zcu: *Zcu, name: []const u8) Allocator.Error!Air.Inst.Ref {
6509 const decl_index = try zcu.getBuiltinDecl(name);
6510 zcu.ensureDeclAnalyzed(decl_index) catch @panic("std.builtin is corrupt");
6511 return Air.internedToRef(zcu.declPtr(decl_index).val.toIntern());
6512}
6513
6514pub fn getBuiltinDecl(zcu: *Zcu, name: []const u8) Allocator.Error!InternPool.DeclIndex {
6515 const gpa = zcu.gpa;
6516 const ip = &zcu.intern_pool;
6517 const std_file = (zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig")).file;
6518 const std_namespace = zcu.declPtr(std_file.root_decl.unwrap().?).getOwnedInnerNamespace(zcu).?;
6519 const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls);
6520 const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'");
6521 zcu.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt");
6522 const builtin_namespace = zcu.declPtr(builtin_decl).getInnerNamespace(zcu) orelse @panic("std.builtin is corrupt");
6523 const name_str = try ip.getOrPutString(gpa, name, .no_embedded_nulls);
6524 return builtin_namespace.decls.getKeyAdapted(name_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std/builtin.zig is corrupt");
6525}
6526
6527pub fn getBuiltinType(zcu: *Zcu, name: []const u8) Allocator.Error!Type {
6528 const ty_inst = try zcu.getBuiltin(name);
6529 const ty = Type.fromInterned(ty_inst.toInterned() orelse @panic("std.builtin is corrupt"));
6530 ty.resolveFully(zcu) catch @panic("std.builtin is corrupt");
6531 return ty;
6532}
src/codegen/llvm.zig+4-1
...@@ -2603,7 +2603,10 @@ pub const Object = struct {...@@ -2603,7 +2603,10 @@ pub const Object = struct {
2603 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;2603 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;
26042604
2605 const field_size = Type.fromInterned(field_ty).abiSize(mod);2605 const field_size = Type.fromInterned(field_ty).abiSize(mod);
2606 const field_align = mod.unionFieldNormalAlignment(union_type, @intCast(field_index));2606 const field_align: InternPool.Alignment = switch (union_type.flagsPtr(ip).layout) {
2607 .@"packed" => .none,
2608 .auto, .@"extern" => mod.unionFieldNormalAlignment(union_type, @intCast(field_index)),
2609 };
26072610
2608 const field_name = tag_type.names.get(ip)[field_index];2611 const field_name = tag_type.names.get(ip)[field_index];
2609 fields.appendAssumeCapacity(try o.builder.debugMemberType(2612 fields.appendAssumeCapacity(try o.builder.debugMemberType(
src/print_value.zig+4-4
...@@ -81,12 +81,12 @@ pub fn print(...@@ -81,12 +81,12 @@ pub fn print(
81 }),81 }),
82 .int => |int| switch (int.storage) {82 .int => |int| switch (int.storage) {
83 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),83 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
84 .lazy_align => |ty| if (opt_sema) |sema| {84 .lazy_align => |ty| if (opt_sema != null) {
85 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;85 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .sema)).scalar;
86 try writer.print("{}", .{a.toByteUnits() orelse 0});86 try writer.print("{}", .{a.toByteUnits() orelse 0});
87 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}),87 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}),
88 .lazy_size => |ty| if (opt_sema) |sema| {88 .lazy_size => |ty| if (opt_sema != null) {
89 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar;89 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .sema)).scalar;
90 try writer.print("{}", .{s});90 try writer.print("{}", .{s});
91 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}),91 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}),
92 },92 },
test/cases/compile_errors/direct_struct_loop.zig-1
...@@ -10,4 +10,3 @@ export fn entry() usize {...@@ -10,4 +10,3 @@ export fn entry() usize {
10// target=native10// target=native
11//11//
12// :1:11: error: struct 'tmp.A' depends on itself12// :1:11: error: struct 'tmp.A' depends on itself
13// :2:5: note: while checking this field
test/cases/compile_errors/indirect_struct_loop.zig-3
...@@ -16,6 +16,3 @@ export fn entry() usize {...@@ -16,6 +16,3 @@ export fn entry() usize {
16// target=native16// target=native
17//17//
18// :1:11: error: struct 'tmp.A' depends on itself18// :1:11: error: struct 'tmp.A' depends on itself
19// :8:5: note: while checking this field
20// :5:5: note: while checking this field
21// :2:5: note: while checking this field
test/cases/compile_errors/instantiating_an_undefined_value_for_an_invalid_struct_that_contains_itself.zig-1
...@@ -13,4 +13,3 @@ export fn entry() usize {...@@ -13,4 +13,3 @@ export fn entry() usize {
13// target=native13// target=native
14//14//
15// :1:13: error: struct 'tmp.Foo' depends on itself15// :1:13: error: struct 'tmp.Foo' depends on itself
16// :2:5: note: while checking this field
test/cases/compile_errors/instantiating_an_undefined_value_for_an_invalid_union_that_contains_itself.zig-1
...@@ -13,4 +13,3 @@ export fn entry() usize {...@@ -13,4 +13,3 @@ export fn entry() usize {
13// target=native13// target=native
14//14//
15// :1:13: error: union 'tmp.Foo' depends on itself15// :1:13: error: union 'tmp.Foo' depends on itself
16// :2:5: note: while checking this field
test/cases/compile_errors/invalid_dependency_on_struct_size.zig-1
...@@ -16,4 +16,3 @@ comptime {...@@ -16,4 +16,3 @@ comptime {
16// target=native16// target=native
17//17//
18// :6:21: error: struct layout depends on it having runtime bits18// :6:21: error: struct layout depends on it having runtime bits
19// :4:13: note: while checking this field
test/cases/compile_errors/struct_depends_on_itself_via_optional_field.zig-2
...@@ -15,5 +15,3 @@ export fn entry() void {...@@ -15,5 +15,3 @@ export fn entry() void {
15// target=native15// target=native
16//16//
17// :1:17: error: struct 'tmp.LhsExpr' depends on itself17// :1:17: error: struct 'tmp.LhsExpr' depends on itself
18// :5:5: note: while checking this field
19// :2:5: note: while checking this field
test/cases/compile_errors/struct_type_returned_from_non-generic_function.zig+1-1
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1pub export fn entry(param: usize) usize {1pub export fn entry(param: usize) usize {
2 return struct { param };2 return struct { @TypeOf(param) };
3}3}
44
5// error5// error
test/src/Cases.zig+33-670
...@@ -395,10 +395,7 @@ fn addFromDirInner(...@@ -395,10 +395,7 @@ fn addFromDirInner(
395 if (entry.kind != .file) continue;395 if (entry.kind != .file) continue;
396396
397 // Ignore stuff such as .swp files397 // Ignore stuff such as .swp files
398 switch (Compilation.classifyFileExt(entry.basename)) {398 if (!knownFileExtension(entry.basename)) continue;
399 .unknown => continue,
400 else => {},
401 }
402 try filenames.append(try ctx.arena.dupe(u8, entry.path));399 try filenames.append(try ctx.arena.dupe(u8, entry.path));
403 }400 }
404401
...@@ -623,8 +620,6 @@ pub fn lowerToBuildSteps(...@@ -623,8 +620,6 @@ pub fn lowerToBuildSteps(
623 b: *std.Build,620 b: *std.Build,
624 parent_step: *std.Build.Step,621 parent_step: *std.Build.Step,
625 test_filters: []const []const u8,622 test_filters: []const []const u8,
626 cases_dir_path: []const u8,
627 incremental_exe: *std.Build.Step.Compile,
628) void {623) void {
629 const host = std.zig.system.resolveTargetQuery(.{}) catch |err|624 const host = std.zig.system.resolveTargetQuery(.{}) catch |err|
630 std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)});625 std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)});
...@@ -637,20 +632,11 @@ pub fn lowerToBuildSteps(...@@ -637,20 +632,11 @@ pub fn lowerToBuildSteps(
637 // compilation is in a happier state.632 // compilation is in a happier state.
638 continue;633 continue;
639 }634 }
640 for (test_filters) |test_filter| {635 // TODO: the logic for running these was bad, so I've ripped it out. Rewrite this
641 if (std.mem.indexOf(u8, incr_case.base_path, test_filter)) |_| break;636 // in a way that actually spawns the compiler, communicating with it over the
642 } else if (test_filters.len > 0) continue;637 // compiler server protocol.
643 const case_base_path_with_dir = std.fs.path.join(b.allocator, &.{638 _ = incr_case;
644 cases_dir_path, incr_case.base_path,639 @panic("TODO implement incremental test case executor");
645 }) catch @panic("OOM");
646 const run = b.addRunArtifact(incremental_exe);
647 run.setName(incr_case.base_path);
648 run.addArgs(&.{
649 case_base_path_with_dir,
650 b.graph.zig_exe,
651 });
652 run.expectStdOutEqual("");
653 parent_step.dependOn(&run.step);
654 }640 }
655641
656 for (self.cases.items) |case| {642 for (self.cases.items) |case| {
...@@ -1236,192 +1222,6 @@ const assert = std.debug.assert;...@@ -1236,192 +1222,6 @@ const assert = std.debug.assert;
1236const Allocator = std.mem.Allocator;1222const Allocator = std.mem.Allocator;
1237const getExternalExecutor = std.zig.system.getExternalExecutor;1223const getExternalExecutor = std.zig.system.getExternalExecutor;
12381224
1239const Compilation = @import("../../src/Compilation.zig");
1240const zig_h = @import("../../src/link.zig").File.C.zig_h;
1241const introspect = @import("../../src/introspect.zig");
1242const ThreadPool = std.Thread.Pool;
1243const WaitGroup = std.Thread.WaitGroup;
1244const build_options = @import("build_options");
1245const Package = @import("../../src/Package.zig");
1246
1247pub const std_options = .{
1248 .log_level = .err,
1249};
1250
1251var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{
1252 .stack_trace_frames = build_options.mem_leak_frames,
1253}){};
1254
1255// TODO: instead of embedding the compiler in this process, spawn the compiler
1256// as a sub-process and communicate the updates using the compiler protocol.
1257pub fn main() !void {
1258 const use_gpa = build_options.force_gpa or !builtin.link_libc;
1259 const gpa = gpa: {
1260 if (use_gpa) {
1261 break :gpa general_purpose_allocator.allocator();
1262 }
1263 // We would prefer to use raw libc allocator here, but cannot
1264 // use it if it won't support the alignment we need.
1265 if (@alignOf(std.c.max_align_t) < @alignOf(i128)) {
1266 break :gpa std.heap.c_allocator;
1267 }
1268 break :gpa std.heap.raw_c_allocator;
1269 };
1270
1271 var single_threaded_arena = std.heap.ArenaAllocator.init(gpa);
1272 defer single_threaded_arena.deinit();
1273
1274 var thread_safe_arena: std.heap.ThreadSafeAllocator = .{
1275 .child_allocator = single_threaded_arena.allocator(),
1276 };
1277 const arena = thread_safe_arena.allocator();
1278
1279 const args = try std.process.argsAlloc(arena);
1280 const case_file_path = args[1];
1281 const zig_exe_path = args[2];
1282
1283 var filenames = std.ArrayList([]const u8).init(arena);
1284
1285 const case_dirname = std.fs.path.dirname(case_file_path).?;
1286 var iterable_dir = try std.fs.cwd().openDir(case_dirname, .{ .iterate = true });
1287 defer iterable_dir.close();
1288
1289 if (std.mem.endsWith(u8, case_file_path, ".0.zig")) {
1290 const stem = case_file_path[case_dirname.len + 1 .. case_file_path.len - "0.zig".len];
1291 var it = iterable_dir.iterate();
1292 while (try it.next()) |entry| {
1293 if (entry.kind != .file) continue;
1294 if (!std.mem.startsWith(u8, entry.name, stem)) continue;
1295 try filenames.append(try std.fs.path.join(arena, &.{ case_dirname, entry.name }));
1296 }
1297 } else {
1298 try filenames.append(case_file_path);
1299 }
1300
1301 if (filenames.items.len == 0) {
1302 std.debug.print("failed to find the input source file(s) from '{s}'\n", .{
1303 case_file_path,
1304 });
1305 std.process.exit(1);
1306 }
1307
1308 // Sort filenames, so that incremental tests are contiguous and in-order
1309 sortTestFilenames(filenames.items);
1310
1311 var ctx = Cases.init(gpa, arena);
1312
1313 var test_it = TestIterator{ .filenames = filenames.items };
1314 while (try test_it.next()) |batch| {
1315 const strategy: TestStrategy = if (batch.len > 1) .incremental else .independent;
1316 var cases = std.ArrayList(usize).init(arena);
1317
1318 for (batch) |filename| {
1319 const max_file_size = 10 * 1024 * 1024;
1320 const src = try iterable_dir.readFileAllocOptions(arena, filename, max_file_size, null, 1, 0);
1321
1322 // Parse the manifest
1323 var manifest = try TestManifest.parse(arena, src);
1324
1325 if (cases.items.len == 0) {
1326 const backends = try manifest.getConfigForKeyAlloc(arena, "backend", Backend);
1327 const targets = try manifest.getConfigForKeyAlloc(arena, "target", std.Target.Query);
1328 const c_frontends = try manifest.getConfigForKeyAlloc(ctx.arena, "c_frontend", CFrontend);
1329 const is_test = try manifest.getConfigForKeyAssertSingle("is_test", bool);
1330 const link_libc = try manifest.getConfigForKeyAssertSingle("link_libc", bool);
1331 const output_mode = try manifest.getConfigForKeyAssertSingle("output_mode", std.builtin.OutputMode);
1332
1333 if (manifest.type == .translate_c) {
1334 for (c_frontends) |c_frontend| {
1335 for (targets) |target_query| {
1336 const output = try manifest.trailingLinesSplit(ctx.arena);
1337 try ctx.translate.append(.{
1338 .name = std.fs.path.stem(filename),
1339 .c_frontend = c_frontend,
1340 .target = resolveTargetQuery(target_query),
1341 .is_test = is_test,
1342 .link_libc = link_libc,
1343 .input = src,
1344 .kind = .{ .translate = output },
1345 });
1346 }
1347 }
1348 continue;
1349 }
1350 if (manifest.type == .run_translated_c) {
1351 for (c_frontends) |c_frontend| {
1352 for (targets) |target_query| {
1353 const output = try manifest.trailingSplit(ctx.arena);
1354 try ctx.translate.append(.{
1355 .name = std.fs.path.stem(filename),
1356 .c_frontend = c_frontend,
1357 .target = resolveTargetQuery(target_query),
1358 .is_test = is_test,
1359 .link_libc = link_libc,
1360 .output = output,
1361 .input = src,
1362 .kind = .{ .run = output },
1363 });
1364 }
1365 }
1366 continue;
1367 }
1368
1369 // Cross-product to get all possible test combinations
1370 for (backends) |backend| {
1371 for (targets) |target| {
1372 const next = ctx.cases.items.len;
1373 try ctx.cases.append(.{
1374 .name = std.fs.path.stem(filename),
1375 .target = target,
1376 .backend = backend,
1377 .updates = std.ArrayList(Cases.Update).init(ctx.cases.allocator),
1378 .is_test = is_test,
1379 .output_mode = output_mode,
1380 .link_libc = backend == .llvm,
1381 .deps = std.ArrayList(DepModule).init(ctx.cases.allocator),
1382 });
1383 try cases.append(next);
1384 }
1385 }
1386 }
1387
1388 for (cases.items) |case_index| {
1389 const case = &ctx.cases.items[case_index];
1390 if (strategy == .incremental and case.backend == .stage2 and case.target.getCpuArch() == .x86_64 and !case.link_libc and case.target.getOsTag() != .plan9) {
1391 // https://github.com/ziglang/zig/issues/15174
1392 continue;
1393 }
1394
1395 switch (manifest.type) {
1396 .compile => {
1397 case.addCompile(src);
1398 },
1399 .@"error" => {
1400 const errors = try manifest.trailingLines(arena);
1401 switch (strategy) {
1402 .independent => {
1403 case.addError(src, errors);
1404 },
1405 .incremental => {
1406 case.addErrorNamed("update", src, errors);
1407 },
1408 }
1409 },
1410 .run => {
1411 const output = try manifest.trailingSplit(ctx.arena);
1412 case.addCompareOutput(src, output);
1413 },
1414 .translate_c => @panic("c_frontend specified for compile case"),
1415 .run_translated_c => @panic("c_frontend specified for compile case"),
1416 .cli => @panic("TODO cli tests"),
1417 }
1418 }
1419 }
1420 }
1421
1422 return runCases(&ctx, zig_exe_path);
1423}
1424
1425fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {1225fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {
1426 return .{1226 return .{
1427 .query = query,1227 .query = query,
...@@ -1430,470 +1230,33 @@ fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {...@@ -1430,470 +1230,33 @@ fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {
1430 };1230 };
1431}1231}
14321232
1433fn runCases(self: *Cases, zig_exe_path: []const u8) !void {1233fn knownFileExtension(filename: []const u8) bool {
1434 const host = try std.zig.system.resolveTargetQuery(.{});1234 // List taken from `Compilation.classifyFileExt` in the compiler.
14351235 for ([_][]const u8{
1436 var progress = std.Progress{};1236 ".c", ".C", ".cc", ".cpp",
1437 const root_node = progress.start("compiler", self.cases.items.len);1237 ".cxx", ".stub", ".m", ".mm",
1438 progress.terminal = null;1238 ".ll", ".bc", ".s", ".S",
1439 defer root_node.end();1239 ".h", ".zig", ".so", ".dll",
14401240 ".dylib", ".tbd", ".a", ".lib",
1441 var zig_lib_directory = try introspect.findZigLibDirFromSelfExe(self.gpa, zig_exe_path);1241 ".o", ".obj", ".cu", ".def",
1442 defer zig_lib_directory.handle.close();1242 ".rc", ".res", ".manifest",
1443 defer self.gpa.free(zig_lib_directory.path.?);1243 }) |ext| {
14441244 if (std.mem.endsWith(u8, filename, ext)) return true;
1445 var aux_thread_pool: ThreadPool = undefined;
1446 try aux_thread_pool.init(.{ .allocator = self.gpa });
1447 defer aux_thread_pool.deinit();
1448
1449 // Use the same global cache dir for all the tests, such that we for example don't have to
1450 // rebuild musl libc for every case (when LLVM backend is enabled).
1451 var global_tmp = std.testing.tmpDir(.{});
1452 defer global_tmp.cleanup();
1453
1454 var cache_dir = try global_tmp.dir.makeOpenPath(".zig-cache", .{});
1455 defer cache_dir.close();
1456 const tmp_dir_path = try std.fs.path.join(self.gpa, &[_][]const u8{ ".", ".zig-cache", "tmp", &global_tmp.sub_path });
1457 defer self.gpa.free(tmp_dir_path);
1458
1459 const global_cache_directory: Compilation.Directory = .{
1460 .handle = cache_dir,
1461 .path = try std.fs.path.join(self.gpa, &[_][]const u8{ tmp_dir_path, ".zig-cache" }),
1462 };
1463 defer self.gpa.free(global_cache_directory.path.?);
1464
1465 {
1466 for (self.cases.items) |*case| {
1467 if (build_options.skip_non_native) {
1468 if (case.target.getCpuArch() != builtin.cpu.arch)
1469 continue;
1470 if (case.target.getObjectFormat() != builtin.object_format)
1471 continue;
1472 }
1473
1474 // Skip tests that require LLVM backend when it is not available
1475 if (!build_options.have_llvm and case.backend == .llvm)
1476 continue;
1477
1478 assert(case.backend != .stage1);
1479
1480 for (build_options.test_filters) |test_filter| {
1481 if (std.mem.indexOf(u8, case.name, test_filter)) |_| break;
1482 } else if (build_options.test_filters.len > 0) continue;
1483
1484 var prg_node = root_node.start(case.name, case.updates.items.len);
1485 prg_node.activate();
1486 defer prg_node.end();
1487
1488 try runOneCase(
1489 self.gpa,
1490 &prg_node,
1491 case.*,
1492 zig_lib_directory,
1493 zig_exe_path,
1494 &aux_thread_pool,
1495 global_cache_directory,
1496 host,
1497 );
1498 }
1499
1500 for (self.translate.items) |*case| {
1501 _ = case;
1502 @panic("TODO is this even used?");
1503 }
1504 }
1505}
1506
1507fn runOneCase(
1508 allocator: Allocator,
1509 root_node: *std.Progress.Node,
1510 case: Case,
1511 zig_lib_directory: Compilation.Directory,
1512 zig_exe_path: []const u8,
1513 thread_pool: *ThreadPool,
1514 global_cache_directory: Compilation.Directory,
1515 host: std.Target,
1516) !void {
1517 const tmp_src_path = "tmp.zig";
1518 const enable_rosetta = build_options.enable_rosetta;
1519 const enable_qemu = build_options.enable_qemu;
1520 const enable_wine = build_options.enable_wine;
1521 const enable_wasmtime = build_options.enable_wasmtime;
1522 const enable_darling = build_options.enable_darling;
1523 const glibc_runtimes_dir: ?[]const u8 = build_options.glibc_runtimes_dir;
1524
1525 const target = try std.zig.system.resolveTargetQuery(case.target);
1526
1527 var arena_allocator = std.heap.ArenaAllocator.init(allocator);
1528 defer arena_allocator.deinit();
1529 const arena = arena_allocator.allocator();
1530
1531 var tmp = std.testing.tmpDir(.{});
1532 defer tmp.cleanup();
1533
1534 var cache_dir = try tmp.dir.makeOpenPath(".zig-cache", .{});
1535 defer cache_dir.close();
1536
1537 const tmp_dir_path = try std.fs.path.join(
1538 arena,
1539 &[_][]const u8{ ".", ".zig-cache", "tmp", &tmp.sub_path },
1540 );
1541 const local_cache_path = try std.fs.path.join(
1542 arena,
1543 &[_][]const u8{ tmp_dir_path, ".zig-cache" },
1544 );
1545
1546 const zig_cache_directory: Compilation.Directory = .{
1547 .handle = cache_dir,
1548 .path = local_cache_path,
1549 };
1550
1551 var main_pkg: Package = .{
1552 .root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },
1553 .root_src_path = tmp_src_path,
1554 };
1555 defer {
1556 var it = main_pkg.table.iterator();
1557 while (it.next()) |kv| {
1558 allocator.free(kv.key_ptr.*);
1559 kv.value_ptr.*.destroy(allocator);
1560 }
1561 main_pkg.table.deinit(allocator);
1562 }
1563
1564 for (case.deps.items) |dep| {
1565 var pkg = try Package.create(
1566 allocator,
1567 tmp_dir_path,
1568 dep.path,
1569 );
1570 errdefer pkg.destroy(allocator);
1571 try main_pkg.add(allocator, dep.name, pkg);
1572 }1245 }
15731246 // Final check for .so.X, .so.X.Y, .so.X.Y.Z.
1574 const bin_name = try std.zig.binNameAlloc(arena, .{1247 // From `Compilation.hasSharedLibraryExt`.
1575 .root_name = "test_case",1248 var it = std.mem.splitScalar(u8, filename, '.');
1576 .target = target,1249 _ = it.first();
1577 .output_mode = case.output_mode,1250 var so_txt = it.next() orelse return false;
1578 });1251 while (!std.mem.eql(u8, so_txt, "so")) {
15791252 so_txt = it.next() orelse return false;
1580 const emit_directory: Compilation.Directory = .{
1581 .path = tmp_dir_path,
1582 .handle = tmp.dir,
1583 };
1584 const emit_bin: Compilation.EmitLoc = .{
1585 .directory = emit_directory,
1586 .basename = bin_name,
1587 };
1588 const emit_h: ?Compilation.EmitLoc = if (case.emit_h) .{
1589 .directory = emit_directory,
1590 .basename = "test_case.h",
1591 } else null;
1592 const use_llvm: bool = switch (case.backend) {
1593 .llvm => true,
1594 else => false,
1595 };
1596 const comp = try Compilation.create(allocator, .{
1597 .local_cache_directory = zig_cache_directory,
1598 .global_cache_directory = global_cache_directory,
1599 .zig_lib_directory = zig_lib_directory,
1600 .thread_pool = thread_pool,
1601 .root_name = "test_case",
1602 .target = target,
1603 // TODO: support tests for object file building, and library builds
1604 // and linking. This will require a rework to support multi-file
1605 // tests.
1606 .output_mode = case.output_mode,
1607 .is_test = case.is_test,
1608 .optimize_mode = case.optimize_mode,
1609 .emit_bin = emit_bin,
1610 .emit_h = emit_h,
1611 .main_pkg = &main_pkg,
1612 .keep_source_files_loaded = true,
1613 .is_native_os = case.target.isNativeOs(),
1614 .is_native_abi = case.target.isNativeAbi(),
1615 .dynamic_linker = target.dynamic_linker.get(),
1616 .link_libc = case.link_libc,
1617 .use_llvm = use_llvm,
1618 .self_exe_path = zig_exe_path,
1619 // TODO instead of turning off color, pass in a std.Progress.Node
1620 .color = .off,
1621 .reference_trace = 0,
1622 // TODO: force self-hosted linkers with stage2 backend to avoid LLD creeping in
1623 // until the auto-select mechanism deems them worthy
1624 .use_lld = switch (case.backend) {
1625 .stage2 => false,
1626 else => null,
1627 },
1628 });
1629 defer comp.destroy();
1630
1631 update: for (case.updates.items, 0..) |update, update_index| {
1632 var update_node = root_node.start(update.name, 3);
1633 update_node.activate();
1634 defer update_node.end();
1635
1636 var sync_node = update_node.start("write", 0);
1637 sync_node.activate();
1638 for (update.files.items) |file| {
1639 try tmp.dir.writeFile(.{ .sub_path = file.path, .data = file.src });
1640 }
1641 sync_node.end();
1642
1643 var module_node = update_node.start("parse/analysis/codegen", 0);
1644 module_node.activate();
1645 try comp.makeBinFileWritable();
1646 try comp.update(&module_node);
1647 module_node.end();
1648
1649 if (update.case != .Error) {
1650 var all_errors = try comp.getAllErrorsAlloc();
1651 defer all_errors.deinit(allocator);
1652 if (all_errors.errorMessageCount() > 0) {
1653 all_errors.renderToStdErr(.{
1654 .ttyconf = std.io.tty.detectConfig(std.io.getStdErr()),
1655 });
1656 // TODO print generated C code
1657 return error.UnexpectedCompileErrors;
1658 }
1659 }
1660
1661 switch (update.case) {
1662 .Header => |expected_output| {
1663 var file = try tmp.dir.openFile("test_case.h", .{ .mode = .read_only });
1664 defer file.close();
1665 const out = try file.reader().readAllAlloc(arena, 5 * 1024 * 1024);
1666
1667 try std.testing.expectEqualStrings(expected_output, out);
1668 },
1669 .CompareObjectFile => |expected_output| {
1670 var file = try tmp.dir.openFile(bin_name, .{ .mode = .read_only });
1671 defer file.close();
1672 const out = try file.reader().readAllAlloc(arena, 5 * 1024 * 1024);
1673
1674 try std.testing.expectEqualStrings(expected_output, out);
1675 },
1676 .Compile => {},
1677 .Error => |expected_errors| {
1678 var test_node = update_node.start("assert", 0);
1679 test_node.activate();
1680 defer test_node.end();
1681
1682 var error_bundle = try comp.getAllErrorsAlloc();
1683 defer error_bundle.deinit(allocator);
1684
1685 if (error_bundle.errorMessageCount() == 0) {
1686 return error.ExpectedCompilationErrors;
1687 }
1688
1689 var actual_stderr = std.ArrayList(u8).init(arena);
1690 try error_bundle.renderToWriter(.{
1691 .ttyconf = .no_color,
1692 .include_reference_trace = false,
1693 .include_source_line = false,
1694 }, actual_stderr.writer());
1695
1696 // Render the expected lines into a string that we can compare verbatim.
1697 var expected_generated = std.ArrayList(u8).init(arena);
1698
1699 var actual_line_it = std.mem.splitScalar(u8, actual_stderr.items, '\n');
1700 for (expected_errors) |expect_line| {
1701 const actual_line = actual_line_it.next() orelse {
1702 try expected_generated.appendSlice(expect_line);
1703 try expected_generated.append('\n');
1704 continue;
1705 };
1706 if (std.mem.endsWith(u8, actual_line, expect_line)) {
1707 try expected_generated.appendSlice(actual_line);
1708 try expected_generated.append('\n');
1709 continue;
1710 }
1711 if (std.mem.startsWith(u8, expect_line, ":?:?: ")) {
1712 if (std.mem.endsWith(u8, actual_line, expect_line[":?:?: ".len..])) {
1713 try expected_generated.appendSlice(actual_line);
1714 try expected_generated.append('\n');
1715 continue;
1716 }
1717 }
1718 try expected_generated.appendSlice(expect_line);
1719 try expected_generated.append('\n');
1720 }
1721
1722 try std.testing.expectEqualStrings(expected_generated.items, actual_stderr.items);
1723 },
1724 .Execution => |expected_stdout| {
1725 if (!std.process.can_spawn) {
1726 std.debug.print("Unable to spawn child processes on {s}, skipping test.\n", .{@tagName(builtin.os.tag)});
1727 continue :update; // Pass test.
1728 }
1729
1730 update_node.setEstimatedTotalItems(4);
1731
1732 var argv = std.ArrayList([]const u8).init(allocator);
1733 defer argv.deinit();
1734
1735 const exec_result = x: {
1736 var exec_node = update_node.start("execute", 0);
1737 exec_node.activate();
1738 defer exec_node.end();
1739
1740 // We go out of our way here to use the unique temporary directory name in
1741 // the exe_path so that it makes its way into the cache hash, avoiding
1742 // cache collisions from multiple threads doing `zig run` at the same time
1743 // on the same test_case.c input filename.
1744 const ss = std.fs.path.sep_str;
1745 const exe_path = try std.fmt.allocPrint(
1746 arena,
1747 ".." ++ ss ++ "{s}" ++ ss ++ "{s}",
1748 .{ &tmp.sub_path, bin_name },
1749 );
1750 if (case.target.ofmt != null and case.target.ofmt.? == .c) {
1751 if (getExternalExecutor(host, &target, .{ .link_libc = true }) != .native) {
1752 // We wouldn't be able to run the compiled C code.
1753 continue :update; // Pass test.
1754 }
1755 try argv.appendSlice(&[_][]const u8{
1756 zig_exe_path,
1757 "run",
1758 "-cflags",
1759 "-std=c99",
1760 "-pedantic",
1761 "-Werror",
1762 "-Wno-incompatible-library-redeclaration", // https://github.com/ziglang/zig/issues/875
1763 "--",
1764 "-lc",
1765 exe_path,
1766 });
1767 if (zig_lib_directory.path) |p| {
1768 try argv.appendSlice(&.{ "-I", p });
1769 }
1770 } else switch (getExternalExecutor(host, &target, .{ .link_libc = case.link_libc })) {
1771 .native => {
1772 if (case.backend == .stage2 and case.target.getCpuArch().isArmOrThumb()) {
1773 // https://github.com/ziglang/zig/issues/13623
1774 continue :update; // Pass test.
1775 }
1776 try argv.append(exe_path);
1777 },
1778 .bad_dl, .bad_os_or_cpu => continue :update, // Pass test.
1779
1780 .rosetta => if (enable_rosetta) {
1781 try argv.append(exe_path);
1782 } else {
1783 continue :update; // Rosetta not available, pass test.
1784 },
1785
1786 .qemu => |qemu_bin_name| if (enable_qemu) {
1787 const need_cross_glibc = target.isGnuLibC() and case.link_libc;
1788 const glibc_dir_arg: ?[]const u8 = if (need_cross_glibc)
1789 glibc_runtimes_dir orelse continue :update // glibc dir not available; pass test
1790 else
1791 null;
1792 try argv.append(qemu_bin_name);
1793 if (glibc_dir_arg) |dir| {
1794 const linux_triple = try target.linuxTriple(arena);
1795 const full_dir = try std.fs.path.join(arena, &[_][]const u8{
1796 dir,
1797 linux_triple,
1798 });
1799
1800 try argv.append("-L");
1801 try argv.append(full_dir);
1802 }
1803 try argv.append(exe_path);
1804 } else {
1805 continue :update; // QEMU not available; pass test.
1806 },
1807
1808 .wine => |wine_bin_name| if (enable_wine) {
1809 try argv.append(wine_bin_name);
1810 try argv.append(exe_path);
1811 } else {
1812 continue :update; // Wine not available; pass test.
1813 },
1814
1815 .wasmtime => |wasmtime_bin_name| if (enable_wasmtime) {
1816 try argv.append(wasmtime_bin_name);
1817 try argv.append("--dir=.");
1818 try argv.append(exe_path);
1819 } else {
1820 continue :update; // wasmtime not available; pass test.
1821 },
1822
1823 .darling => |darling_bin_name| if (enable_darling) {
1824 try argv.append(darling_bin_name);
1825 // Since we use relative to cwd here, we invoke darling with
1826 // "shell" subcommand.
1827 try argv.append("shell");
1828 try argv.append(exe_path);
1829 } else {
1830 continue :update; // Darling not available; pass test.
1831 },
1832 }
1833
1834 try comp.makeBinFileExecutable();
1835
1836 while (true) {
1837 break :x std.process.Child.run(.{
1838 .allocator = allocator,
1839 .argv = argv.items,
1840 .cwd_dir = tmp.dir,
1841 .cwd = tmp_dir_path,
1842 }) catch |err| switch (err) {
1843 error.FileBusy => {
1844 // There is a fundamental design flaw in Unix systems with how
1845 // ETXTBSY interacts with fork+exec.
1846 // https://github.com/golang/go/issues/22315
1847 // https://bugs.openjdk.org/browse/JDK-8068370
1848 // Unfortunately, this could be a real error, but we can't
1849 // tell the difference here.
1850 continue;
1851 },
1852 else => {
1853 std.debug.print("\n{s}.{d} The following command failed with {s}:\n", .{
1854 case.name, update_index, @errorName(err),
1855 });
1856 dumpArgs(argv.items);
1857 return error.ChildProcessExecution;
1858 },
1859 };
1860 }
1861 };
1862 var test_node = update_node.start("test", 0);
1863 test_node.activate();
1864 defer test_node.end();
1865 defer allocator.free(exec_result.stdout);
1866 defer allocator.free(exec_result.stderr);
1867 switch (exec_result.term) {
1868 .Exited => |code| {
1869 if (code != 0) {
1870 std.debug.print("\n{s}\n{s}: execution exited with code {d}:\n", .{
1871 exec_result.stderr, case.name, code,
1872 });
1873 dumpArgs(argv.items);
1874 return error.ChildProcessExecution;
1875 }
1876 },
1877 else => {
1878 std.debug.print("\n{s}\n{s}: execution crashed:\n", .{
1879 exec_result.stderr, case.name,
1880 });
1881 dumpArgs(argv.items);
1882 return error.ChildProcessExecution;
1883 },
1884 }
1885 try std.testing.expectEqualStrings(expected_stdout, exec_result.stdout);
1886 // We allow stderr to have garbage in it because wasmtime prints a
1887 // warning about --invoke even though we don't pass it.
1888 //std.testing.expectEqualStrings("", exec_result.stderr);
1889 },
1890 }
1891 }
1892}
1893
1894fn dumpArgs(argv: []const []const u8) void {
1895 for (argv) |arg| {
1896 std.debug.print("{s} ", .{arg});
1897 }1253 }
1898 std.debug.print("\n", .{});1254 const n1 = it.next() orelse return false;
1255 const n2 = it.next();
1256 const n3 = it.next();
1257 _ = std.fmt.parseInt(u32, n1, 10) catch return false;
1258 if (n2) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false;
1259 if (n3) |x| _ = std.fmt.parseInt(u32, x, 10) catch return false;
1260 if (it.next() != null) return false;
1261 return false;
1899}1262}
test/tests.zig-4
...@@ -1250,7 +1250,6 @@ pub fn addCases(...@@ -1250,7 +1250,6 @@ pub fn addCases(
1250 b: *std.Build,1250 b: *std.Build,
1251 parent_step: *Step,1251 parent_step: *Step,
1252 test_filters: []const []const u8,1252 test_filters: []const []const u8,
1253 check_case_exe: *std.Build.Step.Compile,
1254 target: std.Build.ResolvedTarget,1253 target: std.Build.ResolvedTarget,
1255 translate_c_options: @import("src/Cases.zig").TranslateCOptions,1254 translate_c_options: @import("src/Cases.zig").TranslateCOptions,
1256 build_options: @import("cases.zig").BuildOptions,1255 build_options: @import("cases.zig").BuildOptions,
...@@ -1268,12 +1267,9 @@ pub fn addCases(...@@ -1268,12 +1267,9 @@ pub fn addCases(
12681267
1269 cases.lowerToTranslateCSteps(b, parent_step, test_filters, target, translate_c_options);1268 cases.lowerToTranslateCSteps(b, parent_step, test_filters, target, translate_c_options);
12701269
1271 const cases_dir_path = try b.build_root.join(b.allocator, &.{ "test", "cases" });
1272 cases.lowerToBuildSteps(1270 cases.lowerToBuildSteps(
1273 b,1271 b,
1274 parent_step,1272 parent_step,
1275 test_filters,1273 test_filters,
1276 cases_dir_path,
1277 check_case_exe,
1278 );1274 );
1279}1275}