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 {
8282 docs_step.dependOn(langref_step);
8383 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
9485 const skip_debug = b.option(bool, "skip-debug", "Main test suite skips debug builds") orelse false;
9586 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
9687 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 {
222213 if (target.result.os.tag == .windows and target.result.abi == .gnu) {
223214 // LTO is currently broken on mingw, this can be removed when it's fixed.
224215 exe.want_lto = false;
225 check_case_exe.want_lto = false;
226216 }
227217
228218 const use_llvm = b.option(bool, "use-llvm", "Use the llvm backend");
......@@ -245,7 +235,6 @@ pub fn build(b: *std.Build) !void {
245235
246236 if (link_libc) {
247237 exe.linkLibC();
248 check_case_exe.linkLibC();
249238 }
250239
251240 const is_debug = optimize == .Debug;
......@@ -339,21 +328,17 @@ pub fn build(b: *std.Build) !void {
339328 }
340329
341330 try addCmakeCfgOptionsToExe(b, cfg, exe, use_zig_libcxx);
342 try addCmakeCfgOptionsToExe(b, cfg, check_case_exe, use_zig_libcxx);
343331 } else {
344332 // Here we are -Denable-llvm but no cmake integration.
345333 try addStaticLlvmOptionsToExe(exe);
346 try addStaticLlvmOptionsToExe(check_case_exe);
347334 }
348335 if (target.result.os.tag == .windows) {
349 inline for (.{ exe, check_case_exe }) |artifact| {
350 // LLVM depends on networking as of version 18.
351 artifact.linkSystemLibrary("ws2_32");
336 // LLVM depends on networking as of version 18.
337 exe.linkSystemLibrary("ws2_32");
352338
353 artifact.linkSystemLibrary("version");
354 artifact.linkSystemLibrary("uuid");
355 artifact.linkSystemLibrary("ole32");
356 }
339 exe.linkSystemLibrary("version");
340 exe.linkSystemLibrary("uuid");
341 exe.linkSystemLibrary("ole32");
357342 }
358343 }
359344
......@@ -394,7 +379,6 @@ pub fn build(b: *std.Build) !void {
394379 const test_filters = b.option([]const []const u8, "test-filter", "Skip tests that do not match any filter") orelse &[0][]const u8{};
395380
396381 const test_cases_options = b.addOptions();
397 check_case_exe.root_module.addOptions("build_options", test_cases_options);
398382
399383 test_cases_options.addOption(bool, "enable_tracy", false);
400384 test_cases_options.addOption(bool, "enable_debug_extensions", enable_debug_extensions);
......@@ -458,7 +442,7 @@ pub fn build(b: *std.Build) !void {
458442 test_step.dependOn(check_fmt);
459443
460444 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, .{
462446 .skip_translate_c = skip_translate_c,
463447 .skip_run_translated_c = skip_run_translated_c,
464448 }, .{
src/Air.zig+2
......@@ -1801,3 +1801,5 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
18011801 .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtrIp(ip),
18021802 };
18031803}
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;
3737const c_codegen = @import("codegen/c.zig");
3838const libtsan = @import("libtsan.zig");
3939const Zir = std.zig.Zir;
40const Air = @import("Air.zig");
4041const Builtin = @import("Builtin.zig");
4142const LlvmObject = @import("codegen/llvm.zig").Object;
4243
......@@ -316,18 +317,29 @@ const Job = union(enum) {
316317 codegen_decl: InternPool.DeclIndex,
317318 /// Write the machine code for a function to the output file.
318319 /// 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 },
320326 /// Render the .h file snippet for the Decl.
321327 emit_h_decl: InternPool.DeclIndex,
322328 /// The Decl needs to be analyzed and possibly export itself.
323329 /// It may have already be analyzed, or it may have been determined
324330 /// to be outdated; in this case perform semantic analysis again.
325331 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,
326336 /// The source file containing the Decl has been updated, and so the
327337 /// Decl may need its line number information updated in the debug info.
328338 update_line_number: InternPool.DeclIndex,
329339 /// The main source file for the module needs to be analyzed.
330340 analyze_mod: *Package.Module,
341 /// Fully resolve the given `struct` or `union` type.
342 resolve_type_fully: InternPool.Index,
331343
332344 /// one of the glibc static objects
333345 glibc_crt_file: glibc.CRTFile,
......@@ -3389,7 +3401,7 @@ pub fn performAllTheWork(
33893401 if (try zcu.findOutdatedToAnalyze()) |outdated| {
33903402 switch (outdated.unwrap()) {
33913403 .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 }),
33933405 }
33943406 continue;
33953407 }
......@@ -3439,6 +3451,14 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
34393451 const named_frame = tracy.namedFrame("codegen_func");
34403452 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
34423462 const module = comp.module.?;
34433463 module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
34443464 error.OutOfMemory => return error.OutOfMemory,
......@@ -3518,6 +3538,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo
35183538 try module.ensureFuncBodyAnalysisQueued(decl.val.toIntern());
35193539 }
35203540 },
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 },
35213551 .update_line_number => |decl_index| {
35223552 const named_frame = tracy.namedFrame("update_line_number");
35233553 defer named_frame.end();
src/Sema.zig+430-1028
......@@ -64,14 +64,6 @@ generic_owner: InternPool.Index = .none,
6464/// instantiation can point back to the instantiation site in addition to the
6565/// declaration site.
6666generic_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) = .{},
7567/// These are lazily created runtime blocks from block_inline instructions.
7668/// They are created when an break_inline passes through a runtime condition, because
7769/// Sema must convert comptime control flow to runtime control flow, which means
......@@ -872,7 +864,6 @@ pub fn deinit(sema: *Sema) void {
872864 sema.air_extra.deinit(gpa);
873865 sema.inst_map.deinit(gpa);
874866 sema.decl_val_table.deinit(gpa);
875 sema.types_to_resolve.deinit(gpa);
876867 {
877868 var it = sema.post_hoc_blocks.iterator();
878869 while (it.next()) |entry| {
......@@ -2078,8 +2069,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize)
20782069 const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty));
20792070
20802071 // var st: StackTrace = undefined;
2081 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
2082 try sema.resolveTypeFields(stack_trace_ty);
2072 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
2073 try stack_trace_ty.resolveFields(mod);
20832074 const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty));
20842075
20852076 // st.instruction_addresses = &addrs;
......@@ -2628,7 +2619,7 @@ fn analyzeAsInt(
26282619 const mod = sema.mod;
26292620 const coerced = try sema.coerce(block, dest_ty, air_ref, src);
26302621 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
2631 return (try val.getUnsignedIntAdvanced(mod, sema)).?;
2622 return (try val.getUnsignedIntAdvanced(mod, .sema)).?;
26322623}
26332624
26342625/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
......@@ -2832,6 +2823,7 @@ fn zirStructDecl(
28322823 }
28332824
28342825 try mod.finalizeAnonDecl(new_decl_index);
2826 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
28352827 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
28362828}
28372829
......@@ -3332,7 +3324,7 @@ fn zirUnionDecl(
33323324 }
33333325
33343326 try mod.finalizeAnonDecl(new_decl_index);
3335
3327 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
33363328 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, new_namespace_index));
33373329}
33383330
......@@ -3457,12 +3449,12 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
34573449 defer tracy.end();
34583450
34593451 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);
34613453 return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none);
34623454 }
34633455
34643456 const target = sema.mod.getTarget();
3465 const ptr_type = try sema.ptrType(.{
3457 const ptr_type = try sema.mod.ptrTypeSema(.{
34663458 .child = sema.fn_ret_ty.toIntern(),
34673459 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
34683460 });
......@@ -3471,7 +3463,6 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
34713463 // We are inlining a function call; this should be emitted as an alloc, not a ret_ptr.
34723464 // TODO when functions gain result location support, the inlining struct in
34733465 // Block should contain the return pointer, and we would pass that through here.
3474 try sema.queueFullTypeResolution(sema.fn_ret_ty);
34753466 return block.addTy(.alloc, ptr_type);
34763467 }
34773468
......@@ -3667,8 +3658,8 @@ fn zirAllocExtended(
36673658 try sema.validateVarType(block, ty_src, var_ty, false);
36683659 }
36693660 const target = sema.mod.getTarget();
3670 try sema.resolveTypeLayout(var_ty);
3671 const ptr_type = try sema.ptrType(.{
3661 try var_ty.resolveLayout(sema.mod);
3662 const ptr_type = try sema.mod.ptrTypeSema(.{
36723663 .child = var_ty.toIntern(),
36733664 .flags = .{
36743665 .alignment = alignment,
......@@ -3902,7 +3893,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
39023893 const idx_val = (try sema.resolveValue(data.rhs)).?;
39033894 break :blk .{
39043895 data.lhs,
3905 .{ .elem = try idx_val.toUnsignedIntAdvanced(sema) },
3896 .{ .elem = try idx_val.toUnsignedIntSema(zcu) },
39063897 };
39073898 },
39083899 .bitcast => .{
......@@ -3940,7 +3931,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
39403931 .val = payload_val.toIntern(),
39413932 } });
39423933 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();
39443935 },
39453936 .eu_payload => ptr: {
39463937 // Set the error union to non-error at comptime.
......@@ -3953,7 +3944,7 @@ fn resolveComptimeKnownAllocPtr(sema: *Sema, block: *Block, alloc: Air.Inst.Ref,
39533944 .val = .{ .payload = payload_val.toIntern() },
39543945 } });
39553946 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();
39573948 },
39583949 .field => |idx| ptr: {
39593950 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,
39673958 const store_val = try zcu.unionValue(maybe_union_ty, tag_val, payload_val);
39683959 try sema.storePtrVal(block, LazySrcLoc.unneeded, Value.fromInterned(decl_parent_ptr), store_val, maybe_union_ty);
39693960 }
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();
39713962 },
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(),
39733964 };
39743965 try ptr_mapping.put(air_ptr, new_ptr);
39753966 }
......@@ -4060,7 +4051,7 @@ fn finishResolveComptimeKnownAllocPtr(
40604051fn makePtrTyConst(sema: *Sema, ptr_ty: Type) CompileError!Type {
40614052 var ptr_info = ptr_ty.ptrInfo(sema.mod);
40624053 ptr_info.flags.is_const = true;
4063 return sema.ptrType(ptr_info);
4054 return sema.mod.ptrTypeSema(ptr_info);
40644055}
40654056
40664057fn 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
41034094 return sema.analyzeComptimeAlloc(block, var_ty, .none);
41044095 }
41054096 const target = sema.mod.getTarget();
4106 const ptr_type = try sema.ptrType(.{
4097 const ptr_type = try sema.mod.ptrTypeSema(.{
41074098 .child = var_ty.toIntern(),
41084099 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
41094100 });
4110 try sema.queueFullTypeResolution(var_ty);
41114101 const ptr = try block.addTy(.alloc, ptr_type);
41124102 const ptr_inst = ptr.toIndex().?;
41134103 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
41274117 }
41284118 try sema.validateVarType(block, ty_src, var_ty, false);
41294119 const target = sema.mod.getTarget();
4130 const ptr_type = try sema.ptrType(.{
4120 const ptr_type = try sema.mod.ptrTypeSema(.{
41314121 .child = var_ty.toIntern(),
41324122 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
41334123 });
4134 try sema.queueFullTypeResolution(var_ty);
41354124 return block.addTy(.alloc, ptr_type);
41364125}
41374126
......@@ -4227,7 +4216,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
42274216 }
42284217 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(.{
42314220 .child = final_elem_ty.toIntern(),
42324221 .flags = .{
42334222 .alignment = ia1.alignment,
......@@ -4247,7 +4236,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
42474236 // Unless the block is comptime, `alloc_inferred` always produces
42484237 // a runtime constant. The final inferred type needs to be
42494238 // fully resolved so it can be lowered in codegen.
4250 try sema.resolveTypeFully(final_elem_ty);
4239 try final_elem_ty.resolveFully(mod);
42514240
42524241 return;
42534242 }
......@@ -4259,8 +4248,6 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
42594248 return sema.fail(block, src, "value with comptime-only type '{}' depends on runtime control flow", .{final_elem_ty.fmt(mod)});
42604249 }
42614250
4262 try sema.queueFullTypeResolution(final_elem_ty);
4263
42644251 // Change it to a normal alloc.
42654252 sema.air_instructions.set(@intFromEnum(ptr_inst), .{
42664253 .tag = .alloc,
......@@ -4633,7 +4620,7 @@ fn validateArrayInitTy(
46334620 return;
46344621 },
46354622 .Struct => if (ty.isTuple(mod)) {
4636 try sema.resolveTypeFields(ty);
4623 try ty.resolveFields(mod);
46374624 const array_len = ty.arrayLen(mod);
46384625 if (init_count > array_len) {
46394626 return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{
......@@ -4911,7 +4898,7 @@ fn validateStructInit(
49114898 if (block.is_comptime and
49124899 (try sema.resolveDefinedValue(block, init_src, struct_ptr)) != null)
49134900 {
4914 try sema.resolveStructLayout(struct_ty);
4901 try struct_ty.resolveLayout(mod);
49154902 // In this case the only thing we need to do is evaluate the implicit
49164903 // store instructions for default field values, and report any missing fields.
49174904 // Avoid the cost of the extra machinery for detecting a comptime struct init value.
......@@ -4919,7 +4906,7 @@ fn validateStructInit(
49194906 const i: u32 = @intCast(i_usize);
49204907 if (field_ptr != .none) continue;
49214908
4922 try sema.resolveStructFieldInits(struct_ty);
4909 try struct_ty.resolveStructFieldInits(mod);
49234910 const default_val = struct_ty.structFieldDefaultValue(i, mod);
49244911 if (default_val.toIntern() == .unreachable_value) {
49254912 const field_name = struct_ty.structFieldName(i, mod).unwrap() orelse {
......@@ -4968,7 +4955,7 @@ fn validateStructInit(
49684955 const air_tags = sema.air_instructions.items(.tag);
49694956 const air_datas = sema.air_instructions.items(.data);
49704957
4971 try sema.resolveStructFieldInits(struct_ty);
4958 try struct_ty.resolveStructFieldInits(mod);
49724959
49734960 // We collect the comptime field values in case the struct initialization
49744961 // ends up being comptime-known.
......@@ -5127,7 +5114,7 @@ fn validateStructInit(
51275114 try sema.storePtr2(block, init_src, struct_ptr, init_src, struct_init, init_src, .store);
51285115 return;
51295116 }
5130 try sema.resolveStructLayout(struct_ty);
5117 try struct_ty.resolveLayout(mod);
51315118
51325119 // Our task is to insert `store` instructions for all the default field values.
51335120 for (found_fields, 0..) |field_ptr, i| {
......@@ -5172,7 +5159,7 @@ fn zirValidatePtrArrayInit(
51725159 var root_msg: ?*Module.ErrorMsg = null;
51735160 errdefer if (root_msg) |msg| msg.destroy(sema.gpa);
51745161
5175 try sema.resolveStructFieldInits(array_ty);
5162 try array_ty.resolveStructFieldInits(mod);
51765163 var i = instrs.len;
51775164 while (i < array_len) : (i += 1) {
51785165 const default_val = array_ty.structFieldDefaultValue(i, mod).toIntern();
......@@ -5241,7 +5228,7 @@ fn zirValidatePtrArrayInit(
52415228
52425229 if (array_ty.isTuple(mod)) {
52435230 if (array_ty.structFieldIsComptime(i, mod))
5244 try sema.resolveStructFieldInits(array_ty);
5231 try array_ty.resolveStructFieldInits(mod);
52455232 if (try array_ty.structFieldValueComptime(mod, i)) |opv| {
52465233 element_vals[i] = opv.toIntern();
52475234 continue;
......@@ -5581,7 +5568,7 @@ fn storeToInferredAllocComptime(
55815568 .needed_comptime_reason = "value being stored to a comptime variable must be comptime-known",
55825569 });
55835570 };
5584 const alloc_ty = try sema.ptrType(.{
5571 const alloc_ty = try zcu.ptrTypeSema(.{
55855572 .child = operand_ty.toIntern(),
55865573 .flags = .{
55875574 .alignment = iac.alignment,
......@@ -5688,7 +5675,7 @@ fn anonDeclRef(sema: *Sema, val: InternPool.Index) CompileError!Air.Inst.Ref {
56885675
56895676fn refValue(sema: *Sema, val: InternPool.Index) CompileError!InternPool.Index {
56905677 const mod = sema.mod;
5691 const ptr_ty = (try sema.ptrType(.{
5678 const ptr_ty = (try mod.ptrTypeSema(.{
56925679 .child = mod.intern_pool.typeOf(val),
56935680 .flags = .{
56945681 .alignment = .none,
......@@ -6645,8 +6632,6 @@ fn addDbgVar(
66456632 // real `block` instruction.
66466633 if (block.need_debug_scope) |ptr| ptr.* = true;
66476634
6648 try sema.queueFullTypeResolution(operand_ty);
6649
66506635 // Add the name to the AIR.
66516636 const name_extra_index: u32 = @intCast(sema.air_extra.items.len);
66526637 const elements_used = name.len / 4 + 1;
......@@ -6832,14 +6817,8 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref
68326817
68336818 if (!block.ownerModule().error_tracing) return .none;
68346819
6835 const stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) {
6836 error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable,
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 };
6820 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
6821 try stack_trace_ty.resolveFields(mod);
68436822 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
68446823 const field_index = sema.structFieldIndex(block, stack_trace_ty, field_name, LazySrcLoc.unneeded) catch |err| switch (err) {
68456824 error.AnalysisFail => @panic("std.builtin.StackTrace is corrupt"),
......@@ -6879,8 +6858,8 @@ fn popErrorReturnTrace(
68796858 // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or
68806859 // the result is comptime-known to be a non-error. Either way, pop unconditionally.
68816860
6882 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6883 try sema.resolveTypeFields(stack_trace_ty);
6861 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
6862 try stack_trace_ty.resolveFields(mod);
68846863 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
68856864 const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty);
68866865 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
......@@ -6905,8 +6884,8 @@ fn popErrorReturnTrace(
69056884 defer then_block.instructions.deinit(gpa);
69066885
69076886 // If non-error, then pop the error return trace by restoring the index.
6908 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
6909 try sema.resolveTypeFields(stack_trace_ty);
6887 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
6888 try stack_trace_ty.resolveFields(mod);
69106889 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
69116890 const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty);
69126891 const field_name = try mod.intern_pool.getOrPutString(gpa, "index", .no_embedded_nulls);
......@@ -7032,8 +7011,8 @@ fn zirCall(
70327011 // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only
70337012 // need to clean-up our own trace if we were passed to a non-error-handling expression.
70347013 if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) {
7035 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
7036 try sema.resolveTypeFields(stack_trace_ty);
7014 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
7015 try stack_trace_ty.resolveFields(mod);
70377016 const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index", .no_embedded_nulls);
70387017 const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src);
70397018
......@@ -7264,10 +7243,6 @@ const CallArgsInfo = union(enum) {
72647243 ) CompileError!Air.Inst.Ref {
72657244 const mod = sema.mod;
72667245 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 };
72717246 const uncoerced_arg: Air.Inst.Ref = switch (cai) {
72727247 inline .resolved, .call_builtin => |resolved| resolved.args[arg_index],
72737248 .zir_call => |zir_call| arg_val: {
......@@ -7494,24 +7469,19 @@ fn analyzeCall(
74947469
74957470 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;
74987473 var is_comptime_call = block.is_comptime or modifier == .compile_time;
74997474 var is_inline_call = is_comptime_call or modifier == .always_inline or func_ty_info.cc == .Inline;
75007475 var comptime_reason: ?*const Block.ComptimeReason = null;
75017476 if (!is_inline_call and !is_comptime_call) {
7502 if (sema.typeRequiresComptime(Type.fromInterned(func_ty_info.return_type))) |ct| {
7503 is_comptime_call = ct;
7504 is_inline_call = ct;
7505 if (ct) {
7506 comptime_reason = &.{ .comptime_ret_ty = .{
7507 .func = func,
7508 .func_src = func_src,
7509 .return_ty = Type.fromInterned(func_ty_info.return_type),
7510 } };
7511 }
7512 } else |err| switch (err) {
7513 error.GenericPoison => is_generic_call = true,
7514 else => |e| return e,
7477 if (try sema.typeRequiresComptime(Type.fromInterned(func_ty_info.return_type))) {
7478 is_comptime_call = true;
7479 is_inline_call = true;
7480 comptime_reason = &.{ .comptime_ret_ty = .{
7481 .func = func,
7482 .func_src = func_src,
7483 .return_ty = Type.fromInterned(func_ty_info.return_type),
7484 } };
75157485 }
75167486 }
75177487
......@@ -7871,7 +7841,6 @@ fn analyzeCall(
78717841
78727842 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
78737843
7874 try sema.queueFullTypeResolution(Type.fromInterned(func_ty_info.return_type));
78757844 if (sema.owner_func_index != .none and Type.fromInterned(func_ty_info.return_type).isError(mod)) {
78767845 ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true;
78777846 }
......@@ -8281,7 +8250,6 @@ fn instantiateGenericCall(
82818250 }
82828251 } else {
82838252 // The parameter is runtime-known.
8284 try sema.queueFullTypeResolution(arg_ty);
82858253 child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
82868254 .tag = .arg,
82878255 .data = .{ .arg = .{
......@@ -8330,8 +8298,6 @@ fn instantiateGenericCall(
83308298 return error.GenericPoison;
83318299 }
83328300
8333 try sema.queueFullTypeResolution(Type.fromInterned(func_ty_info.return_type));
8334
83358301 if (call_dbg_node) |some| try sema.zirDbgStmt(block, some);
83368302
83378303 if (sema.owner_func_index != .none and
......@@ -8423,7 +8389,7 @@ fn zirArrayInitElemType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compil
84238389 else => |e| return e,
84248390 };
84258391 const indexable_ty = maybe_wrapped_indexable_ty.optEuBaseType(mod);
8426 try sema.resolveTypeFields(indexable_ty);
8392 try indexable_ty.resolveFields(mod);
84278393 assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction
84288394 if (indexable_ty.zigTypeTag(mod) == .Struct) {
84298395 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
86878653 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
86888654
86898655 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));
86918657 if (int > mod.global_error_set.count() or int == 0)
86928658 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
86938659 return Air.internedToRef((try mod.intern(.{ .err = .{
......@@ -8791,7 +8757,7 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
87918757 const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) {
87928758 .Enum => operand,
87938759 .Union => blk: {
8794 try sema.resolveTypeFields(operand_ty);
8760 try operand_ty.resolveFields(mod);
87958761 const tag_ty = operand_ty.unionTagType(mod) orelse {
87968762 return sema.fail(
87978763 block,
......@@ -8933,7 +8899,7 @@ fn analyzeOptionalPayloadPtr(
89338899 }
89348900
89358901 const child_type = opt_type.optionalChild(zcu);
8936 const child_pointer = try sema.ptrType(.{
8902 const child_pointer = try zcu.ptrTypeSema(.{
89378903 .child = child_type.toIntern(),
89388904 .flags = .{
89398905 .is_const = optional_ptr_ty.isConstPtr(zcu),
......@@ -8957,13 +8923,13 @@ fn analyzeOptionalPayloadPtr(
89578923 const opt_payload_ptr = try block.addTyOp(.optional_payload_ptr_set, child_pointer, optional_ptr);
89588924 try sema.checkKnownAllocPtr(block, optional_ptr, opt_payload_ptr);
89598925 }
8960 return Air.internedToRef((try ptr_val.ptrOptPayload(sema)).toIntern());
8926 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());
89618927 }
89628928 if (try sema.pointerDeref(block, src, ptr_val, optional_ptr_ty)) |val| {
89638929 if (val.isNull(zcu)) {
89648930 return sema.fail(block, src, "unable to unwrap null", .{});
89658931 }
8966 return Air.internedToRef((try ptr_val.ptrOptPayload(sema)).toIntern());
8932 return Air.internedToRef((try ptr_val.ptrOptPayload(zcu)).toIntern());
89678933 }
89688934 }
89698935
......@@ -9006,7 +8972,7 @@ fn zirOptionalPayload(
90068972 // TODO https://github.com/ziglang/zig/issues/6597
90078973 if (true) break :t operand_ty;
90088974 const ptr_info = operand_ty.ptrInfo(mod);
9009 break :t try sema.ptrType(.{
8975 break :t try mod.ptrTypeSema(.{
90108976 .child = ptr_info.child,
90118977 .flags = .{
90128978 .alignment = ptr_info.flags.alignment,
......@@ -9124,7 +9090,7 @@ fn analyzeErrUnionPayloadPtr(
91249090
91259091 const err_union_ty = operand_ty.childType(zcu);
91269092 const payload_ty = err_union_ty.errorUnionPayload(zcu);
9127 const operand_pointer_ty = try sema.ptrType(.{
9093 const operand_pointer_ty = try zcu.ptrTypeSema(.{
91289094 .child = payload_ty.toIntern(),
91299095 .flags = .{
91309096 .is_const = operand_ty.isConstPtr(zcu),
......@@ -9149,13 +9115,13 @@ fn analyzeErrUnionPayloadPtr(
91499115 const eu_payload_ptr = try block.addTyOp(.errunion_payload_ptr_set, operand_pointer_ty, operand);
91509116 try sema.checkKnownAllocPtr(block, operand, eu_payload_ptr);
91519117 }
9152 return Air.internedToRef((try ptr_val.ptrEuPayload(sema)).toIntern());
9118 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());
91539119 }
91549120 if (try sema.pointerDeref(block, src, ptr_val, operand_ty)) |val| {
91559121 if (val.getErrorName(zcu).unwrap()) |name| {
91569122 return sema.failWithComptimeErrorRetTrace(block, src, name);
91579123 }
9158 return Air.internedToRef((try ptr_val.ptrEuPayload(sema)).toIntern());
9124 return Air.internedToRef((try ptr_val.ptrEuPayload(zcu)).toIntern());
91599125 }
91609126 }
91619127
......@@ -9603,17 +9569,8 @@ fn funcCommon(
96039569 }
96049570 }
96059571
9606 var ret_ty_requires_comptime = false;
9607 const ret_poison = if (sema.typeRequiresComptime(bare_return_type)) |ret_comptime| rp: {
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 };
9572 const ret_ty_requires_comptime = try sema.typeRequiresComptime(bare_return_type);
9573 const ret_poison = bare_return_type.isGenericPoison();
96179574 const final_is_generic = is_generic or comptime_bits != 0 or ret_ty_requires_comptime;
96189575
96199576 const param_types = block.params.items(.ty);
......@@ -9961,8 +9918,8 @@ fn finishFunc(
99619918 if (!final_is_generic and sema.wantErrorReturnTracing(return_type)) {
99629919 // Make sure that StackTrace's fields are resolved so that the backend can
99639920 // lower this fn type.
9964 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
9965 try sema.resolveTypeFields(unresolved_stack_trace_ty);
9921 const unresolved_stack_trace_ty = try mod.getBuiltinType("StackTrace");
9922 try unresolved_stack_trace_ty.resolveFields(mod);
99669923 }
99679924
99689925 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
......@@ -10021,21 +9978,7 @@ fn zirParam(
100219978 }
100229979 };
100239980
10024 const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) {
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;
9981 const is_comptime = try sema.typeRequiresComptime(param_ty) or comptime_syntax;
100399982
100409983 try block.params.append(sema.arena, .{
100419984 .ty = param_ty.toIntern(),
......@@ -10162,7 +10105,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1016210105 }
1016310106 return Air.internedToRef((try zcu.intValue(
1016410107 Type.usize,
10165 (try operand_val.getUnsignedIntAdvanced(zcu, sema)).?,
10108 (try operand_val.getUnsignedIntAdvanced(zcu, .sema)).?,
1016610109 )).toIntern());
1016710110 }
1016810111 const len = operand_ty.vectorLen(zcu);
......@@ -10174,7 +10117,7 @@ fn zirIntFromPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
1017410117 new_elem.* = (try zcu.undefValue(Type.usize)).toIntern();
1017510118 continue;
1017610119 }
10177 const addr = try ptr_val.getUnsignedIntAdvanced(zcu, sema) orelse {
10120 const addr = try ptr_val.getUnsignedIntAdvanced(zcu, .sema) orelse {
1017810121 // A vector element wasn't an integer pointer. This is a runtime operation.
1017910122 break :ct;
1018010123 };
......@@ -11047,7 +10990,7 @@ const SwitchProngAnalysis = struct {
1104710990 const union_obj = zcu.typeToUnion(operand_ty).?;
1104810991 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
1104910992 if (capture_byref) {
11050 const ptr_field_ty = try sema.ptrType(.{
10993 const ptr_field_ty = try zcu.ptrTypeSema(.{
1105110994 .child = field_ty.toIntern(),
1105210995 .flags = .{
1105310996 .is_const = !operand_ptr_ty.ptrIsMutable(zcu),
......@@ -11056,7 +10999,7 @@ const SwitchProngAnalysis = struct {
1105610999 },
1105711000 });
1105811001 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());
1106011003 }
1106111004 return block.addStructFieldPtr(spa.operand_ptr, field_index, ptr_field_ty);
1106211005 } else {
......@@ -11150,7 +11093,7 @@ const SwitchProngAnalysis = struct {
1115011093 const dummy_captures = try sema.arena.alloc(Air.Inst.Ref, case_vals.len);
1115111094 for (field_indices, dummy_captures) |field_idx, *dummy| {
1115211095 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(.{
1115411097 .child = field_ty.toIntern(),
1115511098 .flags = .{
1115611099 .is_const = operand_ptr_info.flags.is_const,
......@@ -11186,7 +11129,7 @@ const SwitchProngAnalysis = struct {
1118611129
1118711130 if (try sema.resolveDefinedValue(block, operand_src, spa.operand_ptr)) |op_ptr_val| {
1118811131 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);
1119011133 return Air.internedToRef((try zcu.getCoerced(field_ptr_val, capture_ptr_ty)).toIntern());
1119111134 }
1119211135
......@@ -11399,7 +11342,7 @@ fn switchCond(
1139911342 },
1140011343
1140111344 .Union => {
11402 try sema.resolveTypeFields(operand_ty);
11345 try operand_ty.resolveFields(mod);
1140311346 const enum_ty = operand_ty.unionTagType(mod) orelse {
1140411347 const msg = msg: {
1140511348 const msg = try sema.errMsg(src, "switch on union with no attached enum", .{});
......@@ -13691,7 +13634,7 @@ fn maybeErrorUnwrap(
1369113634 return true;
1369213635 }
1369313636
13694 const panic_fn = try sema.getBuiltin("panicUnwrapError");
13637 const panic_fn = try mod.getBuiltin("panicUnwrapError");
1369513638 const err_return_trace = try sema.getErrorReturnTrace(block);
1369613639 const args: [2]Air.Inst.Ref = .{ err_return_trace, operand };
1369713640 try sema.callBuiltin(block, operand_src, panic_fn, .auto, &args, .@"safety check");
......@@ -13701,7 +13644,7 @@ fn maybeErrorUnwrap(
1370113644 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1370213645 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");
1370513648 const err_return_trace = try sema.getErrorReturnTrace(block);
1370613649 const args: [3]Air.Inst.Ref = .{ msg_inst, err_return_trace, .null_value };
1370713650 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
1376613709 const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, .{
1376713710 .needed_comptime_reason = "field name must be comptime-known",
1376813711 });
13769 try sema.resolveTypeFields(ty);
13712 try ty.resolveFields(mod);
1377013713 const ip = &mod.intern_pool;
1377113714
1377213715 const has_field = hf: {
......@@ -13946,7 +13889,7 @@ fn zirShl(
1394613889 return mod.undefRef(sema.typeOf(lhs));
1394713890 }
1394813891 // 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)) {
1395013893 return lhs;
1395113894 }
1395213895 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt and air_tag != .shl_sat) {
......@@ -14111,7 +14054,7 @@ fn zirShr(
1411114054 return mod.undefRef(lhs_ty);
1411214055 }
1411314056 // 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)) {
1411514058 return lhs;
1411614059 }
1411714060 if (scalar_ty.zigTypeTag(mod) != .ComptimeInt) {
......@@ -14158,7 +14101,7 @@ fn zirShr(
1415814101 if (air_tag == .shr_exact) {
1415914102 // Detect if any ones would be shifted out.
1416014103 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))) {
1416214105 return sema.fail(block, src, "exact shift shifted out 1 bits", .{});
1416314106 }
1416414107 }
......@@ -14582,12 +14525,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1458214525 try sema.requireRuntimeBlock(block, src, runtime_src);
1458314526
1458414527 if (ptr_addrspace) |ptr_as| {
14585 const alloc_ty = try sema.ptrType(.{
14528 const alloc_ty = try mod.ptrTypeSema(.{
1458614529 .child = result_ty.toIntern(),
1458714530 .flags = .{ .address_space = ptr_as },
1458814531 });
1458914532 const alloc = try block.addTy(.alloc, alloc_ty);
14590 const elem_ptr_ty = try sema.ptrType(.{
14533 const elem_ptr_ty = try mod.ptrTypeSema(.{
1459114534 .child = resolved_elem_ty.toIntern(),
1459214535 .flags = .{ .address_space = ptr_as },
1459314536 });
......@@ -14670,7 +14613,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins
1467014613 .none => null,
1467114614 else => Value.fromInterned(ptr_info.sentinel),
1467214615 },
14673 .len = try val.sliceLen(sema),
14616 .len = try val.sliceLen(mod),
1467414617 };
1467514618 },
1467614619 .One => {
......@@ -14912,12 +14855,12 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1491214855 }
1491314856
1491414857 if (ptr_addrspace) |ptr_as| {
14915 const alloc_ty = try sema.ptrType(.{
14858 const alloc_ty = try mod.ptrTypeSema(.{
1491614859 .child = result_ty.toIntern(),
1491714860 .flags = .{ .address_space = ptr_as },
1491814861 });
1491914862 const alloc = try block.addTy(.alloc, alloc_ty);
14920 const elem_ptr_ty = try sema.ptrType(.{
14863 const elem_ptr_ty = try mod.ptrTypeSema(.{
1492114864 .child = lhs_info.elem_type.toIntern(),
1492214865 .flags = .{ .address_space = ptr_as },
1492314866 });
......@@ -15105,7 +15048,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1510515048 .Int, .ComptimeInt, .ComptimeFloat => {
1510615049 if (maybe_lhs_val) |lhs_val| {
1510715050 if (!lhs_val.isUndef(mod)) {
15108 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
15051 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1510915052 const scalar_zero = switch (scalar_tag) {
1511015053 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1511115054 .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
1512015063 if (rhs_val.isUndef(mod)) {
1512115064 return sema.failWithUseOfUndef(block, rhs_src);
1512215065 }
15123 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15066 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1512415067 return sema.failWithDivideByZero(block, rhs_src);
1512515068 }
1512615069 // 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
1524115184 if (lhs_val.isUndef(mod)) {
1524215185 return sema.failWithUseOfUndef(block, rhs_src);
1524315186 } else {
15244 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
15187 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1524515188 const scalar_zero = switch (scalar_tag) {
1524615189 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1524715190 .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
1525615199 if (rhs_val.isUndef(mod)) {
1525715200 return sema.failWithUseOfUndef(block, rhs_src);
1525815201 }
15259 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15202 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1526015203 return sema.failWithDivideByZero(block, rhs_src);
1526115204 }
1526215205 // 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
1540815351 // If the lhs is undefined, result is undefined.
1540915352 if (maybe_lhs_val) |lhs_val| {
1541015353 if (!lhs_val.isUndef(mod)) {
15411 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
15354 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1541215355 const scalar_zero = switch (scalar_tag) {
1541315356 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1541415357 .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
1542315366 if (rhs_val.isUndef(mod)) {
1542415367 return sema.failWithUseOfUndef(block, rhs_src);
1542515368 }
15426 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15369 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1542715370 return sema.failWithDivideByZero(block, rhs_src);
1542815371 }
1542915372 // 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
1551815461 // If the lhs is undefined, result is undefined.
1551915462 if (maybe_lhs_val) |lhs_val| {
1552015463 if (!lhs_val.isUndef(mod)) {
15521 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
15464 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1552215465 const scalar_zero = switch (scalar_tag) {
1552315466 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1552415467 .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
1553315476 if (rhs_val.isUndef(mod)) {
1553415477 return sema.failWithUseOfUndef(block, rhs_src);
1553515478 }
15536 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15479 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1553715480 return sema.failWithDivideByZero(block, rhs_src);
1553815481 }
1553915482 }
......@@ -15758,7 +15701,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1575815701 if (lhs_val.isUndef(mod)) {
1575915702 return sema.failWithUseOfUndef(block, lhs_src);
1576015703 }
15761 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
15704 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1576215705 const scalar_zero = switch (scalar_tag) {
1576315706 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1576415707 .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.
1577715720 if (rhs_val.isUndef(mod)) {
1577815721 return sema.failWithUseOfUndef(block, rhs_src);
1577915722 }
15780 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15723 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1578115724 return sema.failWithDivideByZero(block, rhs_src);
1578215725 }
15783 if (!(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))) {
15726 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {
1578415727 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
1578515728 }
1578615729 if (maybe_lhs_val) |lhs_val| {
1578715730 const rem_result = try sema.intRem(resolved_type, lhs_val, rhs_val);
1578815731 // If this answer could possibly be different by doing `intMod`,
1578915732 // we must emit a compile error. Otherwise, it's OK.
15790 if (!(try lhs_val.compareAllWithZeroAdvanced(.gte, sema)) and
15791 !(try rem_result.compareAllWithZeroAdvanced(.eq, sema)))
15733 if (!(try lhs_val.compareAllWithZeroSema(.gte, mod)) and
15734 !(try rem_result.compareAllWithZeroSema(.eq, mod)))
1579215735 {
1579315736 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
1579415737 }
......@@ -15806,14 +15749,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1580615749 if (rhs_val.isUndef(mod)) {
1580715750 return sema.failWithUseOfUndef(block, rhs_src);
1580815751 }
15809 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15752 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1581015753 return sema.failWithDivideByZero(block, rhs_src);
1581115754 }
15812 if (!(try rhs_val.compareAllWithZeroAdvanced(.gte, sema))) {
15755 if (!(try rhs_val.compareAllWithZeroSema(.gte, mod))) {
1581315756 return sema.failWithModRemNegative(block, rhs_src, lhs_ty, rhs_ty);
1581415757 }
1581515758 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))) {
1581715760 return sema.failWithModRemNegative(block, lhs_src, lhs_ty, rhs_ty);
1581815761 }
1581915762 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
1586415807 // resorting to BigInt first.
1586515808 var lhs_space: Value.BigIntSpace = undefined;
1586615809 var rhs_space: Value.BigIntSpace = undefined;
15867 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
15868 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
15810 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
15811 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
1586915812 const limbs_q = try sema.arena.alloc(
1587015813 math.big.Limb,
1587115814 lhs_bigint.limbs.len,
......@@ -15941,7 +15884,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1594115884 if (rhs_val.isUndef(mod)) {
1594215885 return sema.failWithUseOfUndef(block, rhs_src);
1594315886 }
15944 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15887 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1594515888 return sema.failWithDivideByZero(block, rhs_src);
1594615889 }
1594715890 if (maybe_lhs_val) |lhs_val| {
......@@ -15957,7 +15900,7 @@ fn zirMod(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1595715900 if (rhs_val.isUndef(mod)) {
1595815901 return sema.failWithUseOfUndef(block, rhs_src);
1595915902 }
15960 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15903 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1596115904 return sema.failWithDivideByZero(block, rhs_src);
1596215905 }
1596315906 }
......@@ -16036,7 +15979,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1603615979 if (rhs_val.isUndef(mod)) {
1603715980 return sema.failWithUseOfUndef(block, rhs_src);
1603815981 }
16039 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15982 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1604015983 return sema.failWithDivideByZero(block, rhs_src);
1604115984 }
1604215985 if (maybe_lhs_val) |lhs_val| {
......@@ -16052,7 +15995,7 @@ fn zirRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1605215995 if (rhs_val.isUndef(mod)) {
1605315996 return sema.failWithUseOfUndef(block, rhs_src);
1605415997 }
16055 if (!(try rhs_val.compareAllWithZeroAdvanced(.neq, sema))) {
15998 if (!(try rhs_val.compareAllWithZeroSema(.neq, mod))) {
1605615999 return sema.failWithDivideByZero(block, rhs_src);
1605716000 }
1605816001 }
......@@ -16139,12 +16082,12 @@ fn zirOverflowArithmetic(
1613916082 // to the result, even if it is undefined..
1614016083 // Otherwise, if either of the argument is undefined, undefined is returned.
1614116084 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))) {
1614316086 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
1614416087 }
1614516088 }
1614616089 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))) {
1614816091 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1614916092 }
1615016093 }
......@@ -16165,7 +16108,7 @@ fn zirOverflowArithmetic(
1616516108 if (maybe_rhs_val) |rhs_val| {
1616616109 if (rhs_val.isUndef(mod)) {
1616716110 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)) {
1616916112 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1617016113 } else if (maybe_lhs_val) |lhs_val| {
1617116114 if (lhs_val.isUndef(mod)) {
......@@ -16184,7 +16127,7 @@ fn zirOverflowArithmetic(
1618416127 const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1);
1618516128 if (maybe_lhs_val) |lhs_val| {
1618616129 if (!lhs_val.isUndef(mod)) {
16187 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16130 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1618816131 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1618916132 } else if (try sema.compareAll(lhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
1619016133 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
......@@ -16194,7 +16137,7 @@ fn zirOverflowArithmetic(
1619416137
1619516138 if (maybe_rhs_val) |rhs_val| {
1619616139 if (!rhs_val.isUndef(mod)) {
16197 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16140 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1619816141 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = rhs };
1619916142 } else if (try sema.compareAll(rhs_val, .eq, try sema.splat(dest_ty, scalar_one), dest_ty)) {
1620016143 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
......@@ -16218,12 +16161,12 @@ fn zirOverflowArithmetic(
1621816161 // If rhs is zero, the result is lhs (even if undefined) and no overflow occurred.
1621916162 // Oterhwise if either of the arguments is undefined, both results are undefined.
1622016163 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))) {
1622216165 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1622316166 }
1622416167 }
1622516168 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))) {
1622716170 break :result .{ .overflow_bit = try sema.splat(overflow_ty, zero_bit), .inst = lhs };
1622816171 }
1622916172 }
......@@ -16374,7 +16317,7 @@ fn analyzeArithmetic(
1637416317 // overflow (max_int), causing illegal behavior.
1637516318 // For floats: either operand being undef makes the result undef.
1637616319 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))) {
1637816321 return casted_rhs;
1637916322 }
1638016323 }
......@@ -16386,7 +16329,7 @@ fn analyzeArithmetic(
1638616329 return mod.undefRef(resolved_type);
1638716330 }
1638816331 }
16389 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16332 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1639016333 return casted_lhs;
1639116334 }
1639216335 }
......@@ -16418,7 +16361,7 @@ fn analyzeArithmetic(
1641816361 // If either of the operands are zero, the other operand is returned.
1641916362 // If either of the operands are undefined, the result is undefined.
1642016363 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))) {
1642216365 return casted_rhs;
1642316366 }
1642416367 }
......@@ -16426,7 +16369,7 @@ fn analyzeArithmetic(
1642616369 if (rhs_val.isUndef(mod)) {
1642716370 return mod.undefRef(resolved_type);
1642816371 }
16429 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16372 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1643016373 return casted_lhs;
1643116374 }
1643216375 if (maybe_lhs_val) |lhs_val| {
......@@ -16439,7 +16382,7 @@ fn analyzeArithmetic(
1643916382 // If either of the operands are zero, then the other operand is returned.
1644016383 // If either of the operands are undefined, the result is undefined.
1644116384 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))) {
1644316386 return casted_rhs;
1644416387 }
1644516388 }
......@@ -16447,7 +16390,7 @@ fn analyzeArithmetic(
1644716390 if (rhs_val.isUndef(mod)) {
1644816391 return mod.undefRef(resolved_type);
1644916392 }
16450 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16393 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1645116394 return casted_lhs;
1645216395 }
1645316396 if (maybe_lhs_val) |lhs_val| {
......@@ -16488,7 +16431,7 @@ fn analyzeArithmetic(
1648816431 return mod.undefRef(resolved_type);
1648916432 }
1649016433 }
16491 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16434 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1649216435 return casted_lhs;
1649316436 }
1649416437 }
......@@ -16523,7 +16466,7 @@ fn analyzeArithmetic(
1652316466 if (rhs_val.isUndef(mod)) {
1652416467 return mod.undefRef(resolved_type);
1652516468 }
16526 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16469 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1652716470 return casted_lhs;
1652816471 }
1652916472 }
......@@ -16544,7 +16487,7 @@ fn analyzeArithmetic(
1654416487 if (rhs_val.isUndef(mod)) {
1654516488 return mod.undefRef(resolved_type);
1654616489 }
16547 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16490 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1654816491 return casted_lhs;
1654916492 }
1655016493 }
......@@ -16591,7 +16534,7 @@ fn analyzeArithmetic(
1659116534 if (lhs_val.isNan(mod)) {
1659216535 return Air.internedToRef(lhs_val.toIntern());
1659316536 }
16594 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) lz: {
16537 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) lz: {
1659516538 if (maybe_rhs_val) |rhs_val| {
1659616539 if (rhs_val.isNan(mod)) {
1659716540 return Air.internedToRef(rhs_val.toIntern());
......@@ -16622,7 +16565,7 @@ fn analyzeArithmetic(
1662216565 if (rhs_val.isNan(mod)) {
1662316566 return Air.internedToRef(rhs_val.toIntern());
1662416567 }
16625 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) rz: {
16568 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) rz: {
1662616569 if (maybe_lhs_val) |lhs_val| {
1662716570 if (lhs_val.isInf(mod)) {
1662816571 return Air.internedToRef((try mod.floatValue(resolved_type, std.math.nan(f128))).toIntern());
......@@ -16674,7 +16617,7 @@ fn analyzeArithmetic(
1667416617 };
1667516618 if (maybe_lhs_val) |lhs_val| {
1667616619 if (!lhs_val.isUndef(mod)) {
16677 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16620 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1667816621 const zero_val = try sema.splat(resolved_type, scalar_zero);
1667916622 return Air.internedToRef(zero_val.toIntern());
1668016623 }
......@@ -16687,7 +16630,7 @@ fn analyzeArithmetic(
1668716630 if (rhs_val.isUndef(mod)) {
1668816631 return mod.undefRef(resolved_type);
1668916632 }
16690 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16633 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1669116634 const zero_val = try sema.splat(resolved_type, scalar_zero);
1669216635 return Air.internedToRef(zero_val.toIntern());
1669316636 }
......@@ -16719,7 +16662,7 @@ fn analyzeArithmetic(
1671916662 };
1672016663 if (maybe_lhs_val) |lhs_val| {
1672116664 if (!lhs_val.isUndef(mod)) {
16722 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16665 if (try lhs_val.compareAllWithZeroSema(.eq, mod)) {
1672316666 const zero_val = try sema.splat(resolved_type, scalar_zero);
1672416667 return Air.internedToRef(zero_val.toIntern());
1672516668 }
......@@ -16732,7 +16675,7 @@ fn analyzeArithmetic(
1673216675 if (rhs_val.isUndef(mod)) {
1673316676 return mod.undefRef(resolved_type);
1673416677 }
16735 if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
16678 if (try rhs_val.compareAllWithZeroSema(.eq, mod)) {
1673616679 const zero_val = try sema.splat(resolved_type, scalar_zero);
1673716680 return Air.internedToRef(zero_val.toIntern());
1673816681 }
......@@ -16828,7 +16771,7 @@ fn analyzePtrArithmetic(
1682816771
1682916772 const new_ptr_ty = t: {
1683016773 // Calculate the new pointer alignment.
16831 // This code is duplicated in `elemPtrType`.
16774 // This code is duplicated in `Type.elemPtrType`.
1683216775 if (ptr_info.flags.alignment == .none) {
1683316776 // ABI-aligned pointer. Any pointer arithmetic maintains the same ABI-alignedness.
1683416777 break :t ptr_ty;
......@@ -16837,7 +16780,7 @@ fn analyzePtrArithmetic(
1683716780 // it being a multiple of the type size.
1683816781 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));
1683916782 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));
1684116784 break :a elem_size * off_int;
1684216785 } else elem_size;
1684316786
......@@ -16850,7 +16793,7 @@ fn analyzePtrArithmetic(
1685016793 ));
1685116794 assert(new_align != .none);
1685216795
16853 break :t try sema.ptrType(.{
16796 break :t try mod.ptrTypeSema(.{
1685416797 .child = ptr_info.child,
1685516798 .sentinel = ptr_info.sentinel,
1685616799 .flags = .{
......@@ -16869,14 +16812,14 @@ fn analyzePtrArithmetic(
1686916812 if (opt_off_val) |offset_val| {
1687016813 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));
1687316816 if (offset_int == 0) return ptr;
1687416817 if (air_tag == .ptr_sub) {
1687516818 const elem_size = try sema.typeAbiSize(Type.fromInterned(ptr_info.child));
1687616819 const new_ptr_val = try sema.ptrSubtract(block, op_src, ptr_val, offset_int * elem_size, new_ptr_ty);
1687716820 return Air.internedToRef(new_ptr_val.toIntern());
1687816821 } 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);
1688016823 return Air.internedToRef(new_ptr_val.toIntern());
1688116824 }
1688216825 } else break :rs offset_src;
......@@ -16975,7 +16918,6 @@ fn zirAsm(
1697516918 // Indicate the output is the asm instruction return value.
1697616919 arg.* = .none;
1697716920 const out_ty = try sema.resolveType(block, ret_ty_src, output.data.operand);
16978 try sema.queueFullTypeResolution(out_ty);
1697916921 expr_ty = Air.internedToRef(out_ty.toIntern());
1698016922 } else {
1698116923 arg.* = try sema.resolveInst(output.data.operand);
......@@ -17010,7 +16952,6 @@ fn zirAsm(
1701016952 .ComptimeFloat => arg.* = try sema.coerce(block, Type.f64, uncasted_arg, src),
1701116953 else => {
1701216954 arg.* = uncasted_arg;
17013 try sema.queueFullTypeResolution(uncasted_arg_ty);
1701416955 },
1701516956 }
1701616957
......@@ -17169,7 +17110,7 @@ fn analyzeCmpUnionTag(
1716917110) CompileError!Air.Inst.Ref {
1717017111 const mod = sema.mod;
1717117112 const union_ty = sema.typeOf(un);
17172 try sema.resolveTypeFields(union_ty);
17113 try union_ty.resolveFields(mod);
1717317114 const union_tag_ty = union_ty.unionTagType(mod) orelse {
1717417115 const msg = msg: {
1717517116 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.
1738517326 => {},
1738617327 }
1738717328 const val = try ty.lazyAbiSize(mod);
17388 if (val.isLazySize(mod)) {
17389 try sema.queueFullTypeResolution(ty);
17390 }
1739117329 return Air.internedToRef(val.toIntern());
1739217330}
1739317331
......@@ -17427,7 +17365,7 @@ fn zirBitSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1742717365 .AnyFrame,
1742817366 => {},
1742917367 }
17430 const bit_size = try operand_ty.bitSizeAdvanced(mod, sema);
17368 const bit_size = try operand_ty.bitSizeAdvanced(mod, .sema);
1743117369 return mod.intRef(Type.comptime_int, bit_size);
1743217370}
1743317371
......@@ -17613,7 +17551,7 @@ fn zirBuiltinSrc(
1761317551 } });
1761417552 };
1761517553
17616 const src_loc_ty = try sema.getBuiltinType("SourceLocation");
17554 const src_loc_ty = try mod.getBuiltinType("SourceLocation");
1761717555 const fields = .{
1761817556 // file: [:0]const u8,
1761917557 file_name_val,
......@@ -17637,7 +17575,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1763717575 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
1763817576 const src = block.nodeOffset(inst_data.src_node);
1763917577 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");
1764117579 const type_info_tag_ty = type_info_ty.unionTagType(mod).?;
1764217580
1764317581 if (ty.typeDeclInst(mod)) |type_decl_inst| {
......@@ -17718,7 +17656,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1771817656 .ty = new_decl_ty.toIntern(),
1771917657 .storage = .{ .elems = param_vals },
1772017658 } });
17721 const slice_ty = (try sema.ptrType(.{
17659 const slice_ty = (try mod.ptrTypeSema(.{
1772217660 .child = param_info_ty.toIntern(),
1772317661 .flags = .{
1772417662 .size = .Slice,
......@@ -17748,7 +17686,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1774817686 func_ty_info.return_type,
1774917687 } });
1775017688
17751 const callconv_ty = try sema.getBuiltinType("CallingConvention");
17689 const callconv_ty = try mod.getBuiltinType("CallingConvention");
1775217690
1775317691 const field_values = .{
1775417692 // calling_convention: CallingConvention,
......@@ -17782,7 +17720,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1778217720 const int_info_decl = mod.declPtr(int_info_decl_index);
1778317721 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");
1778617724 const info = ty.intInfo(mod);
1778717725 const field_values = .{
1778817726 // signedness: Signedness,
......@@ -17830,12 +17768,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1783017768 else
1783117769 try Type.fromInterned(info.child).lazyAbiAlignment(mod);
1783217770
17833 const addrspace_ty = try sema.getBuiltinType("AddressSpace");
17771 const addrspace_ty = try mod.getBuiltinType("AddressSpace");
1783417772 const pointer_ty = t: {
1783517773 const decl_index = (try sema.namespaceLookup(
1783617774 block,
1783717775 src,
17838 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod),
17776 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),
1783917777 try ip.getOrPutString(gpa, "Pointer", .no_embedded_nulls),
1784017778 )).?;
1784117779 try sema.ensureDeclAnalyzed(decl_index);
......@@ -17984,8 +17922,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1798417922 break :t set_field_ty_decl.val.toType();
1798517923 };
1798617924
17987 try sema.queueFullTypeResolution(error_field_ty);
17988
1798917925 // Build our list of Error values
1799017926 // Optional value is only null if anyerror
1799117927 // Value can be zero-length slice otherwise
......@@ -18036,7 +17972,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1803617972 };
1803717973
1803817974 // Build our ?[]const Error value
18039 const slice_errors_ty = try sema.ptrType(.{
17975 const slice_errors_ty = try mod.ptrTypeSema(.{
1804017976 .child = error_field_ty.toIntern(),
1804117977 .flags = .{
1804217978 .size = .Slice,
......@@ -18182,7 +18118,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1818218118 .ty = fields_array_ty.toIntern(),
1818318119 .storage = .{ .elems = enum_field_vals },
1818418120 } });
18185 const slice_ty = (try sema.ptrType(.{
18121 const slice_ty = (try mod.ptrTypeSema(.{
1818618122 .child = enum_field_ty.toIntern(),
1818718123 .flags = .{
1818818124 .size = .Slice,
......@@ -18262,7 +18198,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1826218198 break :t union_field_ty_decl.val.toType();
1826318199 };
1826418200
18265 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
18201 try ty.resolveLayout(mod); // Getting alignment requires type layout
1826618202 const union_obj = mod.typeToUnion(ty).?;
1826718203 const tag_type = union_obj.loadTagType(ip);
1826818204 const layout = union_obj.getLayout(ip);
......@@ -18298,7 +18234,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1829818234 };
1829918235
1830018236 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),
1830218238 .@"packed" => .none,
1830318239 };
1830418240
......@@ -18326,7 +18262,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1832618262 .ty = array_fields_ty.toIntern(),
1832718263 .storage = .{ .elems = union_field_vals },
1832818264 } });
18329 const slice_ty = (try sema.ptrType(.{
18265 const slice_ty = (try mod.ptrTypeSema(.{
1833018266 .child = union_field_ty.toIntern(),
1833118267 .flags = .{
1833218268 .size = .Slice,
......@@ -18359,7 +18295,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1835918295 const decl_index = (try sema.namespaceLookup(
1836018296 block,
1836118297 src,
18362 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod),
18298 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),
1836318299 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
1836418300 )).?;
1836518301 try sema.ensureDeclAnalyzed(decl_index);
......@@ -18412,7 +18348,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1841218348 break :t struct_field_ty_decl.val.toType();
1841318349 };
1841418350
18415 try sema.resolveTypeLayout(ty); // Getting alignment requires type layout
18351 try ty.resolveLayout(mod); // Getting alignment requires type layout
1841618352
1841718353 var struct_field_vals: []InternPool.Index = &.{};
1841818354 defer gpa.free(struct_field_vals);
......@@ -18452,7 +18388,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1845218388 } });
1845318389 };
1845418390
18455 try sema.resolveTypeLayout(Type.fromInterned(field_ty));
18391 try Type.fromInterned(field_ty).resolveLayout(mod);
1845618392
1845718393 const is_comptime = field_val != .none;
1845818394 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
1848118417 };
1848218418 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
1848618422 for (struct_field_vals, 0..) |*field_val, field_index| {
1848718423 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
1852018456 const default_val_ptr = try sema.optRefValue(opt_default_val);
1852118457 const alignment = switch (struct_type.layout) {
1852218458 .@"packed" => .none,
18523 else => try sema.structFieldAlignment(
18459 else => try mod.structFieldAlignmentAdvanced(
1852418460 struct_type.fieldAlign(ip, field_index),
1852518461 field_ty,
1852618462 struct_type.layout,
18463 .sema,
1852718464 ),
1852818465 };
1852918466
......@@ -18555,7 +18492,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1855518492 .ty = array_fields_ty.toIntern(),
1855618493 .storage = .{ .elems = struct_field_vals },
1855718494 } });
18558 const slice_ty = (try sema.ptrType(.{
18495 const slice_ty = (try mod.ptrTypeSema(.{
1855918496 .child = struct_field_ty.toIntern(),
1856018497 .flags = .{
1856118498 .size = .Slice,
......@@ -18591,7 +18528,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1859118528 const decl_index = (try sema.namespaceLookup(
1859218529 block,
1859318530 src,
18594 (try sema.getBuiltinType("Type")).getNamespaceIndex(mod),
18531 (try mod.getBuiltinType("Type")).getNamespaceIndex(mod),
1859518532 try ip.getOrPutString(gpa, "ContainerLayout", .no_embedded_nulls),
1859618533 )).?;
1859718534 try sema.ensureDeclAnalyzed(decl_index);
......@@ -18635,7 +18572,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1863518572 break :t type_opaque_ty_decl.val.toType();
1863618573 };
1863718574
18638 try sema.resolveTypeFields(ty);
18575 try ty.resolveFields(mod);
1863918576 const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod));
1864018577
1864118578 const field_values = .{
......@@ -18677,7 +18614,6 @@ fn typeInfoDecls(
1867718614 const declaration_ty_decl = mod.declPtr(declaration_ty_decl_index);
1867818615 break :t declaration_ty_decl.val.toType();
1867918616 };
18680 try sema.queueFullTypeResolution(declaration_ty);
1868118617
1868218618 var decl_vals = std.ArrayList(InternPool.Index).init(gpa);
1868318619 defer decl_vals.deinit();
......@@ -18695,7 +18631,7 @@ fn typeInfoDecls(
1869518631 .ty = array_decl_ty.toIntern(),
1869618632 .storage = .{ .elems = decl_vals.items },
1869718633 } });
18698 const slice_ty = (try sema.ptrType(.{
18634 const slice_ty = (try mod.ptrTypeSema(.{
1869918635 .child = declaration_ty.toIntern(),
1870018636 .flags = .{
1870118637 .size = .Slice,
......@@ -19295,7 +19231,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr
1929519231
1929619232 const operand_ty = sema.typeOf(operand);
1929719233 const ptr_info = operand_ty.ptrInfo(mod);
19298 const res_ty = try sema.ptrType(.{
19234 const res_ty = try mod.ptrTypeSema(.{
1929919235 .child = err_union_ty.errorUnionPayload(mod).toIntern(),
1930019236 .flags = .{
1930119237 .is_const = ptr_info.flags.is_const,
......@@ -19528,11 +19464,11 @@ fn retWithErrTracing(
1952819464 else => true,
1952919465 };
1953019466 const gpa = sema.gpa;
19531 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
19532 try sema.resolveTypeFields(stack_trace_ty);
19467 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
19468 try stack_trace_ty.resolveFields(mod);
1953319469 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
1953419470 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");
1953619472 const args: [1]Air.Inst.Ref = .{err_return_trace};
1953719473
1953819474 if (!need_check) {
......@@ -19735,7 +19671,7 @@ fn analyzeRet(
1973519671 return sema.failWithOwnedErrorMsg(block, msg);
1973619672 }
1973719673
19738 try sema.resolveTypeLayout(sema.fn_ret_ty);
19674 try sema.fn_ret_ty.resolveLayout(mod);
1973919675
1974019676 try sema.validateRuntimeValue(block, operand_src, operand);
1974119677
......@@ -19817,7 +19753,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1981719753 },
1981819754 else => {},
1981919755 }
19820 const align_bytes = (try val.getUnsignedIntAdvanced(mod, sema)).?;
19756 const align_bytes = (try val.getUnsignedIntAdvanced(mod, .sema)).?;
1982119757 break :blk try sema.validateAlignAllowZero(block, align_src, align_bytes);
1982219758 } else .none;
1982319759
......@@ -19851,7 +19787,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1985119787 elem_ty.fmt(mod), bit_offset, bit_offset - host_size * 8, host_size,
1985219788 });
1985319789 }
19854 const elem_bit_size = try elem_ty.bitSizeAdvanced(mod, sema);
19790 const elem_bit_size = try elem_ty.bitSizeAdvanced(mod, .sema);
1985519791 if (elem_bit_size > host_size * 8 - bit_offset) {
1985619792 return sema.fail(block, bitoffset_src, "packed type '{}' at bit offset {} ends {} bits after the end of a {} byte host integer", .{
1985719793 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
1989219828 });
1989319829 }
1989419830
19895 const ty = try sema.ptrType(.{
19831 const ty = try mod.ptrTypeSema(.{
1989619832 .child = elem_ty.toIntern(),
1989719833 .sentinel = sentinel,
1989819834 .flags = .{
......@@ -19983,7 +19919,7 @@ fn structInitEmpty(
1998319919 const mod = sema.mod;
1998419920 const gpa = sema.gpa;
1998519921 // This logic must be synchronized with that in `zirStructInit`.
19986 try sema.resolveTypeFields(struct_ty);
19922 try struct_ty.resolveFields(mod);
1998719923
1998819924 // The init values to use for the struct instance.
1998919925 const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod));
......@@ -20054,7 +19990,6 @@ fn unionInit(
2005419990
2005519991 try sema.requireRuntimeBlock(block, init_src, null);
2005619992 _ = union_ty_src;
20057 try sema.queueFullTypeResolution(union_ty);
2005819993 return block.addUnionInit(union_ty, field_index, init);
2005919994}
2006019995
......@@ -20083,7 +20018,7 @@ fn zirStructInit(
2008320018 else => |e| return e,
2008420019 };
2008520020 const resolved_ty = result_ty.optEuBaseType(mod);
20086 try sema.resolveTypeLayout(resolved_ty);
20021 try resolved_ty.resolveLayout(mod);
2008720022
2008820023 if (resolved_ty.zigTypeTag(mod) == .Struct) {
2008920024 // This logic must be synchronized with that in `zirStructInitEmpty`.
......@@ -20124,7 +20059,7 @@ fn zirStructInit(
2012420059 const field_ty = resolved_ty.structFieldType(field_index, mod);
2012520060 field_inits[field_index] = try sema.coerce(block, field_ty, uncoerced_init, field_src);
2012620061 if (!is_packed) {
20127 try sema.resolveStructFieldInits(resolved_ty);
20062 try resolved_ty.resolveStructFieldInits(mod);
2012820063 if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| {
2012920064 const init_val = (try sema.resolveValue(field_inits[field_index])) orelse {
2013020065 return sema.failWithNeededComptime(block, field_src, .{
......@@ -20197,7 +20132,7 @@ fn zirStructInit(
2019720132
2019820133 if (is_ref) {
2019920134 const target = mod.getTarget();
20200 const alloc_ty = try sema.ptrType(.{
20135 const alloc_ty = try mod.ptrTypeSema(.{
2020120136 .child = result_ty.toIntern(),
2020220137 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2020320138 });
......@@ -20211,7 +20146,6 @@ fn zirStructInit(
2021120146 }
2021220147
2021320148 try sema.requireRuntimeBlock(block, src, null);
20214 try sema.queueFullTypeResolution(resolved_ty);
2021520149 const union_val = try block.addUnionInit(resolved_ty, field_index, init_inst);
2021620150 return sema.coerce(block, result_ty, union_val, src);
2021720151 }
......@@ -20288,7 +20222,7 @@ fn finishStructInit(
2028820222 continue;
2028920223 }
2029020224
20291 try sema.resolveStructFieldInits(struct_ty);
20225 try struct_ty.resolveStructFieldInits(mod);
2029220226
2029320227 const field_init = struct_type.fieldInit(ip, i);
2029420228 if (field_init == .none) {
......@@ -20358,9 +20292,9 @@ fn finishStructInit(
2035820292 }
2035920293
2036020294 if (is_ref) {
20361 try sema.resolveStructLayout(struct_ty);
20295 try struct_ty.resolveLayout(mod);
2036220296 const target = sema.mod.getTarget();
20363 const alloc_ty = try sema.ptrType(.{
20297 const alloc_ty = try mod.ptrTypeSema(.{
2036420298 .child = result_ty.toIntern(),
2036520299 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2036620300 });
......@@ -20380,8 +20314,7 @@ fn finishStructInit(
2038020314 .init_node_offset = init_src.offset.node_offset.x,
2038120315 .elem_index = @intCast(runtime_index),
2038220316 } }));
20383 try sema.resolveStructFieldInits(struct_ty);
20384 try sema.queueFullTypeResolution(struct_ty);
20317 try struct_ty.resolveStructFieldInits(mod);
2038520318 const struct_val = try block.addAggregateInit(struct_ty, field_inits);
2038620319 return sema.coerce(block, result_ty, struct_val, init_src);
2038720320}
......@@ -20490,7 +20423,7 @@ fn structInitAnon(
2049020423
2049120424 if (is_ref) {
2049220425 const target = mod.getTarget();
20493 const alloc_ty = try sema.ptrType(.{
20426 const alloc_ty = try mod.ptrTypeSema(.{
2049420427 .child = tuple_ty,
2049520428 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2049620429 });
......@@ -20504,7 +20437,7 @@ fn structInitAnon(
2050420437 };
2050520438 extra_index = item.end;
2050620439
20507 const field_ptr_ty = try sema.ptrType(.{
20440 const field_ptr_ty = try mod.ptrTypeSema(.{
2050820441 .child = field_ty,
2050920442 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2051020443 });
......@@ -20597,7 +20530,7 @@ fn zirArrayInit(
2059720530 dest.* = try sema.coerce(block, elem_ty, resolved_arg, elem_src);
2059820531 if (is_tuple) {
2059920532 if (array_ty.structFieldIsComptime(i, mod))
20600 try sema.resolveStructFieldInits(array_ty);
20533 try array_ty.resolveStructFieldInits(mod);
2060120534 if (try array_ty.structFieldValueComptime(mod, i)) |field_val| {
2060220535 const init_val = try sema.resolveValue(dest.*) orelse {
2060320536 return sema.failWithNeededComptime(block, elem_src, .{
......@@ -20641,11 +20574,10 @@ fn zirArrayInit(
2064120574 .init_node_offset = src.offset.node_offset.x,
2064220575 .elem_index = runtime_index,
2064320576 } }));
20644 try sema.queueFullTypeResolution(array_ty);
2064520577
2064620578 if (is_ref) {
2064720579 const target = mod.getTarget();
20648 const alloc_ty = try sema.ptrType(.{
20580 const alloc_ty = try mod.ptrTypeSema(.{
2064920581 .child = result_ty.toIntern(),
2065020582 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2065120583 });
......@@ -20654,7 +20586,7 @@ fn zirArrayInit(
2065420586
2065520587 if (is_tuple) {
2065620588 for (resolved_args, 0..) |arg, i| {
20657 const elem_ptr_ty = try sema.ptrType(.{
20589 const elem_ptr_ty = try mod.ptrTypeSema(.{
2065820590 .child = array_ty.structFieldType(i, mod).toIntern(),
2065920591 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2066020592 });
......@@ -20667,7 +20599,7 @@ fn zirArrayInit(
2066720599 return sema.makePtrConst(block, alloc);
2066820600 }
2066920601
20670 const elem_ptr_ty = try sema.ptrType(.{
20602 const elem_ptr_ty = try mod.ptrTypeSema(.{
2067120603 .child = array_ty.elemType2(mod).toIntern(),
2067220604 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2067320605 });
......@@ -20755,14 +20687,14 @@ fn arrayInitAnon(
2075520687
2075620688 if (is_ref) {
2075720689 const target = sema.mod.getTarget();
20758 const alloc_ty = try sema.ptrType(.{
20690 const alloc_ty = try mod.ptrTypeSema(.{
2075920691 .child = tuple_ty,
2076020692 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2076120693 });
2076220694 const alloc = try block.addTy(.alloc, alloc_ty);
2076320695 for (operands, 0..) |operand, i_usize| {
2076420696 const i: u32 = @intCast(i_usize);
20765 const field_ptr_ty = try sema.ptrType(.{
20697 const field_ptr_ty = try mod.ptrTypeSema(.{
2076620698 .child = types[i],
2076720699 .flags = .{ .address_space = target_util.defaultAddressSpace(target, .local) },
2076820700 });
......@@ -20832,7 +20764,7 @@ fn fieldType(
2083220764 const ip = &mod.intern_pool;
2083320765 var cur_ty = aggregate_ty;
2083420766 while (true) {
20835 try sema.resolveTypeFields(cur_ty);
20767 try cur_ty.resolveFields(mod);
2083620768 switch (cur_ty.zigTypeTag(mod)) {
2083720769 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {
2083820770 .anon_struct_type => |anon_struct| {
......@@ -20883,8 +20815,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2088320815fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
2088420816 const mod = sema.mod;
2088520817 const ip = &mod.intern_pool;
20886 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
20887 try sema.resolveTypeFields(stack_trace_ty);
20818 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
20819 try stack_trace_ty.resolveFields(mod);
2088820820 const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty);
2088920821 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
2091820850 return sema.fail(block, operand_src, "no align available for type '{}'", .{ty.fmt(sema.mod)});
2091920851 }
2092020852 const val = try ty.lazyAbiAlignment(mod);
20921 if (val.isLazyAlign(mod)) {
20922 try sema.queueFullTypeResolution(ty);
20923 }
2092420853 return Air.internedToRef(val.toIntern());
2092520854}
2092620855
......@@ -21095,7 +21024,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2109521024 const mod = sema.mod;
2109621025 const ip = &mod.intern_pool;
2109721026
21098 try sema.resolveTypeLayout(operand_ty);
21027 try operand_ty.resolveLayout(mod);
2109921028 const enum_ty = switch (operand_ty.zigTypeTag(mod)) {
2110021029 .EnumLiteral => {
2110121030 const val = try sema.resolveConstDefinedValue(block, LazySrcLoc.unneeded, operand, undefined);
......@@ -21171,7 +21100,7 @@ fn zirReify(
2117121100 },
2117221101 },
2117321102 };
21174 const type_info_ty = try sema.getBuiltinType("Type");
21103 const type_info_ty = try mod.getBuiltinType("Type");
2117521104 const uncasted_operand = try sema.resolveInst(extra.operand);
2117621105 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
2117721106 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{
......@@ -21205,7 +21134,7 @@ fn zirReify(
2120521134 );
2120621135
2120721136 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));
2120921138 const ty = try mod.intType(signedness, bits);
2121021139 return Air.internedToRef(ty.toIntern());
2121121140 },
......@@ -21220,7 +21149,7 @@ fn zirReify(
2122021149 try ip.getOrPutString(gpa, "child", .no_embedded_nulls),
2122121150 ).?);
2122221151
21223 const len: u32 = @intCast(try len_val.toUnsignedIntAdvanced(sema));
21152 const len: u32 = @intCast(try len_val.toUnsignedIntSema(mod));
2122421153 const child_ty = child_val.toType();
2122521154
2122621155 try sema.checkVectorElemType(block, src, child_ty);
......@@ -21238,7 +21167,7 @@ fn zirReify(
2123821167 try ip.getOrPutString(gpa, "bits", .no_embedded_nulls),
2123921168 ).?);
2124021169
21241 const bits: u16 = @intCast(try bits_val.toUnsignedIntAdvanced(sema));
21170 const bits: u16 = @intCast(try bits_val.toUnsignedIntSema(mod));
2124221171 const ty = switch (bits) {
2124321172 16 => Type.f16,
2124421173 32 => Type.f32,
......@@ -21288,7 +21217,7 @@ fn zirReify(
2128821217 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
2128921218 }
2129021219
21291 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
21220 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, .sema)).?;
2129221221 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
2129321222 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
2129421223 }
......@@ -21296,7 +21225,7 @@ fn zirReify(
2129621225
2129721226 const elem_ty = child_val.toType();
2129821227 if (abi_align != .none) {
21299 try sema.resolveTypeLayout(elem_ty);
21228 try elem_ty.resolveLayout(mod);
2130021229 }
2130121230
2130221231 const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val);
......@@ -21340,7 +21269,7 @@ fn zirReify(
2134021269 }
2134121270 }
2134221271
21343 const ty = try sema.ptrType(.{
21272 const ty = try mod.ptrTypeSema(.{
2134421273 .child = elem_ty.toIntern(),
2134521274 .sentinel = actual_sentinel,
2134621275 .flags = .{
......@@ -21369,7 +21298,7 @@ fn zirReify(
2136921298 try ip.getOrPutString(gpa, "sentinel", .no_embedded_nulls),
2137021299 ).?);
2137121300
21372 const len = try len_val.toUnsignedIntAdvanced(sema);
21301 const len = try len_val.toUnsignedIntSema(mod);
2137321302 const child_ty = child_val.toType();
2137421303 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
2137521304 const ptr_ty = try mod.singleMutPtrType(child_ty);
......@@ -21476,7 +21405,7 @@ fn zirReify(
2147621405 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
2147721406
2147821407 // Decls
21479 if (try decls_val.sliceLen(sema) > 0) {
21408 if (try decls_val.sliceLen(mod) > 0) {
2148021409 return sema.fail(block, src, "reified structs must have no decls", .{});
2148121410 }
2148221411
......@@ -21509,7 +21438,7 @@ fn zirReify(
2150921438 try ip.getOrPutString(gpa, "is_exhaustive", .no_embedded_nulls),
2151021439 ).?);
2151121440
21512 if (try decls_val.sliceLen(sema) > 0) {
21441 if (try decls_val.sliceLen(mod) > 0) {
2151321442 return sema.fail(block, src, "reified enums must have no decls", .{});
2151421443 }
2151521444
......@@ -21527,7 +21456,7 @@ fn zirReify(
2152721456 ).?);
2152821457
2152921458 // Decls
21530 if (try decls_val.sliceLen(sema) > 0) {
21459 if (try decls_val.sliceLen(mod) > 0) {
2153121460 return sema.fail(block, src, "reified opaque must have no decls", .{});
2153221461 }
2153321462
......@@ -21575,7 +21504,7 @@ fn zirReify(
2157521504 try ip.getOrPutString(gpa, "decls", .no_embedded_nulls),
2157621505 ).?);
2157721506
21578 if (try decls_val.sliceLen(sema) > 0) {
21507 if (try decls_val.sliceLen(mod) > 0) {
2157921508 return sema.fail(block, src, "reified unions must have no decls", .{});
2158021509 }
2158121510 const layout = mod.toEnum(std.builtin.Type.ContainerLayout, layout_val);
......@@ -21934,7 +21863,7 @@ fn reifyUnion(
2193421863
2193521864 field_ty.* = field_type_val.toIntern();
2193621865 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);
2193821867 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
2193921868 // TODO: better source location
2194021869 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
......@@ -21979,7 +21908,7 @@ fn reifyUnion(
2197921908
2198021909 field_ty.* = field_type_val.toIntern();
2198121910 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);
2198321912 if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) {
2198421913 // TODO: better source location
2198521914 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align});
......@@ -22036,6 +21965,7 @@ fn reifyUnion(
2203621965 loaded_union.flagsPtr(ip).status = .have_field_types;
2203721966
2203821967 try mod.finalizeAnonDecl(new_decl_index);
21968 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
2203921969 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
2204021970}
2204121971
......@@ -22109,7 +22039,7 @@ fn reifyStruct(
2210922039
2211022040 if (field_is_comptime) any_comptime_fields = true;
2211122041 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)) {
2211322043 .eq => {},
2211422044 .gt => any_aligned_fields = true,
2211522045 .lt => unreachable,
......@@ -22192,7 +22122,7 @@ fn reifyStruct(
2219222122 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
2219322123 }
2219422124
22195 const byte_align = try field_alignment_val.toUnsignedIntAdvanced(sema);
22125 const byte_align = try field_alignment_val.toUnsignedIntSema(mod);
2219622126 if (byte_align == 0) {
2219722127 if (layout != .@"packed") {
2219822128 struct_type.field_aligns.get(ip)[field_idx] = .none;
......@@ -22278,7 +22208,7 @@ fn reifyStruct(
2227822208 var fields_bit_sum: u64 = 0;
2227922209 for (0..struct_type.field_types.len) |field_idx| {
2228022210 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) {
2228222212 error.AnalysisFail => {
2228322213 const msg = sema.err orelse return err;
2228422214 try sema.errNote(src, msg, "while checking a field of this struct", .{});
......@@ -22300,11 +22230,12 @@ fn reifyStruct(
2230022230 }
2230122231
2230222232 try mod.finalizeAnonDecl(new_decl_index);
22233 try mod.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
2230322234 return Air.internedToRef(wip_ty.finish(ip, new_decl_index, .none));
2230422235}
2230522236
2230622237fn 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");
2230822239 const va_list_ptr = try sema.mod.singleMutPtrType(va_list_ty);
2230922240
2231022241 const inst = try sema.resolveInst(zir_ref);
......@@ -22343,7 +22274,7 @@ fn zirCVaCopy(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData)
2234322274 const va_list_src = block.builtinCallArgSrc(extra.node, 0);
2234422275
2234522276 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
2234822279 try sema.requireRuntimeBlock(block, src, null);
2234922280 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
2236322294fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
2236422295 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");
2236722298 try sema.requireRuntimeBlock(block, src, null);
2236822299 return block.addInst(.{
2236922300 .tag = .c_va_start,
......@@ -22497,7 +22428,7 @@ fn zirFloatFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
2249722428 _ = try sema.checkIntType(block, operand_src, operand_scalar_ty);
2249822429
2249922430 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);
2250122432 return Air.internedToRef(result_val.toIntern());
2250222433 } else if (dest_scalar_ty.zigTypeTag(mod) == .ComptimeFloat) {
2250322434 return sema.failWithNeededComptime(block, operand_src, .{
......@@ -22545,7 +22476,7 @@ fn zirPtrFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2254522476 try sema.checkPtrType(block, src, ptr_ty, true);
2254622477
2254722478 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
2255022481 if (ptr_ty.isSlice(mod)) {
2255122482 const msg = msg: {
......@@ -22644,7 +22575,7 @@ fn ptrFromIntVal(
2264422575 }
2264522576 return sema.failWithUseOfUndef(block, operand_src);
2264622577 }
22647 const addr = try operand_val.toUnsignedIntAdvanced(sema);
22578 const addr = try operand_val.toUnsignedIntSema(zcu);
2264822579 if (!ptr_ty.isAllowzeroPtr(zcu) and addr == 0)
2264922580 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(zcu)});
2265022581 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))
......@@ -22842,8 +22773,8 @@ fn ptrCastFull(
2284222773 const src_info = operand_ty.ptrInfo(mod);
2284322774 const dest_info = dest_ty.ptrInfo(mod);
2284422775
22845 try sema.resolveTypeLayout(Type.fromInterned(src_info.child));
22846 try sema.resolveTypeLayout(Type.fromInterned(dest_info.child));
22776 try Type.fromInterned(src_info.child).resolveLayout(mod);
22777 try Type.fromInterned(dest_info.child).resolveLayout(mod);
2284722778
2284822779 const src_slice_like = src_info.flags.size == .Slice or
2284922780 (src_info.flags.size == .One and Type.fromInterned(src_info.child).zigTypeTag(mod) == .Array);
......@@ -23091,7 +23022,7 @@ fn ptrCastFull(
2309123022 // Only convert to a many-pointer at first
2309223023 var info = dest_info;
2309323024 info.flags.size = .Many;
23094 const ty = try sema.ptrType(info);
23025 const ty = try mod.ptrTypeSema(info);
2309523026 if (dest_ty.zigTypeTag(mod) == .Optional) {
2309623027 break :blk try mod.optionalType(ty.toIntern());
2309723028 } else {
......@@ -23109,7 +23040,7 @@ fn ptrCastFull(
2310923040 return sema.fail(block, operand_src, "null pointer casted to type '{}'", .{dest_ty.fmt(mod)});
2311023041 }
2311123042 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| {
2311323044 if (!dest_align.check(addr)) {
2311423045 return sema.fail(block, operand_src, "pointer address 0x{X} is not aligned to {d} bytes", .{
2311523046 addr,
......@@ -23176,7 +23107,7 @@ fn ptrCastFull(
2317623107 // We can't change address spaces with a bitcast, so this requires two instructions
2317723108 var intermediate_info = src_info;
2317823109 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);
2318023111 const intermediate_ty = if (dest_ptr_ty.zigTypeTag(mod) == .Optional) blk: {
2318123112 break :blk try mod.optionalType(intermediate_ptr_ty.toIntern());
2318223113 } else intermediate_ptr_ty;
......@@ -23233,7 +23164,7 @@ fn zirPtrCastNoDest(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst
2323323164 if (flags.volatile_cast) ptr_info.flags.is_volatile = false;
2323423165
2323523166 const dest_ty = blk: {
23236 const dest_ty = try sema.ptrType(ptr_info);
23167 const dest_ty = try mod.ptrTypeSema(ptr_info);
2323723168 if (operand_ty.zigTypeTag(mod) == .Optional) {
2323823169 break :blk try mod.optionalType(dest_ty.toIntern());
2323923170 }
......@@ -23523,7 +23454,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2352323454
2352423455 const mod = sema.mod;
2352523456 const ip = &mod.intern_pool;
23526 try sema.resolveTypeLayout(ty);
23457 try ty.resolveLayout(mod);
2352723458 switch (ty.zigTypeTag(mod)) {
2352823459 .Struct => {},
2352923460 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}),
......@@ -23766,7 +23697,7 @@ fn checkAtomicPtrOperand(
2376623697 const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) {
2376723698 .Pointer => ptr_ty.ptrInfo(mod),
2376823699 else => {
23769 const wanted_ptr_ty = try sema.ptrType(wanted_ptr_data);
23700 const wanted_ptr_ty = try mod.ptrTypeSema(wanted_ptr_data);
2377023701 _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2377123702 unreachable;
2377223703 },
......@@ -23776,7 +23707,7 @@ fn checkAtomicPtrOperand(
2377623707 wanted_ptr_data.flags.is_allowzero = ptr_data.flags.is_allowzero;
2377723708 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);
2378023711 const casted_ptr = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src);
2378123712
2378223713 return casted_ptr;
......@@ -23953,7 +23884,7 @@ fn resolveExportOptions(
2395323884 const mod = sema.mod;
2395423885 const gpa = sema.gpa;
2395523886 const ip = &mod.intern_pool;
23956 const export_options_ty = try sema.getBuiltinType("ExportOptions");
23887 const export_options_ty = try mod.getBuiltinType("ExportOptions");
2395723888 const air_ref = try sema.resolveInst(zir_ref);
2395823889 const options = try sema.coerce(block, export_options_ty, air_ref, src);
2395923890
......@@ -24017,7 +23948,7 @@ fn resolveBuiltinEnum(
2401723948 reason: NeededComptimeReason,
2401823949) CompileError!@field(std.builtin, name) {
2401923950 const mod = sema.mod;
24020 const ty = try sema.getBuiltinType(name);
23951 const ty = try mod.getBuiltinType(name);
2402123952 const air_ref = try sema.resolveInst(zir_ref);
2402223953 const coerced = try sema.coerce(block, ty, air_ref, src);
2402323954 const val = try sema.resolveConstDefinedValue(block, src, coerced, reason);
......@@ -24777,7 +24708,7 @@ fn zirBuiltinCall(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
2477724708 const extra = sema.code.extraData(Zir.Inst.BuiltinCall, inst_data.payload_index).data;
2477824709 const func = try sema.resolveInst(extra.callee);
2477924710
24780 const modifier_ty = try sema.getBuiltinType("CallModifier");
24711 const modifier_ty = try mod.getBuiltinType("CallModifier");
2478124712 const air_ref = try sema.resolveInst(extra.modifier);
2478224713 const modifier_ref = try sema.coerce(block, modifier_ty, air_ref, modifier_src);
2478324714 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
2488124812 .Struct, .Union => {},
2488224813 else => return sema.fail(block, inst_src, "expected pointer to struct or union type, found '{}'", .{parent_ptr_ty.fmt(zcu)}),
2488324814 }
24884 try sema.resolveTypeLayout(parent_ty);
24815 try parent_ty.resolveLayout(zcu);
2488524816
2488624817 const field_name = try sema.resolveConstStringIntern(block, field_name_src, extra.field_name, .{
2488724818 .needed_comptime_reason = "field name must be comptime-known",
......@@ -24912,7 +24843,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2491224843 var actual_parent_ptr_info: InternPool.Key.PtrType = .{
2491324844 .child = parent_ty.toIntern(),
2491424845 .flags = .{
24915 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(zcu, sema),
24846 .alignment = try parent_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),
2491624847 .is_const = field_ptr_info.flags.is_const,
2491724848 .is_volatile = field_ptr_info.flags.is_volatile,
2491824849 .is_allowzero = field_ptr_info.flags.is_allowzero,
......@@ -24924,7 +24855,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2492424855 var actual_field_ptr_info: InternPool.Key.PtrType = .{
2492524856 .child = field_ty.toIntern(),
2492624857 .flags = .{
24927 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(zcu, sema),
24858 .alignment = try field_ptr_ty.ptrAlignmentAdvanced(zcu, .sema),
2492824859 .is_const = field_ptr_info.flags.is_const,
2492924860 .is_volatile = field_ptr_info.flags.is_volatile,
2493024861 .is_allowzero = field_ptr_info.flags.is_allowzero,
......@@ -24935,12 +24866,13 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2493524866 switch (parent_ty.containerLayout(zcu)) {
2493624867 .auto => {
2493724868 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(
2493924870 struct_obj.fieldAlign(ip, field_index),
2494024871 field_ty,
2494124872 struct_obj.layout,
24873 .sema,
2494224874 ) 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)
2494424876 else
2494524877 actual_field_ptr_info.flags.alignment,
2494624878 );
......@@ -24970,9 +24902,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2497024902 },
2497124903 }
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);
2497424906 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
2497724909 const result = if (try sema.resolveDefinedValue(block, field_ptr_src, casted_field_ptr)) |field_ptr_val| result: {
2497824910 switch (parent_ty.zigTypeTag(zcu)) {
......@@ -25032,7 +24964,6 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Ins
2503224964 break :result try sema.coerce(block, actual_parent_ptr_ty, Air.internedToRef(field.base), inst_src);
2503324965 } else result: {
2503424966 try sema.requireRuntimeBlock(block, inst_src, field_ptr_src);
25035 try sema.queueFullTypeResolution(parent_ty);
2503624967 break :result try block.addInst(.{
2503724968 .tag = .field_parent_ptr,
2503824969 .data = .{ .ty_pl = .{
......@@ -25345,7 +25276,7 @@ fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !A
2534525276 // Already an array pointer.
2534625277 return ptr;
2534725278 }
25348 const new_ty = try sema.ptrType(.{
25279 const new_ty = try mod.ptrTypeSema(.{
2534925280 .child = (try mod.arrayType(.{
2535025281 .len = len,
2535125282 .sentinel = info.sentinel,
......@@ -25444,7 +25375,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2544425375 const runtime_src = if (try sema.resolveDefinedValue(block, dest_src, dest_ptr)) |dest_ptr_val| rs: {
2544525376 if (!sema.isComptimeMutablePtr(dest_ptr_val)) break :rs dest_src;
2544625377 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)).?;
2544825379 const len = try sema.usizeCast(block, dest_src, len_u64);
2544925380 for (0..len) |i| {
2545025381 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
2550325434 var new_dest_ptr = dest_ptr;
2550425435 var new_src_ptr = src_ptr;
2550525436 if (len_val) |val| {
25506 const len = try val.toUnsignedIntAdvanced(sema);
25437 const len = try val.toUnsignedIntSema(mod);
2550725438 if (len == 0) {
2550825439 // This AIR instruction guarantees length > 0 if it is comptime-known.
2550925440 return;
......@@ -25550,7 +25481,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2555025481 assert(dest_manyptr_ty_key.flags.size == .One);
2555125482 dest_manyptr_ty_key.child = dest_elem_ty.toIntern();
2555225483 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);
2555425485 } else new_dest_ptr;
2555525486
2555625487 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
2556125492 assert(src_manyptr_ty_key.flags.size == .One);
2556225493 src_manyptr_ty_key.child = src_elem_ty.toIntern();
2556325494 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);
2556525496 } else new_src_ptr;
2556625497
2556725498 // ok1: dest >= src + len
......@@ -25628,7 +25559,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2562825559 const ptr_val = try sema.resolveDefinedValue(block, dest_src, dest_ptr) orelse break :rs dest_src;
2562925560 const len_air_ref = try sema.fieldVal(block, src, dest_ptr, try ip.getOrPutString(gpa, "len", .no_embedded_nulls), dest_src);
2563025561 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)).?;
2563225563 const len = try sema.usizeCast(block, dest_src, len_u64);
2563325564 if (len == 0) {
2563425565 // 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
2580825739 if (val.isGenericPoison()) {
2580925740 break :blk null;
2581025741 }
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));
2581225743 const default = target_util.defaultFunctionAlignment(target);
2581325744 break :blk if (alignment == default) .none else alignment;
2581425745 } 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
2582825759 error.GenericPoison => break :blk null,
2582925760 else => |e| return e,
2583025761 };
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));
2583225763 const default = target_util.defaultFunctionAlignment(target);
2583325764 break :blk if (alignment == default) .none else alignment;
2583425765 } else .none;
......@@ -25904,7 +25835,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2590425835 const body = sema.code.bodySlice(extra_index, body_len);
2590525836 extra_index += body.len;
2590625837
25907 const cc_ty = try sema.getBuiltinType("CallingConvention");
25838 const cc_ty = try mod.getBuiltinType("CallingConvention");
2590825839 const val = try sema.resolveGenericBody(block, cc_src, body, inst, cc_ty, .{
2590925840 .needed_comptime_reason = "calling convention must be comptime-known",
2591025841 });
......@@ -26117,7 +26048,7 @@ fn resolvePrefetchOptions(
2611726048 const mod = sema.mod;
2611826049 const gpa = sema.gpa;
2611926050 const ip = &mod.intern_pool;
26120 const options_ty = try sema.getBuiltinType("PrefetchOptions");
26051 const options_ty = try mod.getBuiltinType("PrefetchOptions");
2612126052 const options = try sema.coerce(block, options_ty, try sema.resolveInst(zir_ref), src);
2612226053
2612326054 const rw_src = block.src(.{ .init_field_rw = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -26141,7 +26072,7 @@ fn resolvePrefetchOptions(
2614126072
2614226073 return std.builtin.PrefetchOptions{
2614326074 .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)),
2614526076 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),
2614626077 };
2614726078}
......@@ -26189,7 +26120,7 @@ fn resolveExternOptions(
2618926120 const gpa = sema.gpa;
2619026121 const ip = &mod.intern_pool;
2619126122 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");
2619326124 const options = try sema.coerce(block, extern_options_ty, options_inst, src);
2619426125
2619526126 const name_src = block.src(.{ .init_field_name = src.offset.node_offset_builtin_call_arg.builtin_call_node });
......@@ -26440,7 +26371,7 @@ fn explainWhyTypeIsComptime(
2644026371 var type_set = TypeSet{};
2644126372 defer type_set.deinit(sema.gpa);
2644226373
26443 try sema.resolveTypeFully(ty);
26374 try ty.resolveFully(sema.mod);
2644426375 return sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty, &type_set);
2644526376}
2644626377
......@@ -26567,7 +26498,7 @@ const ExternPosition = enum {
2656726498
2656826499/// Returns true if `ty` is allowed in extern types.
2656926500/// Does *NOT* require `ty` to be resolved in any way.
26570/// Calls `resolveTypeLayout` for packed containers.
26501/// Calls `resolveLayout` for packed containers.
2657126502fn validateExternType(
2657226503 sema: *Sema,
2657326504 ty: Type,
......@@ -26618,7 +26549,7 @@ fn validateExternType(
2661826549 .Struct, .Union => switch (ty.containerLayout(mod)) {
2661926550 .@"extern" => return true,
2662026551 .@"packed" => {
26621 const bit_size = try ty.bitSizeAdvanced(mod, sema);
26552 const bit_size = try ty.bitSizeAdvanced(mod, .sema);
2662226553 switch (bit_size) {
2662326554 0, 8, 16, 32, 64, 128 => return true,
2662426555 else => return false,
......@@ -26796,11 +26727,11 @@ fn explainWhyTypeIsNotPacked(
2679626727 }
2679726728}
2679826729
26799fn prepareSimplePanic(sema: *Sema, block: *Block) !void {
26730fn prepareSimplePanic(sema: *Sema) !void {
2680026731 const mod = sema.mod;
2680126732
2680226733 if (mod.panic_func_index == .none) {
26803 const decl_index = (try sema.getBuiltinDecl(block, "panic"));
26734 const decl_index = (try mod.getBuiltinDecl("panic"));
2680426735 // decl_index may be an alias; we must find the decl that actually
2680526736 // owns the function.
2680626737 try sema.ensureDeclAnalyzed(decl_index);
......@@ -26813,10 +26744,10 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void {
2681326744 }
2681426745
2681526746 if (mod.null_stack_trace == .none) {
26816 const stack_trace_ty = try sema.getBuiltinType("StackTrace");
26817 try sema.resolveTypeFields(stack_trace_ty);
26747 const stack_trace_ty = try mod.getBuiltinType("StackTrace");
26748 try stack_trace_ty.resolveFields(mod);
2681826749 const target = mod.getTarget();
26819 const ptr_stack_trace_ty = try sema.ptrType(.{
26750 const ptr_stack_trace_ty = try mod.ptrTypeSema(.{
2682026751 .child = stack_trace_ty.toIntern(),
2682126752 .flags = .{
2682226753 .address_space = target_util.defaultAddressSpace(target, .global_constant),
......@@ -26838,9 +26769,9 @@ fn preparePanicId(sema: *Sema, block: *Block, panic_id: Module.PanicId) !InternP
2683826769 const gpa = sema.gpa;
2683926770 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");
2684426775 const msg_decl_index = (sema.namespaceLookup(
2684526776 block,
2684626777 LazySrcLoc.unneeded,
......@@ -26946,7 +26877,7 @@ fn panicWithMsg(sema: *Sema, block: *Block, src: LazySrcLoc, msg_inst: Air.Inst.
2694626877 return;
2694726878 }
2694826879
26949 try sema.prepareSimplePanic(block);
26880 try sema.prepareSimplePanic();
2695026881
2695126882 const panic_func = mod.funcInfo(mod.panic_func_index);
2695226883 const panic_fn = try sema.analyzeDeclVal(block, src, panic_func.owner_decl);
......@@ -26992,7 +26923,7 @@ fn panicUnwrapError(
2699226923 if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) {
2699326924 _ = try fail_block.addNoOp(.trap);
2699426925 } else {
26995 const panic_fn = try sema.getBuiltin("panicUnwrapError");
26926 const panic_fn = try sema.mod.getBuiltin("panicUnwrapError");
2699626927 const err = try fail_block.addTyOp(unwrap_err_tag, Type.anyerror, operand);
2699726928 const err_return_trace = try sema.getErrorReturnTrace(&fail_block);
2699826929 const args: [2]Air.Inst.Ref = .{ err_return_trace, err };
......@@ -27051,7 +26982,7 @@ fn panicSentinelMismatch(
2705126982 const actual_sentinel = if (ptr_ty.isSlice(mod))
2705226983 try parent_block.addBinOp(.slice_elem_val, ptr, sentinel_index)
2705326984 else blk: {
27054 const elem_ptr_ty = try sema.elemPtrType(ptr_ty, null);
26985 const elem_ptr_ty = try ptr_ty.elemPtrType(null, mod);
2705526986 const sentinel_ptr = try parent_block.addPtrElemPtr(ptr, sentinel_index, elem_ptr_ty);
2705626987 break :blk try parent_block.addTyOp(.load, sentinel_ty, sentinel_ptr);
2705726988 };
......@@ -27069,7 +27000,7 @@ fn panicSentinelMismatch(
2706927000 } else if (sentinel_ty.isSelfComparable(mod, true))
2707027001 try parent_block.addBinOp(.cmp_eq, expected_sentinel, actual_sentinel)
2707127002 else {
27072 const panic_fn = try sema.getBuiltin("checkNonScalarSentinel");
27003 const panic_fn = try mod.getBuiltin("checkNonScalarSentinel");
2707327004 const args: [2]Air.Inst.Ref = .{ expected_sentinel, actual_sentinel };
2707427005 try sema.callBuiltin(parent_block, src, panic_fn, .auto, &args, .@"safety check");
2707527006 return;
......@@ -27108,7 +27039,7 @@ fn safetyCheckFormatted(
2710827039 if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) {
2710927040 _ = try fail_block.addNoOp(.trap);
2711027041 } else {
27111 const panic_fn = try sema.getBuiltin(func);
27042 const panic_fn = try sema.mod.getBuiltin(func);
2711227043 try sema.callBuiltin(&fail_block, src, panic_fn, .auto, args, .@"safety check");
2711327044 }
2711427045 try sema.addSafetyCheckExtra(parent_block, ok, &fail_block);
......@@ -27170,7 +27101,7 @@ fn fieldVal(
2717027101 return Air.internedToRef((try mod.intValue(Type.usize, inner_ty.arrayLen(mod))).toIntern());
2717127102 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2717227103 const ptr_info = object_ty.ptrInfo(mod);
27173 const result_ty = try sema.ptrType(.{
27104 const result_ty = try mod.ptrTypeSema(.{
2717427105 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
2717527106 .sentinel = if (inner_ty.sentinel(mod)) |s| s.toIntern() else .none,
2717627107 .flags = .{
......@@ -27267,7 +27198,7 @@ fn fieldVal(
2726727198 if (try sema.namespaceLookupVal(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
2726827199 return inst;
2726927200 }
27270 try sema.resolveTypeFields(child_type);
27201 try child_type.resolveFields(mod);
2727127202 if (child_type.unionTagType(mod)) |enum_ty| {
2727227203 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| {
2727327204 const field_index: u32 = @intCast(field_index_usize);
......@@ -27361,7 +27292,7 @@ fn fieldPtr(
2736127292 return anonDeclRef(sema, int_val.toIntern());
2736227293 } else if (field_name.eqlSlice("ptr", ip) and is_pointer_to) {
2736327294 const ptr_info = object_ty.ptrInfo(mod);
27364 const new_ptr_ty = try sema.ptrType(.{
27295 const new_ptr_ty = try mod.ptrTypeSema(.{
2736527296 .child = Type.fromInterned(ptr_info.child).childType(mod).toIntern(),
2736627297 .sentinel = if (object_ty.sentinel(mod)) |s| s.toIntern() else .none,
2736727298 .flags = .{
......@@ -27376,7 +27307,7 @@ fn fieldPtr(
2737627307 .packed_offset = ptr_info.packed_offset,
2737727308 });
2737827309 const ptr_ptr_info = object_ptr_ty.ptrInfo(mod);
27379 const result_ty = try sema.ptrType(.{
27310 const result_ty = try mod.ptrTypeSema(.{
2738027311 .child = new_ptr_ty.toIntern(),
2738127312 .sentinel = if (object_ptr_ty.sentinel(mod)) |s| s.toIntern() else .none,
2738227313 .flags = .{
......@@ -27410,7 +27341,7 @@ fn fieldPtr(
2741027341 if (field_name.eqlSlice("ptr", ip)) {
2741127342 const slice_ptr_ty = inner_ty.slicePtrFieldType(mod);
2741227343
27413 const result_ty = try sema.ptrType(.{
27344 const result_ty = try mod.ptrTypeSema(.{
2741427345 .child = slice_ptr_ty.toIntern(),
2741527346 .flags = .{
2741627347 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
......@@ -27420,7 +27351,7 @@ fn fieldPtr(
2742027351 });
2742127352
2742227353 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());
2742427355 }
2742527356 try sema.requireRuntimeBlock(block, src, null);
2742627357
......@@ -27428,7 +27359,7 @@ fn fieldPtr(
2742827359 try sema.checkKnownAllocPtr(block, inner_ptr, field_ptr);
2742927360 return field_ptr;
2743027361 } else if (field_name.eqlSlice("len", ip)) {
27431 const result_ty = try sema.ptrType(.{
27362 const result_ty = try mod.ptrTypeSema(.{
2743227363 .child = .usize_type,
2743327364 .flags = .{
2743427365 .is_const = !attr_ptr_ty.ptrIsMutable(mod),
......@@ -27438,7 +27369,7 @@ fn fieldPtr(
2743827369 });
2743927370
2744027371 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());
2744227373 }
2744327374 try sema.requireRuntimeBlock(block, src, null);
2744427375
......@@ -27506,7 +27437,7 @@ fn fieldPtr(
2750627437 if (try sema.namespaceLookupRef(block, src, child_type.getNamespaceIndex(mod), field_name)) |inst| {
2750727438 return inst;
2750827439 }
27509 try sema.resolveTypeFields(child_type);
27440 try child_type.resolveFields(mod);
2751027441 if (child_type.unionTagType(mod)) |enum_ty| {
2751127442 if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| {
2751227443 const field_index_u32: u32 = @intCast(field_index);
......@@ -27601,7 +27532,7 @@ fn fieldCallBind(
2760127532 find_field: {
2760227533 switch (concrete_ty.zigTypeTag(mod)) {
2760327534 .Struct => {
27604 try sema.resolveTypeFields(concrete_ty);
27535 try concrete_ty.resolveFields(mod);
2760527536 if (mod.typeToStruct(concrete_ty)) |struct_type| {
2760627537 const field_index = struct_type.nameIndex(ip, field_name) orelse
2760727538 break :find_field;
......@@ -27627,7 +27558,7 @@ fn fieldCallBind(
2762727558 }
2762827559 },
2762927560 .Union => {
27630 try sema.resolveTypeFields(concrete_ty);
27561 try concrete_ty.resolveFields(mod);
2763127562 const union_obj = mod.typeToUnion(concrete_ty).?;
2763227563 _ = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse break :find_field;
2763327564 const field_ptr = try unionFieldPtr(sema, block, src, object_ptr, field_name, field_name_src, concrete_ty, false);
......@@ -27737,7 +27668,7 @@ fn finishFieldCallBind(
2773727668 object_ptr: Air.Inst.Ref,
2773827669) CompileError!ResolvedFieldCallee {
2773927670 const mod = sema.mod;
27740 const ptr_field_ty = try sema.ptrType(.{
27671 const ptr_field_ty = try mod.ptrTypeSema(.{
2774127672 .child = field_ty.toIntern(),
2774227673 .flags = .{
2774327674 .is_const = !ptr_ty.ptrIsMutable(mod),
......@@ -27748,14 +27679,14 @@ fn finishFieldCallBind(
2774827679 const container_ty = ptr_ty.childType(mod);
2774927680 if (container_ty.zigTypeTag(mod) == .Struct) {
2775027681 if (container_ty.structFieldIsComptime(field_index, mod)) {
27751 try sema.resolveStructFieldInits(container_ty);
27682 try container_ty.resolveStructFieldInits(mod);
2775227683 const default_val = (try container_ty.structFieldValueComptime(mod, field_index)).?;
2775327684 return .{ .direct = Air.internedToRef(default_val.toIntern()) };
2775427685 }
2775527686 }
2775627687
2775727688 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);
2775927690 const pointer = Air.internedToRef(ptr_val.toIntern());
2776027691 return .{ .direct = try sema.analyzeLoad(block, src, pointer, src) };
2776127692 }
......@@ -27831,8 +27762,8 @@ fn structFieldPtr(
2783127762 const ip = &mod.intern_pool;
2783227763 assert(struct_ty.zigTypeTag(mod) == .Struct);
2783327764
27834 try sema.resolveTypeFields(struct_ty);
27835 try sema.resolveStructLayout(struct_ty);
27765 try struct_ty.resolveFields(mod);
27766 try struct_ty.resolveLayout(mod);
2783627767
2783727768 if (struct_ty.isTuple(mod)) {
2783827769 if (field_name.eqlSlice("len", ip)) {
......@@ -27871,7 +27802,7 @@ fn structFieldPtrByIndex(
2787127802 }
2787227803
2787327804 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);
2787527806 return Air.internedToRef(val.toIntern());
2787627807 }
2787727808
......@@ -27915,10 +27846,11 @@ fn structFieldPtrByIndex(
2791527846 @enumFromInt(@min(@intFromEnum(parent_align), @ctz(field_offset)));
2791627847 } else {
2791727848 // Our alignment is capped at the field alignment.
27918 const field_align = try sema.structFieldAlignment(
27849 const field_align = try mod.structFieldAlignmentAdvanced(
2791927850 struct_type.fieldAlign(ip, field_index),
2792027851 Type.fromInterned(field_ty),
2792127852 struct_type.layout,
27853 .sema,
2792227854 );
2792327855 ptr_ty_data.flags.alignment = if (struct_ptr_ty_info.flags.alignment == .none)
2792427856 field_align
......@@ -27926,10 +27858,10 @@ fn structFieldPtrByIndex(
2792627858 field_align.min(parent_align);
2792727859 }
2792827860
27929 const ptr_field_ty = try sema.ptrType(ptr_ty_data);
27861 const ptr_field_ty = try mod.ptrTypeSema(ptr_ty_data);
2793027862
2793127863 if (struct_type.fieldIsComptime(ip, field_index)) {
27932 try sema.resolveStructFieldInits(struct_ty);
27864 try struct_ty.resolveStructFieldInits(mod);
2793327865 const val = try mod.intern(.{ .ptr = .{
2793427866 .ty = ptr_field_ty.toIntern(),
2793527867 .base_addr = .{ .comptime_field = struct_type.field_inits.get(ip)[field_index] },
......@@ -27955,7 +27887,7 @@ fn structFieldVal(
2795527887 const ip = &mod.intern_pool;
2795627888 assert(struct_ty.zigTypeTag(mod) == .Struct);
2795727889
27958 try sema.resolveTypeFields(struct_ty);
27890 try struct_ty.resolveFields(mod);
2795927891
2796027892 switch (ip.indexToKey(struct_ty.toIntern())) {
2796127893 .struct_type => {
......@@ -27966,7 +27898,7 @@ fn structFieldVal(
2796627898 const field_index = struct_type.nameIndex(ip, field_name) orelse
2796727899 return sema.failWithBadStructFieldAccess(block, struct_ty, struct_type, field_name_src, field_name);
2796827900 if (struct_type.fieldIsComptime(ip, field_index)) {
27969 try sema.resolveStructFieldInits(struct_ty);
27901 try struct_ty.resolveStructFieldInits(mod);
2797027902 return Air.internedToRef(struct_type.field_inits.get(ip)[field_index]);
2797127903 }
2797227904
......@@ -27983,7 +27915,7 @@ fn structFieldVal(
2798327915 }
2798427916
2798527917 try sema.requireRuntimeBlock(block, src, null);
27986 try sema.resolveTypeLayout(field_ty);
27918 try field_ty.resolveLayout(mod);
2798727919 return block.addStructFieldVal(struct_byval, field_index, field_ty);
2798827920 },
2798927921 .anon_struct_type => |anon_struct| {
......@@ -28050,7 +27982,7 @@ fn tupleFieldValByIndex(
2805027982 const field_ty = tuple_ty.structFieldType(field_index, mod);
2805127983
2805227984 if (tuple_ty.structFieldIsComptime(field_index, mod))
28053 try sema.resolveStructFieldInits(tuple_ty);
27985 try tuple_ty.resolveStructFieldInits(mod);
2805427986 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
2805527987 return Air.internedToRef(default_value.toIntern());
2805627988 }
......@@ -28071,7 +28003,7 @@ fn tupleFieldValByIndex(
2807128003 }
2807228004
2807328005 try sema.requireRuntimeBlock(block, src, null);
28074 try sema.resolveTypeLayout(field_ty);
28006 try field_ty.resolveLayout(mod);
2807528007 return block.addStructFieldVal(tuple_byval, field_index, field_ty);
2807628008}
2807728009
......@@ -28092,11 +28024,11 @@ fn unionFieldPtr(
2809228024
2809328025 const union_ptr_ty = sema.typeOf(union_ptr);
2809428026 const union_ptr_info = union_ptr_ty.ptrInfo(mod);
28095 try sema.resolveTypeFields(union_ty);
28027 try union_ty.resolveFields(mod);
2809628028 const union_obj = mod.typeToUnion(union_ty).?;
2809728029 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2809828030 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(.{
2810028032 .child = field_ty.toIntern(),
2810128033 .flags = .{
2810228034 .is_const = union_ptr_info.flags.is_const,
......@@ -28107,7 +28039,7 @@ fn unionFieldPtr(
2810728039 union_ptr_info.flags.alignment
2810828040 else
2810928041 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);
2811128043 break :blk union_align.min(field_align);
2811228044 } else union_ptr_info.flags.alignment,
2811328045 },
......@@ -28163,7 +28095,7 @@ fn unionFieldPtr(
2816328095 },
2816428096 .@"packed", .@"extern" => {},
2816528097 }
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);
2816728099 return Air.internedToRef(field_ptr_val.toIntern());
2816828100 }
2816928101
......@@ -28198,7 +28130,7 @@ fn unionFieldVal(
2819828130 const ip = &zcu.intern_pool;
2819928131 assert(union_ty.zigTypeTag(zcu) == .Union);
2820028132
28201 try sema.resolveTypeFields(union_ty);
28133 try union_ty.resolveFields(zcu);
2820228134 const union_obj = zcu.typeToUnion(union_ty).?;
2820328135 const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src);
2820428136 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
......@@ -28237,7 +28169,7 @@ fn unionFieldVal(
2823728169 .@"packed" => if (tag_matches) {
2823828170 // Fast path - no need to use bitcast logic.
2823928171 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| {
2824128173 return Air.internedToRef(field_val.toIntern());
2824228174 },
2824328175 }
......@@ -28256,7 +28188,7 @@ fn unionFieldVal(
2825628188 _ = try block.addNoOp(.unreach);
2825728189 return .unreachable_value;
2825828190 }
28259 try sema.resolveTypeLayout(field_ty);
28191 try field_ty.resolveLayout(zcu);
2826028192 return block.addStructFieldVal(union_byval, field_index, field_ty);
2826128193}
2826228194
......@@ -28287,7 +28219,7 @@ fn elemPtr(
2828728219 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
2828828220 .needed_comptime_reason = "tuple field access index must be comptime-known",
2828928221 });
28290 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));
28222 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));
2829128223 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
2829228224 },
2829328225 else => {
......@@ -28325,11 +28257,11 @@ fn elemPtrOneLayerOnly(
2832528257 const runtime_src = rs: {
2832628258 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;
2832728259 const index_val = maybe_index_val orelse break :rs elem_index_src;
28328 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));
28329 const elem_ptr = try ptr_val.ptrElem(index, sema);
28260 const index: usize = @intCast(try index_val.toUnsignedIntSema(mod));
28261 const elem_ptr = try ptr_val.ptrElem(index, mod);
2833028262 return Air.internedToRef(elem_ptr.toIntern());
2833128263 };
28332 const result_ty = try sema.elemPtrType(indexable_ty, null);
28264 const result_ty = try indexable_ty.elemPtrType(null, mod);
2833328265
2833428266 try sema.requireRuntimeBlock(block, src, runtime_src);
2833528267 return block.addPtrElemPtr(indexable, elem_index, result_ty);
......@@ -28343,7 +28275,7 @@ fn elemPtrOneLayerOnly(
2834328275 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
2834428276 .needed_comptime_reason = "tuple field access index must be comptime-known",
2834528277 });
28346 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));
28278 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));
2834728279 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);
2834828280 },
2834928281 else => unreachable, // Guaranteed by checkIndexable
......@@ -28383,12 +28315,12 @@ fn elemVal(
2838328315 const runtime_src = rs: {
2838428316 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
2838528317 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));
2838728319 const elem_ty = indexable_ty.elemType2(mod);
2838828320 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);
2838928321 const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty);
2839028322 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);
2839228324 if (try sema.pointerDeref(block, indexable_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
2839328325 return Air.internedToRef((try mod.getCoerced(elem_val, elem_ty)).toIntern());
2839428326 }
......@@ -28404,7 +28336,7 @@ fn elemVal(
2840428336 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;
2840528337 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;
2840628338 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));
2840828340 if (index != inner_ty.arrayLen(mod)) break :arr_sent;
2840928341 return Air.internedToRef(sentinel.toIntern());
2841028342 }
......@@ -28422,7 +28354,7 @@ fn elemVal(
2842228354 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
2842328355 .needed_comptime_reason = "tuple field access index must be comptime-known",
2842428356 });
28425 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));
28357 const index: u32 = @intCast(try index_val.toUnsignedIntSema(mod));
2842628358 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
2842728359 },
2842828360 else => unreachable,
......@@ -28467,7 +28399,7 @@ fn tupleFieldPtr(
2846728399 const mod = sema.mod;
2846828400 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
2846928401 const tuple_ty = tuple_ptr_ty.childType(mod);
28470 try sema.resolveTypeFields(tuple_ty);
28402 try tuple_ty.resolveFields(mod);
2847128403 const field_count = tuple_ty.structFieldCount(mod);
2847228404
2847328405 if (field_count == 0) {
......@@ -28481,7 +28413,7 @@ fn tupleFieldPtr(
2848128413 }
2848228414
2848328415 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(.{
2848528417 .child = field_ty.toIntern(),
2848628418 .flags = .{
2848728419 .is_const = !tuple_ptr_ty.ptrIsMutable(mod),
......@@ -28491,7 +28423,7 @@ fn tupleFieldPtr(
2849128423 });
2849228424
2849328425 if (tuple_ty.structFieldIsComptime(field_index, mod))
28494 try sema.resolveStructFieldInits(tuple_ty);
28426 try tuple_ty.resolveStructFieldInits(mod);
2849528427
2849628428 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| {
2849728429 return Air.internedToRef((try mod.intern(.{ .ptr = .{
......@@ -28502,7 +28434,7 @@ fn tupleFieldPtr(
2850228434 }
2850328435
2850428436 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);
2850628438 return Air.internedToRef(field_ptr_val.toIntern());
2850728439 }
2850828440
......@@ -28524,7 +28456,7 @@ fn tupleField(
2852428456) CompileError!Air.Inst.Ref {
2852528457 const mod = sema.mod;
2852628458 const tuple_ty = sema.typeOf(tuple);
28527 try sema.resolveTypeFields(tuple_ty);
28459 try tuple_ty.resolveFields(mod);
2852828460 const field_count = tuple_ty.structFieldCount(mod);
2852928461
2853028462 if (field_count == 0) {
......@@ -28540,7 +28472,7 @@ fn tupleField(
2854028472 const field_ty = tuple_ty.structFieldType(field_index, mod);
2854128473
2854228474 if (tuple_ty.structFieldIsComptime(field_index, mod))
28543 try sema.resolveStructFieldInits(tuple_ty);
28475 try tuple_ty.resolveStructFieldInits(mod);
2854428476 if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| {
2854528477 return Air.internedToRef(default_value.toIntern()); // comptime field
2854628478 }
......@@ -28553,7 +28485,7 @@ fn tupleField(
2855328485 try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src);
2855428486
2855528487 try sema.requireRuntimeBlock(block, tuple_src, null);
28556 try sema.resolveTypeLayout(field_ty);
28488 try field_ty.resolveLayout(mod);
2855728489 return block.addStructFieldVal(tuple, field_index, field_ty);
2855828490}
2855928491
......@@ -28583,7 +28515,7 @@ fn elemValArray(
2858328515 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2858428516
2858528517 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));
2858728519 if (array_sent) |s| {
2858828520 if (index == array_len) {
2858928521 return Air.internedToRef(s.toIntern());
......@@ -28599,7 +28531,7 @@ fn elemValArray(
2859928531 return mod.undefRef(elem_ty);
2860028532 }
2860128533 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));
2860328535 const elem_val = try array_val.elemValue(mod, index);
2860428536 return Air.internedToRef(elem_val.toIntern());
2860528537 }
......@@ -28621,7 +28553,6 @@ fn elemValArray(
2862128553 return Air.internedToRef(elem_val.toIntern());
2862228554
2862328555 try sema.requireRuntimeBlock(block, src, runtime_src);
28624 try sema.queueFullTypeResolution(array_ty);
2862528556 return block.addBinOp(.array_elem_val, array, elem_index);
2862628557}
2862728558
......@@ -28650,7 +28581,7 @@ fn elemPtrArray(
2865028581 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);
2865128582 // The index must not be undefined since it can be out of bounds.
2865228583 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));
2865428585 if (index >= array_len_s) {
2865528586 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
2865628587 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(
2865828589 break :o index;
2865928590 } 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
2866328594 if (maybe_undef_array_ptr_val) |array_ptr_val| {
2866428595 if (array_ptr_val.isUndef(mod)) {
2866528596 return mod.undefRef(elem_ptr_ty);
2866628597 }
2866728598 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);
2866928600 return Air.internedToRef(elem_ptr.toIntern());
2867028601 }
2867128602 }
......@@ -28710,19 +28641,19 @@ fn elemValSlice(
2871028641
2871128642 if (maybe_slice_val) |slice_val| {
2871228643 runtime_src = elem_index_src;
28713 const slice_len = try slice_val.sliceLen(sema);
28644 const slice_len = try slice_val.sliceLen(mod);
2871428645 const slice_len_s = slice_len + @intFromBool(slice_sent);
2871528646 if (slice_len_s == 0) {
2871628647 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
2871728648 }
2871828649 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));
2872028651 if (index >= slice_len_s) {
2872128652 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
2872228653 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
2872328654 }
28724 const elem_ptr_ty = try sema.elemPtrType(slice_ty, index);
28725 const elem_ptr_val = try slice_val.ptrElem(index, sema);
28655 const elem_ptr_ty = try slice_ty.elemPtrType(index, mod);
28656 const elem_ptr_val = try slice_val.ptrElem(index, mod);
2872628657 if (try sema.pointerDeref(block, slice_src, elem_ptr_val, elem_ptr_ty)) |elem_val| {
2872728658 return Air.internedToRef(elem_val.toIntern());
2872828659 }
......@@ -28735,13 +28666,12 @@ fn elemValSlice(
2873528666 try sema.requireRuntimeBlock(block, src, runtime_src);
2873628667 if (oob_safety and block.wantSafety()) {
2873728668 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))
2873928670 else
2874028671 try block.addTyOp(.slice_len, Type.usize, slice);
2874128672 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
2874228673 try sema.panicIndexOutOfBounds(block, src, elem_index, len_inst, cmp_op);
2874328674 }
28744 try sema.queueFullTypeResolution(sema.typeOf(slice));
2874528675 return block.addBinOp(.slice_elem_val, slice, elem_index);
2874628676}
2874728677
......@@ -28762,17 +28692,17 @@ fn elemPtrSlice(
2876228692 const maybe_undef_slice_val = try sema.resolveValue(slice);
2876328693 // The index must not be undefined since it can be out of bounds.
2876428694 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));
2876628696 break :o index;
2876728697 } 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
2877128701 if (maybe_undef_slice_val) |slice_val| {
2877228702 if (slice_val.isUndef(mod)) {
2877328703 return mod.undefRef(elem_ptr_ty);
2877428704 }
28775 const slice_len = try slice_val.sliceLen(sema);
28705 const slice_len = try slice_val.sliceLen(mod);
2877628706 const slice_len_s = slice_len + @intFromBool(slice_sent);
2877728707 if (slice_len_s == 0) {
2877828708 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
......@@ -28782,7 +28712,7 @@ fn elemPtrSlice(
2878228712 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
2878328713 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
2878428714 }
28785 const elem_ptr_val = try slice_val.ptrElem(index, sema);
28715 const elem_ptr_val = try slice_val.ptrElem(index, mod);
2878628716 return Air.internedToRef(elem_ptr_val.toIntern());
2878728717 }
2878828718 }
......@@ -28795,7 +28725,7 @@ fn elemPtrSlice(
2879528725 const len_inst = len: {
2879628726 if (maybe_undef_slice_val) |slice_val|
2879728727 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));
2879928729 break :len try block.addTyOp(.slice_len, Type.usize, slice);
2880028730 };
2880128731 const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt;
......@@ -28860,9 +28790,9 @@ fn coerceExtra(
2886028790 if (dest_ty.isGenericPoison()) return inst;
2886128791 const zcu = sema.mod;
2886228792 const dest_ty_src = inst_src; // TODO better source location
28863 try sema.resolveTypeFields(dest_ty);
28793 try dest_ty.resolveFields(zcu);
2886428794 const inst_ty = sema.typeOf(inst);
28865 try sema.resolveTypeFields(inst_ty);
28795 try inst_ty.resolveFields(zcu);
2886628796 const target = zcu.getTarget();
2886728797 // If the types are the same, we can return the operand.
2886828798 if (dest_ty.eql(inst_ty, zcu))
......@@ -28876,7 +28806,6 @@ fn coerceExtra(
2887628806 return sema.coerceInMemory(val, dest_ty);
2887728807 }
2887828808 try sema.requireRuntimeBlock(block, inst_src, null);
28879 try sema.queueFullTypeResolution(dest_ty);
2888028809 const new_val = try block.addBitCast(dest_ty, inst);
2888128810 try sema.checkKnownAllocPtr(block, inst, new_val);
2888228811 return new_val;
......@@ -29172,7 +29101,7 @@ fn coerceExtra(
2917229101 // empty tuple to zero-length slice
2917329102 // note that this allows coercing to a mutable slice.
2917429103 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);
2917629105 return Air.internedToRef(try zcu.intern(.{ .slice = .{
2917729106 .ty = dest_ty.toIntern(),
2917829107 .ptr = try zcu.intern(.{ .ptr = .{
......@@ -29317,7 +29246,7 @@ fn coerceExtra(
2931729246 }
2931829247 break :int;
2931929248 };
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);
2932129250 // TODO implement this compile error
2932229251 //const int_again_val = try result_val.intFromFloat(sema.arena, inst_ty);
2932329252 //if (!int_again_val.eql(val, inst_ty, zcu)) {
......@@ -30649,7 +30578,6 @@ fn storePtr2(
3064930578 }
3065030579
3065130580 try sema.requireRuntimeBlock(block, src, runtime_src);
30652 try sema.queueFullTypeResolution(elem_ty);
3065330581
3065430582 if (ptr_ty.ptrInfo(mod).flags.vector_index == .runtime) {
3065530583 const ptr_inst = ptr.toIndex().?;
......@@ -30871,10 +30799,10 @@ fn bitCast(
3087130799 operand_src: ?LazySrcLoc,
3087230800) CompileError!Air.Inst.Ref {
3087330801 const zcu = sema.mod;
30874 try sema.resolveTypeLayout(dest_ty);
30802 try dest_ty.resolveLayout(zcu);
3087530803
3087630804 const old_ty = sema.typeOf(inst);
30877 try sema.resolveTypeLayout(old_ty);
30805 try old_ty.resolveLayout(zcu);
3087830806
3087930807 const dest_bits = dest_ty.bitSize(zcu);
3088030808 const old_bits = old_ty.bitSize(zcu);
......@@ -31056,7 +30984,7 @@ fn coerceEnumToUnion(
3105630984
3105730985 const union_obj = mod.typeToUnion(union_ty).?;
3105830986 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);
3106030988 if (field_ty.zigTypeTag(mod) == .NoReturn) {
3106130989 const msg = msg: {
3106230990 const msg = try sema.errMsg(inst_src, "cannot initialize 'noreturn' field of union", .{});
......@@ -31469,8 +31397,8 @@ fn coerceTupleToStruct(
3146931397) !Air.Inst.Ref {
3147031398 const mod = sema.mod;
3147131399 const ip = &mod.intern_pool;
31472 try sema.resolveTypeFields(struct_ty);
31473 try sema.resolveStructFieldInits(struct_ty);
31400 try struct_ty.resolveFields(mod);
31401 try struct_ty.resolveStructFieldInits(mod);
3147431402
3147531403 if (struct_ty.isTupleOrAnonStruct(mod)) {
3147631404 return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src);
......@@ -31817,7 +31745,7 @@ fn analyzeDeclRefInner(sema: *Sema, src: LazySrcLoc, decl_index: InternPool.Decl
3181731745 });
3181831746 // TODO: if this is a `decl_ref` of a non-variable decl, only depend on decl type
3181931747 try sema.declareDependency(.{ .decl_val = decl_index });
31820 const ptr_ty = try sema.ptrType(.{
31748 const ptr_ty = try mod.ptrTypeSema(.{
3182131749 .child = decl_val.typeOf(mod).toIntern(),
3182231750 .flags = .{
3182331751 .alignment = owner_decl.alignment,
......@@ -31864,14 +31792,14 @@ fn analyzeRef(
3186431792
3186531793 try sema.requireRuntimeBlock(block, src, null);
3186631794 const address_space = target_util.defaultAddressSpace(mod.getTarget(), .local);
31867 const ptr_type = try sema.ptrType(.{
31795 const ptr_type = try mod.ptrTypeSema(.{
3186831796 .child = operand_ty.toIntern(),
3186931797 .flags = .{
3187031798 .is_const = true,
3187131799 .address_space = address_space,
3187231800 },
3187331801 });
31874 const mut_ptr_type = try sema.ptrType(.{
31802 const mut_ptr_type = try mod.ptrTypeSema(.{
3187531803 .child = operand_ty.toIntern(),
3187631804 .flags = .{ .address_space = address_space },
3187731805 });
......@@ -31979,7 +31907,7 @@ fn analyzeSliceLen(
3197931907 if (slice_val.isUndef(mod)) {
3198031908 return mod.undefRef(Type.usize);
3198131909 }
31982 return mod.intRef(Type.usize, try slice_val.sliceLen(sema));
31910 return mod.intRef(Type.usize, try slice_val.sliceLen(mod));
3198331911 }
3198431912 try sema.requireRuntimeBlock(block, src, null);
3198531913 return block.addTyOp(.slice_len, Type.usize, slice_inst);
......@@ -32347,7 +32275,7 @@ fn analyzeSlice(
3234732275 assert(manyptr_ty_key.flags.size == .One);
3234832276 manyptr_ty_key.child = elem_ty.toIntern();
3234932277 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);
3235132279 } else ptr_or_slice;
3235232280
3235332281 const start = try sema.coerce(block, Type.usize, uncasted_start, start_src);
......@@ -32416,7 +32344,7 @@ fn analyzeSlice(
3241632344 return sema.fail(block, src, "slice of undefined", .{});
3241732345 }
3241832346 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);
3242032348 const len_plus_sent = slice_len + @intFromBool(has_sentinel);
3242132349 const slice_len_val_with_sentinel = try mod.intValue(Type.usize, len_plus_sent);
3242232350 if (!(try sema.compareAll(end_val, .lte, slice_len_val_with_sentinel, Type.usize))) {
......@@ -32431,7 +32359,7 @@ fn analyzeSlice(
3243132359 "end index {} out of bounds for slice of length {d}{s}",
3243232360 .{
3243332361 end_val.fmtValue(mod, sema),
32434 try slice_val.sliceLen(sema),
32362 try slice_val.sliceLen(mod),
3243532363 sentinel_label,
3243632364 },
3243732365 );
......@@ -32504,7 +32432,7 @@ fn analyzeSlice(
3250432432
3250532433 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);
3250632434 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);
3250832436 const res = try sema.pointerDerefExtra(block, src, elem_ptr);
3250932437 const actual_sentinel = switch (res) {
3251032438 .runtime_load => break :sentinel_check,
......@@ -32567,9 +32495,9 @@ fn analyzeSlice(
3256732495 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;
3256832496
3256932497 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(.{
3257332501 .child = (try mod.arrayType(.{
3257432502 .len = new_len_int,
3257532503 .sentinel = if (sentinel) |s| s.toIntern() else .none,
......@@ -32631,7 +32559,7 @@ fn analyzeSlice(
3263132559 return sema.fail(block, src, "non-zero length slice of undefined pointer", .{});
3263232560 }
3263332561
32634 const return_ty = try sema.ptrType(.{
32562 const return_ty = try mod.ptrTypeSema(.{
3263532563 .child = elem_ty.toIntern(),
3263632564 .sentinel = if (sentinel) |s| s.toIntern() else .none,
3263732565 .flags = .{
......@@ -32659,7 +32587,7 @@ fn analyzeSlice(
3265932587 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {
3266032588 // we don't need to add one for sentinels because the
3266132589 // 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));
3266332591 }
3266432592
3266532593 const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice);
......@@ -32751,7 +32679,7 @@ fn cmpNumeric(
3275132679 if (lhs_val.isNan(mod) or rhs_val.isNan(mod)) {
3275232680 return if (op == std.math.CompareOperator.neq) .bool_true else .bool_false;
3275332681 }
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))
3275532683 .bool_true
3275632684 else
3275732685 .bool_false;
......@@ -32820,11 +32748,11 @@ fn cmpNumeric(
3282032748 // a signed integer with mantissa bits + 1, and if there was any non-integral part of the float,
3282132749 // add/subtract 1.
3282232750 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))
3282432752 else
3282532753 (lhs_ty.isRuntimeFloat() or lhs_ty.isSignedInt(mod));
3282632754 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))
3282832756 else
3282932757 (rhs_ty.isRuntimeFloat() or rhs_ty.isSignedInt(mod));
3283032758 const dest_int_is_signed = lhs_is_signed or rhs_is_signed;
......@@ -32972,7 +32900,7 @@ fn compareIntsOnlyPossibleResult(
3297232900) Allocator.Error!?bool {
3297332901 const mod = sema.mod;
3297432902 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;
3297632904 const is_zero = vs_zero == .eq;
3297732905 const is_negative = vs_zero == .lt;
3297832906 const is_positive = vs_zero == .gt;
......@@ -33136,7 +33064,6 @@ fn wrapErrorUnionPayload(
3313633064 } })));
3313733065 }
3313833066 try sema.requireRuntimeBlock(block, inst_src, null);
33139 try sema.queueFullTypeResolution(dest_payload_ty);
3314033067 return block.addTyOp(.wrap_errunion_payload, dest_ty, coerced);
3314133068}
3314233069
......@@ -33939,7 +33866,7 @@ fn resolvePeerTypesInner(
3393933866
3394033867 opt_ptr_info = ptr_info;
3394133868 }
33942 return .{ .success = try sema.ptrType(opt_ptr_info.?) };
33869 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };
3394333870 },
3394433871
3394533872 .ptr => {
......@@ -34249,7 +34176,7 @@ fn resolvePeerTypesInner(
3424934176 },
3425034177 }
3425134178
34252 return .{ .success = try sema.ptrType(opt_ptr_info.?) };
34179 return .{ .success = try mod.ptrTypeSema(opt_ptr_info.?) };
3425334180 },
3425434181
3425534182 .func => {
......@@ -34606,7 +34533,7 @@ fn resolvePeerTypesInner(
3460634533 var comptime_val: ?Value = null;
3460734534 for (peer_tys) |opt_ty| {
3460834535 const struct_ty = opt_ty orelse continue;
34609 try sema.resolveStructFieldInits(struct_ty);
34536 try struct_ty.resolveStructFieldInits(mod);
3461034537
3461134538 const uncoerced_field_val = try struct_ty.structFieldValueComptime(mod, field_index) orelse {
3461234539 comptime_val = null;
......@@ -34742,181 +34669,22 @@ pub fn resolveFnTypes(sema: *Sema, fn_ty: Type) CompileError!void {
3474234669 const ip = &mod.intern_pool;
3474334670 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
3474734674 if (mod.comp.config.any_error_tracing and
3474834675 Type.fromInterned(fn_ty_info.return_type).isError(mod))
3474934676 {
3475034677 // Ensure the type exists so that backends can assume that.
34751 _ = try sema.getBuiltinType("StackTrace");
34678 _ = try mod.getBuiltinType("StackTrace");
3475234679 }
3475334680
3475434681 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);
3475634683 }
3475734684}
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.
3476134686fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value {
34762 const mod = 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 }
34687 return val.resolveLazy(sema.arena, sema.mod);
3492034688}
3492134689
3492234690/// Resolve a struct's alignment only without triggering resolution of its layout.
......@@ -34925,11 +34693,13 @@ pub fn resolveStructAlignment(
3492534693 sema: *Sema,
3492634694 ty: InternPool.Index,
3492734695 struct_type: InternPool.LoadedStructType,
34928) CompileError!Alignment {
34696) SemaError!void {
3492934697 const mod = sema.mod;
3493034698 const ip = &mod.intern_pool;
3493134699 const target = mod.getTarget();
3493234700
34701 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
34702
3493334703 assert(struct_type.flagsPtr(ip).alignment == .none);
3493434704 assert(struct_type.layout != .@"packed");
3493534705
......@@ -34940,7 +34710,7 @@ pub fn resolveStructAlignment(
3494034710 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
3494134711 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
3494234712 struct_type.flagsPtr(ip).alignment = result;
34943 return result;
34713 return;
3494434714 }
3494534715
3494634716 try sema.resolveTypeFieldsStruct(ty, struct_type);
......@@ -34952,7 +34722,7 @@ pub fn resolveStructAlignment(
3495234722 struct_type.flagsPtr(ip).assumed_pointer_aligned = true;
3495334723 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
3495434724 struct_type.flagsPtr(ip).alignment = result;
34955 return result;
34725 return;
3495634726 }
3495734727 defer struct_type.clearAlignmentWip(ip);
3495834728
......@@ -34962,30 +34732,35 @@ pub fn resolveStructAlignment(
3496234732 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
3496334733 if (struct_type.fieldIsComptime(ip, i) or try sema.typeRequiresComptime(field_ty))
3496434734 continue;
34965 const field_align = try sema.structFieldAlignment(
34735 const field_align = try mod.structFieldAlignmentAdvanced(
3496634736 struct_type.fieldAlign(ip, i),
3496734737 field_ty,
3496834738 struct_type.layout,
34739 .sema,
3496934740 );
3497034741 result = result.maxStrict(field_align);
3497134742 }
3497234743
3497334744 struct_type.flagsPtr(ip).alignment = result;
34974 return result;
3497534745}
3497634746
34977fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
34747pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void {
3497834748 const zcu = sema.mod;
3497934749 const ip = &zcu.intern_pool;
3498034750 const struct_type = zcu.typeToStruct(ty) orelse return;
3498134751
34752 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
34753
3498234754 if (struct_type.haveLayout(ip))
3498334755 return;
3498434756
34985 try sema.resolveTypeFields(ty);
34757 try ty.resolveFields(zcu);
3498634758
3498734759 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 };
3498934764 return;
3499034765 }
3499134766
......@@ -35021,10 +34796,11 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void {
3502134796 },
3502234797 else => return err,
3502334798 };
35024 field_align.* = try sema.structFieldAlignment(
34799 field_align.* = try zcu.structFieldAlignmentAdvanced(
3502534800 struct_type.fieldAlign(ip, i),
3502634801 field_ty,
3502734802 struct_type.layout,
34803 .sema,
3502834804 );
3502934805 big_align = big_align.maxStrict(field_align.*);
3503034806 }
......@@ -35160,7 +34936,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co
3516034936 var accumulator: u64 = 0;
3516134937 for (0..struct_type.field_types.len) |i| {
3516234938 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);
3516434940 }
3516534941 break :blk accumulator;
3516634942 };
......@@ -35270,11 +35046,13 @@ pub fn resolveUnionAlignment(
3527035046 sema: *Sema,
3527135047 ty: Type,
3527235048 union_type: InternPool.LoadedUnionType,
35273) CompileError!Alignment {
35049) SemaError!void {
3527435050 const mod = sema.mod;
3527535051 const ip = &mod.intern_pool;
3527635052 const target = mod.getTarget();
3527735053
35054 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35055
3527835056 assert(!union_type.haveLayout(ip));
3527935057
3528035058 if (union_type.flagsPtr(ip).status == .field_types_wip) {
......@@ -35284,7 +35062,7 @@ pub fn resolveUnionAlignment(
3528435062 union_type.flagsPtr(ip).assumed_pointer_aligned = true;
3528535063 const result = Alignment.fromByteUnits(@divExact(target.ptrBitWidth(), 8));
3528635064 union_type.flagsPtr(ip).alignment = result;
35287 return result;
35065 return;
3528835066 }
3528935067
3529035068 try sema.resolveTypeFieldsUnion(ty, union_type);
......@@ -35304,11 +35082,10 @@ pub fn resolveUnionAlignment(
3530435082 }
3530535083
3530635084 union_type.flagsPtr(ip).alignment = max_align;
35307 return max_align;
3530835085}
3530935086
3531035087/// 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 {
3531235089 const zcu = sema.mod;
3531335090 const ip = &zcu.intern_pool;
3531435091
......@@ -35317,6 +35094,8 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3531735094 // Load again, since the tag type might have changed due to resolution.
3531835095 const union_type = ip.loadUnionType(ty.ip_index);
3531935096
35097 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35098
3532035099 switch (union_type.flagsPtr(ip).status) {
3532135100 .none, .have_field_types => {},
3532235101 .field_types_wip, .layout_wip => {
......@@ -35425,53 +35204,15 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3542535204
3542635205/// Returns `error.AnalysisFail` if any of the types (recursively) failed to
3542735206/// be resolved.
35428pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!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 {
35207pub fn resolveStructFully(sema: *Sema, ty: Type) SemaError!void {
3546935208 try sema.resolveStructLayout(ty);
3547035209
3547135210 const mod = sema.mod;
3547235211 const ip = &mod.intern_pool;
3547335212 const struct_type = mod.typeToStruct(ty).?;
3547435213
35214 assert(sema.ownerUnit().unwrap().decl == struct_type.decl.unwrap().?);
35215
3547535216 if (struct_type.setFullyResolved(ip)) return;
3547635217 errdefer struct_type.clearFullyResolved(ip);
3547735218
......@@ -35481,16 +35222,19 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void {
3548135222
3548235223 for (0..struct_type.field_types.len) |i| {
3548335224 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]);
35484 try sema.resolveTypeFully(field_ty);
35225 try field_ty.resolveFully(mod);
3548535226 }
3548635227}
3548735228
35488fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
35229pub fn resolveUnionFully(sema: *Sema, ty: Type) SemaError!void {
3548935230 try sema.resolveUnionLayout(ty);
3549035231
3549135232 const mod = sema.mod;
3549235233 const ip = &mod.intern_pool;
3549335234 const union_obj = mod.typeToUnion(ty).?;
35235
35236 assert(sema.ownerUnit().unwrap().decl == union_obj.decl);
35237
3549435238 switch (union_obj.flagsPtr(ip).status) {
3549535239 .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
3549635240 .fully_resolved_wip, .fully_resolved => return,
......@@ -35506,7 +35250,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
3550635250 union_obj.flagsPtr(ip).status = .fully_resolved_wip;
3550735251 for (0..union_obj.field_types.len) |field_index| {
3550835252 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);
3551035254 }
3551135255 union_obj.flagsPtr(ip).status = .fully_resolved;
3551235256 }
......@@ -35515,135 +35259,18 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void {
3551535259 _ = try sema.typeRequiresComptime(ty);
3551635260}
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
3563735262pub fn resolveTypeFieldsStruct(
3563835263 sema: *Sema,
3563935264 ty: InternPool.Index,
3564035265 struct_type: InternPool.LoadedStructType,
35641) CompileError!void {
35266) SemaError!void {
3564235267 const zcu = sema.mod;
3564335268 const ip = &zcu.intern_pool;
3564435269 // If there is no owner decl it means the struct has no fields.
3564535270 const owner_decl = struct_type.decl.unwrap() orelse return;
3564635271
35272 assert(sema.ownerUnit().unwrap().decl == owner_decl);
35273
3564735274 switch (zcu.declPtr(owner_decl).analysis) {
3564835275 .file_failure,
3564935276 .dependency_failure,
......@@ -35674,16 +35301,19 @@ pub fn resolveTypeFieldsStruct(
3567435301 }
3567535302 return error.AnalysisFail;
3567635303 },
35677 else => |e| return e,
35304 error.OutOfMemory => return error.OutOfMemory,
35305 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3567835306 };
3567935307}
3568035308
35681pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {
35309pub fn resolveStructFieldInits(sema: *Sema, ty: Type) SemaError!void {
3568235310 const zcu = sema.mod;
3568335311 const ip = &zcu.intern_pool;
3568435312 const struct_type = zcu.typeToStruct(ty) orelse return;
3568535313 const owner_decl = struct_type.decl.unwrap() orelse return;
3568635314
35315 assert(sema.ownerUnit().unwrap().decl == owner_decl);
35316
3568735317 // Inits can start as resolved
3568835318 if (struct_type.haveFieldInits(ip)) return;
3568935319
......@@ -35706,15 +35336,19 @@ pub fn resolveStructFieldInits(sema: *Sema, ty: Type) CompileError!void {
3570635336 }
3570735337 return error.AnalysisFail;
3570835338 },
35709 else => |e| return e,
35339 error.OutOfMemory => return error.OutOfMemory,
35340 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3571035341 };
3571135342 struct_type.setHaveFieldInits(ip);
3571235343}
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 {
3571535346 const zcu = sema.mod;
3571635347 const ip = &zcu.intern_pool;
3571735348 const owner_decl = zcu.declPtr(union_type.decl);
35349
35350 assert(sema.ownerUnit().unwrap().decl == union_type.decl);
35351
3571835352 switch (owner_decl.analysis) {
3571935353 .file_failure,
3572035354 .dependency_failure,
......@@ -35752,7 +35386,8 @@ pub fn resolveTypeFieldsUnion(sema: *Sema, ty: Type, union_type: InternPool.Load
3575235386 }
3575335387 return error.AnalysisFail;
3575435388 },
35755 else => |e| return e,
35389 error.OutOfMemory => return error.OutOfMemory,
35390 error.ComptimeBreak, error.ComptimeReturn, error.GenericPoison => unreachable,
3575635391 };
3575735392 union_type.flagsPtr(ip).status = .have_field_types;
3575835393}
......@@ -36801,106 +36436,6 @@ fn generateUnionTagTypeSimple(
3680136436 return enum_ty;
3680236437}
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
3690436439/// There is another implementation of this in `Type.onePossibleValue`. This one
3690536440/// in `Sema` is for calling during semantic analysis, and performs field resolution
3690636441/// 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 {
3710436639 },
3710536640
3710636641 .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
3710736646 const struct_type = ip.loadStructType(ty.toIntern());
37108 try sema.resolveTypeFieldsStruct(ty.toIntern(), struct_type);
3710936647
3711036648 if (struct_type.field_types.len == 0) {
3711136649 // In this case the struct has no fields at all and
......@@ -37122,20 +36660,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3712236660 );
3712336661 for (field_vals, 0..) |*field_val, i| {
3712436662 if (struct_type.fieldIsComptime(ip, i)) {
37125 try sema.resolveStructFieldInits(ty);
36663 try ty.resolveStructFieldInits(zcu);
3712636664 field_val.* = struct_type.field_inits.get(ip)[i];
3712736665 continue;
3712836666 }
3712936667 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 }
3713936668 if (try sema.typeHasOnePossibleValue(field_ty)) |field_opv| {
3714036669 field_val.* = field_opv.toIntern();
3714136670 } else return null;
......@@ -37163,8 +36692,11 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3716336692 },
3716436693
3716536694 .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
3716636699 const union_obj = ip.loadUnionType(ty.toIntern());
37167 try sema.resolveTypeFieldsUnion(ty, union_obj);
3716836700 const tag_val = (try sema.typeHasOnePossibleValue(Type.fromInterned(union_obj.tagTypePtr(ip).*))) orelse
3716936701 return null;
3717036702 if (union_obj.field_types.len == 0) {
......@@ -37172,15 +36704,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3717236704 return Value.fromInterned(only);
3717336705 }
3717436706 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 }
3718436707 const val_val = (try sema.typeHasOnePossibleValue(only_field_ty)) orelse
3718536708 return null;
3718636709 const only = try zcu.intern(.{ .un = .{
......@@ -37298,7 +36821,7 @@ fn analyzeComptimeAlloc(
3729836821 // Needed to make an anon decl with type `var_type` (the `finish()` call below).
3729936822 _ = try sema.typeHasOnePossibleValue(var_type);
3730036823
37301 const ptr_type = try sema.ptrType(.{
36824 const ptr_type = try mod.ptrTypeSema(.{
3730236825 .child = var_type.toIntern(),
3730336826 .flags = .{
3730436827 .alignment = alignment,
......@@ -37485,64 +37008,28 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3748537008
3748637009/// `generic_poison` will return false.
3748737010/// May return false negatives when structs and unions are having their field types resolved.
37488pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
37489 return ty.comptimeOnlyAdvanced(sema.mod, sema);
37011pub fn typeRequiresComptime(sema: *Sema, ty: Type) SemaError!bool {
37012 return ty.comptimeOnlyAdvanced(sema.mod, .sema);
3749037013}
3749137014
37492pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
37493 const mod = sema.mod;
37494 return ty.hasRuntimeBitsAdvanced(mod, false, .{ .sema = sema }) catch |err| switch (err) {
37015pub fn typeHasRuntimeBits(sema: *Sema, ty: Type) SemaError!bool {
37016 return ty.hasRuntimeBitsAdvanced(sema.mod, false, .sema) catch |err| switch (err) {
3749537017 error.NeedLazy => unreachable,
3749637018 else => |e| return e,
3749737019 };
3749837020}
3749937021
37500pub fn typeAbiSize(sema: *Sema, ty: Type) !u64 {
37501 try sema.resolveTypeLayout(ty);
37022pub fn typeAbiSize(sema: *Sema, ty: Type) SemaError!u64 {
37023 try ty.resolveLayout(sema.mod);
3750237024 return ty.abiSize(sema.mod);
3750337025}
3750437026
37505pub fn typeAbiAlignment(sema: *Sema, ty: Type) CompileError!Alignment {
37506 return (try ty.abiAlignmentAdvanced(sema.mod, .{ .sema = 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;
37027pub fn typeAbiAlignment(sema: *Sema, ty: Type) SemaError!Alignment {
37028 return (try ty.abiAlignmentAdvanced(sema.mod, .sema)).scalar;
3754237029}
3754337030
3754437031pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool {
37545 return ty.fnHasRuntimeBitsAdvanced(sema.mod, sema);
37032 return ty.fnHasRuntimeBitsAdvanced(sema.mod, .sema);
3754637033}
3754737034
3754837035fn unionFieldIndex(
......@@ -37554,7 +37041,7 @@ fn unionFieldIndex(
3755437041) !u32 {
3755537042 const mod = sema.mod;
3755637043 const ip = &mod.intern_pool;
37557 try sema.resolveTypeFields(union_ty);
37044 try union_ty.resolveFields(mod);
3755837045 const union_obj = mod.typeToUnion(union_ty).?;
3755937046 const field_index = union_obj.loadTagType(ip).nameIndex(ip, field_name) orelse
3756037047 return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name);
......@@ -37570,7 +37057,7 @@ fn structFieldIndex(
3757037057) !u32 {
3757137058 const mod = sema.mod;
3757237059 const ip = &mod.intern_pool;
37573 try sema.resolveTypeFields(struct_ty);
37060 try struct_ty.resolveFields(mod);
3757437061 if (struct_ty.isAnonStruct(mod)) {
3757537062 return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src);
3757637063 } else {
......@@ -37601,10 +37088,6 @@ fn anonStructFieldIndex(
3760137088 });
3760237089}
3760337090
37604fn queueFullTypeResolution(sema: *Sema, ty: Type) !void {
37605 try sema.types_to_resolve.put(sema.gpa, ty.toIntern(), {});
37606}
37607
3760837091/// If the value overflowed the type, returns a comptime_int (or vector thereof) instead, setting
3760937092/// overflow_idx to the vector index the overflow was at (or 0 for a scalar).
3761037093fn 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 {
3766237145 // resorting to BigInt first.
3766337146 var lhs_space: Value.BigIntSpace = undefined;
3766437147 var rhs_space: Value.BigIntSpace = undefined;
37665 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
37666 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
37148 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
37149 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
3766737150 const limbs = try sema.arena.alloc(
3766837151 std.math.big.Limb,
3766937152 @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 {
3775237235 // resorting to BigInt first.
3775337236 var lhs_space: Value.BigIntSpace = undefined;
3775437237 var rhs_space: Value.BigIntSpace = undefined;
37755 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
37756 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
37238 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
37239 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
3775737240 const limbs = try sema.arena.alloc(
3775837241 std.math.big.Limb,
3775937242 @max(lhs_bigint.limbs.len, rhs_bigint.limbs.len) + 1,
......@@ -37836,8 +37319,8 @@ fn intSubWithOverflowScalar(
3783637319
3783737320 var lhs_space: Value.BigIntSpace = undefined;
3783837321 var rhs_space: Value.BigIntSpace = undefined;
37839 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
37840 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
37322 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
37323 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
3784137324 const limbs = try sema.arena.alloc(
3784237325 std.math.big.Limb,
3784337326 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -38024,7 +37507,7 @@ fn intFitsInType(
3802437507
3802537508fn intInRange(sema: *Sema, tag_ty: Type, int_val: Value, end: usize) !bool {
3802637509 const mod = sema.mod;
38027 if (!(try int_val.compareAllWithZeroAdvanced(.gte, sema))) return false;
37510 if (!(try int_val.compareAllWithZeroSema(.gte, mod))) return false;
3802837511 const end_val = try mod.intValue(tag_ty, end);
3802937512 if (!(try sema.compareAll(int_val, .lt, end_val, tag_ty))) return false;
3803037513 return true;
......@@ -38094,8 +37577,8 @@ fn intAddWithOverflowScalar(
3809437577
3809537578 var lhs_space: Value.BigIntSpace = undefined;
3809637579 var rhs_space: Value.BigIntSpace = undefined;
38097 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, sema);
38098 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, sema);
37580 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_space, mod, .sema);
37581 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_space, mod, .sema);
3809937582 const limbs = try sema.arena.alloc(
3810037583 std.math.big.Limb,
3810137584 std.math.big.int.calcTwosCompLimbCount(info.bits),
......@@ -38149,7 +37632,7 @@ fn compareScalar(
3814937632 switch (op) {
3815037633 .eq => return sema.valuesEqual(coerced_lhs, coerced_rhs, ty),
3815137634 .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),
3815337636 }
3815437637}
3815537638
......@@ -38185,80 +37668,6 @@ fn compareVector(
3818537668 } })));
3818637669}
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
3826237671/// Merge lhs with rhs.
3826337672/// Asserts that lhs and rhs are both error sets and are resolved.
3826437673fn 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
3829937708 return sema.typeOf(ref).zigTypeTag(sema.mod) == tag;
3830037709}
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
3830937711pub fn declareDependency(sema: *Sema, dependee: InternPool.Dependee) !void {
3831037712 if (!sema.mod.comp.debug_incremental) return;
3831137713
......@@ -38425,12 +37827,12 @@ fn maybeDerefSliceAsArray(
3842537827 else => unreachable,
3842637828 };
3842737829 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);
3842937831 const array_ty = try zcu.arrayType(.{
3843037832 .child = elem_ty.toIntern(),
3843137833 .len = len,
3843237834 });
38433 const ptr_ty = try sema.ptrType(p: {
37835 const ptr_ty = try zcu.ptrTypeSema(p: {
3843437836 var p = Type.fromInterned(slice.ty).ptrInfo(zcu);
3843537837 p.flags.size = .One;
3843637838 p.child = array_ty.toIntern();
src/Sema/bitcast.zig+4-4
......@@ -78,8 +78,8 @@ fn bitCastInner(
7878
7979 const val_ty = val.typeOf(zcu);
8080
81 try sema.resolveTypeLayout(val_ty);
82 try sema.resolveTypeLayout(dest_ty);
81 try val_ty.resolveLayout(zcu);
82 try dest_ty.resolveLayout(zcu);
8383
8484 assert(val_ty.hasWellDefinedLayout(zcu));
8585
......@@ -136,8 +136,8 @@ fn bitCastSpliceInner(
136136 const val_ty = val.typeOf(zcu);
137137 const splice_val_ty = splice_val.typeOf(zcu);
138138
139 try sema.resolveTypeLayout(val_ty);
140 try sema.resolveTypeLayout(splice_val_ty);
139 try val_ty.resolveLayout(zcu);
140 try splice_val_ty.resolveLayout(zcu);
141141
142142 const splice_bits = splice_val_ty.bitSize(zcu);
143143
src/Type.zig+508-116
......@@ -5,6 +5,7 @@
55
66const std = @import("std");
77const builtin = @import("builtin");
8const Allocator = std.mem.Allocator;
89const Value = @import("Value.zig");
910const assert = std.debug.assert;
1011const Target = std.Target;
......@@ -18,6 +19,7 @@ const InternPool = @import("InternPool.zig");
1819const Alignment = InternPool.Alignment;
1920const Zir = std.zig.Zir;
2021const Type = @This();
22const SemaError = Zcu.SemaError;
2123
2224ip_index: InternPool.Index,
2325
......@@ -458,7 +460,7 @@ pub fn toValue(self: Type) Value {
458460 return Value.fromInterned(self.toIntern());
459461}
460462
461const RuntimeBitsError = Module.CompileError || error{NeedLazy};
463const RuntimeBitsError = SemaError || error{NeedLazy};
462464
463465/// true if and only if the type takes up space in memory at runtime.
464466/// There are two reasons a type will return false:
......@@ -475,7 +477,7 @@ pub fn hasRuntimeBitsAdvanced(
475477 ty: Type,
476478 mod: *Module,
477479 ignore_comptime_only: bool,
478 strat: AbiAlignmentAdvancedStrat,
480 strat: ResolveStratLazy,
479481) RuntimeBitsError!bool {
480482 const ip = &mod.intern_pool;
481483 return switch (ty.toIntern()) {
......@@ -488,8 +490,8 @@ pub fn hasRuntimeBitsAdvanced(
488490 // to comptime-only types do not, with the exception of function pointers.
489491 if (ignore_comptime_only) return true;
490492 return switch (strat) {
491 .sema => |sema| !(try sema.typeRequiresComptime(ty)),
492 .eager => !comptimeOnly(ty, mod),
493 .sema => !try ty.comptimeOnlyAdvanced(mod, .sema),
494 .eager => !ty.comptimeOnly(mod),
493495 .lazy => error.NeedLazy,
494496 };
495497 },
......@@ -506,8 +508,8 @@ pub fn hasRuntimeBitsAdvanced(
506508 }
507509 if (ignore_comptime_only) return true;
508510 return switch (strat) {
509 .sema => |sema| !(try sema.typeRequiresComptime(child_ty)),
510 .eager => !comptimeOnly(child_ty, mod),
511 .sema => !try child_ty.comptimeOnlyAdvanced(mod, .sema),
512 .eager => !child_ty.comptimeOnly(mod),
511513 .lazy => error.NeedLazy,
512514 };
513515 },
......@@ -578,7 +580,7 @@ pub fn hasRuntimeBitsAdvanced(
578580 return true;
579581 }
580582 switch (strat) {
581 .sema => |sema| _ = try sema.resolveTypeFields(ty),
583 .sema => try ty.resolveFields(mod),
582584 .eager => assert(struct_type.haveFieldTypes(ip)),
583585 .lazy => if (!struct_type.haveFieldTypes(ip)) return error.NeedLazy,
584586 }
......@@ -622,7 +624,7 @@ pub fn hasRuntimeBitsAdvanced(
622624 },
623625 }
624626 switch (strat) {
625 .sema => |sema| _ = try sema.resolveTypeFields(ty),
627 .sema => try ty.resolveFields(mod),
626628 .eager => assert(union_type.flagsPtr(ip).status.haveFieldTypes()),
627629 .lazy => if (!union_type.flagsPtr(ip).status.haveFieldTypes())
628630 return error.NeedLazy,
......@@ -784,19 +786,18 @@ pub fn hasRuntimeBitsIgnoreComptime(ty: Type, mod: *Module) bool {
784786}
785787
786788pub fn fnHasRuntimeBits(ty: Type, mod: *Module) bool {
787 return ty.fnHasRuntimeBitsAdvanced(mod, null) catch unreachable;
789 return ty.fnHasRuntimeBitsAdvanced(mod, .normal) catch unreachable;
788790}
789791
790792/// Determines whether a function type has runtime bits, i.e. whether a
791793/// function with this type can exist at runtime.
792794/// Asserts that `ty` is a function type.
793/// If `opt_sema` is not provided, asserts that the return type is sufficiently resolved.
794pub fn fnHasRuntimeBitsAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.CompileError!bool {
795pub fn fnHasRuntimeBitsAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool {
795796 const fn_info = mod.typeToFunc(ty).?;
796797 if (fn_info.is_generic) return false;
797798 if (fn_info.is_var_args) return true;
798799 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);
800801}
801802
802803pub fn isFnOrHasRuntimeBits(ty: Type, mod: *Module) bool {
......@@ -820,23 +821,23 @@ pub fn isNoReturn(ty: Type, mod: *Module) bool {
820821
821822/// Returns `none` if the pointer is naturally aligned and the element type is 0-bit.
822823pub fn ptrAlignment(ty: Type, mod: *Module) Alignment {
823 return ptrAlignmentAdvanced(ty, mod, null) catch unreachable;
824 return ptrAlignmentAdvanced(ty, mod, .normal) catch unreachable;
824825}
825826
826pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !Alignment {
827pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) !Alignment {
827828 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
828829 .ptr_type => |ptr_type| {
829830 if (ptr_type.flags.alignment != .none)
830831 return ptr_type.flags.alignment;
831832
832 if (opt_sema) |sema| {
833 const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .{ .sema = sema });
833 if (strat == .sema) {
834 const res = try Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .sema);
834835 return res.scalar;
835836 }
836837
837838 return (Type.fromInterned(ptr_type.child).abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
838839 },
839 .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(mod, opt_sema),
840 .opt_type => |child| Type.fromInterned(child).ptrAlignmentAdvanced(mod, strat),
840841 else => unreachable,
841842 };
842843}
......@@ -868,10 +869,34 @@ pub const AbiAlignmentAdvanced = union(enum) {
868869 val: Value,
869870};
870871
871pub const AbiAlignmentAdvancedStrat = union(enum) {
872 eager,
872pub const ResolveStratLazy = enum {
873 /// Return a `lazy_size` or `lazy_align` value if necessary.
874 /// This value can be resolved later using `Value.resolveLazy`.
873875 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 }
875900};
876901
877902/// If you pass `eager` you will get back `scalar` and assert the type is resolved.
......@@ -883,17 +908,12 @@ pub const AbiAlignmentAdvancedStrat = union(enum) {
883908pub fn abiAlignmentAdvanced(
884909 ty: Type,
885910 mod: *Module,
886 strat: AbiAlignmentAdvancedStrat,
887) Module.CompileError!AbiAlignmentAdvanced {
911 strat: ResolveStratLazy,
912) SemaError!AbiAlignmentAdvanced {
888913 const target = mod.getTarget();
889914 const use_llvm = mod.comp.config.use_llvm;
890915 const ip = &mod.intern_pool;
891916
892 const opt_sema = switch (strat) {
893 .sema => |sema| sema,
894 else => null,
895 };
896
897917 switch (ty.toIntern()) {
898918 .empty_struct_type => return AbiAlignmentAdvanced{ .scalar = .@"1" },
899919 else => switch (ip.indexToKey(ty.toIntern())) {
......@@ -911,7 +931,7 @@ pub fn abiAlignmentAdvanced(
911931 if (vector_type.len == 0) return .{ .scalar = .@"1" };
912932 switch (mod.comp.getZigBackend()) {
913933 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));
915935 if (elem_bits == 0) return .{ .scalar = .@"1" };
916936 const bytes = ((elem_bits * vector_type.len) + 7) / 8;
917937 const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes);
......@@ -1024,7 +1044,7 @@ pub fn abiAlignmentAdvanced(
10241044 const struct_type = ip.loadStructType(ty.toIntern());
10251045 if (struct_type.layout == .@"packed") {
10261046 switch (strat) {
1027 .sema => |sema| try sema.resolveTypeLayout(ty),
1047 .sema => try ty.resolveLayout(mod),
10281048 .lazy => if (struct_type.backingIntType(ip).* == .none) return .{
10291049 .val = Value.fromInterned((try mod.intern(.{ .int = .{
10301050 .ty = .comptime_int_type,
......@@ -1036,19 +1056,16 @@ pub fn abiAlignmentAdvanced(
10361056 return .{ .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiAlignment(mod) };
10371057 }
10381058
1039 const flags = struct_type.flagsPtr(ip).*;
1040 if (flags.alignment != .none) return .{ .scalar = flags.alignment };
1041
1042 return switch (strat) {
1059 if (struct_type.flagsPtr(ip).alignment == .none) switch (strat) {
10431060 .eager => unreachable, // struct alignment not resolved
1044 .sema => |sema| .{
1045 .scalar = try sema.resolveStructAlignment(ty.toIntern(), struct_type),
1046 },
1047 .lazy => .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{
1061 .sema => try ty.resolveStructAlignment(mod),
1062 .lazy => return .{ .val = Value.fromInterned(try mod.intern(.{ .int = .{
10481063 .ty = .comptime_int_type,
10491064 .storage = .{ .lazy_align = ty.toIntern() },
1050 } }))) },
1065 } })) },
10511066 };
1067
1068 return .{ .scalar = struct_type.flagsPtr(ip).alignment };
10521069 },
10531070 .anon_struct_type => |tuple| {
10541071 var big_align: Alignment = .@"1";
......@@ -1070,12 +1087,10 @@ pub fn abiAlignmentAdvanced(
10701087 },
10711088 .union_type => {
10721089 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) {
10771092 .eager => unreachable, // union layout not resolved
1078 .sema => |sema| return .{ .scalar = try sema.resolveUnionAlignment(ty, union_type) },
1093 .sema => try ty.resolveUnionAlignment(mod),
10791094 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{
10801095 .ty = .comptime_int_type,
10811096 .storage = .{ .lazy_align = ty.toIntern() },
......@@ -1117,9 +1132,9 @@ pub fn abiAlignmentAdvanced(
11171132fn abiAlignmentAdvancedErrorUnion(
11181133 ty: Type,
11191134 mod: *Module,
1120 strat: AbiAlignmentAdvancedStrat,
1135 strat: ResolveStratLazy,
11211136 payload_ty: Type,
1122) Module.CompileError!AbiAlignmentAdvanced {
1137) SemaError!AbiAlignmentAdvanced {
11231138 // This code needs to be kept in sync with the equivalent switch prong
11241139 // in abiSizeAdvanced.
11251140 const code_align = abiAlignment(Type.anyerror, mod);
......@@ -1154,8 +1169,8 @@ fn abiAlignmentAdvancedErrorUnion(
11541169fn abiAlignmentAdvancedOptional(
11551170 ty: Type,
11561171 mod: *Module,
1157 strat: AbiAlignmentAdvancedStrat,
1158) Module.CompileError!AbiAlignmentAdvanced {
1172 strat: ResolveStratLazy,
1173) SemaError!AbiAlignmentAdvanced {
11591174 const target = mod.getTarget();
11601175 const child_type = ty.optionalChild(mod);
11611176
......@@ -1217,8 +1232,8 @@ const AbiSizeAdvanced = union(enum) {
12171232pub fn abiSizeAdvanced(
12181233 ty: Type,
12191234 mod: *Module,
1220 strat: AbiAlignmentAdvancedStrat,
1221) Module.CompileError!AbiSizeAdvanced {
1235 strat: ResolveStratLazy,
1236) SemaError!AbiSizeAdvanced {
12221237 const target = mod.getTarget();
12231238 const use_llvm = mod.comp.config.use_llvm;
12241239 const ip = &mod.intern_pool;
......@@ -1252,9 +1267,9 @@ pub fn abiSizeAdvanced(
12521267 }
12531268 },
12541269 .vector_type => |vector_type| {
1255 const opt_sema = switch (strat) {
1256 .sema => |sema| sema,
1257 .eager => null,
1270 const sub_strat: ResolveStrat = switch (strat) {
1271 .sema => .sema,
1272 .eager => .normal,
12581273 .lazy => return .{ .val = Value.fromInterned((try mod.intern(.{ .int = .{
12591274 .ty = .comptime_int_type,
12601275 .storage = .{ .lazy_size = ty.toIntern() },
......@@ -1269,7 +1284,7 @@ pub fn abiSizeAdvanced(
12691284 };
12701285 const total_bytes = switch (mod.comp.getZigBackend()) {
12711286 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);
12731288 const total_bits = elem_bits * vector_type.len;
12741289 break :total_bytes (total_bits + 7) / 8;
12751290 },
......@@ -1403,7 +1418,7 @@ pub fn abiSizeAdvanced(
14031418 .struct_type => {
14041419 const struct_type = ip.loadStructType(ty.toIntern());
14051420 switch (strat) {
1406 .sema => |sema| try sema.resolveTypeLayout(ty),
1421 .sema => try ty.resolveLayout(mod),
14071422 .lazy => switch (struct_type.layout) {
14081423 .@"packed" => {
14091424 if (struct_type.backingIntType(ip).* == .none) return .{
......@@ -1436,7 +1451,7 @@ pub fn abiSizeAdvanced(
14361451 },
14371452 .anon_struct_type => |tuple| {
14381453 switch (strat) {
1439 .sema => |sema| try sema.resolveTypeLayout(ty),
1454 .sema => try ty.resolveLayout(mod),
14401455 .lazy, .eager => {},
14411456 }
14421457 const field_count = tuple.types.len;
......@@ -1449,7 +1464,7 @@ pub fn abiSizeAdvanced(
14491464 .union_type => {
14501465 const union_type = ip.loadUnionType(ty.toIntern());
14511466 switch (strat) {
1452 .sema => |sema| try sema.resolveTypeLayout(ty),
1467 .sema => try ty.resolveLayout(mod),
14531468 .lazy => if (!union_type.flagsPtr(ip).status.haveLayout()) return .{
14541469 .val = Value.fromInterned((try mod.intern(.{ .int = .{
14551470 .ty = .comptime_int_type,
......@@ -1493,8 +1508,8 @@ pub fn abiSizeAdvanced(
14931508fn abiSizeAdvancedOptional(
14941509 ty: Type,
14951510 mod: *Module,
1496 strat: AbiAlignmentAdvancedStrat,
1497) Module.CompileError!AbiSizeAdvanced {
1511 strat: ResolveStratLazy,
1512) SemaError!AbiSizeAdvanced {
14981513 const child_ty = ty.optionalChild(mod);
14991514
15001515 if (child_ty.isNoReturn(mod)) {
......@@ -1661,21 +1676,18 @@ pub fn maxIntAlignment(target: std.Target, use_llvm: bool) u16 {
16611676}
16621677
16631678pub fn bitSize(ty: Type, mod: *Module) u64 {
1664 return bitSizeAdvanced(ty, mod, null) catch unreachable;
1679 return bitSizeAdvanced(ty, mod, .normal) catch unreachable;
16651680}
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.
16701682pub fn bitSizeAdvanced(
16711683 ty: Type,
16721684 mod: *Module,
1673 opt_sema: ?*Sema,
1674) Module.CompileError!u64 {
1685 strat: ResolveStrat,
1686) SemaError!u64 {
16751687 const target = mod.getTarget();
16761688 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
16801692 switch (ip.indexToKey(ty.toIntern())) {
16811693 .int_type => |int_type| return int_type.bits,
......@@ -1690,22 +1702,22 @@ pub fn bitSizeAdvanced(
16901702 if (len == 0) return 0;
16911703 const elem_ty = Type.fromInterned(array_type.child);
16921704 const elem_size = @max(
1693 (try elem_ty.abiAlignmentAdvanced(mod, strat)).scalar.toByteUnits() orelse 0,
1694 (try elem_ty.abiSizeAdvanced(mod, strat)).scalar,
1705 (try elem_ty.abiAlignmentAdvanced(mod, strat_lazy)).scalar.toByteUnits() orelse 0,
1706 (try elem_ty.abiSizeAdvanced(mod, strat_lazy)).scalar,
16951707 );
16961708 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);
16981710 return (len - 1) * 8 * elem_size + elem_bit_size;
16991711 },
17001712 .vector_type => |vector_type| {
17011713 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);
17031715 return elem_bit_size * vector_type.len;
17041716 },
17051717 .opt_type => {
17061718 // Optionals and error unions are not packed so their bitsize
17071719 // includes padding bits.
1708 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
1720 return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8;
17091721 },
17101722
17111723 .error_set_type, .inferred_error_set_type => return mod.errorSetBits(),
......@@ -1713,7 +1725,7 @@ pub fn bitSizeAdvanced(
17131725 .error_union_type => {
17141726 // Optionals and error unions are not packed so their bitsize
17151727 // includes padding bits.
1716 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
1728 return (try abiSizeAdvanced(ty, mod, strat_lazy)).scalar * 8;
17171729 },
17181730 .func_type => unreachable, // represents machine code; not a pointer
17191731 .simple_type => |t| switch (t) {
......@@ -1770,43 +1782,43 @@ pub fn bitSizeAdvanced(
17701782 .struct_type => {
17711783 const struct_type = ip.loadStructType(ty.toIntern());
17721784 const is_packed = struct_type.layout == .@"packed";
1773 if (opt_sema) |sema| {
1774 try sema.resolveTypeFields(ty);
1775 if (is_packed) try sema.resolveTypeLayout(ty);
1785 if (strat == .sema) {
1786 try ty.resolveFields(mod);
1787 if (is_packed) try ty.resolveLayout(mod);
17761788 }
17771789 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);
17791791 }
1780 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1792 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;
17811793 },
17821794
17831795 .anon_struct_type => {
1784 if (opt_sema) |sema| try sema.resolveTypeFields(ty);
1785 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1796 if (strat == .sema) try ty.resolveFields(mod);
1797 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;
17861798 },
17871799
17881800 .union_type => {
17891801 const union_type = ip.loadUnionType(ty.toIntern());
17901802 const is_packed = ty.containerLayout(mod) == .@"packed";
1791 if (opt_sema) |sema| {
1792 try sema.resolveTypeFields(ty);
1793 if (is_packed) try sema.resolveTypeLayout(ty);
1803 if (strat == .sema) {
1804 try ty.resolveFields(mod);
1805 if (is_packed) try ty.resolveLayout(mod);
17941806 }
17951807 if (!is_packed) {
1796 return (try ty.abiSizeAdvanced(mod, strat)).scalar * 8;
1808 return (try ty.abiSizeAdvanced(mod, strat_lazy)).scalar * 8;
17971809 }
17981810 assert(union_type.flagsPtr(ip).status.haveFieldTypes());
17991811
18001812 var size: u64 = 0;
18011813 for (0..union_type.field_types.len) |field_index| {
18021814 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));
18041816 }
18051817
18061818 return size;
18071819 },
18081820 .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
18111823 // values, not types
18121824 .undef,
......@@ -2722,13 +2734,12 @@ pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value {
27222734/// During semantic analysis, instead call `Sema.typeRequiresComptime` which
27232735/// resolves field types rather than asserting they are already resolved.
27242736pub fn comptimeOnly(ty: Type, mod: *Module) bool {
2725 return ty.comptimeOnlyAdvanced(mod, null) catch unreachable;
2737 return ty.comptimeOnlyAdvanced(mod, .normal) catch unreachable;
27262738}
27272739
27282740/// `generic_poison` will return false.
27292741/// 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.
2731pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.CompileError!bool {
2742pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, strat: ResolveStrat) SemaError!bool {
27322743 const ip = &mod.intern_pool;
27332744 return switch (ty.toIntern()) {
27342745 .empty_struct_type => false,
......@@ -2738,19 +2749,19 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
27382749 .ptr_type => |ptr_type| {
27392750 const child_ty = Type.fromInterned(ptr_type.child);
27402751 switch (child_ty.zigTypeTag(mod)) {
2741 .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(mod, opt_sema),
2752 .Fn => return !try child_ty.fnHasRuntimeBitsAdvanced(mod, strat),
27422753 .Opaque => return false,
2743 else => return child_ty.comptimeOnlyAdvanced(mod, opt_sema),
2754 else => return child_ty.comptimeOnlyAdvanced(mod, strat),
27442755 }
27452756 },
27462757 .anyframe_type => |child| {
27472758 if (child == .none) return false;
2748 return Type.fromInterned(child).comptimeOnlyAdvanced(mod, opt_sema);
2759 return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat);
27492760 },
2750 .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(mod, opt_sema),
2751 .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(mod, opt_sema),
2752 .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(mod, opt_sema),
2753 .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(mod, opt_sema),
2761 .array_type => |array_type| return Type.fromInterned(array_type.child).comptimeOnlyAdvanced(mod, strat),
2762 .vector_type => |vector_type| return Type.fromInterned(vector_type.child).comptimeOnlyAdvanced(mod, strat),
2763 .opt_type => |child| return Type.fromInterned(child).comptimeOnlyAdvanced(mod, strat),
2764 .error_union_type => |error_union_type| return Type.fromInterned(error_union_type.payload_type).comptimeOnlyAdvanced(mod, strat),
27542765
27552766 .error_set_type,
27562767 .inferred_error_set_type,
......@@ -2817,8 +2828,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
28172828 .no, .wip => false,
28182829 .yes => true,
28192830 .unknown => {
2820 // The type is not resolved; assert that we have a Sema.
2821 const sema = opt_sema.?;
2831 assert(strat == .sema);
28222832
28232833 if (struct_type.flagsPtr(ip).field_types_wip)
28242834 return false;
......@@ -2826,13 +2836,13 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
28262836 struct_type.flagsPtr(ip).requires_comptime = .wip;
28272837 errdefer struct_type.flagsPtr(ip).requires_comptime = .unknown;
28282838
2829 try sema.resolveTypeFieldsStruct(ty.toIntern(), struct_type);
2839 try ty.resolveFields(mod);
28302840
28312841 for (0..struct_type.field_types.len) |i_usize| {
28322842 const i: u32 = @intCast(i_usize);
28332843 if (struct_type.fieldIsComptime(ip, i)) continue;
28342844 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)) {
28362846 // Note that this does not cause the layout to
28372847 // be considered resolved. Comptime-only types
28382848 // still maintain a layout of their
......@@ -2851,7 +2861,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
28512861 .anon_struct_type => |tuple| {
28522862 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
28532863 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;
28552865 }
28562866 return false;
28572867 },
......@@ -2862,8 +2872,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
28622872 .no, .wip => return false,
28632873 .yes => return true,
28642874 .unknown => {
2865 // The type is not resolved; assert that we have a Sema.
2866 const sema = opt_sema.?;
2875 assert(strat == .sema);
28672876
28682877 if (union_type.flagsPtr(ip).status == .field_types_wip)
28692878 return false;
......@@ -2871,11 +2880,11 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
28712880 union_type.flagsPtr(ip).requires_comptime = .wip;
28722881 errdefer union_type.flagsPtr(ip).requires_comptime = .unknown;
28732882
2874 try sema.resolveTypeFieldsUnion(ty, union_type);
2883 try ty.resolveFields(mod);
28752884
28762885 for (0..union_type.field_types.len) |field_idx| {
28772886 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)) {
28792888 union_type.flagsPtr(ip).requires_comptime = .yes;
28802889 return true;
28812890 }
......@@ -2889,7 +2898,7 @@ pub fn comptimeOnlyAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) Module.Com
28892898
28902899 .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
28942903 // values, not types
28952904 .undef,
......@@ -3180,10 +3189,10 @@ pub fn structFieldType(ty: Type, index: usize, mod: *Module) Type {
31803189}
31813190
31823191pub 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;
31843193}
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 {
31873196 const ip = &zcu.intern_pool;
31883197 switch (ip.indexToKey(ty.toIntern())) {
31893198 .struct_type => {
......@@ -3191,22 +3200,14 @@ pub fn structFieldAlignAdvanced(ty: Type, index: usize, zcu: *Zcu, opt_sema: ?*S
31913200 assert(struct_type.layout != .@"packed");
31923201 const explicit_align = struct_type.fieldAlign(ip, index);
31933202 const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[index]);
3194 if (opt_sema) |sema| {
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 }
3203 return zcu.structFieldAlignmentAdvanced(explicit_align, field_ty, struct_type.layout, strat);
31993204 },
32003205 .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;
32023207 },
32033208 .union_type => {
32043209 const union_obj = ip.loadUnionType(ty.toIntern());
3205 if (opt_sema) |sema| {
3206 return sema.unionFieldAlignment(union_obj, @intCast(index));
3207 } else {
3208 return zcu.unionFieldNormalAlignment(union_obj, @intCast(index));
3209 }
3210 return zcu.unionFieldNormalAlignmentAdvanced(union_obj, @intCast(index), strat);
32103211 },
32113212 else => unreachable,
32123213 }
......@@ -3546,6 +3547,397 @@ pub fn packedStructFieldPtrInfo(struct_ty: Type, parent_ptr_ty: Type, field_idx:
35463547 } };
35473548}
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
35493941pub const @"u1": Type = .{ .ip_index = .u1_type };
35503942pub const @"u8": Type = .{ .ip_index = .u8_type };
35513943pub 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 {
161161 };
162162}
163163
164pub const ResolveStrat = Type.ResolveStrat;
165
164166/// Asserts the value is an integer.
165167pub 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;
167169}
168170
169171/// Asserts the value is an integer.
......@@ -171,7 +173,7 @@ pub fn toBigIntAdvanced(
171173 val: Value,
172174 space: *BigIntSpace,
173175 mod: *Module,
174 opt_sema: ?*Sema,
176 strat: ResolveStrat,
175177) Module.CompileError!BigIntConst {
176178 return switch (val.toIntern()) {
177179 .bool_false => BigIntMutable.init(&space.limbs, 0).toConst(),
......@@ -181,7 +183,7 @@ pub fn toBigIntAdvanced(
181183 .int => |int| switch (int.storage) {
182184 .u64, .i64, .big_int => int.storage.toBigInt(space),
183185 .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);
185187 const x = switch (int.storage) {
186188 else => unreachable,
187189 .lazy_align => Type.fromInterned(ty).abiAlignment(mod).toByteUnits() orelse 0,
......@@ -190,10 +192,10 @@ pub fn toBigIntAdvanced(
190192 return BigIntMutable.init(&space.limbs, x).toConst();
191193 },
192194 },
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),
194196 .opt, .ptr => BigIntMutable.init(
195197 &space.limbs,
196 (try val.getUnsignedIntAdvanced(mod, opt_sema)).?,
198 (try val.getUnsignedIntAdvanced(mod, strat)).?,
197199 ).toConst(),
198200 else => unreachable,
199201 },
......@@ -228,12 +230,12 @@ pub fn getVariable(val: Value, mod: *Module) ?InternPool.Key.Variable {
228230/// If the value fits in a u64, return it, otherwise null.
229231/// Asserts not undefined.
230232pub fn getUnsignedInt(val: Value, mod: *Module) ?u64 {
231 return getUnsignedIntAdvanced(val, mod, null) catch unreachable;
233 return getUnsignedIntAdvanced(val, mod, .normal) catch unreachable;
232234}
233235
234236/// If the value fits in a u64, return it, otherwise null.
235237/// Asserts not undefined.
236pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64 {
238pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, strat: ResolveStrat) !?u64 {
237239 return switch (val.toIntern()) {
238240 .undef => unreachable,
239241 .bool_false => 0,
......@@ -244,28 +246,22 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64
244246 .big_int => |big_int| big_int.to(u64) catch null,
245247 .u64 => |x| x,
246248 .i64 => |x| std.math.cast(u64, x),
247 .lazy_align => |ty| if (opt_sema) |sema|
248 (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar.toByteUnits() orelse 0
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),
249 .lazy_align => |ty| (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).scalar.toByteUnits() orelse 0,
250 .lazy_size => |ty| (try Type.fromInterned(ty).abiSizeAdvanced(mod, strat.toLazy())).scalar,
255251 },
256252 .ptr => |ptr| switch (ptr.base_addr) {
257253 .int => ptr.byte_offset,
258254 .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;
260256 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);
262258 return base_addr + struct_ty.structFieldOffset(@intCast(field.index), mod) + ptr.byte_offset;
263259 },
264260 else => null,
265261 },
266262 .opt => |opt| switch (opt.val) {
267263 .none => 0,
268 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(mod, opt_sema),
264 else => |payload| Value.fromInterned(payload).getUnsignedIntAdvanced(mod, strat),
269265 },
270266 else => null,
271267 },
......@@ -273,13 +269,13 @@ pub fn getUnsignedIntAdvanced(val: Value, mod: *Module, opt_sema: ?*Sema) !?u64
273269}
274270
275271/// Asserts the value is an integer and it fits in a u64
276pub fn toUnsignedInt(val: Value, mod: *Module) u64 {
277 return getUnsignedInt(val, mod).?;
272pub fn toUnsignedInt(val: Value, zcu: *Zcu) u64 {
273 return getUnsignedInt(val, zcu).?;
278274}
279275
280276/// Asserts the value is an integer and it fits in a u64
281pub fn toUnsignedIntAdvanced(val: Value, sema: *Sema) !u64 {
282 return (try getUnsignedIntAdvanced(val, sema.mod, sema)).?;
277pub fn toUnsignedIntSema(val: Value, zcu: *Zcu) !u64 {
278 return (try getUnsignedIntAdvanced(val, zcu, .sema)).?;
283279}
284280
285281/// 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 {
10281024}
10291025
10301026pub 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;
10321028}
10331029
10341030pub fn orderAgainstZeroAdvanced(
10351031 lhs: Value,
10361032 mod: *Module,
1037 opt_sema: ?*Sema,
1033 strat: ResolveStrat,
10381034) Module.CompileError!std.math.Order {
10391035 return switch (lhs.toIntern()) {
10401036 .bool_false => .eq,
......@@ -1052,13 +1048,13 @@ pub fn orderAgainstZeroAdvanced(
10521048 .lazy_size => |ty| return if (Type.fromInterned(ty).hasRuntimeBitsAdvanced(
10531049 mod,
10541050 false,
1055 if (opt_sema) |sema| .{ .sema = sema } else .eager,
1051 strat.toLazy(),
10561052 ) catch |err| switch (err) {
10571053 error.NeedLazy => unreachable,
10581054 else => |e| return e,
10591055 }) .gt else .eq,
10601056 },
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),
10621058 .float => |float| switch (float.storage) {
10631059 inline else => |x| std.math.order(x, 0),
10641060 },
......@@ -1069,14 +1065,13 @@ pub fn orderAgainstZeroAdvanced(
10691065
10701066/// Asserts the value is comparable.
10711067pub 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;
10731069}
10741070
10751071/// Asserts the value is comparable.
1076/// If opt_sema is null then this function asserts things are resolved and cannot fail.
1077pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, opt_sema: ?*Sema) !std.math.Order {
1078 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, opt_sema);
1079 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, opt_sema);
1072pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, strat: ResolveStrat) !std.math.Order {
1073 const lhs_against_zero = try lhs.orderAgainstZeroAdvanced(mod, strat);
1074 const rhs_against_zero = try rhs.orderAgainstZeroAdvanced(mod, strat);
10801075 switch (lhs_against_zero) {
10811076 .lt => if (rhs_against_zero != .lt) return .lt,
10821077 .eq => return rhs_against_zero.invert(),
......@@ -1096,15 +1091,15 @@ pub fn orderAdvanced(lhs: Value, rhs: Value, mod: *Module, opt_sema: ?*Sema) !st
10961091
10971092 var lhs_bigint_space: BigIntSpace = undefined;
10981093 var rhs_bigint_space: BigIntSpace = undefined;
1099 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, opt_sema);
1100 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, opt_sema);
1094 const lhs_bigint = try lhs.toBigIntAdvanced(&lhs_bigint_space, mod, strat);
1095 const rhs_bigint = try rhs.toBigIntAdvanced(&rhs_bigint_space, mod, strat);
11011096 return lhs_bigint.order(rhs_bigint);
11021097}
11031098
11041099/// Asserts the value is comparable. Does not take a type parameter because it supports
11051100/// comparisons between heterogeneous types.
11061101pub 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;
11081103}
11091104
11101105pub fn compareHeteroAdvanced(
......@@ -1112,7 +1107,7 @@ pub fn compareHeteroAdvanced(
11121107 op: std.math.CompareOperator,
11131108 rhs: Value,
11141109 mod: *Module,
1115 opt_sema: ?*Sema,
1110 strat: ResolveStrat,
11161111) !bool {
11171112 if (lhs.pointerDecl(mod)) |lhs_decl| {
11181113 if (rhs.pointerDecl(mod)) |rhs_decl| {
......@@ -1135,7 +1130,7 @@ pub fn compareHeteroAdvanced(
11351130 else => {},
11361131 }
11371132 }
1138 return (try orderAdvanced(lhs, rhs, mod, opt_sema)).compare(op);
1133 return (try orderAdvanced(lhs, rhs, mod, strat)).compare(op);
11391134}
11401135
11411136/// Asserts the values are comparable. Both operands have type `ty`.
......@@ -1176,22 +1171,22 @@ pub fn compareScalar(
11761171///
11771172/// Note that `!compareAllWithZero(.eq, ...) != compareAllWithZero(.neq, ...)`
11781173pub 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;
11801175}
11811176
1182pub fn compareAllWithZeroAdvanced(
1177pub fn compareAllWithZeroSema(
11831178 lhs: Value,
11841179 op: std.math.CompareOperator,
1185 sema: *Sema,
1180 zcu: *Zcu,
11861181) Module.CompileError!bool {
1187 return compareAllWithZeroAdvancedExtra(lhs, op, sema.mod, sema);
1182 return compareAllWithZeroAdvancedExtra(lhs, op, zcu, .sema);
11881183}
11891184
11901185pub fn compareAllWithZeroAdvancedExtra(
11911186 lhs: Value,
11921187 op: std.math.CompareOperator,
11931188 mod: *Module,
1194 opt_sema: ?*Sema,
1189 strat: ResolveStrat,
11951190) Module.CompileError!bool {
11961191 if (lhs.isInf(mod)) {
11971192 switch (op) {
......@@ -1211,14 +1206,14 @@ pub fn compareAllWithZeroAdvancedExtra(
12111206 if (!std.math.order(byte, 0).compare(op)) break false;
12121207 } else true,
12131208 .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;
12151210 } 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),
12171212 },
12181213 .undef => return false,
12191214 else => {},
12201215 }
1221 return (try orderAgainstZeroAdvanced(lhs, mod, opt_sema)).compare(op);
1216 return (try orderAgainstZeroAdvanced(lhs, mod, strat)).compare(op);
12221217}
12231218
12241219pub fn eql(a: Value, b: Value, ty: Type, mod: *Module) bool {
......@@ -1279,9 +1274,9 @@ pub fn slicePtr(val: Value, mod: *Module) Value {
12791274}
12801275
12811276/// Gets the `len` field of a slice value as a `u64`.
1282/// Resolves the length using the provided `Sema` if necessary.
1283pub fn sliceLen(val: Value, sema: *Sema) !u64 {
1284 return Value.fromInterned(sema.mod.intern_pool.sliceLen(val.toIntern())).toUnsignedIntAdvanced(sema);
1277/// Resolves the length using `Sema` if necessary.
1278pub fn sliceLen(val: Value, zcu: *Zcu) !u64 {
1279 return Value.fromInterned(zcu.intern_pool.sliceLen(val.toIntern())).toUnsignedIntSema(zcu);
12851280}
12861281
12871282/// 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 {
14821477}
14831478
14841479pub 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) {
14861481 error.OutOfMemory => return error.OutOfMemory,
14871482 else => unreachable,
14881483 };
14891484}
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 {
14921487 if (int_ty.zigTypeTag(mod) == .Vector) {
14931488 const result_data = try arena.alloc(InternPool.Index, int_ty.vectorLen(mod));
14941489 const scalar_ty = float_ty.scalarType(mod);
14951490 for (result_data, 0..) |*scalar, i| {
14961491 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();
14981493 }
14991494 return Value.fromInterned((try mod.intern(.{ .aggregate = .{
15001495 .ty = float_ty.toIntern(),
15011496 .storage = .{ .elems = result_data },
15021497 } })));
15031498 }
1504 return floatFromIntScalar(val, float_ty, mod, opt_sema);
1499 return floatFromIntScalar(val, float_ty, mod, strat);
15051500}
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 {
15081503 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
15091504 .undef => try mod.undefValue(float_ty),
15101505 .int => |int| switch (int.storage) {
......@@ -1513,16 +1508,8 @@ pub fn floatFromIntScalar(val: Value, float_ty: Type, mod: *Module, opt_sema: ?*
15131508 return mod.floatValue(float_ty, float);
15141509 },
15151510 inline .u64, .i64 => |x| floatFromIntInner(x, float_ty, mod),
1516 .lazy_align => |ty| if (opt_sema) |sema| {
1517 return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar.toByteUnits() orelse 0, 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 },
1511 .lazy_align => |ty| return floatFromIntInner((try Type.fromInterned(ty).abiAlignmentAdvanced(mod, strat.toLazy())).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),
15261513 },
15271514 else => unreachable,
15281515 };
......@@ -3616,17 +3603,15 @@ pub const RuntimeIndex = InternPool.RuntimeIndex;
36163603
36173604/// `parent_ptr` must be a single-pointer to some optional.
36183605/// Returns a pointer to the payload of the optional.
3619/// This takes a `Sema` because it may need to perform type resolution.
3620pub fn ptrOptPayload(parent_ptr: Value, sema: *Sema) !Value {
3621 const zcu = sema.mod;
3622
3606/// May perform type resolution.
3607pub fn ptrOptPayload(parent_ptr: Value, zcu: *Zcu) !Value {
36233608 const parent_ptr_ty = parent_ptr.typeOf(zcu);
36243609 const opt_ty = parent_ptr_ty.childType(zcu);
36253610
36263611 assert(parent_ptr_ty.ptrSize(zcu) == .One);
36273612 assert(opt_ty.zigTypeTag(zcu) == .Optional);
36283613
3629 const result_ty = try sema.ptrType(info: {
3614 const result_ty = try zcu.ptrTypeSema(info: {
36303615 var new = parent_ptr_ty.ptrInfo(zcu);
36313616 // We can correctly preserve alignment `.none`, since an optional has the same
36323617 // natural alignment as its child type.
......@@ -3651,17 +3636,15 @@ pub fn ptrOptPayload(parent_ptr: Value, sema: *Sema) !Value {
36513636
36523637/// `parent_ptr` must be a single-pointer to some error union.
36533638/// Returns a pointer to the payload of the error union.
3654/// This takes a `Sema` because it may need to perform type resolution.
3655pub fn ptrEuPayload(parent_ptr: Value, sema: *Sema) !Value {
3656 const zcu = sema.mod;
3657
3639/// May perform type resolution.
3640pub fn ptrEuPayload(parent_ptr: Value, zcu: *Zcu) !Value {
36583641 const parent_ptr_ty = parent_ptr.typeOf(zcu);
36593642 const eu_ty = parent_ptr_ty.childType(zcu);
36603643
36613644 assert(parent_ptr_ty.ptrSize(zcu) == .One);
36623645 assert(eu_ty.zigTypeTag(zcu) == .ErrorUnion);
36633646
3664 const result_ty = try sema.ptrType(info: {
3647 const result_ty = try zcu.ptrTypeSema(info: {
36653648 var new = parent_ptr_ty.ptrInfo(zcu);
36663649 // We can correctly preserve alignment `.none`, since an error union has a
36673650 // 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 {
36823665/// `parent_ptr` must be a single-pointer to a struct, union, or slice.
36833666/// Returns a pointer to the aggregate field at the specified index.
36843667/// For slices, uses `slice_ptr_index` and `slice_len_index`.
3685/// This takes a `Sema` because it may need to perform type resolution.
3686pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
3687 const zcu = sema.mod;
3688
3668/// May perform type resolution.
3669pub fn ptrField(parent_ptr: Value, field_idx: u32, zcu: *Zcu) !Value {
36893670 const parent_ptr_ty = parent_ptr.typeOf(zcu);
36903671 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 {
36983679 .Struct => field: {
36993680 const field_ty = aggregate_ty.structFieldType(field_idx, zcu);
37003681 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) },
37023683 .@"extern" => {
37033684 // Well-defined layout, so just offset the pointer appropriately.
37043685 const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);
37053686 const field_align = a: {
37063687 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;
37083689 } else parent_ptr_info.flags.alignment;
37093690 break :a InternPool.Alignment.fromLog2Units(@min(parent_align.toLog2Units(), @ctz(byte_off)));
37103691 };
3711 const result_ty = try sema.ptrType(info: {
3692 const result_ty = try zcu.ptrTypeSema(info: {
37123693 var new = parent_ptr_info;
37133694 new.child = field_ty.toIntern();
37143695 new.flags.alignment = field_align;
......@@ -3723,14 +3704,14 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
37233704 new.packed_offset = packed_offset;
37243705 new.child = field_ty.toIntern();
37253706 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;
37273708 }
37283709 break :info new;
37293710 });
37303711 return zcu.getCoerced(parent_ptr, result_ty);
37313712 },
37323713 .byte_ptr => |ptr_info| {
3733 const result_ty = try sema.ptrType(info: {
3714 const result_ty = try zcu.ptrTypeSema(info: {
37343715 var new = parent_ptr_info;
37353716 new.child = field_ty.toIntern();
37363717 new.packed_offset = .{
......@@ -3749,10 +3730,10 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
37493730 const union_obj = zcu.typeToUnion(aggregate_ty).?;
37503731 const field_ty = Type.fromInterned(union_obj.field_types.get(&zcu.intern_pool)[field_idx]);
37513732 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) },
37533734 .@"extern" => {
37543735 // Point to the same address.
3755 const result_ty = try sema.ptrType(info: {
3736 const result_ty = try zcu.ptrTypeSema(info: {
37563737 var new = parent_ptr_info;
37573738 new.child = field_ty.toIntern();
37583739 break :info new;
......@@ -3762,28 +3743,28 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
37623743 .@"packed" => {
37633744 // If the field has an ABI size matching its bit size, then we can continue to use a
37643745 // 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)) {
37663747 // We must offset the pointer on big-endian targets, since the bits of packed memory don't align nicely.
37673748 const byte_offset = switch (zcu.getTarget().cpu.arch.endian()) {
37683749 .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,
37703751 };
3771 const result_ty = try sema.ptrType(info: {
3752 const result_ty = try zcu.ptrTypeSema(info: {
37723753 var new = parent_ptr_info;
37733754 new.child = field_ty.toIntern();
37743755 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().?),
37763757 );
37773758 break :info new;
37783759 });
37793760 return parent_ptr.getOffsetPtr(byte_offset, result_ty, zcu);
37803761 } else {
37813762 // 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: {
37833764 var new = parent_ptr_info;
37843765 new.child = field_ty.toIntern();
37853766 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);
37873768 assert(new.packed_offset.bit_offset == 0);
37883769 }
37893770 break :info new;
......@@ -3805,14 +3786,14 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
38053786 };
38063787
38073788 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;
38093790 const true_field_align = if (field_align == .none) ty_align else field_align;
38103791 const new_align = true_field_align.min(parent_ptr_info.flags.alignment);
38113792 if (new_align == ty_align) break :a .none;
38123793 break :a new_align;
38133794 } else field_align;
38143795
3815 const result_ty = try sema.ptrType(info: {
3796 const result_ty = try zcu.ptrTypeSema(info: {
38163797 var new = parent_ptr_info;
38173798 new.child = field_ty.toIntern();
38183799 new.flags.alignment = new_align;
......@@ -3834,10 +3815,8 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, sema: *Sema) !Value {
38343815
38353816/// `orig_parent_ptr` must be either a single-pointer to an array or vector, or a many-pointer or C-pointer or slice.
38363817/// Returns a pointer to the element at the specified index.
3837/// This takes a `Sema` because it may need to perform type resolution.
3838pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, sema: *Sema) !Value {
3839 const zcu = sema.mod;
3840
3818/// May perform type resolution.
3819pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, zcu: *Zcu) !Value {
38413820 const parent_ptr = switch (orig_parent_ptr.typeOf(zcu).ptrSize(zcu)) {
38423821 .One, .Many, .C => orig_parent_ptr,
38433822 .Slice => orig_parent_ptr.slicePtr(zcu),
......@@ -3845,7 +3824,7 @@ pub fn ptrElem(orig_parent_ptr: Value, field_idx: u64, sema: *Sema) !Value {
38453824
38463825 const parent_ptr_ty = parent_ptr.typeOf(zcu);
38473826 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
38503829 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 {
38623841
38633842 const strat: PtrStrat = switch (parent_ptr_ty.ptrSize(zcu)) {
38643843 .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) },
38663845 .Array => strat: {
38673846 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)) {
38693848 break :strat .{ .elem_ptr = arr_elem_ty };
38703849 }
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 };
38723851 },
38733852 else => unreachable,
38743853 },
38753854
3876 .Many, .C => if (try sema.typeRequiresComptime(elem_ty))
3855 .Many, .C => if (try elem_ty.comptimeOnlyAdvanced(zcu, .sema))
38773856 .{ .elem_ptr = elem_ty }
38783857 else
3879 .{ .offset = field_idx * try sema.typeAbiSize(elem_ty) },
3858 .{ .offset = field_idx * (try elem_ty.abiSizeAdvanced(zcu, .sema)).scalar },
38803859
38813860 .Slice => unreachable,
38823861 };
......@@ -4014,11 +3993,7 @@ pub const PointerDeriveStep = union(enum) {
40143993pub fn pointerDerivation(ptr_val: Value, arena: Allocator, zcu: *Zcu) Allocator.Error!PointerDeriveStep {
40153994 return ptr_val.pointerDerivationAdvanced(arena, zcu, null) catch |err| switch (err) {
40163995 error.OutOfMemory => |e| return e,
4017 error.AnalysisFail,
4018 error.GenericPoison,
4019 error.ComptimeReturn,
4020 error.ComptimeBreak,
4021 => unreachable,
3996 error.AnalysisFail => unreachable,
40223997 };
40233998}
40243999
......@@ -4087,8 +4062,8 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
40874062 const base_ptr_ty = base_ptr.typeOf(zcu);
40884063 const agg_ty = base_ptr_ty.childType(zcu);
40894064 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) },
4091 .Union => .{ agg_ty.unionFieldTypeByIndex(@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) },
4066 .Union => .{ agg_ty.unionFieldTypeByIndex(@intCast(field.index), zcu), try agg_ty.structFieldAlignAdvanced(@intCast(field.index), zcu, .sema) },
40924067 .Pointer => .{ switch (field.index) {
40934068 Value.slice_ptr_index => agg_ty.slicePtrFieldType(zcu),
40944069 Value.slice_len_index => Type.usize,
......@@ -4269,3 +4244,118 @@ pub fn pointerDerivationAdvanced(ptr_val: Value, arena: Allocator, zcu: *Zcu, op
42694244 .new_ptr_ty = Type.fromInterned(ptr.ty),
42704245 } };
42714246}
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
35933593 },
35943594 error.OutOfMemory => return error.OutOfMemory,
35953595 };
3596 defer air.deinit(gpa);
3596 errdefer air.deinit(gpa);
35973597
35983598 const invalidate_ies_deps = i: {
35993599 if (!was_outdated) break :i false;
......@@ -3615,13 +3615,36 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
36153615 const dump_llvm_ir = build_options.enable_debug_extensions and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
36163616
36173617 if (comp.bin_file == null and zcu.llvm_object == null and !dump_air and !dump_llvm_ir) {
3618 air.deinit(gpa);
36183619 return;
36193620 }
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
36213644 var liveness = try Liveness.analyze(gpa, air, ip);
36223645 defer liveness.deinit(gpa);
36233646
3624 if (dump_air) {
3647 if (build_options.enable_debug_extensions and comp.verbose_air) {
36253648 const fqn = try decl.fullyQualifiedName(zcu);
36263649 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
36273650 @import("print_air.zig").dump(zcu, air, liveness);
......@@ -3629,7 +3652,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
36293652 }
36303653
36313654 if (std.debug.runtime_safety) {
3632 var verify = Liveness.Verify{
3655 var verify: Liveness.Verify = .{
36333656 .gpa = gpa,
36343657 .air = air,
36353658 .liveness = liveness,
......@@ -3642,7 +3665,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
36423665 else => {
36433666 try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1);
36443667 zcu.failed_analysis.putAssumeCapacityNoClobber(
3645 AnalUnit.wrap(.{ .decl = decl_index }),
3668 AnalUnit.wrap(.{ .func = func_index }),
36463669 try Module.ErrorMsg.create(
36473670 gpa,
36483671 decl.navSrcLoc(zcu),
......@@ -3659,7 +3682,13 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
36593682 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(zcu)).toSlice(ip), 0);
36603683 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| {
36633692 lf.updateFunc(zcu, func_index, air, liveness) catch |err| switch (err) {
36643693 error.OutOfMemory => return error.OutOfMemory,
36653694 error.AnalysisFail => {
......@@ -3667,7 +3696,7 @@ pub fn ensureFuncBodyAnalyzed(zcu: *Zcu, maybe_coerced_func_index: InternPool.In
36673696 },
36683697 else => {
36693698 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(
36713700 gpa,
36723701 decl.navSrcLoc(zcu),
36733702 "unable to codegen: {s}",
......@@ -3735,7 +3764,7 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index)
37353764
37363765 // 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 });
37393768 if (mod.emit_h != null) {
37403769 // TODO: we ideally only want to do this if the function's type changed
37413770 // since the last update
......@@ -3812,7 +3841,7 @@ fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespa
38123841 decl.analysis = .complete;
38133842
38143843 try zcu.scanNamespace(namespace_index, decls, decl);
3815
3844 try zcu.comp.work_queue.writeItem(.{ .resolve_type_fully = wip_ty.index });
38163845 return wip_ty.finish(ip, decl_index, namespace_index.toOptional());
38173846}
38183847
......@@ -4103,7 +4132,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
41034132 // Note this resolves the type of the Decl, not the value; if this Decl
41044133 // is a struct, for example, this resolves `type` (which needs no resolution),
41054134 // not the struct itself.
4106 try sema.resolveTypeLayout(decl_ty);
4135 try decl_ty.resolveLayout(mod);
41074136
41084137 if (decl.kind == .@"usingnamespace") {
41094138 if (!decl_ty.eql(Type.type, mod)) {
......@@ -4220,7 +4249,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult {
42204249 if (has_runtime_bits) {
42214250 // Needed for codegen_decl which will call updateDecl and then the
42224251 // codegen backend wants full access to the Decl Type.
4223 try sema.resolveTypeFully(decl_ty);
4252 try decl_ty.resolveFully(mod);
42244253
42254254 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
52125241 else => |e| return e,
52135242 };
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
52325244 try sema.flushExports();
52335245
52345246 return .{
......@@ -5793,6 +5805,16 @@ pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type
57935805 return Type.fromInterned((try intern(mod, .{ .ptr_type = canon_info })));
57945806}
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
57965818pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
57975819 return ptrType(mod, .{ .child = child_type.toIntern() });
57985820}
......@@ -6368,15 +6390,21 @@ pub fn unionAbiAlignment(mod: *Module, loaded_union: InternPool.LoadedUnionType)
63686390 return max_align;
63696391}
63706392
6371/// Returns the field alignment, assuming the union is not packed.
6372/// Keep implementation in sync with `Sema.unionFieldAlignment`.
6373/// Prefer to call that function instead of this one during Sema.
6374pub fn unionFieldNormalAlignment(mod: *Module, loaded_union: InternPool.LoadedUnionType, field_index: u32) Alignment {
6375 const ip = &mod.intern_pool;
6393/// Returns the field alignment of a non-packed union. Asserts the layout is not packed.
6394pub fn unionFieldNormalAlignment(zcu: *Zcu, loaded_union: InternPool.LoadedUnionType, field_index: u32) Alignment {
6395 return zcu.unionFieldNormalAlignmentAdvanced(loaded_union, field_index, .normal) catch unreachable;
6396}
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");
63766403 const field_align = loaded_union.fieldAlign(ip, field_index);
63776404 if (field_align != .none) return field_align;
63786405 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;
63806408}
63816409
63826410/// 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
63876415 return loaded_union.loadTagType(ip).tagValueIndex(ip, enum_tag.toIntern());
63886416}
63896417
6390/// Returns the field alignment of a non-packed struct in byte units.
6391/// Keep implementation in sync with `Sema.structFieldAlignment`.
6392/// asserts the layout is not packed.
6418/// Returns the field alignment of a non-packed struct. Asserts the layout is not packed.
63936419pub fn structFieldAlignment(
6394 mod: *Module,
6420 zcu: *Zcu,
63956421 explicit_alignment: InternPool.Alignment,
63966422 field_ty: Type,
63976423 layout: std.builtin.Type.ContainerLayout,
63986424) 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 {
63996437 assert(layout != .@"packed");
64006438 if (explicit_alignment != .none) return explicit_alignment;
6439 const ty_abi_align = (try field_ty.abiAlignmentAdvanced(zcu, strat.toLazy())).scalar;
64016440 switch (layout) {
64026441 .@"packed" => unreachable,
6403 .auto => {
6404 if (mod.getTarget().ofmt == .c) {
6405 return structFieldAlignmentExtern(mod, field_ty);
6406 } else {
6407 return field_ty.abiAlignment(mod);
6408 }
6409 },
6410 .@"extern" => return structFieldAlignmentExtern(mod, field_ty),
6442 .auto => if (zcu.getTarget().ofmt != .c) return ty_abi_align,
6443 .@"extern" => {},
64116444 }
6412}
6413
6414/// Returns the field alignment of an extern struct in byte units.
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");
6445 // extern
6446 if (field_ty.isAbiInt(zcu) and field_ty.intInfo(zcu).bits >= 128) {
6447 return ty_abi_align.maxStrict(.@"16");
64236448 }
6424
64256449 return ty_abi_align;
64266450}
64276451
......@@ -6480,3 +6504,29 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
64806504
64816505 return result;
64826506}
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 {
26032603 if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;
26042604
26052605 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
26082611 const field_name = tag_type.names.get(ip)[field_index];
26092612 fields.appendAssumeCapacity(try o.builder.debugMemberType(
src/print_value.zig+4-4
......@@ -81,12 +81,12 @@ pub fn print(
8181 }),
8282 .int => |int| switch (int.storage) {
8383 inline .u64, .i64, .big_int => |x| try writer.print("{}", .{x}),
84 .lazy_align => |ty| if (opt_sema) |sema| {
85 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .{ .sema = sema })).scalar;
84 .lazy_align => |ty| if (opt_sema != null) {
85 const a = (try Type.fromInterned(ty).abiAlignmentAdvanced(mod, .sema)).scalar;
8686 try writer.print("{}", .{a.toByteUnits() orelse 0});
8787 } else try writer.print("@alignOf({})", .{Type.fromInterned(ty).fmt(mod)}),
88 .lazy_size => |ty| if (opt_sema) |sema| {
89 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .{ .sema = sema })).scalar;
88 .lazy_size => |ty| if (opt_sema != null) {
89 const s = (try Type.fromInterned(ty).abiSizeAdvanced(mod, .sema)).scalar;
9090 try writer.print("{}", .{s});
9191 } else try writer.print("@sizeOf({})", .{Type.fromInterned(ty).fmt(mod)}),
9292 },
test/cases/compile_errors/direct_struct_loop.zig-1
......@@ -10,4 +10,3 @@ export fn entry() usize {
1010// target=native
1111//
1212// :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 {
1616// target=native
1717//
1818// :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 {
1313// target=native
1414//
1515// :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 {
1313// target=native
1414//
1515// :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 {
1616// target=native
1717//
1818// :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 {
1515// target=native
1616//
1717// :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 @@
11pub export fn entry(param: usize) usize {
2 return struct { param };
2 return struct { @TypeOf(param) };
33}
44
55// error
test/src/Cases.zig+33-670
......@@ -395,10 +395,7 @@ fn addFromDirInner(
395395 if (entry.kind != .file) continue;
396396
397397 // Ignore stuff such as .swp files
398 switch (Compilation.classifyFileExt(entry.basename)) {
399 .unknown => continue,
400 else => {},
401 }
398 if (!knownFileExtension(entry.basename)) continue;
402399 try filenames.append(try ctx.arena.dupe(u8, entry.path));
403400 }
404401
......@@ -623,8 +620,6 @@ pub fn lowerToBuildSteps(
623620 b: *std.Build,
624621 parent_step: *std.Build.Step,
625622 test_filters: []const []const u8,
626 cases_dir_path: []const u8,
627 incremental_exe: *std.Build.Step.Compile,
628623) void {
629624 const host = std.zig.system.resolveTargetQuery(.{}) catch |err|
630625 std.debug.panic("unable to detect native host: {s}\n", .{@errorName(err)});
......@@ -637,20 +632,11 @@ pub fn lowerToBuildSteps(
637632 // compilation is in a happier state.
638633 continue;
639634 }
640 for (test_filters) |test_filter| {
641 if (std.mem.indexOf(u8, incr_case.base_path, test_filter)) |_| break;
642 } else if (test_filters.len > 0) continue;
643 const case_base_path_with_dir = std.fs.path.join(b.allocator, &.{
644 cases_dir_path, incr_case.base_path,
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);
635 // TODO: the logic for running these was bad, so I've ripped it out. Rewrite this
636 // in a way that actually spawns the compiler, communicating with it over the
637 // compiler server protocol.
638 _ = incr_case;
639 @panic("TODO implement incremental test case executor");
654640 }
655641
656642 for (self.cases.items) |case| {
......@@ -1236,192 +1222,6 @@ const assert = std.debug.assert;
12361222const Allocator = std.mem.Allocator;
12371223const 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
14251225fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {
14261226 return .{
14271227 .query = query,
......@@ -1430,470 +1230,33 @@ fn resolveTargetQuery(query: std.Target.Query) std.Build.ResolvedTarget {
14301230 };
14311231}
14321232
1433fn runCases(self: *Cases, zig_exe_path: []const u8) !void {
1434 const host = try std.zig.system.resolveTargetQuery(.{});
1435
1436 var progress = std.Progress{};
1437 const root_node = progress.start("compiler", self.cases.items.len);
1438 progress.terminal = null;
1439 defer root_node.end();
1440
1441 var zig_lib_directory = try introspect.findZigLibDirFromSelfExe(self.gpa, zig_exe_path);
1442 defer zig_lib_directory.handle.close();
1443 defer self.gpa.free(zig_lib_directory.path.?);
1444
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);
1233fn knownFileExtension(filename: []const u8) bool {
1234 // List taken from `Compilation.classifyFileExt` in the compiler.
1235 for ([_][]const u8{
1236 ".c", ".C", ".cc", ".cpp",
1237 ".cxx", ".stub", ".m", ".mm",
1238 ".ll", ".bc", ".s", ".S",
1239 ".h", ".zig", ".so", ".dll",
1240 ".dylib", ".tbd", ".a", ".lib",
1241 ".o", ".obj", ".cu", ".def",
1242 ".rc", ".res", ".manifest",
1243 }) |ext| {
1244 if (std.mem.endsWith(u8, filename, ext)) return true;
15721245 }
1573
1574 const bin_name = try std.zig.binNameAlloc(arena, .{
1575 .root_name = "test_case",
1576 .target = target,
1577 .output_mode = case.output_mode,
1578 });
1579
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});
1246 // Final check for .so.X, .so.X.Y, .so.X.Y.Z.
1247 // From `Compilation.hasSharedLibraryExt`.
1248 var it = std.mem.splitScalar(u8, filename, '.');
1249 _ = it.first();
1250 var so_txt = it.next() orelse return false;
1251 while (!std.mem.eql(u8, so_txt, "so")) {
1252 so_txt = it.next() orelse return false;
18971253 }
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;
18991262}
test/tests.zig-4
......@@ -1250,7 +1250,6 @@ pub fn addCases(
12501250 b: *std.Build,
12511251 parent_step: *Step,
12521252 test_filters: []const []const u8,
1253 check_case_exe: *std.Build.Step.Compile,
12541253 target: std.Build.ResolvedTarget,
12551254 translate_c_options: @import("src/Cases.zig").TranslateCOptions,
12561255 build_options: @import("cases.zig").BuildOptions,
......@@ -1268,12 +1267,9 @@ pub fn addCases(
12681267
12691268 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" });
12721270 cases.lowerToBuildSteps(
12731271 b,
12741272 parent_step,
12751273 test_filters,
1276 cases_dir_path,
1277 check_case_exe,
12781274 );
12791275}