| ... | ... | @@ -107,6 +107,10 @@ comptime_mutable_decls: *std.ArrayList(Decl.Index), |
| 107 | 107 | /// one encountered, the conflicting source location can be shown. |
| 108 | 108 | prev_stack_alignment_src: ?LazySrcLoc = null, |
| 109 | 109 | |
| 110 | /// While analyzing a type which has a special InternPool index, this is set to the index at which |
| 111 | /// the struct/enum/union type created should be placed. Otherwise, it is `.none`. |
| 112 | builtin_type_target_index: InternPool.Index = .none, |
| 113 | |
| 110 | 114 | const std = @import("std"); |
| 111 | 115 | const math = std.math; |
| 112 | 116 | const mem = std.mem; |
| ... | ... | @@ -1956,8 +1960,8 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) |
| 1956 | 1960 | const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty)); |
| 1957 | 1961 | |
| 1958 | 1962 | // var st: StackTrace = undefined; |
| 1959 | | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 1960 | | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 1963 | const stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 1964 | try sema.resolveTypeFields(stack_trace_ty); |
| 1961 | 1965 | const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty)); |
| 1962 | 1966 | |
| 1963 | 1967 | // st.instruction_addresses = &addrs; |
| ... | ... | @@ -2890,10 +2894,17 @@ fn zirStructDecl( |
| 2890 | 2894 | }); |
| 2891 | 2895 | errdefer mod.destroyStruct(struct_index); |
| 2892 | 2896 | |
| 2893 | | const struct_ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{ |
| 2894 | | .index = struct_index.toOptional(), |
| 2895 | | .namespace = new_namespace_index.toOptional(), |
| 2896 | | } }); |
| 2897 | const struct_ty = ty: { |
| 2898 | const ty = try mod.intern_pool.get(gpa, .{ .struct_type = .{ |
| 2899 | .index = struct_index.toOptional(), |
| 2900 | .namespace = new_namespace_index.toOptional(), |
| 2901 | } }); |
| 2902 | if (sema.builtin_type_target_index != .none) { |
| 2903 | mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, ty); |
| 2904 | break :ty sema.builtin_type_target_index; |
| 2905 | } |
| 2906 | break :ty ty; |
| 2907 | }; |
| 2897 | 2908 | // TODO: figure out InternPool removals for incremental compilation |
| 2898 | 2909 | //errdefer mod.intern_pool.remove(struct_ty); |
| 2899 | 2910 | |
| ... | ... | @@ -3084,18 +3095,25 @@ fn zirEnumDecl( |
| 3084 | 3095 | if (bag != 0) break true; |
| 3085 | 3096 | } else false; |
| 3086 | 3097 | |
| 3087 | | const incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{ |
| 3088 | | .decl = new_decl_index, |
| 3089 | | .namespace = new_namespace_index.toOptional(), |
| 3090 | | .fields_len = fields_len, |
| 3091 | | .has_values = any_values, |
| 3092 | | .tag_mode = if (small.nonexhaustive) |
| 3093 | | .nonexhaustive |
| 3094 | | else if (tag_type_ref == .none) |
| 3095 | | .auto |
| 3096 | | else |
| 3097 | | .explicit, |
| 3098 | | }); |
| 3098 | const incomplete_enum = incomplete_enum: { |
| 3099 | var incomplete_enum = try mod.intern_pool.getIncompleteEnum(gpa, .{ |
| 3100 | .decl = new_decl_index, |
| 3101 | .namespace = new_namespace_index.toOptional(), |
| 3102 | .fields_len = fields_len, |
| 3103 | .has_values = any_values, |
| 3104 | .tag_mode = if (small.nonexhaustive) |
| 3105 | .nonexhaustive |
| 3106 | else if (tag_type_ref == .none) |
| 3107 | .auto |
| 3108 | else |
| 3109 | .explicit, |
| 3110 | }); |
| 3111 | if (sema.builtin_type_target_index != .none) { |
| 3112 | mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, incomplete_enum.index); |
| 3113 | incomplete_enum.index = sema.builtin_type_target_index; |
| 3114 | } |
| 3115 | break :incomplete_enum incomplete_enum; |
| 3116 | }; |
| 3099 | 3117 | // TODO: figure out InternPool removals for incremental compilation |
| 3100 | 3118 | //errdefer if (!done) mod.intern_pool.remove(incomplete_enum.index); |
| 3101 | 3119 | |
| ... | ... | @@ -3336,17 +3354,24 @@ fn zirUnionDecl( |
| 3336 | 3354 | }); |
| 3337 | 3355 | errdefer mod.destroyUnion(union_index); |
| 3338 | 3356 | |
| 3339 | | const union_ty = try mod.intern_pool.get(gpa, .{ .union_type = .{ |
| 3340 | | .index = union_index, |
| 3341 | | .runtime_tag = if (small.has_tag_type or small.auto_enum_tag) |
| 3342 | | .tagged |
| 3343 | | else if (small.layout != .Auto) |
| 3344 | | .none |
| 3345 | | else switch (block.sema.mod.optimizeMode()) { |
| 3346 | | .Debug, .ReleaseSafe => .safety, |
| 3347 | | .ReleaseFast, .ReleaseSmall => .none, |
| 3348 | | }, |
| 3349 | | } }); |
| 3357 | const union_ty = ty: { |
| 3358 | const ty = try mod.intern_pool.get(gpa, .{ .union_type = .{ |
| 3359 | .index = union_index, |
| 3360 | .runtime_tag = if (small.has_tag_type or small.auto_enum_tag) |
| 3361 | .tagged |
| 3362 | else if (small.layout != .Auto) |
| 3363 | .none |
| 3364 | else switch (block.sema.mod.optimizeMode()) { |
| 3365 | .Debug, .ReleaseSafe => .safety, |
| 3366 | .ReleaseFast, .ReleaseSmall => .none, |
| 3367 | }, |
| 3368 | } }); |
| 3369 | if (sema.builtin_type_target_index != .none) { |
| 3370 | mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, ty); |
| 3371 | break :ty sema.builtin_type_target_index; |
| 3372 | } |
| 3373 | break :ty ty; |
| 3374 | }; |
| 3350 | 3375 | // TODO: figure out InternPool removals for incremental compilation |
| 3351 | 3376 | //errdefer mod.intern_pool.remove(union_ty); |
| 3352 | 3377 | |
| ... | ... | @@ -3473,8 +3498,8 @@ fn zirRetPtr(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 3473 | 3498 | defer tracy.end(); |
| 3474 | 3499 | |
| 3475 | 3500 | if (block.is_comptime or try sema.typeRequiresComptime(sema.fn_ret_ty)) { |
| 3476 | | const fn_ret_ty = try sema.resolveTypeFields(sema.fn_ret_ty); |
| 3477 | | return sema.analyzeComptimeAlloc(block, fn_ret_ty, .none); |
| 3501 | try sema.resolveTypeFields(sema.fn_ret_ty); |
| 3502 | return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty, .none); |
| 3478 | 3503 | } |
| 3479 | 3504 | |
| 3480 | 3505 | const target = sema.mod.getTarget(); |
| ... | ... | @@ -4371,7 +4396,7 @@ fn zirValidateArrayInitTy( |
| 4371 | 4396 | return; |
| 4372 | 4397 | }, |
| 4373 | 4398 | .Struct => if (ty.isTuple(mod)) { |
| 4374 | | _ = try sema.resolveTypeFields(ty); |
| 4399 | try sema.resolveTypeFields(ty); |
| 4375 | 4400 | const array_len = ty.arrayLen(mod); |
| 4376 | 4401 | if (extra.init_count > array_len) { |
| 4377 | 4402 | return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{ |
| ... | ... | @@ -6476,11 +6501,11 @@ pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref |
| 6476 | 6501 | if (block.is_comptime) |
| 6477 | 6502 | return .none; |
| 6478 | 6503 | |
| 6479 | | const unresolved_stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) { |
| 6504 | const stack_trace_ty = sema.getBuiltinType("StackTrace") catch |err| switch (err) { |
| 6480 | 6505 | error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, |
| 6481 | 6506 | else => |e| return e, |
| 6482 | 6507 | }; |
| 6483 | | const stack_trace_ty = sema.resolveTypeFields(unresolved_stack_trace_ty) catch |err| switch (err) { |
| 6508 | sema.resolveTypeFields(stack_trace_ty) catch |err| switch (err) { |
| 6484 | 6509 | error.NeededSourceLocation, error.GenericPoison, error.ComptimeReturn, error.ComptimeBreak => unreachable, |
| 6485 | 6510 | else => |e| return e, |
| 6486 | 6511 | }; |
| ... | ... | @@ -6522,8 +6547,8 @@ fn popErrorReturnTrace( |
| 6522 | 6547 | // AstGen determined this result does not go to an error-handling expr (try/catch/return etc.), or |
| 6523 | 6548 | // the result is comptime-known to be a non-error. Either way, pop unconditionally. |
| 6524 | 6549 | |
| 6525 | | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 6526 | | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 6550 | const stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 6551 | try sema.resolveTypeFields(stack_trace_ty); |
| 6527 | 6552 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); |
| 6528 | 6553 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 6529 | 6554 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index"); |
| ... | ... | @@ -6548,8 +6573,8 @@ fn popErrorReturnTrace( |
| 6548 | 6573 | defer then_block.instructions.deinit(gpa); |
| 6549 | 6574 | |
| 6550 | 6575 | // If non-error, then pop the error return trace by restoring the index. |
| 6551 | | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 6552 | | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 6576 | const stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 6577 | try sema.resolveTypeFields(stack_trace_ty); |
| 6553 | 6578 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); |
| 6554 | 6579 | const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 6555 | 6580 | const field_name = try mod.intern_pool.getOrPutString(gpa, "index"); |
| ... | ... | @@ -6671,8 +6696,8 @@ fn zirCall( |
| 6671 | 6696 | // If any input is an error-type, we might need to pop any trace it generated. Otherwise, we only |
| 6672 | 6697 | // need to clean-up our own trace if we were passed to a non-error-handling expression. |
| 6673 | 6698 | if (input_is_error or (pop_error_return_trace and return_ty.isError(mod))) { |
| 6674 | | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 6675 | | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 6699 | const stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 6700 | try sema.resolveTypeFields(stack_trace_ty); |
| 6676 | 6701 | const field_name = try mod.intern_pool.getOrPutString(sema.gpa, "index"); |
| 6677 | 6702 | const field_index = try sema.structFieldIndex(block, stack_trace_ty, field_name, call_src); |
| 6678 | 6703 | |
| ... | ... | @@ -8084,7 +8109,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro |
| 8084 | 8109 | fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 8085 | 8110 | const mod = sema.mod; |
| 8086 | 8111 | const bin = sema.code.instructions.items(.data)[inst].bin; |
| 8087 | | const operand = sema.resolveType(block, .unneeded, bin.lhs) catch |err| switch (err) { |
| 8112 | const indexable_ty = sema.resolveType(block, .unneeded, bin.lhs) catch |err| switch (err) { |
| 8088 | 8113 | // Since this is a ZIR instruction that returns a type, encountering |
| 8089 | 8114 | // generic poison should not result in a failed compilation, but the |
| 8090 | 8115 | // generic poison type. This prevents unnecessary failures when |
| ... | ... | @@ -8092,7 +8117,7 @@ fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 8092 | 8117 | error.GenericPoison => return .generic_poison_type, |
| 8093 | 8118 | else => |e| return e, |
| 8094 | 8119 | }; |
| 8095 | | const indexable_ty = try sema.resolveTypeFields(operand); |
| 8120 | try sema.resolveTypeFields(indexable_ty); |
| 8096 | 8121 | assert(indexable_ty.isIndexable(mod)); // validated by a previous instruction |
| 8097 | 8122 | if (indexable_ty.zigTypeTag(mod) == .Struct) { |
| 8098 | 8123 | const elem_type = indexable_ty.structFieldType(@intFromEnum(bin.rhs), mod); |
| ... | ... | @@ -8420,8 +8445,8 @@ fn zirIntFromEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 8420 | 8445 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag(mod)) { |
| 8421 | 8446 | .Enum => operand, |
| 8422 | 8447 | .Union => blk: { |
| 8423 | | const union_ty = try sema.resolveTypeFields(operand_ty); |
| 8424 | | const tag_ty = union_ty.unionTagType(mod) orelse { |
| 8448 | try sema.resolveTypeFields(operand_ty); |
| 8449 | const tag_ty = operand_ty.unionTagType(mod) orelse { |
| 8425 | 8450 | return sema.fail( |
| 8426 | 8451 | block, |
| 8427 | 8452 | operand_src, |
| ... | ... | @@ -9573,7 +9598,7 @@ fn finishFunc( |
| 9573 | 9598 | // Make sure that StackTrace's fields are resolved so that the backend can |
| 9574 | 9599 | // lower this fn type. |
| 9575 | 9600 | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 9576 | | _ = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 9601 | try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 9577 | 9602 | } |
| 9578 | 9603 | |
| 9579 | 9604 | return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty); |
| ... | ... | @@ -10890,12 +10915,12 @@ fn switchCond( |
| 10890 | 10915 | }, |
| 10891 | 10916 | |
| 10892 | 10917 | .Union => { |
| 10893 | | const union_ty = try sema.resolveTypeFields(operand_ty); |
| 10894 | | const enum_ty = union_ty.unionTagType(mod) orelse { |
| 10918 | try sema.resolveTypeFields(operand_ty); |
| 10919 | const enum_ty = operand_ty.unionTagType(mod) orelse { |
| 10895 | 10920 | const msg = msg: { |
| 10896 | 10921 | const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{}); |
| 10897 | 10922 | errdefer msg.destroy(sema.gpa); |
| 10898 | | if (union_ty.declSrcLocOrNull(mod)) |union_src| { |
| 10923 | if (operand_ty.declSrcLocOrNull(mod)) |union_src| { |
| 10899 | 10924 | try mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{}); |
| 10900 | 10925 | } |
| 10901 | 10926 | break :msg msg; |
| ... | ... | @@ -12780,9 +12805,9 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 12780 | 12805 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 12781 | 12806 | const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 12782 | 12807 | const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 12783 | | const unresolved_ty = try sema.resolveType(block, ty_src, extra.lhs); |
| 12808 | const ty = try sema.resolveType(block, ty_src, extra.lhs); |
| 12784 | 12809 | const field_name = try sema.resolveConstStringIntern(block, name_src, extra.rhs, "field name must be comptime-known"); |
| 12785 | | const ty = try sema.resolveTypeFields(unresolved_ty); |
| 12810 | try sema.resolveTypeFields(ty); |
| 12786 | 12811 | const ip = &mod.intern_pool; |
| 12787 | 12812 | |
| 12788 | 12813 | const has_field = hf: { |
| ... | ... | @@ -16141,7 +16166,8 @@ fn analyzeCmpUnionTag( |
| 16141 | 16166 | op: std.math.CompareOperator, |
| 16142 | 16167 | ) CompileError!Air.Inst.Ref { |
| 16143 | 16168 | const mod = sema.mod; |
| 16144 | | const union_ty = try sema.resolveTypeFields(sema.typeOf(un)); |
| 16169 | const union_ty = sema.typeOf(un); |
| 16170 | try sema.resolveTypeFields(union_ty); |
| 16145 | 16171 | const union_tag_ty = union_ty.unionTagType(mod) orelse { |
| 16146 | 16172 | const msg = msg: { |
| 16147 | 16173 | const msg = try sema.errMsg(block, un_src, "comparison of union and enum literal is only valid for tagged union types", .{}); |
| ... | ... | @@ -17278,11 +17304,10 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17278 | 17304 | break :t union_field_ty_decl.val.toType(); |
| 17279 | 17305 | }; |
| 17280 | 17306 | |
| 17281 | | const union_ty = try sema.resolveTypeFields(ty); |
| 17282 | 17307 | try sema.resolveTypeLayout(ty); // Getting alignment requires type layout |
| 17283 | | const layout = union_ty.containerLayout(mod); |
| 17308 | const layout = ty.containerLayout(mod); |
| 17284 | 17309 | |
| 17285 | | const union_fields = union_ty.unionFields(mod); |
| 17310 | const union_fields = ty.unionFields(mod); |
| 17286 | 17311 | const union_field_vals = try gpa.alloc(InternPool.Index, union_fields.count()); |
| 17287 | 17312 | defer gpa.free(union_field_vals); |
| 17288 | 17313 | |
| ... | ... | @@ -17357,11 +17382,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17357 | 17382 | } }); |
| 17358 | 17383 | }; |
| 17359 | 17384 | |
| 17360 | | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, union_ty.getNamespaceIndex(mod)); |
| 17385 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); |
| 17361 | 17386 | |
| 17362 | 17387 | const enum_tag_ty_val = try mod.intern(.{ .opt = .{ |
| 17363 | 17388 | .ty = (try mod.optionalType(.type_type)).toIntern(), |
| 17364 | | .val = if (union_ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none, |
| 17389 | .val = if (ty.unionTagType(mod)) |tag_ty| tag_ty.toIntern() else .none, |
| 17365 | 17390 | } }); |
| 17366 | 17391 | |
| 17367 | 17392 | const container_layout_ty = t: { |
| ... | ... | @@ -17429,18 +17454,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17429 | 17454 | break :t struct_field_ty_decl.val.toType(); |
| 17430 | 17455 | }; |
| 17431 | 17456 | |
| 17432 | | const struct_ty = try sema.resolveTypeFields(ty); |
| 17433 | 17457 | try sema.resolveTypeLayout(ty); // Getting alignment requires type layout |
| 17434 | | const layout = struct_ty.containerLayout(mod); |
| 17458 | const layout = ty.containerLayout(mod); |
| 17435 | 17459 | |
| 17436 | 17460 | var struct_field_vals: []InternPool.Index = &.{}; |
| 17437 | 17461 | defer gpa.free(struct_field_vals); |
| 17438 | 17462 | fv: { |
| 17439 | | const struct_type = switch (ip.indexToKey(struct_ty.toIntern())) { |
| 17463 | const struct_type = switch (ip.indexToKey(ty.toIntern())) { |
| 17440 | 17464 | .anon_struct_type => |tuple| { |
| 17441 | 17465 | struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len); |
| 17442 | 17466 | for (struct_field_vals, 0..) |*struct_field_val, i| { |
| 17443 | | const anon_struct_type = ip.indexToKey(struct_ty.toIntern()).anon_struct_type; |
| 17467 | const anon_struct_type = ip.indexToKey(ty.toIntern()).anon_struct_type; |
| 17444 | 17468 | const field_ty = anon_struct_type.types[i]; |
| 17445 | 17469 | const field_val = anon_struct_type.values[i]; |
| 17446 | 17470 | const name_val = v: { |
| ... | ... | @@ -17449,7 +17473,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17449 | 17473 | // TODO: write something like getCoercedInts to avoid needing to dupe |
| 17450 | 17474 | const bytes = if (tuple.names.len != 0) |
| 17451 | 17475 | // https://github.com/ziglang/zig/issues/15709 |
| 17452 | | try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(struct_ty.toIntern()).anon_struct_type.names[i])) |
| 17476 | try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names[i])) |
| 17453 | 17477 | else |
| 17454 | 17478 | try std.fmt.allocPrint(sema.arena, "{d}", .{i}); |
| 17455 | 17479 | const new_decl_ty = try mod.arrayType(.{ |
| ... | ... | @@ -17582,12 +17606,12 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17582 | 17606 | } }); |
| 17583 | 17607 | }; |
| 17584 | 17608 | |
| 17585 | | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, struct_ty.getNamespaceIndex(mod)); |
| 17609 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); |
| 17586 | 17610 | |
| 17587 | 17611 | const backing_integer_val = try mod.intern(.{ .opt = .{ |
| 17588 | 17612 | .ty = (try mod.optionalType(.type_type)).toIntern(), |
| 17589 | 17613 | .val = if (layout == .Packed) val: { |
| 17590 | | const struct_obj = mod.typeToStruct(struct_ty).?; |
| 17614 | const struct_obj = mod.typeToStruct(ty).?; |
| 17591 | 17615 | assert(struct_obj.haveLayout()); |
| 17592 | 17616 | assert(struct_obj.backing_int_ty.isInt(mod)); |
| 17593 | 17617 | break :val struct_obj.backing_int_ty.toIntern(); |
| ... | ... | @@ -17617,7 +17641,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17617 | 17641 | // decls: []const Declaration, |
| 17618 | 17642 | decls_val, |
| 17619 | 17643 | // is_tuple: bool, |
| 17620 | | Value.makeBool(struct_ty.isTuple(mod)).toIntern(), |
| 17644 | Value.makeBool(ty.isTuple(mod)).toIntern(), |
| 17621 | 17645 | }; |
| 17622 | 17646 | return Air.internedToRef((try mod.intern(.{ .un = .{ |
| 17623 | 17647 | .ty = type_info_ty.toIntern(), |
| ... | ... | @@ -17644,8 +17668,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 17644 | 17668 | break :t type_opaque_ty_decl.val.toType(); |
| 17645 | 17669 | }; |
| 17646 | 17670 | |
| 17647 | | const opaque_ty = try sema.resolveTypeFields(ty); |
| 17648 | | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, opaque_ty.getNamespaceIndex(mod)); |
| 17671 | try sema.resolveTypeFields(ty); |
| 17672 | const decls_val = try sema.typeInfoDecls(block, src, type_info_ty, ty.getNamespaceIndex(mod)); |
| 17649 | 17673 | |
| 17650 | 17674 | const field_values = .{ |
| 17651 | 17675 | // decls: []const Declaration, |
| ... | ... | @@ -18511,8 +18535,8 @@ fn retWithErrTracing( |
| 18511 | 18535 | else => true, |
| 18512 | 18536 | }; |
| 18513 | 18537 | const gpa = sema.gpa; |
| 18514 | | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 18515 | | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 18538 | const stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 18539 | try sema.resolveTypeFields(stack_trace_ty); |
| 18516 | 18540 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); |
| 18517 | 18541 | const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); |
| 18518 | 18542 | const return_err_fn = try sema.getBuiltin("returnError"); |
| ... | ... | @@ -18874,14 +18898,14 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 18874 | 18898 | fn structInitEmpty( |
| 18875 | 18899 | sema: *Sema, |
| 18876 | 18900 | block: *Block, |
| 18877 | | obj_ty: Type, |
| 18901 | struct_ty: Type, |
| 18878 | 18902 | dest_src: LazySrcLoc, |
| 18879 | 18903 | init_src: LazySrcLoc, |
| 18880 | 18904 | ) CompileError!Air.Inst.Ref { |
| 18881 | 18905 | const mod = sema.mod; |
| 18882 | 18906 | const gpa = sema.gpa; |
| 18883 | 18907 | // This logic must be synchronized with that in `zirStructInit`. |
| 18884 | | const struct_ty = try sema.resolveTypeFields(obj_ty); |
| 18908 | try sema.resolveTypeFields(struct_ty); |
| 18885 | 18909 | |
| 18886 | 18910 | // The init values to use for the struct instance. |
| 18887 | 18911 | const field_inits = try gpa.alloc(Air.Inst.Ref, struct_ty.structFieldCount(mod)); |
| ... | ... | @@ -19674,8 +19698,7 @@ fn fieldType( |
| 19674 | 19698 | const mod = sema.mod; |
| 19675 | 19699 | var cur_ty = aggregate_ty; |
| 19676 | 19700 | while (true) { |
| 19677 | | const resolved_ty = try sema.resolveTypeFields(cur_ty); |
| 19678 | | cur_ty = resolved_ty; |
| 19701 | try sema.resolveTypeFields(cur_ty); |
| 19679 | 19702 | switch (cur_ty.zigTypeTag(mod)) { |
| 19680 | 19703 | .Struct => switch (mod.intern_pool.indexToKey(cur_ty.toIntern())) { |
| 19681 | 19704 | .anon_struct_type => |anon_struct| { |
| ... | ... | @@ -19709,7 +19732,7 @@ fn fieldType( |
| 19709 | 19732 | else => {}, |
| 19710 | 19733 | } |
| 19711 | 19734 | return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{ |
| 19712 | | resolved_ty.fmt(sema.mod), |
| 19735 | cur_ty.fmt(sema.mod), |
| 19713 | 19736 | }); |
| 19714 | 19737 | } |
| 19715 | 19738 | } |
| ... | ... | @@ -19721,8 +19744,8 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 19721 | 19744 | fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 19722 | 19745 | const mod = sema.mod; |
| 19723 | 19746 | const ip = &mod.intern_pool; |
| 19724 | | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 19725 | | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 19747 | const stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 19748 | try sema.resolveTypeFields(stack_trace_ty); |
| 19726 | 19749 | const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); |
| 19727 | 19750 | const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern()); |
| 19728 | 19751 | |
| ... | ... | @@ -20048,14 +20071,10 @@ fn zirReify( |
| 20048 | 20071 | (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?, |
| 20049 | 20072 | ); |
| 20050 | 20073 | |
| 20051 | | const unresolved_elem_ty = child_val.toType(); |
| 20052 | | const elem_ty = if (abi_align == .none) |
| 20053 | | unresolved_elem_ty |
| 20054 | | else t: { |
| 20055 | | const elem_ty = try sema.resolveTypeFields(unresolved_elem_ty); |
| 20074 | const elem_ty = child_val.toType(); |
| 20075 | if (abi_align != .none) { |
| 20056 | 20076 | try sema.resolveTypeLayout(elem_ty); |
| 20057 | | break :t elem_ty; |
| 20058 | | }; |
| 20077 | } |
| 20059 | 20078 | |
| 20060 | 20079 | const ptr_size = mod.toEnum(std.builtin.Type.Pointer.Size, size_val); |
| 20061 | 20080 | |
| ... | ... | @@ -25070,8 +25089,8 @@ fn prepareSimplePanic(sema: *Sema, block: *Block) !void { |
| 25070 | 25089 | } |
| 25071 | 25090 | |
| 25072 | 25091 | if (mod.null_stack_trace == .none) { |
| 25073 | | const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 25074 | | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 25092 | const stack_trace_ty = try sema.getBuiltinType("StackTrace"); |
| 25093 | try sema.resolveTypeFields(stack_trace_ty); |
| 25075 | 25094 | const target = mod.getTarget(); |
| 25076 | 25095 | const ptr_stack_trace_ty = try mod.ptrType(.{ |
| 25077 | 25096 | .child = stack_trace_ty.toIntern(), |
| ... | ... | @@ -25523,14 +25542,14 @@ fn fieldVal( |
| 25523 | 25542 | return inst; |
| 25524 | 25543 | } |
| 25525 | 25544 | } |
| 25526 | | const union_ty = try sema.resolveTypeFields(child_type); |
| 25527 | | if (union_ty.unionTagType(mod)) |enum_ty| { |
| 25545 | try sema.resolveTypeFields(child_type); |
| 25546 | if (child_type.unionTagType(mod)) |enum_ty| { |
| 25528 | 25547 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index_usize| { |
| 25529 | 25548 | const field_index = @as(u32, @intCast(field_index_usize)); |
| 25530 | 25549 | return Air.internedToRef((try mod.enumValueFieldIndex(enum_ty, field_index)).toIntern()); |
| 25531 | 25550 | } |
| 25532 | 25551 | } |
| 25533 | | return sema.failWithBadMemberAccess(block, union_ty, field_name_src, field_name); |
| 25552 | return sema.failWithBadMemberAccess(block, child_type, field_name_src, field_name); |
| 25534 | 25553 | }, |
| 25535 | 25554 | .Enum => { |
| 25536 | 25555 | if (child_type.getNamespaceIndex(mod).unwrap()) |namespace| { |
| ... | ... | @@ -25749,8 +25768,8 @@ fn fieldPtr( |
| 25749 | 25768 | return inst; |
| 25750 | 25769 | } |
| 25751 | 25770 | } |
| 25752 | | const union_ty = try sema.resolveTypeFields(child_type); |
| 25753 | | if (union_ty.unionTagType(mod)) |enum_ty| { |
| 25771 | try sema.resolveTypeFields(child_type); |
| 25772 | if (child_type.unionTagType(mod)) |enum_ty| { |
| 25754 | 25773 | if (enum_ty.enumFieldIndex(field_name, mod)) |field_index| { |
| 25755 | 25774 | const field_index_u32 = @as(u32, @intCast(field_index)); |
| 25756 | 25775 | var anon_decl = try block.startAnonDecl(); |
| ... | ... | @@ -25854,35 +25873,35 @@ fn fieldCallBind( |
| 25854 | 25873 | find_field: { |
| 25855 | 25874 | switch (concrete_ty.zigTypeTag(mod)) { |
| 25856 | 25875 | .Struct => { |
| 25857 | | const struct_ty = try sema.resolveTypeFields(concrete_ty); |
| 25858 | | if (mod.typeToStruct(struct_ty)) |struct_obj| { |
| 25876 | try sema.resolveTypeFields(concrete_ty); |
| 25877 | if (mod.typeToStruct(concrete_ty)) |struct_obj| { |
| 25859 | 25878 | const field_index_usize = struct_obj.fields.getIndex(field_name) orelse |
| 25860 | 25879 | break :find_field; |
| 25861 | 25880 | const field_index = @as(u32, @intCast(field_index_usize)); |
| 25862 | 25881 | const field = struct_obj.fields.values()[field_index]; |
| 25863 | 25882 | |
| 25864 | 25883 | return sema.finishFieldCallBind(block, src, ptr_ty, field.ty, field_index, object_ptr); |
| 25865 | | } else if (struct_ty.isTuple(mod)) { |
| 25884 | } else if (concrete_ty.isTuple(mod)) { |
| 25866 | 25885 | if (ip.stringEqlSlice(field_name, "len")) { |
| 25867 | | return .{ .direct = try mod.intRef(Type.usize, struct_ty.structFieldCount(mod)) }; |
| 25886 | return .{ .direct = try mod.intRef(Type.usize, concrete_ty.structFieldCount(mod)) }; |
| 25868 | 25887 | } |
| 25869 | 25888 | if (field_name.toUnsigned(ip)) |field_index| { |
| 25870 | | if (field_index >= struct_ty.structFieldCount(mod)) break :find_field; |
| 25871 | | return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(field_index, mod), field_index, object_ptr); |
| 25889 | if (field_index >= concrete_ty.structFieldCount(mod)) break :find_field; |
| 25890 | return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(field_index, mod), field_index, object_ptr); |
| 25872 | 25891 | } |
| 25873 | 25892 | } else { |
| 25874 | | const max = struct_ty.structFieldCount(mod); |
| 25893 | const max = concrete_ty.structFieldCount(mod); |
| 25875 | 25894 | for (0..max) |i_usize| { |
| 25876 | 25895 | const i = @as(u32, @intCast(i_usize)); |
| 25877 | | if (field_name == struct_ty.structFieldName(i, mod)) { |
| 25878 | | return sema.finishFieldCallBind(block, src, ptr_ty, struct_ty.structFieldType(i, mod), i, object_ptr); |
| 25896 | if (field_name == concrete_ty.structFieldName(i, mod)) { |
| 25897 | return sema.finishFieldCallBind(block, src, ptr_ty, concrete_ty.structFieldType(i, mod), i, object_ptr); |
| 25879 | 25898 | } |
| 25880 | 25899 | } |
| 25881 | 25900 | } |
| 25882 | 25901 | }, |
| 25883 | 25902 | .Union => { |
| 25884 | | const union_ty = try sema.resolveTypeFields(concrete_ty); |
| 25885 | | const fields = union_ty.unionFields(mod); |
| 25903 | try sema.resolveTypeFields(concrete_ty); |
| 25904 | const fields = concrete_ty.unionFields(mod); |
| 25886 | 25905 | const field_index_usize = fields.getIndex(field_name) orelse break :find_field; |
| 25887 | 25906 | const field_index = @as(u32, @intCast(field_index_usize)); |
| 25888 | 25907 | const field = fields.values()[field_index]; |
| ... | ... | @@ -26081,13 +26100,13 @@ fn structFieldPtr( |
| 26081 | 26100 | struct_ptr: Air.Inst.Ref, |
| 26082 | 26101 | field_name: InternPool.NullTerminatedString, |
| 26083 | 26102 | field_name_src: LazySrcLoc, |
| 26084 | | unresolved_struct_ty: Type, |
| 26103 | struct_ty: Type, |
| 26085 | 26104 | initializing: bool, |
| 26086 | 26105 | ) CompileError!Air.Inst.Ref { |
| 26087 | 26106 | const mod = sema.mod; |
| 26088 | | assert(unresolved_struct_ty.zigTypeTag(mod) == .Struct); |
| 26107 | assert(struct_ty.zigTypeTag(mod) == .Struct); |
| 26089 | 26108 | |
| 26090 | | const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty); |
| 26109 | try sema.resolveTypeFields(struct_ty); |
| 26091 | 26110 | try sema.resolveStructLayout(struct_ty); |
| 26092 | 26111 | |
| 26093 | 26112 | if (struct_ty.isTuple(mod)) { |
| ... | ... | @@ -26234,12 +26253,12 @@ fn structFieldVal( |
| 26234 | 26253 | struct_byval: Air.Inst.Ref, |
| 26235 | 26254 | field_name: InternPool.NullTerminatedString, |
| 26236 | 26255 | field_name_src: LazySrcLoc, |
| 26237 | | unresolved_struct_ty: Type, |
| 26256 | struct_ty: Type, |
| 26238 | 26257 | ) CompileError!Air.Inst.Ref { |
| 26239 | 26258 | const mod = sema.mod; |
| 26240 | | assert(unresolved_struct_ty.zigTypeTag(mod) == .Struct); |
| 26259 | assert(struct_ty.zigTypeTag(mod) == .Struct); |
| 26241 | 26260 | |
| 26242 | | const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty); |
| 26261 | try sema.resolveTypeFields(struct_ty); |
| 26243 | 26262 | switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) { |
| 26244 | 26263 | .struct_type => |struct_type| { |
| 26245 | 26264 | const struct_obj = mod.structPtrUnwrap(struct_type.index).?; |
| ... | ... | @@ -26361,17 +26380,17 @@ fn unionFieldPtr( |
| 26361 | 26380 | union_ptr: Air.Inst.Ref, |
| 26362 | 26381 | field_name: InternPool.NullTerminatedString, |
| 26363 | 26382 | field_name_src: LazySrcLoc, |
| 26364 | | unresolved_union_ty: Type, |
| 26383 | union_ty: Type, |
| 26365 | 26384 | initializing: bool, |
| 26366 | 26385 | ) CompileError!Air.Inst.Ref { |
| 26367 | 26386 | const mod = sema.mod; |
| 26368 | 26387 | const ip = &mod.intern_pool; |
| 26369 | 26388 | |
| 26370 | | assert(unresolved_union_ty.zigTypeTag(mod) == .Union); |
| 26389 | assert(union_ty.zigTypeTag(mod) == .Union); |
| 26371 | 26390 | |
| 26372 | 26391 | const union_ptr_ty = sema.typeOf(union_ptr); |
| 26373 | 26392 | const union_ptr_info = union_ptr_ty.ptrInfo(mod); |
| 26374 | | const union_ty = try sema.resolveTypeFields(unresolved_union_ty); |
| 26393 | try sema.resolveTypeFields(union_ty); |
| 26375 | 26394 | const union_obj = mod.typeToUnion(union_ty).?; |
| 26376 | 26395 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 26377 | 26396 | const field = union_obj.fields.values()[field_index]; |
| ... | ... | @@ -26467,13 +26486,13 @@ fn unionFieldVal( |
| 26467 | 26486 | union_byval: Air.Inst.Ref, |
| 26468 | 26487 | field_name: InternPool.NullTerminatedString, |
| 26469 | 26488 | field_name_src: LazySrcLoc, |
| 26470 | | unresolved_union_ty: Type, |
| 26489 | union_ty: Type, |
| 26471 | 26490 | ) CompileError!Air.Inst.Ref { |
| 26472 | 26491 | const mod = sema.mod; |
| 26473 | 26492 | const ip = &mod.intern_pool; |
| 26474 | | assert(unresolved_union_ty.zigTypeTag(mod) == .Union); |
| 26493 | assert(union_ty.zigTypeTag(mod) == .Union); |
| 26475 | 26494 | |
| 26476 | | const union_ty = try sema.resolveTypeFields(unresolved_union_ty); |
| 26495 | try sema.resolveTypeFields(union_ty); |
| 26477 | 26496 | const union_obj = mod.typeToUnion(union_ty).?; |
| 26478 | 26497 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 26479 | 26498 | const field = union_obj.fields.values()[field_index]; |
| ... | ... | @@ -26733,7 +26752,7 @@ fn tupleFieldPtr( |
| 26733 | 26752 | const mod = sema.mod; |
| 26734 | 26753 | const tuple_ptr_ty = sema.typeOf(tuple_ptr); |
| 26735 | 26754 | const tuple_ty = tuple_ptr_ty.childType(mod); |
| 26736 | | _ = try sema.resolveTypeFields(tuple_ty); |
| 26755 | try sema.resolveTypeFields(tuple_ty); |
| 26737 | 26756 | const field_count = tuple_ty.structFieldCount(mod); |
| 26738 | 26757 | |
| 26739 | 26758 | if (field_count == 0) { |
| ... | ... | @@ -26790,7 +26809,8 @@ fn tupleField( |
| 26790 | 26809 | field_index: u32, |
| 26791 | 26810 | ) CompileError!Air.Inst.Ref { |
| 26792 | 26811 | const mod = sema.mod; |
| 26793 | | const tuple_ty = try sema.resolveTypeFields(sema.typeOf(tuple)); |
| 26812 | const tuple_ty = sema.typeOf(tuple); |
| 26813 | try sema.resolveTypeFields(tuple_ty); |
| 26794 | 26814 | const field_count = tuple_ty.structFieldCount(mod); |
| 26795 | 26815 | |
| 26796 | 26816 | if (field_count == 0) { |
| ... | ... | @@ -27114,16 +27134,17 @@ const CoerceOpts = struct { |
| 27114 | 27134 | fn coerceExtra( |
| 27115 | 27135 | sema: *Sema, |
| 27116 | 27136 | block: *Block, |
| 27117 | | dest_ty_unresolved: Type, |
| 27137 | dest_ty: Type, |
| 27118 | 27138 | inst: Air.Inst.Ref, |
| 27119 | 27139 | inst_src: LazySrcLoc, |
| 27120 | 27140 | opts: CoerceOpts, |
| 27121 | 27141 | ) CoersionError!Air.Inst.Ref { |
| 27122 | | if (dest_ty_unresolved.isGenericPoison()) return inst; |
| 27142 | if (dest_ty.isGenericPoison()) return inst; |
| 27123 | 27143 | const mod = sema.mod; |
| 27124 | 27144 | const dest_ty_src = inst_src; // TODO better source location |
| 27125 | | const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved); |
| 27126 | | const inst_ty = try sema.resolveTypeFields(sema.typeOf(inst)); |
| 27145 | try sema.resolveTypeFields(dest_ty); |
| 27146 | const inst_ty = sema.typeOf(inst); |
| 27147 | try sema.resolveTypeFields(inst_ty); |
| 27127 | 27148 | const target = mod.getTarget(); |
| 27128 | 27149 | // If the types are the same, we can return the operand. |
| 27129 | 27150 | if (dest_ty.eql(inst_ty, mod)) |
| ... | ... | @@ -29831,16 +29852,15 @@ fn beginComptimePtrLoad( |
| 29831 | 29852 | fn bitCast( |
| 29832 | 29853 | sema: *Sema, |
| 29833 | 29854 | block: *Block, |
| 29834 | | dest_ty_unresolved: Type, |
| 29855 | dest_ty: Type, |
| 29835 | 29856 | inst: Air.Inst.Ref, |
| 29836 | 29857 | inst_src: LazySrcLoc, |
| 29837 | 29858 | operand_src: ?LazySrcLoc, |
| 29838 | 29859 | ) CompileError!Air.Inst.Ref { |
| 29839 | 29860 | const mod = sema.mod; |
| 29840 | | const dest_ty = try sema.resolveTypeFields(dest_ty_unresolved); |
| 29841 | 29861 | try sema.resolveTypeLayout(dest_ty); |
| 29842 | 29862 | |
| 29843 | | const old_ty = try sema.resolveTypeFields(sema.typeOf(inst)); |
| 29863 | const old_ty = sema.typeOf(inst); |
| 29844 | 29864 | try sema.resolveTypeLayout(old_ty); |
| 29845 | 29865 | |
| 29846 | 29866 | const dest_bits = dest_ty.bitSize(mod); |
| ... | ... | @@ -30043,8 +30063,8 @@ fn coerceEnumToUnion( |
| 30043 | 30063 | |
| 30044 | 30064 | const union_obj = mod.typeToUnion(union_ty).?; |
| 30045 | 30065 | const field = union_obj.fields.values()[field_index]; |
| 30046 | | const field_ty = try sema.resolveTypeFields(field.ty); |
| 30047 | | if (field_ty.zigTypeTag(mod) == .NoReturn) { |
| 30066 | try sema.resolveTypeFields(field.ty); |
| 30067 | if (field.ty.zigTypeTag(mod) == .NoReturn) { |
| 30048 | 30068 | const msg = msg: { |
| 30049 | 30069 | const msg = try sema.errMsg(block, inst_src, "cannot initialize 'noreturn' field of union", .{}); |
| 30050 | 30070 | errdefer msg.destroy(sema.gpa); |
| ... | ... | @@ -30058,12 +30078,12 @@ fn coerceEnumToUnion( |
| 30058 | 30078 | }; |
| 30059 | 30079 | return sema.failWithOwnedErrorMsg(msg); |
| 30060 | 30080 | } |
| 30061 | | const opv = (try sema.typeHasOnePossibleValue(field_ty)) orelse { |
| 30081 | const opv = (try sema.typeHasOnePossibleValue(field.ty)) orelse { |
| 30062 | 30082 | const msg = msg: { |
| 30063 | 30083 | const field_name = union_obj.fields.keys()[field_index]; |
| 30064 | 30084 | const msg = try sema.errMsg(block, inst_src, "coercion from enum '{}' to union '{}' must initialize '{}' field '{}'", .{ |
| 30065 | 30085 | inst_ty.fmt(sema.mod), union_ty.fmt(sema.mod), |
| 30066 | | field_ty.fmt(sema.mod), field_name.fmt(ip), |
| 30086 | field.ty.fmt(sema.mod), field_name.fmt(ip), |
| 30067 | 30087 | }); |
| 30068 | 30088 | errdefer msg.destroy(sema.gpa); |
| 30069 | 30089 | |
| ... | ... | @@ -30427,13 +30447,13 @@ fn coerceTupleToArrayPtrs( |
| 30427 | 30447 | fn coerceTupleToStruct( |
| 30428 | 30448 | sema: *Sema, |
| 30429 | 30449 | block: *Block, |
| 30430 | | dest_ty: Type, |
| 30450 | struct_ty: Type, |
| 30431 | 30451 | inst: Air.Inst.Ref, |
| 30432 | 30452 | inst_src: LazySrcLoc, |
| 30433 | 30453 | ) !Air.Inst.Ref { |
| 30434 | 30454 | const mod = sema.mod; |
| 30435 | 30455 | const ip = &mod.intern_pool; |
| 30436 | | const struct_ty = try sema.resolveTypeFields(dest_ty); |
| 30456 | try sema.resolveTypeFields(struct_ty); |
| 30437 | 30457 | |
| 30438 | 30458 | if (struct_ty.isTupleOrAnonStruct(mod)) { |
| 30439 | 30459 | return sema.coerceTupleToTuple(block, struct_ty, inst, inst_src); |
| ... | ... | @@ -33729,6 +33749,10 @@ fn resolveLazyValue(sema: *Sema, val: Value) CompileError!Value { |
| 33729 | 33749 | |
| 33730 | 33750 | pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void { |
| 33731 | 33751 | const mod = sema.mod; |
| 33752 | switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 33753 | .simple_type => |simple_type| return sema.resolveSimpleType(simple_type), |
| 33754 | else => {}, |
| 33755 | } |
| 33732 | 33756 | switch (ty.zigTypeTag(mod)) { |
| 33733 | 33757 | .Struct => return sema.resolveStructLayout(ty), |
| 33734 | 33758 | .Union => return sema.resolveUnionLayout(ty), |
| ... | ... | @@ -33769,8 +33793,8 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void { |
| 33769 | 33793 | |
| 33770 | 33794 | fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void { |
| 33771 | 33795 | const mod = sema.mod; |
| 33772 | | const resolved_ty = try sema.resolveTypeFields(ty); |
| 33773 | | if (mod.typeToStruct(resolved_ty)) |struct_obj| { |
| 33796 | try sema.resolveTypeFields(ty); |
| 33797 | if (mod.typeToStruct(ty)) |struct_obj| { |
| 33774 | 33798 | switch (struct_obj.status) { |
| 33775 | 33799 | .none, .have_field_types => {}, |
| 33776 | 33800 | .field_types_wip, .layout_wip => { |
| ... | ... | @@ -33806,9 +33830,9 @@ fn resolveStructLayout(sema: *Sema, ty: Type) CompileError!void { |
| 33806 | 33830 | } |
| 33807 | 33831 | |
| 33808 | 33832 | struct_obj.status = .have_layout; |
| 33809 | | _ = try sema.resolveTypeRequiresComptime(resolved_ty); |
| 33833 | _ = try sema.resolveTypeRequiresComptime(ty); |
| 33810 | 33834 | |
| 33811 | | if (struct_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) { |
| 33835 | if (struct_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) { |
| 33812 | 33836 | const msg = try Module.ErrorMsg.create( |
| 33813 | 33837 | sema.gpa, |
| 33814 | 33838 | struct_obj.srcLoc(mod), |
| ... | ... | @@ -34020,8 +34044,8 @@ fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void |
| 34020 | 34044 | |
| 34021 | 34045 | fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void { |
| 34022 | 34046 | const mod = sema.mod; |
| 34023 | | const resolved_ty = try sema.resolveTypeFields(ty); |
| 34024 | | const union_obj = mod.typeToUnion(resolved_ty).?; |
| 34047 | try sema.resolveTypeFields(ty); |
| 34048 | const union_obj = mod.typeToUnion(ty).?; |
| 34025 | 34049 | switch (union_obj.status) { |
| 34026 | 34050 | .none, .have_field_types => {}, |
| 34027 | 34051 | .field_types_wip, .layout_wip => { |
| ... | ... | @@ -34052,9 +34076,9 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void { |
| 34052 | 34076 | }; |
| 34053 | 34077 | } |
| 34054 | 34078 | union_obj.status = .have_layout; |
| 34055 | | _ = try sema.resolveTypeRequiresComptime(resolved_ty); |
| 34079 | _ = try sema.resolveTypeRequiresComptime(ty); |
| 34056 | 34080 | |
| 34057 | | if (union_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(resolved_ty))) { |
| 34081 | if (union_obj.assumed_runtime_bits and !(try sema.typeHasRuntimeBits(ty))) { |
| 34058 | 34082 | const msg = try Module.ErrorMsg.create( |
| 34059 | 34083 | sema.gpa, |
| 34060 | 34084 | union_obj.srcLoc(sema.mod), |
| ... | ... | @@ -34228,8 +34252,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { |
| 34228 | 34252 | const mod = sema.mod; |
| 34229 | 34253 | switch (ty.zigTypeTag(mod)) { |
| 34230 | 34254 | .Pointer => { |
| 34231 | | const child_ty = try sema.resolveTypeFields(ty.childType(mod)); |
| 34232 | | return sema.resolveTypeFully(child_ty); |
| 34255 | return sema.resolveTypeFully(ty.childType(mod)); |
| 34233 | 34256 | }, |
| 34234 | 34257 | .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 34235 | 34258 | .struct_type => return sema.resolveStructFully(ty), |
| ... | ... | @@ -34238,6 +34261,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { |
| 34238 | 34261 | try sema.resolveTypeFully(field_ty.toType()); |
| 34239 | 34262 | } |
| 34240 | 34263 | }, |
| 34264 | .simple_type => |simple_type| try sema.resolveSimpleType(simple_type), |
| 34241 | 34265 | else => {}, |
| 34242 | 34266 | }, |
| 34243 | 34267 | .Union => return sema.resolveUnionFully(ty), |
| ... | ... | @@ -34268,8 +34292,8 @@ fn resolveStructFully(sema: *Sema, ty: Type) CompileError!void { |
| 34268 | 34292 | try sema.resolveStructLayout(ty); |
| 34269 | 34293 | |
| 34270 | 34294 | const mod = sema.mod; |
| 34271 | | const resolved_ty = try sema.resolveTypeFields(ty); |
| 34272 | | const struct_obj = mod.typeToStruct(resolved_ty).?; |
| 34295 | try sema.resolveTypeFields(ty); |
| 34296 | const struct_obj = mod.typeToStruct(ty).?; |
| 34273 | 34297 | |
| 34274 | 34298 | switch (struct_obj.status) { |
| 34275 | 34299 | .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {}, |
| ... | ... | @@ -34298,8 +34322,8 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void { |
| 34298 | 34322 | try sema.resolveUnionLayout(ty); |
| 34299 | 34323 | |
| 34300 | 34324 | const mod = sema.mod; |
| 34301 | | const resolved_ty = try sema.resolveTypeFields(ty); |
| 34302 | | const union_obj = mod.typeToUnion(resolved_ty).?; |
| 34325 | try sema.resolveTypeFields(ty); |
| 34326 | const union_obj = mod.typeToUnion(ty).?; |
| 34303 | 34327 | switch (union_obj.status) { |
| 34304 | 34328 | .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {}, |
| 34305 | 34329 | .fully_resolved_wip, .fully_resolved => return, |
| ... | ... | @@ -34323,7 +34347,7 @@ fn resolveUnionFully(sema: *Sema, ty: Type) CompileError!void { |
| 34323 | 34347 | _ = try sema.typeRequiresComptime(ty); |
| 34324 | 34348 | } |
| 34325 | 34349 | |
| 34326 | | pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type { |
| 34350 | pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!void { |
| 34327 | 34351 | const mod = sema.mod; |
| 34328 | 34352 | |
| 34329 | 34353 | switch (ty.toIntern()) { |
| ... | ... | @@ -34386,7 +34410,7 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type { |
| 34386 | 34410 | .anyerror_void_error_union_type, |
| 34387 | 34411 | .generic_poison_type, |
| 34388 | 34412 | .empty_struct_type, |
| 34389 | | => return ty, |
| 34413 | => {}, |
| 34390 | 34414 | |
| 34391 | 34415 | .undef => unreachable, |
| 34392 | 34416 | .zero => unreachable, |
| ... | ... | @@ -34407,42 +34431,52 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type { |
| 34407 | 34431 | .empty_struct => unreachable, |
| 34408 | 34432 | .generic_poison => unreachable, |
| 34409 | 34433 | |
| 34410 | | .type_info_type => return sema.getBuiltinType("Type"), |
| 34411 | | .extern_options_type => return sema.getBuiltinType("ExternOptions"), |
| 34412 | | .export_options_type => return sema.getBuiltinType("ExportOptions"), |
| 34413 | | .atomic_order_type => return sema.getBuiltinType("AtomicOrder"), |
| 34414 | | .atomic_rmw_op_type => return sema.getBuiltinType("AtomicRmwOp"), |
| 34415 | | .calling_convention_type => return sema.getBuiltinType("CallingConvention"), |
| 34416 | | .address_space_type => return sema.getBuiltinType("AddressSpace"), |
| 34417 | | .float_mode_type => return sema.getBuiltinType("FloatMode"), |
| 34418 | | .reduce_op_type => return sema.getBuiltinType("ReduceOp"), |
| 34419 | | .call_modifier_type => return sema.getBuiltinType("CallModifier"), |
| 34420 | | .prefetch_options_type => return sema.getBuiltinType("PrefetchOptions"), |
| 34421 | | |
| 34422 | | _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) { |
| 34434 | else => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) { |
| 34423 | 34435 | .type_struct, |
| 34424 | 34436 | .type_struct_ns, |
| 34425 | 34437 | .type_union_tagged, |
| 34426 | 34438 | .type_union_untagged, |
| 34427 | 34439 | .type_union_safety, |
| 34440 | .simple_type, |
| 34428 | 34441 | => switch (mod.intern_pool.indexToKey(ty.toIntern())) { |
| 34429 | 34442 | .struct_type => |struct_type| { |
| 34430 | | const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return ty; |
| 34443 | const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return; |
| 34431 | 34444 | try sema.resolveTypeFieldsStruct(ty, struct_obj); |
| 34432 | | return ty; |
| 34433 | 34445 | }, |
| 34434 | 34446 | .union_type => |union_type| { |
| 34435 | 34447 | const union_obj = mod.unionPtr(union_type.index); |
| 34436 | 34448 | try sema.resolveTypeFieldsUnion(ty, union_obj); |
| 34437 | | return ty; |
| 34438 | 34449 | }, |
| 34450 | .simple_type => |simple_type| try sema.resolveSimpleType(simple_type), |
| 34439 | 34451 | else => unreachable, |
| 34440 | 34452 | }, |
| 34441 | | else => return ty, |
| 34453 | else => {}, |
| 34442 | 34454 | }, |
| 34443 | 34455 | } |
| 34444 | 34456 | } |
| 34445 | 34457 | |
| 34458 | /// Fully resolves a simple type. This is usually a nop, but for builtin types with |
| 34459 | /// special InternPool indices (such as std.builtin.Type) it will analyze and fully |
| 34460 | /// resolve the container type. |
| 34461 | fn resolveSimpleType(sema: *Sema, simple_type: InternPool.SimpleType) CompileError!void { |
| 34462 | const builtin_type_name: []const u8 = switch (simple_type) { |
| 34463 | .atomic_order => "AtomicOrder", |
| 34464 | .atomic_rmw_op => "AtomicRmwOp", |
| 34465 | .calling_convention => "CallingConvention", |
| 34466 | .address_space => "AddressSpace", |
| 34467 | .float_mode => "FloatMode", |
| 34468 | .reduce_op => "ReduceOp", |
| 34469 | .call_modifier => "CallModifer", |
| 34470 | .prefetch_options => "PrefetchOptions", |
| 34471 | .export_options => "ExportOptions", |
| 34472 | .extern_options => "ExternOptions", |
| 34473 | .type_info => "Type", |
| 34474 | else => return, |
| 34475 | }; |
| 34476 | // This will fully resolve the type. |
| 34477 | _ = try sema.getBuiltinType(builtin_type_name); |
| 34478 | } |
| 34479 | |
| 34446 | 34480 | fn resolveTypeFieldsStruct( |
| 34447 | 34481 | sema: *Sema, |
| 34448 | 34482 | ty: Type, |
| ... | ... | @@ -35785,7 +35819,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 35785 | 35819 | }, |
| 35786 | 35820 | |
| 35787 | 35821 | .struct_type => |struct_type| { |
| 35788 | | const resolved_ty = try sema.resolveTypeFields(ty); |
| 35822 | try sema.resolveTypeFields(ty); |
| 35789 | 35823 | if (mod.structPtrUnwrap(struct_type.index)) |s| { |
| 35790 | 35824 | const field_vals = try sema.arena.alloc(InternPool.Index, s.fields.count()); |
| 35791 | 35825 | for (field_vals, s.fields.values(), 0..) |*field_val, field, i| { |
| ... | ... | @@ -35793,14 +35827,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 35793 | 35827 | field_val.* = field.default_val; |
| 35794 | 35828 | continue; |
| 35795 | 35829 | } |
| 35796 | | if (field.ty.eql(resolved_ty, sema.mod)) { |
| 35830 | if (field.ty.eql(ty, sema.mod)) { |
| 35797 | 35831 | const msg = try Module.ErrorMsg.create( |
| 35798 | 35832 | sema.gpa, |
| 35799 | 35833 | s.srcLoc(sema.mod), |
| 35800 | 35834 | "struct '{}' depends on itself", |
| 35801 | 35835 | .{ty.fmt(sema.mod)}, |
| 35802 | 35836 | ); |
| 35803 | | try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{}); |
| 35837 | try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{}); |
| 35804 | 35838 | return sema.failWithOwnedErrorMsg(msg); |
| 35805 | 35839 | } |
| 35806 | 35840 | if (try sema.typeHasOnePossibleValue(field.ty)) |field_opv| { |
| ... | ... | @@ -35838,7 +35872,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 35838 | 35872 | }, |
| 35839 | 35873 | |
| 35840 | 35874 | .union_type => |union_type| { |
| 35841 | | const resolved_ty = try sema.resolveTypeFields(ty); |
| 35875 | try sema.resolveTypeFields(ty); |
| 35842 | 35876 | const union_obj = mod.unionPtr(union_type.index); |
| 35843 | 35877 | const tag_val = (try sema.typeHasOnePossibleValue(union_obj.tag_ty)) orelse |
| 35844 | 35878 | return null; |
| ... | ... | @@ -35848,20 +35882,20 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 35848 | 35882 | return only.toValue(); |
| 35849 | 35883 | } |
| 35850 | 35884 | const only_field = fields[0]; |
| 35851 | | if (only_field.ty.eql(resolved_ty, sema.mod)) { |
| 35885 | if (only_field.ty.eql(ty, sema.mod)) { |
| 35852 | 35886 | const msg = try Module.ErrorMsg.create( |
| 35853 | 35887 | sema.gpa, |
| 35854 | 35888 | union_obj.srcLoc(sema.mod), |
| 35855 | 35889 | "union '{}' depends on itself", |
| 35856 | 35890 | .{ty.fmt(sema.mod)}, |
| 35857 | 35891 | ); |
| 35858 | | try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{}); |
| 35892 | try sema.addFieldErrNote(ty, 0, msg, "while checking this field", .{}); |
| 35859 | 35893 | return sema.failWithOwnedErrorMsg(msg); |
| 35860 | 35894 | } |
| 35861 | 35895 | const val_val = (try sema.typeHasOnePossibleValue(only_field.ty)) orelse |
| 35862 | 35896 | return null; |
| 35863 | 35897 | const only = try mod.intern(.{ .un = .{ |
| 35864 | | .ty = resolved_ty.toIntern(), |
| 35898 | .ty = ty.toIntern(), |
| 35865 | 35899 | .tag = tag_val.toIntern(), |
| 35866 | 35900 | .val = val_val.toIntern(), |
| 35867 | 35901 | } }); |
| ... | ... | @@ -36431,12 +36465,12 @@ pub fn fnHasRuntimeBits(sema: *Sema, ty: Type) CompileError!bool { |
| 36431 | 36465 | fn unionFieldIndex( |
| 36432 | 36466 | sema: *Sema, |
| 36433 | 36467 | block: *Block, |
| 36434 | | unresolved_union_ty: Type, |
| 36468 | union_ty: Type, |
| 36435 | 36469 | field_name: InternPool.NullTerminatedString, |
| 36436 | 36470 | field_src: LazySrcLoc, |
| 36437 | 36471 | ) !u32 { |
| 36438 | 36472 | const mod = sema.mod; |
| 36439 | | const union_ty = try sema.resolveTypeFields(unresolved_union_ty); |
| 36473 | try sema.resolveTypeFields(union_ty); |
| 36440 | 36474 | const union_obj = mod.typeToUnion(union_ty).?; |
| 36441 | 36475 | const field_index_usize = union_obj.fields.getIndex(field_name) orelse |
| 36442 | 36476 | return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name); |
| ... | ... | @@ -36446,12 +36480,12 @@ fn unionFieldIndex( |
| 36446 | 36480 | fn structFieldIndex( |
| 36447 | 36481 | sema: *Sema, |
| 36448 | 36482 | block: *Block, |
| 36449 | | unresolved_struct_ty: Type, |
| 36483 | struct_ty: Type, |
| 36450 | 36484 | field_name: InternPool.NullTerminatedString, |
| 36451 | 36485 | field_src: LazySrcLoc, |
| 36452 | 36486 | ) !u32 { |
| 36453 | 36487 | const mod = sema.mod; |
| 36454 | | const struct_ty = try sema.resolveTypeFields(unresolved_struct_ty); |
| 36488 | try sema.resolveTypeFields(struct_ty); |
| 36455 | 36489 | if (struct_ty.isAnonStruct(mod)) { |
| 36456 | 36490 | return sema.anonStructFieldIndex(block, struct_ty, field_name, field_src); |
| 36457 | 36491 | } else { |