| ... | @@ -30662,14 +30662,19 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30662,14 +30662,19 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30662 | const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); | 30662 | const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); |
| 30663 | if (gop.found_existing) { | 30663 | if (gop.found_existing) { |
| 30664 | const msg = msg: { | 30664 | const msg = msg: { |
| 30665 | const tree = try sema.getAstTree(&block_scope); | 30665 | const field_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30666 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 30666 | .index = field_i, |
| | 30667 | .range = .name, |
| | 30668 | }).lazy; |
| 30667 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{field_name}); | 30669 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{field_name}); |
| 30668 | errdefer msg.destroy(gpa); | 30670 | errdefer msg.destroy(gpa); |
| 30669 | | 30671 | |
| 30670 | const prev_field_index = struct_obj.fields.getIndex(field_name).?; | 30672 | const prev_field_index = struct_obj.fields.getIndex(field_name).?; |
| 30671 | const prev_field_src = enumFieldSrcLoc(decl, tree.*, 0, prev_field_index); | 30673 | const prev_field_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30672 | try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{}); | 30674 | .index = prev_field_index, |
| | 30675 | .range = .name, |
| | 30676 | }); |
| | 30677 | try sema.mod.errNoteNonLazy(prev_field_src, msg, "other field here", .{}); |
| 30673 | try sema.errNote(&block_scope, src, msg, "struct declared here", .{}); | 30678 | try sema.errNote(&block_scope, src, msg, "struct declared here", .{}); |
| 30674 | break :msg msg; | 30679 | break :msg msg; |
| 30675 | }; | 30680 | }; |
| ... | @@ -30699,34 +30704,51 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30699,34 +30704,51 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30699 | // so that init values may depend on type layout. | 30704 | // so that init values may depend on type layout. |
| 30700 | const bodies_index = extra_index; | 30705 | const bodies_index = extra_index; |
| 30701 | | 30706 | |
| 30702 | for (fields) |zir_field, i| { | 30707 | for (fields) |zir_field, field_i| { |
| 30703 | // TODO emit compile errors for invalid field types | | |
| 30704 | // such as arrays and pointers inside packed structs. | | |
| 30705 | const field_ty: Type = ty: { | 30708 | const field_ty: Type = ty: { |
| 30706 | if (zir_field.type_ref != .none) { | 30709 | if (zir_field.type_ref != .none) { |
| 30707 | // TODO: if we need to report an error here, use a source location | 30710 | break :ty sema.resolveType(&block_scope, .unneeded, zir_field.type_ref) catch |err| switch (err) { |
| 30708 | // that points to this type expression rather than the struct. | 30711 | error.NeededSourceLocation => { |
| 30709 | // But only resolve the source location if we need to emit a compile error. | 30712 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30710 | break :ty try sema.resolveType(&block_scope, src, zir_field.type_ref); | 30713 | .index = field_i, |
| | 30714 | .range = .type, |
| | 30715 | }).lazy; |
| | 30716 | _ = try sema.resolveType(&block_scope, ty_src, zir_field.type_ref); |
| | 30717 | unreachable; |
| | 30718 | }, |
| | 30719 | else => |e| return e, |
| | 30720 | }; |
| 30711 | } | 30721 | } |
| 30712 | assert(zir_field.type_body_len != 0); | 30722 | assert(zir_field.type_body_len != 0); |
| 30713 | const body = zir.extra[extra_index..][0..zir_field.type_body_len]; | 30723 | const body = zir.extra[extra_index..][0..zir_field.type_body_len]; |
| 30714 | extra_index += body.len; | 30724 | extra_index += body.len; |
| 30715 | const ty_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); | 30725 | const ty_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); |
| 30716 | break :ty try sema.analyzeAsType(&block_scope, src, ty_ref); | 30726 | break :ty sema.analyzeAsType(&block_scope, .unneeded, ty_ref) catch |err| switch (err) { |
| | 30727 | error.NeededSourceLocation => { |
| | 30728 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| | 30729 | .index = field_i, |
| | 30730 | .range = .type, |
| | 30731 | }).lazy; |
| | 30732 | _ = try sema.analyzeAsType(&block_scope, ty_src, ty_ref); |
| | 30733 | unreachable; |
| | 30734 | }, |
| | 30735 | else => |e| return e, |
| | 30736 | }; |
| 30717 | }; | 30737 | }; |
| 30718 | if (field_ty.tag() == .generic_poison) { | 30738 | if (field_ty.tag() == .generic_poison) { |
| 30719 | return error.GenericPoison; | 30739 | return error.GenericPoison; |
| 30720 | } | 30740 | } |
| 30721 | | 30741 | |
| 30722 | const field = &struct_obj.fields.values()[i]; | 30742 | const field = &struct_obj.fields.values()[field_i]; |
| 30723 | field.ty = try field_ty.copy(decl_arena_allocator); | 30743 | field.ty = try field_ty.copy(decl_arena_allocator); |
| 30724 | | 30744 | |
| 30725 | if (field_ty.zigTypeTag() == .Opaque) { | 30745 | if (field_ty.zigTypeTag() == .Opaque) { |
| 30726 | const msg = msg: { | 30746 | const msg = msg: { |
| 30727 | const tree = try sema.getAstTree(&block_scope); | 30747 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30728 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30748 | .index = field_i, |
| 30729 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); | 30749 | .range = .type, |
| | 30750 | }).lazy; |
| | 30751 | const msg = try sema.errMsg(&block_scope, ty_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| 30730 | errdefer msg.destroy(sema.gpa); | 30752 | errdefer msg.destroy(sema.gpa); |
| 30731 | | 30753 | |
| 30732 | try sema.addDeclaredHereNote(msg, field_ty); | 30754 | try sema.addDeclaredHereNote(msg, field_ty); |
| ... | @@ -30736,9 +30758,11 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30736,9 +30758,11 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30736 | } | 30758 | } |
| 30737 | if (field_ty.zigTypeTag() == .NoReturn) { | 30759 | if (field_ty.zigTypeTag() == .NoReturn) { |
| 30738 | const msg = msg: { | 30760 | const msg = msg: { |
| 30739 | const tree = try sema.getAstTree(&block_scope); | 30761 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30740 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30762 | .index = field_i, |
| 30741 | const msg = try sema.errMsg(&block_scope, field_src, "struct fields cannot be 'noreturn'", .{}); | 30763 | .range = .type, |
| | 30764 | }).lazy; |
| | 30765 | const msg = try sema.errMsg(&block_scope, ty_src, "struct fields cannot be 'noreturn'", .{}); |
| 30742 | errdefer msg.destroy(sema.gpa); | 30766 | errdefer msg.destroy(sema.gpa); |
| 30743 | | 30767 | |
| 30744 | try sema.addDeclaredHereNote(msg, field_ty); | 30768 | try sema.addDeclaredHereNote(msg, field_ty); |
| ... | @@ -30748,12 +30772,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30748,12 +30772,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30748 | } | 30772 | } |
| 30749 | if (struct_obj.layout == .Extern and !try sema.validateExternType(field.ty, .struct_field)) { | 30773 | if (struct_obj.layout == .Extern and !try sema.validateExternType(field.ty, .struct_field)) { |
| 30750 | const msg = msg: { | 30774 | const msg = msg: { |
| 30751 | const tree = try sema.getAstTree(&block_scope); | 30775 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30752 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30776 | .index = field_i, |
| 30753 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | 30777 | .range = .type, |
| | 30778 | }); |
| | 30779 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 30754 | errdefer msg.destroy(sema.gpa); | 30780 | errdefer msg.destroy(sema.gpa); |
| 30755 | | 30781 | |
| 30756 | try sema.explainWhyTypeIsNotExtern(msg, fields_src.toSrcLoc(decl), field.ty, .struct_field); | 30782 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, field.ty, .struct_field); |
| 30757 | | 30783 | |
| 30758 | try sema.addDeclaredHereNote(msg, field.ty); | 30784 | try sema.addDeclaredHereNote(msg, field.ty); |
| 30759 | break :msg msg; | 30785 | break :msg msg; |
| ... | @@ -30761,12 +30787,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30761,12 +30787,14 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30761 | return sema.failWithOwnedErrorMsg(msg); | 30787 | return sema.failWithOwnedErrorMsg(msg); |
| 30762 | } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) { | 30788 | } else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) { |
| 30763 | const msg = msg: { | 30789 | const msg = msg: { |
| 30764 | const tree = try sema.getAstTree(&block_scope); | 30790 | const ty_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| 30765 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i); | 30791 | .index = field_i, |
| 30766 | const msg = try sema.errMsg(&block_scope, fields_src, "packed structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | 30792 | .range = .type, |
| | 30793 | }); |
| | 30794 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "packed structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| 30767 | errdefer msg.destroy(sema.gpa); | 30795 | errdefer msg.destroy(sema.gpa); |
| 30768 | | 30796 | |
| 30769 | try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field.ty); | 30797 | try sema.explainWhyTypeIsNotPacked(msg, ty_src, field.ty); |
| 30770 | | 30798 | |
| 30771 | try sema.addDeclaredHereNote(msg, field.ty); | 30799 | try sema.addDeclaredHereNote(msg, field.ty); |
| 30772 | break :msg msg; | 30800 | break :msg msg; |
| ... | @@ -30778,7 +30806,17 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -30778,7 +30806,17 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 30778 | const body = zir.extra[extra_index..][0..zir_field.align_body_len]; | 30806 | const body = zir.extra[extra_index..][0..zir_field.align_body_len]; |
| 30779 | extra_index += body.len; | 30807 | extra_index += body.len; |
| 30780 | const align_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); | 30808 | const align_ref = try sema.resolveBody(&block_scope, body, struct_obj.zir_index); |
| 30781 | field.abi_align = try sema.analyzeAsAlign(&block_scope, src, align_ref); | 30809 | field.abi_align = sema.analyzeAsAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) { |
| | 30810 | error.NeededSourceLocation => { |
| | 30811 | const align_src = struct_obj.fieldSrcLoc(sema.mod, .{ |
| | 30812 | .index = field_i, |
| | 30813 | .range = .alignment, |
| | 30814 | }).lazy; |
| | 30815 | _ = try sema.analyzeAsAlign(&block_scope, align_src, align_ref); |
| | 30816 | unreachable; |
| | 30817 | }, |
| | 30818 | else => |e| return e, |
| | 30819 | }; |
| 30782 | } | 30820 | } |
| 30783 | | 30821 | |
| 30784 | extra_index += zir_field.init_body_len; | 30822 | extra_index += zir_field.init_body_len; |
| ... | @@ -31023,9 +31061,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31023,9 +31061,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31023 | | 31061 | |
| 31024 | if (enum_value_map) |map| { | 31062 | if (enum_value_map) |map| { |
| 31025 | const copied_val = if (tag_ref != .none) blk: { | 31063 | const copied_val = if (tag_ref != .none) blk: { |
| 31026 | const tag_src = src; // TODO better source location | 31064 | const val = sema.semaUnionFieldVal(&block_scope, .unneeded, int_tag_ty, tag_ref) catch |err| switch (err) { |
| 31027 | const coerced = try sema.coerce(&block_scope, int_tag_ty, tag_ref, tag_src); | 31065 | error.NeededSourceLocation => { |
| 31028 | const val = try sema.resolveConstValue(&block_scope, tag_src, coerced, "enum tag value must be comptime-known"); | 31066 | const val_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| | 31067 | .index = field_i, |
| | 31068 | .range = .value, |
| | 31069 | }).lazy; |
| | 31070 | _ = try sema.semaUnionFieldVal(&block_scope, val_src, int_tag_ty, tag_ref); |
| | 31071 | unreachable; |
| | 31072 | }, |
| | 31073 | else => |e| return e, |
| | 31074 | }; |
| 31029 | last_tag_val = val; | 31075 | last_tag_val = val; |
| 31030 | | 31076 | |
| 31031 | // This puts the memory into the union arena, not the enum arena, but | 31077 | // This puts the memory into the union arena, not the enum arena, but |
| ... | @@ -31045,9 +31091,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31045,9 +31091,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31045 | .mod = mod, | 31091 | .mod = mod, |
| 31046 | }); | 31092 | }); |
| 31047 | if (gop.found_existing) { | 31093 | if (gop.found_existing) { |
| 31048 | const tree = try sema.getAstTree(&block_scope); | 31094 | const field_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31049 | const field_src = enumFieldSrcLoc(sema.mod.declPtr(block_scope.src_decl), tree.*, src.node_offset.x, field_i); | 31095 | .index = field_i, |
| 31050 | const other_field_src = enumFieldSrcLoc(sema.mod.declPtr(block_scope.src_decl), tree.*, src.node_offset.x, gop.index); | 31096 | .range = .name, |
| | 31097 | }).lazy; |
| | 31098 | const other_field_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| | 31099 | .index = gop.index, |
| | 31100 | .range = .name, |
| | 31101 | }).lazy; |
| 31051 | const msg = msg: { | 31102 | const msg = msg: { |
| 31052 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{copied_val.fmtValue(int_tag_ty, sema.mod)}); | 31103 | const msg = try sema.errMsg(&block_scope, field_src, "enum tag value {} already taken", .{copied_val.fmtValue(int_tag_ty, sema.mod)}); |
| 31053 | errdefer msg.destroy(gpa); | 31104 | errdefer msg.destroy(gpa); |
| ... | @@ -31069,10 +31120,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31069,10 +31120,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31069 | else if (field_type_ref == .none) | 31120 | else if (field_type_ref == .none) |
| 31070 | Type.initTag(.noreturn) | 31121 | Type.initTag(.noreturn) |
| 31071 | else | 31122 | else |
| 31072 | // TODO: if we need to report an error here, use a source location | 31123 | sema.resolveType(&block_scope, .unneeded, field_type_ref) catch |err| switch (err) { |
| 31073 | // that points to this type expression rather than the union. | 31124 | error.NeededSourceLocation => { |
| 31074 | // But only resolve the source location if we need to emit a compile error. | 31125 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31075 | try sema.resolveType(&block_scope, src, field_type_ref); | 31126 | .index = field_i, |
| | 31127 | .range = .type, |
| | 31128 | }).lazy; |
| | 31129 | _ = try sema.resolveType(&block_scope, ty_src, field_type_ref); |
| | 31130 | unreachable; |
| | 31131 | }, |
| | 31132 | else => |e| return e, |
| | 31133 | }; |
| 31076 | | 31134 | |
| 31077 | if (field_ty.tag() == .generic_poison) { | 31135 | if (field_ty.tag() == .generic_poison) { |
| 31078 | return error.GenericPoison; | 31136 | return error.GenericPoison; |
| ... | @@ -31081,13 +31139,18 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31081,13 +31139,18 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31081 | const gop = union_obj.fields.getOrPutAssumeCapacity(field_name); | 31139 | const gop = union_obj.fields.getOrPutAssumeCapacity(field_name); |
| 31082 | if (gop.found_existing) { | 31140 | if (gop.found_existing) { |
| 31083 | const msg = msg: { | 31141 | const msg = msg: { |
| 31084 | const tree = try sema.getAstTree(&block_scope); | 31142 | const field_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31085 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31143 | .index = field_i, |
| | 31144 | .range = .name, |
| | 31145 | }).lazy; |
| 31086 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{field_name}); | 31146 | const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{field_name}); |
| 31087 | errdefer msg.destroy(gpa); | 31147 | errdefer msg.destroy(gpa); |
| 31088 | | 31148 | |
| 31089 | const prev_field_index = union_obj.fields.getIndex(field_name).?; | 31149 | const prev_field_index = union_obj.fields.getIndex(field_name).?; |
| 31090 | const prev_field_src = enumFieldSrcLoc(decl, tree.*, 0, prev_field_index); | 31150 | const prev_field_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| | 31151 | .index = prev_field_index, |
| | 31152 | .range = .name, |
| | 31153 | }).lazy; |
| 31091 | try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{}); | 31154 | try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{}); |
| 31092 | try sema.errNote(&block_scope, src, msg, "union declared here", .{}); | 31155 | try sema.errNote(&block_scope, src, msg, "union declared here", .{}); |
| 31093 | break :msg msg; | 31156 | break :msg msg; |
| ... | @@ -31099,9 +31162,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31099,9 +31162,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31099 | const enum_has_field = names.orderedRemove(field_name); | 31162 | const enum_has_field = names.orderedRemove(field_name); |
| 31100 | if (!enum_has_field) { | 31163 | if (!enum_has_field) { |
| 31101 | const msg = msg: { | 31164 | const msg = msg: { |
| 31102 | const tree = try sema.getAstTree(&block_scope); | 31165 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31103 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31166 | .index = field_i, |
| 31104 | const msg = try sema.errMsg(&block_scope, field_src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(sema.mod) }); | 31167 | .range = .type, |
| | 31168 | }).lazy; |
| | 31169 | const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(sema.mod) }); |
| 31105 | errdefer msg.destroy(sema.gpa); | 31170 | errdefer msg.destroy(sema.gpa); |
| 31106 | try sema.addDeclaredHereNote(msg, union_obj.tag_ty); | 31171 | try sema.addDeclaredHereNote(msg, union_obj.tag_ty); |
| 31107 | break :msg msg; | 31172 | break :msg msg; |
| ... | @@ -31112,9 +31177,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31112,9 +31177,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31112 | | 31177 | |
| 31113 | if (field_ty.zigTypeTag() == .Opaque) { | 31178 | if (field_ty.zigTypeTag() == .Opaque) { |
| 31114 | const msg = msg: { | 31179 | const msg = msg: { |
| 31115 | const tree = try sema.getAstTree(&block_scope); | 31180 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31116 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31181 | .index = field_i, |
| 31117 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); | 31182 | .range = .type, |
| | 31183 | }).lazy; |
| | 31184 | const msg = try sema.errMsg(&block_scope, ty_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| 31118 | errdefer msg.destroy(sema.gpa); | 31185 | errdefer msg.destroy(sema.gpa); |
| 31119 | | 31186 | |
| 31120 | try sema.addDeclaredHereNote(msg, field_ty); | 31187 | try sema.addDeclaredHereNote(msg, field_ty); |
| ... | @@ -31124,12 +31191,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31124,12 +31191,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31124 | } | 31191 | } |
| 31125 | if (union_obj.layout == .Extern and !try sema.validateExternType(field_ty, .union_field)) { | 31192 | if (union_obj.layout == .Extern and !try sema.validateExternType(field_ty, .union_field)) { |
| 31126 | const msg = msg: { | 31193 | const msg = msg: { |
| 31127 | const tree = try sema.getAstTree(&block_scope); | 31194 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31128 | const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31195 | .index = field_i, |
| 31129 | const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); | 31196 | .range = .type, |
| | 31197 | }); |
| | 31198 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| 31130 | errdefer msg.destroy(sema.gpa); | 31199 | errdefer msg.destroy(sema.gpa); |
| 31131 | | 31200 | |
| 31132 | try sema.explainWhyTypeIsNotExtern(msg, field_src.toSrcLoc(decl), field_ty, .union_field); | 31201 | try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .union_field); |
| 31133 | | 31202 | |
| 31134 | try sema.addDeclaredHereNote(msg, field_ty); | 31203 | try sema.addDeclaredHereNote(msg, field_ty); |
| 31135 | break :msg msg; | 31204 | break :msg msg; |
| ... | @@ -31137,12 +31206,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31137,12 +31206,14 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31137 | return sema.failWithOwnedErrorMsg(msg); | 31206 | return sema.failWithOwnedErrorMsg(msg); |
| 31138 | } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) { | 31207 | } else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) { |
| 31139 | const msg = msg: { | 31208 | const msg = msg: { |
| 31140 | const tree = try sema.getAstTree(&block_scope); | 31209 | const ty_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31141 | const fields_src = enumFieldSrcLoc(decl, tree.*, 0, field_i); | 31210 | .index = field_i, |
| 31142 | const msg = try sema.errMsg(&block_scope, fields_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); | 31211 | .range = .type, |
| | 31212 | }); |
| | 31213 | const msg = try sema.errMsg(&block_scope, ty_src.lazy, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| 31143 | errdefer msg.destroy(sema.gpa); | 31214 | errdefer msg.destroy(sema.gpa); |
| 31144 | | 31215 | |
| 31145 | try sema.explainWhyTypeIsNotPacked(msg, fields_src.toSrcLoc(decl), field_ty); | 31216 | try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty); |
| 31146 | | 31217 | |
| 31147 | try sema.addDeclaredHereNote(msg, field_ty); | 31218 | try sema.addDeclaredHereNote(msg, field_ty); |
| 31148 | break :msg msg; | 31219 | break :msg msg; |
| ... | @@ -31156,10 +31227,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31156,10 +31227,17 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31156 | }; | 31227 | }; |
| 31157 | | 31228 | |
| 31158 | if (align_ref != .none) { | 31229 | if (align_ref != .none) { |
| 31159 | // TODO: if we need to report an error here, use a source location | 31230 | gop.value_ptr.abi_align = sema.resolveAlign(&block_scope, .unneeded, align_ref) catch |err| switch (err) { |
| 31160 | // that points to this alignment expression rather than the struct. | 31231 | error.NeededSourceLocation => { |
| 31161 | // But only resolve the source location if we need to emit a compile error. | 31232 | const align_src = union_obj.fieldSrcLoc(sema.mod, .{ |
| 31162 | gop.value_ptr.abi_align = try sema.resolveAlign(&block_scope, src, align_ref); | 31233 | .index = field_i, |
| | 31234 | .range = .alignment, |
| | 31235 | }).lazy; |
| | 31236 | _ = try sema.resolveAlign(&block_scope, align_src, align_ref); |
| | 31237 | unreachable; |
| | 31238 | }, |
| | 31239 | else => |e| return e, |
| | 31240 | }; |
| 31163 | } else { | 31241 | } else { |
| 31164 | gop.value_ptr.abi_align = 0; | 31242 | gop.value_ptr.abi_align = 0; |
| 31165 | } | 31243 | } |
| ... | @@ -31184,6 +31262,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -31184,6 +31262,11 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 31184 | } | 31262 | } |
| 31185 | } | 31263 | } |
| 31186 | | 31264 | |
| | 31265 | fn semaUnionFieldVal(sema: *Sema, block: *Block, src: LazySrcLoc, int_tag_ty: Type, tag_ref: Air.Inst.Ref) CompileError!Value { |
| | 31266 | const coerced = try sema.coerce(block, int_tag_ty, tag_ref, src); |
| | 31267 | return sema.resolveConstValue(block, src, coerced, "enum tag value must be comptime-known"); |
| | 31268 | } |
| | 31269 | |
| 31187 | fn generateUnionTagTypeNumbered( | 31270 | fn generateUnionTagTypeNumbered( |
| 31188 | sema: *Sema, | 31271 | sema: *Sema, |
| 31189 | block: *Block, | 31272 | block: *Block, |