| ... | @@ -739,6 +739,8 @@ fn analyzeBodyInner( | ... | @@ -739,6 +739,8 @@ fn analyzeBodyInner( |
| 739 | .@"await" => try sema.zirAwait(block, inst, false), | 739 | .@"await" => try sema.zirAwait(block, inst, false), |
| 740 | .await_nosuspend => try sema.zirAwait(block, inst, true), | 740 | .await_nosuspend => try sema.zirAwait(block, inst, true), |
| 741 | .extended => try sema.zirExtended(block, inst), | 741 | .extended => try sema.zirExtended(block, inst), |
| | 742 | .array_base_ptr => try sema.zirArrayBasePtr(block, inst), |
| | 743 | .field_base_ptr => try sema.zirFieldBasePtr(block, inst), |
| 742 | | 744 | |
| 743 | .clz => try sema.zirBitCount(block, inst, .clz, Value.clz), | 745 | .clz => try sema.zirBitCount(block, inst, .clz, Value.clz), |
| 744 | .ctz => try sema.zirBitCount(block, inst, .ctz, Value.ctz), | 746 | .ctz => try sema.zirBitCount(block, inst, .ctz, Value.ctz), |
| ... | @@ -2584,6 +2586,59 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -2584,6 +2586,59 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 2584 | } | 2586 | } |
| 2585 | } | 2587 | } |
| 2586 | | 2588 | |
| | 2589 | fn zirArrayBasePtr( |
| | 2590 | sema: *Sema, |
| | 2591 | block: *Block, |
| | 2592 | inst: Zir.Inst.Index, |
| | 2593 | ) CompileError!Air.Inst.Ref { |
| | 2594 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| | 2595 | const src = inst_data.src(); |
| | 2596 | |
| | 2597 | const start_ptr = sema.resolveInst(inst_data.operand); |
| | 2598 | var base_ptr = start_ptr; |
| | 2599 | while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag()) { |
| | 2600 | .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false), |
| | 2601 | .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false), |
| | 2602 | else => break, |
| | 2603 | }; |
| | 2604 | |
| | 2605 | const elem_ty = sema.typeOf(base_ptr).childType(); |
| | 2606 | switch (elem_ty.zigTypeTag()) { |
| | 2607 | .Array, .Vector => return base_ptr, |
| | 2608 | .Struct => if (elem_ty.isTuple()) return base_ptr, |
| | 2609 | else => {}, |
| | 2610 | } |
| | 2611 | return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{ |
| | 2612 | sema.typeOf(start_ptr).childType(), |
| | 2613 | }); |
| | 2614 | } |
| | 2615 | |
| | 2616 | fn zirFieldBasePtr( |
| | 2617 | sema: *Sema, |
| | 2618 | block: *Block, |
| | 2619 | inst: Zir.Inst.Index, |
| | 2620 | ) CompileError!Air.Inst.Ref { |
| | 2621 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| | 2622 | const src = inst_data.src(); |
| | 2623 | |
| | 2624 | const start_ptr = sema.resolveInst(inst_data.operand); |
| | 2625 | var base_ptr = start_ptr; |
| | 2626 | while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag()) { |
| | 2627 | .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false), |
| | 2628 | .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false), |
| | 2629 | else => break, |
| | 2630 | }; |
| | 2631 | |
| | 2632 | const elem_ty = sema.typeOf(base_ptr).childType(); |
| | 2633 | switch (elem_ty.zigTypeTag()) { |
| | 2634 | .Struct, .Union => return base_ptr, |
| | 2635 | else => {}, |
| | 2636 | } |
| | 2637 | return sema.fail(block, src, "type '{}' does not support struct initialization syntax", .{ |
| | 2638 | sema.typeOf(start_ptr).childType(), |
| | 2639 | }); |
| | 2640 | } |
| | 2641 | |
| 2587 | fn zirValidateStructInit( | 2642 | fn zirValidateStructInit( |
| 2588 | sema: *Sema, | 2643 | sema: *Sema, |
| 2589 | block: *Block, | 2644 | block: *Block, |
| ... | @@ -4377,7 +4432,9 @@ fn analyzeCall( | ... | @@ -4377,7 +4432,9 @@ fn analyzeCall( |
| 4377 | if (payload.data.error_set.tag() == .error_set_inferred) { | 4432 | if (payload.data.error_set.tag() == .error_set_inferred) { |
| 4378 | const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode); | 4433 | const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode); |
| 4379 | node.data = .{ .func = module_fn }; | 4434 | node.data = .{ .func = module_fn }; |
| 4380 | parent_func.?.inferred_error_sets.prepend(node); | 4435 | if (parent_func) |some| { |
| | 4436 | some.inferred_error_sets.prepend(node); |
| | 4437 | } |
| 4381 | | 4438 | |
| 4382 | const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data); | 4439 | const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data); |
| 4383 | break :blk try Type.Tag.error_union.create(sema.arena, .{ | 4440 | break :blk try Type.Tag.error_union.create(sema.arena, .{ |
| ... | @@ -5198,9 +5255,20 @@ fn zirOptionalPayloadPtr( | ... | @@ -5198,9 +5255,20 @@ fn zirOptionalPayloadPtr( |
| 5198 | | 5255 | |
| 5199 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 5256 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5200 | const optional_ptr = sema.resolveInst(inst_data.operand); | 5257 | const optional_ptr = sema.resolveInst(inst_data.operand); |
| | 5258 | const src = inst_data.src(); |
| | 5259 | |
| | 5260 | return sema.analyzeOptionalPayloadPtr(block, src, optional_ptr, safety_check); |
| | 5261 | } |
| | 5262 | |
| | 5263 | fn analyzeOptionalPayloadPtr( |
| | 5264 | sema: *Sema, |
| | 5265 | block: *Block, |
| | 5266 | src: LazySrcLoc, |
| | 5267 | optional_ptr: Air.Inst.Ref, |
| | 5268 | safety_check: bool, |
| | 5269 | ) CompileError!Air.Inst.Ref { |
| 5201 | const optional_ptr_ty = sema.typeOf(optional_ptr); | 5270 | const optional_ptr_ty = sema.typeOf(optional_ptr); |
| 5202 | assert(optional_ptr_ty.zigTypeTag() == .Pointer); | 5271 | assert(optional_ptr_ty.zigTypeTag() == .Pointer); |
| 5203 | const src = inst_data.src(); | | |
| 5204 | | 5272 | |
| 5205 | const opt_type = optional_ptr_ty.elemType(); | 5273 | const opt_type = optional_ptr_ty.elemType(); |
| 5206 | if (opt_type.zigTypeTag() != .Optional) { | 5274 | if (opt_type.zigTypeTag() != .Optional) { |
| ... | @@ -5216,8 +5284,10 @@ fn zirOptionalPayloadPtr( | ... | @@ -5216,8 +5284,10 @@ fn zirOptionalPayloadPtr( |
| 5216 | | 5284 | |
| 5217 | if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| { | 5285 | if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| { |
| 5218 | if (try sema.pointerDeref(block, src, pointer_val, optional_ptr_ty)) |val| { | 5286 | if (try sema.pointerDeref(block, src, pointer_val, optional_ptr_ty)) |val| { |
| 5219 | if (val.isNull()) { | 5287 | if (safety_check) { |
| 5220 | return sema.fail(block, src, "unable to unwrap null", .{}); | 5288 | if (val.isNull()) { |
| | 5289 | return sema.fail(block, src, "unable to unwrap null", .{}); |
| | 5290 | } |
| 5221 | } | 5291 | } |
| 5222 | // The same Value represents the pointer to the optional and the payload. | 5292 | // The same Value represents the pointer to the optional and the payload. |
| 5223 | return sema.addConstant( | 5293 | return sema.addConstant( |
| ... | @@ -5333,8 +5403,19 @@ fn zirErrUnionPayloadPtr( | ... | @@ -5333,8 +5403,19 @@ fn zirErrUnionPayloadPtr( |
| 5333 | defer tracy.end(); | 5403 | defer tracy.end(); |
| 5334 | | 5404 | |
| 5335 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 5405 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5336 | const src = inst_data.src(); | | |
| 5337 | const operand = sema.resolveInst(inst_data.operand); | 5406 | const operand = sema.resolveInst(inst_data.operand); |
| | 5407 | const src = inst_data.src(); |
| | 5408 | |
| | 5409 | return sema.analyzeErrUnionPayloadPtr(block, src, operand, safety_check); |
| | 5410 | } |
| | 5411 | |
| | 5412 | fn analyzeErrUnionPayloadPtr( |
| | 5413 | sema: *Sema, |
| | 5414 | block: *Block, |
| | 5415 | src: LazySrcLoc, |
| | 5416 | operand: Air.Inst.Ref, |
| | 5417 | safety_check: bool, |
| | 5418 | ) CompileError!Air.Inst.Ref { |
| 5338 | const operand_ty = sema.typeOf(operand); | 5419 | const operand_ty = sema.typeOf(operand); |
| 5339 | assert(operand_ty.zigTypeTag() == .Pointer); | 5420 | assert(operand_ty.zigTypeTag() == .Pointer); |
| 5340 | | 5421 | |
| ... | @@ -5350,9 +5431,12 @@ fn zirErrUnionPayloadPtr( | ... | @@ -5350,9 +5431,12 @@ fn zirErrUnionPayloadPtr( |
| 5350 | | 5431 | |
| 5351 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { | 5432 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 5352 | if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { | 5433 | if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { |
| 5353 | if (val.getError()) |name| { | 5434 | if (safety_check) { |
| 5354 | return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); | 5435 | if (val.getError()) |name| { |
| | 5436 | return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); |
| | 5437 | } |
| 5355 | } | 5438 | } |
| | 5439 | |
| 5356 | return sema.addConstant( | 5440 | return sema.addConstant( |
| 5357 | operand_pointer_ty, | 5441 | operand_pointer_ty, |
| 5358 | try Value.Tag.eu_payload_ptr.create(sema.arena, pointer_val), | 5442 | try Value.Tag.eu_payload_ptr.create(sema.arena, pointer_val), |
| ... | @@ -12859,7 +12943,7 @@ fn zirCUndef( | ... | @@ -12859,7 +12943,7 @@ fn zirCUndef( |
| 12859 | extended: Zir.Inst.Extended.InstData, | 12943 | extended: Zir.Inst.Extended.InstData, |
| 12860 | ) CompileError!Air.Inst.Ref { | 12944 | ) CompileError!Air.Inst.Ref { |
| 12861 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 12945 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 12862 | const src: LazySrcLoc = .{ .node_offset = extra.node }; | 12946 | const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 12863 | | 12947 | |
| 12864 | const name = try sema.resolveConstString(block, src, extra.operand); | 12948 | const name = try sema.resolveConstString(block, src, extra.operand); |
| 12865 | try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name}); | 12949 | try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name}); |
| ... | @@ -12872,7 +12956,7 @@ fn zirCInclude( | ... | @@ -12872,7 +12956,7 @@ fn zirCInclude( |
| 12872 | extended: Zir.Inst.Extended.InstData, | 12956 | extended: Zir.Inst.Extended.InstData, |
| 12873 | ) CompileError!Air.Inst.Ref { | 12957 | ) CompileError!Air.Inst.Ref { |
| 12874 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; | 12958 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 12875 | const src: LazySrcLoc = .{ .node_offset = extra.node }; | 12959 | const src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| 12876 | | 12960 | |
| 12877 | const name = try sema.resolveConstString(block, src, extra.operand); | 12961 | const name = try sema.resolveConstString(block, src, extra.operand); |
| 12878 | try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name}); | 12962 | try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name}); |
| ... | @@ -12885,12 +12969,13 @@ fn zirCDefine( | ... | @@ -12885,12 +12969,13 @@ fn zirCDefine( |
| 12885 | extended: Zir.Inst.Extended.InstData, | 12969 | extended: Zir.Inst.Extended.InstData, |
| 12886 | ) CompileError!Air.Inst.Ref { | 12970 | ) CompileError!Air.Inst.Ref { |
| 12887 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; | 12971 | const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 12888 | const src: LazySrcLoc = .{ .node_offset = extra.node }; | 12972 | const name_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; |
| | 12973 | const val_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node }; |
| 12889 | | 12974 | |
| 12890 | const name = try sema.resolveConstString(block, src, extra.lhs); | 12975 | const name = try sema.resolveConstString(block, name_src, extra.lhs); |
| 12891 | const rhs = sema.resolveInst(extra.rhs); | 12976 | const rhs = sema.resolveInst(extra.rhs); |
| 12892 | if (sema.typeOf(rhs).zigTypeTag() != .Void) { | 12977 | if (sema.typeOf(rhs).zigTypeTag() != .Void) { |
| 12893 | const value = try sema.resolveConstString(block, src, extra.rhs); | 12978 | const value = try sema.resolveConstString(block, val_src, extra.rhs); |
| 12894 | try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value }); | 12979 | try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value }); |
| 12895 | } else { | 12980 | } else { |
| 12896 | try block.c_import_buf.?.writer().print("#define {s}\n", .{name}); | 12981 | try block.c_import_buf.?.writer().print("#define {s}\n", .{name}); |