| ... | ... | @@ -739,6 +739,8 @@ fn analyzeBodyInner( |
| 739 | 739 | .@"await" => try sema.zirAwait(block, inst, false), |
| 740 | 740 | .await_nosuspend => try sema.zirAwait(block, inst, true), |
| 741 | 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 | 745 | .clz => try sema.zirBitCount(block, inst, .clz, Value.clz), |
| 744 | 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 | 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 | 2642 | fn zirValidateStructInit( |
| 2588 | 2643 | sema: *Sema, |
| 2589 | 2644 | block: *Block, |
| ... | ... | @@ -4377,7 +4432,9 @@ fn analyzeCall( |
| 4377 | 4432 | if (payload.data.error_set.tag() == .error_set_inferred) { |
| 4378 | 4433 | const node = try sema.gpa.create(Module.Fn.InferredErrorSetListNode); |
| 4379 | 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 | 4439 | const error_set_ty = try Type.Tag.error_set_inferred.create(sema.arena, &node.data); |
| 4383 | 4440 | break :blk try Type.Tag.error_union.create(sema.arena, .{ |
| ... | ... | @@ -5198,9 +5255,20 @@ fn zirOptionalPayloadPtr( |
| 5198 | 5255 | |
| 5199 | 5256 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5200 | 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 | 5270 | const optional_ptr_ty = sema.typeOf(optional_ptr); |
| 5202 | 5271 | assert(optional_ptr_ty.zigTypeTag() == .Pointer); |
| 5203 | | const src = inst_data.src(); |
| 5204 | 5272 | |
| 5205 | 5273 | const opt_type = optional_ptr_ty.elemType(); |
| 5206 | 5274 | if (opt_type.zigTypeTag() != .Optional) { |
| ... | ... | @@ -5216,8 +5284,10 @@ fn zirOptionalPayloadPtr( |
| 5216 | 5284 | |
| 5217 | 5285 | if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| { |
| 5218 | 5286 | if (try sema.pointerDeref(block, src, pointer_val, optional_ptr_ty)) |val| { |
| 5219 | | if (val.isNull()) { |
| 5220 | | return sema.fail(block, src, "unable to unwrap null", .{}); |
| 5287 | if (safety_check) { |
| 5288 | if (val.isNull()) { |
| 5289 | return sema.fail(block, src, "unable to unwrap null", .{}); |
| 5290 | } |
| 5221 | 5291 | } |
| 5222 | 5292 | // The same Value represents the pointer to the optional and the payload. |
| 5223 | 5293 | return sema.addConstant( |
| ... | ... | @@ -5333,8 +5403,19 @@ fn zirErrUnionPayloadPtr( |
| 5333 | 5403 | defer tracy.end(); |
| 5334 | 5404 | |
| 5335 | 5405 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5336 | | const src = inst_data.src(); |
| 5337 | 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 | 5419 | const operand_ty = sema.typeOf(operand); |
| 5339 | 5420 | assert(operand_ty.zigTypeTag() == .Pointer); |
| 5340 | 5421 | |
| ... | ... | @@ -5350,9 +5431,12 @@ fn zirErrUnionPayloadPtr( |
| 5350 | 5431 | |
| 5351 | 5432 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 5352 | 5433 | if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { |
| 5353 | | if (val.getError()) |name| { |
| 5354 | | return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); |
| 5434 | if (safety_check) { |
| 5435 | if (val.getError()) |name| { |
| 5436 | return sema.fail(block, src, "caught unexpected error '{s}'", .{name}); |
| 5437 | } |
| 5355 | 5438 | } |
| 5439 | |
| 5356 | 5440 | return sema.addConstant( |
| 5357 | 5441 | operand_pointer_ty, |
| 5358 | 5442 | try Value.Tag.eu_payload_ptr.create(sema.arena, pointer_val), |
| ... | ... | @@ -12859,7 +12943,7 @@ fn zirCUndef( |
| 12859 | 12943 | extended: Zir.Inst.Extended.InstData, |
| 12860 | 12944 | ) CompileError!Air.Inst.Ref { |
| 12861 | 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 | 12948 | const name = try sema.resolveConstString(block, src, extra.operand); |
| 12865 | 12949 | try block.c_import_buf.?.writer().print("#undefine {s}\n", .{name}); |
| ... | ... | @@ -12872,7 +12956,7 @@ fn zirCInclude( |
| 12872 | 12956 | extended: Zir.Inst.Extended.InstData, |
| 12873 | 12957 | ) CompileError!Air.Inst.Ref { |
| 12874 | 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 | 12961 | const name = try sema.resolveConstString(block, src, extra.operand); |
| 12878 | 12962 | try block.c_import_buf.?.writer().print("#include <{s}>\n", .{name}); |
| ... | ... | @@ -12885,12 +12969,13 @@ fn zirCDefine( |
| 12885 | 12969 | extended: Zir.Inst.Extended.InstData, |
| 12886 | 12970 | ) CompileError!Air.Inst.Ref { |
| 12887 | 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 | 12976 | const rhs = sema.resolveInst(extra.rhs); |
| 12892 | 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 | 12979 | try block.c_import_buf.?.writer().print("#define {s} {s}\n", .{ name, value }); |
| 12895 | 12980 | } else { |
| 12896 | 12981 | try block.c_import_buf.?.writer().print("#define {s}\n", .{name}); |