| ... | ... | @@ -1663,11 +1663,15 @@ fn resolveMaybeUndefValIntable( |
| 1663 | 1663 | inst: Air.Inst.Ref, |
| 1664 | 1664 | ) CompileError!?Value { |
| 1665 | 1665 | const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) orelse return null; |
| 1666 | | switch (val.tag()) { |
| 1667 | | .variable, .decl_ref, .decl_ref_mut => return null, |
| 1666 | var check = val; |
| 1667 | while (true) switch (check.tag()) { |
| 1668 | .variable, .decl_ref, .decl_ref_mut, .comptime_field_ptr => return null, |
| 1669 | .field_ptr => check = check.castTag(.field_ptr).?.data.container_ptr, |
| 1670 | .elem_ptr => check = check.castTag(.elem_ptr).?.data.array_ptr, |
| 1671 | .eu_payload_ptr, .opt_payload_ptr => check = check.cast(Value.Payload.PayloadPtr).?.data.container_ptr, |
| 1668 | 1672 | .generic_poison => return error.GenericPoison, |
| 1669 | 1673 | else => return val, |
| 1670 | | } |
| 1674 | }; |
| 1671 | 1675 | } |
| 1672 | 1676 | |
| 1673 | 1677 | /// Returns all Value tags including `variable` and `undef`. |
| ... | ... | @@ -3871,9 +3875,15 @@ fn zirValidateArrayInit( |
| 3871 | 3875 | const array_len = array_ty.arrayLen(); |
| 3872 | 3876 | |
| 3873 | 3877 | if (instrs.len != array_len) { |
| 3874 | | return sema.fail(block, init_src, "expected {d} array elements; found {d}", .{ |
| 3875 | | array_len, instrs.len, |
| 3876 | | }); |
| 3878 | if (array_ty.zigTypeTag() == .Array) { |
| 3879 | return sema.fail(block, init_src, "expected {d} array elements; found {d}", .{ |
| 3880 | array_len, instrs.len, |
| 3881 | }); |
| 3882 | } else { |
| 3883 | return sema.fail(block, init_src, "expected {d} vector elements; found {d}", .{ |
| 3884 | array_len, instrs.len, |
| 3885 | }); |
| 3886 | } |
| 3877 | 3887 | } |
| 3878 | 3888 | |
| 3879 | 3889 | if ((is_comptime or block.is_comptime) and |
| ... | ... | @@ -7893,7 +7903,7 @@ fn zirPtrToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 7893 | 7903 | if (!ptr_ty.isPtrAtRuntime()) { |
| 7894 | 7904 | return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}); |
| 7895 | 7905 | } |
| 7896 | | if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |ptr_val| { |
| 7906 | if (try sema.resolveMaybeUndefValIntable(block, ptr_src, ptr)) |ptr_val| { |
| 7897 | 7907 | return sema.addConstant(Type.usize, ptr_val); |
| 7898 | 7908 | } |
| 7899 | 7909 | try sema.requireRuntimeBlock(block, ptr_src, ptr_src); |
| ... | ... | @@ -14261,7 +14271,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 14261 | 14271 | |
| 14262 | 14272 | switch (obj_ty.zigTypeTag()) { |
| 14263 | 14273 | .Struct => return sema.structInitEmpty(block, obj_ty, src, src), |
| 14264 | | .Array => return arrayInitEmpty(sema, obj_ty), |
| 14274 | .Array, .Vector => return sema.arrayInitEmpty(block, src, obj_ty), |
| 14265 | 14275 | .Void => return sema.addConstant(obj_ty, Value.void), |
| 14266 | 14276 | else => return sema.failWithArrayInitNotSupported(block, src, obj_ty), |
| 14267 | 14277 | } |
| ... | ... | @@ -14286,7 +14296,15 @@ fn structInitEmpty( |
| 14286 | 14296 | return sema.finishStructInit(block, init_src, dest_src, field_inits, struct_ty, false); |
| 14287 | 14297 | } |
| 14288 | 14298 | |
| 14289 | | fn arrayInitEmpty(sema: *Sema, obj_ty: Type) CompileError!Air.Inst.Ref { |
| 14299 | fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref { |
| 14300 | const arr_len = obj_ty.arrayLen(); |
| 14301 | if (arr_len != 0) { |
| 14302 | if (obj_ty.zigTypeTag() == .Array) { |
| 14303 | return sema.fail(block, src, "expected {d} array elements; found 0", .{arr_len}); |
| 14304 | } else { |
| 14305 | return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len}); |
| 14306 | } |
| 14307 | } |
| 14290 | 14308 | if (obj_ty.sentinel()) |sentinel| { |
| 14291 | 14309 | const val = try Value.Tag.empty_array_sentinel.create(sema.arena, sentinel); |
| 14292 | 14310 | return sema.addConstant(obj_ty, val); |
| ... | ... | @@ -19448,7 +19466,7 @@ fn fieldCallBind( |
| 19448 | 19466 | |
| 19449 | 19467 | const raw_ptr_src = src; // TODO better source location |
| 19450 | 19468 | const raw_ptr_ty = sema.typeOf(raw_ptr); |
| 19451 | | const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and raw_ptr_ty.ptrSize() == .One) |
| 19469 | const inner_ty = if (raw_ptr_ty.zigTypeTag() == .Pointer and (raw_ptr_ty.ptrSize() == .One or raw_ptr_ty.ptrSize() == .C)) |
| 19452 | 19470 | raw_ptr_ty.childType() |
| 19453 | 19471 | else |
| 19454 | 19472 | return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(sema.mod)}); |
| ... | ... | @@ -20974,7 +20992,7 @@ fn coerceExtra( |
| 20974 | 20992 | .Vector => return sema.coerceArrayLike(block, dest_ty, dest_ty_src, inst, inst_src), |
| 20975 | 20993 | .Struct => { |
| 20976 | 20994 | if (inst == .empty_struct) { |
| 20977 | | return arrayInitEmpty(sema, dest_ty); |
| 20995 | return sema.arrayInitEmpty(block, inst_src, dest_ty); |
| 20978 | 20996 | } |
| 20979 | 20997 | if (inst_ty.isTuple()) { |
| 20980 | 20998 | return sema.coerceTupleToArray(block, dest_ty, dest_ty_src, inst, inst_src); |
| ... | ... | @@ -22607,7 +22625,9 @@ fn beginComptimePtrMutation( |
| 22607 | 22625 | } |
| 22608 | 22626 | }, |
| 22609 | 22627 | .opt_payload_ptr => { |
| 22610 | | const opt_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; |
| 22628 | const opt_ptr = if (ptr_val.castTag(.opt_payload_ptr)) |some| some.data else { |
| 22629 | return sema.beginComptimePtrMutation(block, src, ptr_val, try ptr_elem_ty.optionalChildAlloc(sema.arena)); |
| 22630 | }; |
| 22611 | 22631 | var parent = try beginComptimePtrMutation(sema, block, src, opt_ptr.container_ptr, opt_ptr.container_ty); |
| 22612 | 22632 | switch (parent.pointee) { |
| 22613 | 22633 | .direct => |val_ptr| { |
| ... | ... | @@ -22640,7 +22660,11 @@ fn beginComptimePtrMutation( |
| 22640 | 22660 | .ty = payload_ty, |
| 22641 | 22661 | }, |
| 22642 | 22662 | |
| 22643 | | else => unreachable, |
| 22663 | else => return ComptimePtrMutationKit{ |
| 22664 | .decl_ref_mut = parent.decl_ref_mut, |
| 22665 | .pointee = .{ .direct = val_ptr }, |
| 22666 | .ty = payload_ty, |
| 22667 | }, |
| 22644 | 22668 | } |
| 22645 | 22669 | }, |
| 22646 | 22670 | .bad_decl_ty, .bad_ptr_ty => return parent, |
| ... | ... | @@ -22922,8 +22946,13 @@ fn beginComptimePtrLoad( |
| 22922 | 22946 | (try sema.coerceInMemoryAllowed(block, tv.ty, payload_ptr.container_ty, false, target, src, src)) == .ok; |
| 22923 | 22947 | if (coerce_in_mem_ok) { |
| 22924 | 22948 | const payload_val = switch (ptr_val.tag()) { |
| 22925 | | .eu_payload_ptr => tv.val.castTag(.eu_payload).?.data, |
| 22926 | | .opt_payload_ptr => tv.val.castTag(.opt_payload).?.data, |
| 22949 | .eu_payload_ptr => if (tv.val.castTag(.eu_payload)) |some| some.data else { |
| 22950 | return sema.fail(block, src, "attempt to unwrap error: {s}", .{tv.val.castTag(.@"error").?.data.name}); |
| 22951 | }, |
| 22952 | .opt_payload_ptr => if (tv.val.castTag(.opt_payload)) |some| some.data else opt: { |
| 22953 | if (tv.val.isNull()) return sema.fail(block, src, "attempt to use null value", .{}); |
| 22954 | break :opt tv.val; |
| 22955 | }, |
| 22927 | 22956 | else => unreachable, |
| 22928 | 22957 | }; |
| 22929 | 22958 | tv.* = TypedValue{ .ty = payload_ty, .val = payload_val }; |
| ... | ... | @@ -22933,6 +22962,9 @@ fn beginComptimePtrLoad( |
| 22933 | 22962 | deref.pointee = null; |
| 22934 | 22963 | break :blk deref; |
| 22935 | 22964 | }, |
| 22965 | .null_value => { |
| 22966 | return sema.fail(block, src, "attempt to use null value", .{}); |
| 22967 | }, |
| 22936 | 22968 | |
| 22937 | 22969 | .zero, |
| 22938 | 22970 | .one, |