| ... | @@ -14559,13 +14559,23 @@ fn zirStructInitAnon( | ... | @@ -14559,13 +14559,23 @@ fn zirStructInitAnon( |
| 14559 | var runtime_src: ?LazySrcLoc = null; | 14559 | var runtime_src: ?LazySrcLoc = null; |
| 14560 | var extra_index = extra.end; | 14560 | var extra_index = extra.end; |
| 14561 | for (types) |*field_ty, i| { | 14561 | for (types) |*field_ty, i| { |
| | 14562 | const init_src = src; // TODO better source location |
| 14562 | const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index); | 14563 | const item = sema.code.extraData(Zir.Inst.StructInitAnon.Item, extra_index); |
| 14563 | extra_index = item.end; | 14564 | extra_index = item.end; |
| 14564 | | 14565 | |
| 14565 | names[i] = sema.code.nullTerminatedString(item.data.field_name); | 14566 | names[i] = sema.code.nullTerminatedString(item.data.field_name); |
| 14566 | const init = try sema.resolveInst(item.data.init); | 14567 | const init = try sema.resolveInst(item.data.init); |
| 14567 | field_ty.* = sema.typeOf(init); | 14568 | field_ty.* = sema.typeOf(init); |
| 14568 | const init_src = src; // TODO better source location | 14569 | if (types[i].zigTypeTag() == .Opaque) { |
| | 14570 | const msg = msg: { |
| | 14571 | const msg = try sema.errMsg(block, init_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| | 14572 | errdefer msg.destroy(sema.gpa); |
| | 14573 | |
| | 14574 | try sema.addDeclaredHereNote(msg, types[i]); |
| | 14575 | break :msg msg; |
| | 14576 | }; |
| | 14577 | return sema.failWithOwnedErrorMsg(block, msg); |
| | 14578 | } |
| 14569 | if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| { | 14579 | if (try sema.resolveMaybeUndefVal(block, init_src, init)) |init_val| { |
| 14570 | values[i] = init_val; | 14580 | values[i] = init_val; |
| 14571 | } else { | 14581 | } else { |
| ... | @@ -14742,9 +14752,19 @@ fn zirArrayInitAnon( | ... | @@ -14742,9 +14752,19 @@ fn zirArrayInitAnon( |
| 14742 | const opt_runtime_src = rs: { | 14752 | const opt_runtime_src = rs: { |
| 14743 | var runtime_src: ?LazySrcLoc = null; | 14753 | var runtime_src: ?LazySrcLoc = null; |
| 14744 | for (operands) |operand, i| { | 14754 | for (operands) |operand, i| { |
| | 14755 | const operand_src = src; // TODO better source location |
| 14745 | const elem = try sema.resolveInst(operand); | 14756 | const elem = try sema.resolveInst(operand); |
| 14746 | types[i] = sema.typeOf(elem); | 14757 | types[i] = sema.typeOf(elem); |
| 14747 | const operand_src = src; // TODO better source location | 14758 | if (types[i].zigTypeTag() == .Opaque) { |
| | 14759 | const msg = msg: { |
| | 14760 | const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| | 14761 | errdefer msg.destroy(sema.gpa); |
| | 14762 | |
| | 14763 | try sema.addDeclaredHereNote(msg, types[i]); |
| | 14764 | break :msg msg; |
| | 14765 | }; |
| | 14766 | return sema.failWithOwnedErrorMsg(block, msg); |
| | 14767 | } |
| 14748 | if (try sema.resolveMaybeUndefVal(block, operand_src, elem)) |val| { | 14768 | if (try sema.resolveMaybeUndefVal(block, operand_src, elem)) |val| { |
| 14749 | values[i] = val; | 14769 | values[i] = val; |
| 14750 | } else { | 14770 | } else { |
| ... | @@ -18641,6 +18661,8 @@ const ExternPosition = enum { | ... | @@ -18641,6 +18661,8 @@ const ExternPosition = enum { |
| 18641 | other, | 18661 | other, |
| 18642 | }; | 18662 | }; |
| 18643 | | 18663 | |
| | 18664 | /// Returns true if `ty` is allowed in extern types. |
| | 18665 | /// Does *NOT* require `ty` to be resolved in any way. |
| 18644 | fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool { | 18666 | fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileError!bool { |
| 18645 | switch (ty.zigTypeTag()) { | 18667 | switch (ty.zigTypeTag()) { |
| 18646 | .Type, | 18668 | .Type, |
| ... | @@ -25214,20 +25236,6 @@ fn resolveStructFully( | ... | @@ -25214,20 +25236,6 @@ fn resolveStructFully( |
| 25214 | struct_obj.status = .fully_resolved_wip; | 25236 | struct_obj.status = .fully_resolved_wip; |
| 25215 | for (struct_obj.fields.values()) |field| { | 25237 | for (struct_obj.fields.values()) |field| { |
| 25216 | try sema.resolveTypeFully(block, src, field.ty); | 25238 | try sema.resolveTypeFully(block, src, field.ty); |
| 25217 | | | |
| 25218 | if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) { | | |
| 25219 | const msg = msg: { | | |
| 25220 | const msg = try sema.errMsg(block, src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | | |
| 25221 | errdefer msg.destroy(sema.gpa); | | |
| 25222 | | | |
| 25223 | const src_decl = sema.mod.declPtr(block.src_decl); | | |
| 25224 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .other); | | |
| 25225 | | | |
| 25226 | try sema.addDeclaredHereNote(msg, field.ty); | | |
| 25227 | break :msg msg; | | |
| 25228 | }; | | |
| 25229 | return sema.failWithOwnedErrorMsg(block, msg); | | |
| 25230 | } | | |
| 25231 | } | 25239 | } |
| 25232 | struct_obj.status = .fully_resolved; | 25240 | struct_obj.status = .fully_resolved; |
| 25233 | } | 25241 | } |
| ... | @@ -25261,20 +25269,6 @@ fn resolveUnionFully( | ... | @@ -25261,20 +25269,6 @@ fn resolveUnionFully( |
| 25261 | union_obj.status = .fully_resolved_wip; | 25269 | union_obj.status = .fully_resolved_wip; |
| 25262 | for (union_obj.fields.values()) |field| { | 25270 | for (union_obj.fields.values()) |field| { |
| 25263 | try sema.resolveTypeFully(block, src, field.ty); | 25271 | try sema.resolveTypeFully(block, src, field.ty); |
| 25264 | | | |
| 25265 | if (union_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .union_field))) { | | |
| 25266 | const msg = msg: { | | |
| 25267 | const msg = try sema.errMsg(block, src, "extern unions cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); | | |
| 25268 | errdefer msg.destroy(sema.gpa); | | |
| 25269 | | | |
| 25270 | const src_decl = sema.mod.declPtr(block.src_decl); | | |
| 25271 | try sema.explainWhyTypeIsNotExtern(block, src, msg, src.toSrcLoc(src_decl), field.ty, .union_field); | | |
| 25272 | | | |
| 25273 | try sema.addDeclaredHereNote(msg, field.ty); | | |
| 25274 | break :msg msg; | | |
| 25275 | }; | | |
| 25276 | return sema.failWithOwnedErrorMsg(block, msg); | | |
| 25277 | } | | |
| 25278 | } | 25272 | } |
| 25279 | union_obj.status = .fully_resolved; | 25273 | union_obj.status = .fully_resolved; |
| 25280 | } | 25274 | } |
| ... | @@ -25612,6 +25606,33 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void | ... | @@ -25612,6 +25606,33 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void |
| 25612 | const field = &struct_obj.fields.values()[i]; | 25606 | const field = &struct_obj.fields.values()[i]; |
| 25613 | field.ty = try field_ty.copy(decl_arena_allocator); | 25607 | field.ty = try field_ty.copy(decl_arena_allocator); |
| 25614 | | 25608 | |
| | 25609 | if (struct_obj.layout == .Extern and !(try sema.validateExternType(field.ty, .other))) { |
| | 25610 | const msg = msg: { |
| | 25611 | const tree = try sema.getAstTree(&block_scope); |
| | 25612 | const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); |
| | 25613 | const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)}); |
| | 25614 | errdefer msg.destroy(sema.gpa); |
| | 25615 | |
| | 25616 | try sema.explainWhyTypeIsNotExtern(&block_scope, fields_src, msg, fields_src.toSrcLoc(decl), field.ty, .other); |
| | 25617 | |
| | 25618 | try sema.addDeclaredHereNote(msg, field.ty); |
| | 25619 | break :msg msg; |
| | 25620 | }; |
| | 25621 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| | 25622 | } |
| | 25623 | if (field_ty.zigTypeTag() == .Opaque) { |
| | 25624 | const msg = msg: { |
| | 25625 | const tree = try sema.getAstTree(&block_scope); |
| | 25626 | const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i); |
| | 25627 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); |
| | 25628 | errdefer msg.destroy(sema.gpa); |
| | 25629 | |
| | 25630 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 25631 | break :msg msg; |
| | 25632 | }; |
| | 25633 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| | 25634 | } |
| | 25635 | |
| 25615 | if (zir_field.align_body_len > 0) { | 25636 | if (zir_field.align_body_len > 0) { |
| 25616 | const body = zir.extra[extra_index..][0..zir_field.align_body_len]; | 25637 | const body = zir.extra[extra_index..][0..zir_field.align_body_len]; |
| 25617 | extra_index += body.len; | 25638 | extra_index += body.len; |
| ... | @@ -25909,6 +25930,33 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -25909,6 +25930,33 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 25909 | } | 25930 | } |
| 25910 | } | 25931 | } |
| 25911 | | 25932 | |
| | 25933 | if (union_obj.layout == .Extern and !(try sema.validateExternType(field_ty, .union_field))) { |
| | 25934 | const msg = msg: { |
| | 25935 | const tree = try sema.getAstTree(&block_scope); |
| | 25936 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| | 25937 | const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)}); |
| | 25938 | errdefer msg.destroy(sema.gpa); |
| | 25939 | |
| | 25940 | try sema.explainWhyTypeIsNotExtern(&block_scope, field_src, msg, field_src.toSrcLoc(decl), field_ty, .union_field); |
| | 25941 | |
| | 25942 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 25943 | break :msg msg; |
| | 25944 | }; |
| | 25945 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| | 25946 | } |
| | 25947 | if (field_ty.zigTypeTag() == .Opaque) { |
| | 25948 | const msg = msg: { |
| | 25949 | const tree = try sema.getAstTree(&block_scope); |
| | 25950 | const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i); |
| | 25951 | const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); |
| | 25952 | errdefer msg.destroy(sema.gpa); |
| | 25953 | |
| | 25954 | try sema.addDeclaredHereNote(msg, field_ty); |
| | 25955 | break :msg msg; |
| | 25956 | }; |
| | 25957 | return sema.failWithOwnedErrorMsg(&block_scope, msg); |
| | 25958 | } |
| | 25959 | |
| 25912 | gop.value_ptr.* = .{ | 25960 | gop.value_ptr.* = .{ |
| 25913 | .ty = try field_ty.copy(decl_arena_allocator), | 25961 | .ty = try field_ty.copy(decl_arena_allocator), |
| 25914 | .abi_align = 0, | 25962 | .abi_align = 0, |