| ... | ... | @@ -28258,9 +28258,94 @@ fn coerceExtra( |
| 28258 | 28258 | }, |
| 28259 | 28259 | else => {}, |
| 28260 | 28260 | }, |
| 28261 | | .one => {}, |
| 28261 | // []T to *[n]T |
| 28262 | .one => slice_to_array_ptr: { |
| 28263 | if (!inst_ty.isSlice(zcu)) break :slice_to_array_ptr; |
| 28264 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :slice_to_array_ptr; |
| 28265 | const array_ty: Type = .fromInterned(dest_info.child); |
| 28266 | if (array_ty.zigTypeTag(zcu) != .array) break :slice_to_array_ptr; |
| 28267 | const inst_val = maybe_inst_val orelse { |
| 28268 | if (!opts.report_err) return error.NotCoercible; |
| 28269 | return sema.fail( |
| 28270 | block, |
| 28271 | inst_src, |
| 28272 | "coercion from slice to array pointer type '{f}' requires length to be known at compile-time", |
| 28273 | .{dest_ty.fmt(pt)}, |
| 28274 | ); |
| 28275 | }; |
| 28276 | |
| 28277 | const slice: InternPool.Key.Slice = slice: { |
| 28278 | switch (ip.indexToKey(inst_val.toIntern())) { |
| 28279 | .undef => {}, |
| 28280 | .slice => |slice| if (slice.len != .undef_usize) break :slice slice, |
| 28281 | else => unreachable, |
| 28282 | } |
| 28283 | if (!opts.report_err) return error.NotCoercible; |
| 28284 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 28285 | const msg = try sema.errMsg(inst_src, "slice with undefined length cannot cast into array pointer type '{f}'", .{ |
| 28286 | dest_ty.fmt(pt), |
| 28287 | }); |
| 28288 | errdefer msg.destroy(gpa); |
| 28289 | try sema.errNote(inst_src, msg, "length of slice must be defined and match length of array type", .{}); |
| 28290 | break :msg msg; |
| 28291 | }); |
| 28292 | }; |
| 28293 | const slice_len = Value.fromInterned(slice.len).toUnsignedInt(zcu); |
| 28294 | if (array_ty.arrayLen(zcu) != slice_len) { |
| 28295 | if (!opts.report_err) return error.NotCoercible; |
| 28296 | return sema.failWithOwnedErrorMsg(block, msg: { |
| 28297 | const msg = try sema.errMsg(inst_src, "slice of length {d} cannot cast into array pointer type '{f}'", .{ |
| 28298 | slice_len, dest_ty.fmt(pt), |
| 28299 | }); |
| 28300 | errdefer msg.destroy(gpa); |
| 28301 | try sema.errNote(inst_src, msg, "length of slice must match length of array type", .{}); |
| 28302 | break :msg msg; |
| 28303 | }); |
| 28304 | } |
| 28305 | |
| 28306 | const inst_elem_ty = inst_ty.childType(zcu); |
| 28307 | const dest_elem_ty = array_ty.childType(zcu); |
| 28308 | const dest_is_mut = !dest_info.flags.is_const; |
| 28309 | switch (try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, null)) { |
| 28310 | .ok => {}, |
| 28311 | else => |elem_res| { |
| 28312 | in_memory_result = .{ .ptr_child = .{ |
| 28313 | .child = try elem_res.dupe(sema.arena), |
| 28314 | .actual = inst_elem_ty, |
| 28315 | .wanted = dest_elem_ty, |
| 28316 | } }; |
| 28317 | break :slice_to_array_ptr; |
| 28318 | }, |
| 28319 | } |
| 28320 | |
| 28321 | if (array_ty.sentinel(zcu)) |array_sentinel| { |
| 28322 | if (inst_ty.sentinel(zcu)) |slice_sentinel| { |
| 28323 | if (array_sentinel.toIntern() != |
| 28324 | (try pt.getCoerced(slice_sentinel, dest_elem_ty)).toIntern()) |
| 28325 | { |
| 28326 | in_memory_result = .{ .ptr_sentinel = .{ |
| 28327 | .actual = slice_sentinel, |
| 28328 | .wanted = array_sentinel, |
| 28329 | .ty = dest_elem_ty, |
| 28330 | } }; |
| 28331 | break :slice_to_array_ptr; |
| 28332 | } |
| 28333 | } else { |
| 28334 | in_memory_result = .{ .ptr_sentinel = .{ |
| 28335 | .actual = .@"unreachable", |
| 28336 | .wanted = array_sentinel, |
| 28337 | .ty = dest_elem_ty, |
| 28338 | } }; |
| 28339 | break :slice_to_array_ptr; |
| 28340 | } |
| 28341 | } |
| 28342 | |
| 28343 | const array_ptr = try pt.sliceToArrayPtr(slice); |
| 28344 | return sema.coerceCompatiblePtrs(block, dest_ty, .fromValue(array_ptr), inst_src); |
| 28345 | }, |
| 28262 | 28346 | .slice => to_slice: { |
| 28263 | 28347 | if (inst_ty.zigTypeTag(zcu) == .array) { |
| 28348 | if (!opts.report_err) return error.NotCoercible; |
| 28264 | 28349 | return sema.fail( |
| 28265 | 28350 | block, |
| 28266 | 28351 | inst_src, |
| ... | ... | @@ -28288,6 +28373,7 @@ fn coerceExtra( |
| 28288 | 28373 | |
| 28289 | 28374 | // pointer to tuple to slice |
| 28290 | 28375 | if (!dest_info.flags.is_const) { |
| 28376 | if (!opts.report_err) return error.NotCoercible; |
| 28291 | 28377 | const err_msg = err_msg: { |
| 28292 | 28378 | const err_msg = try sema.errMsg(inst_src, "cannot cast pointer to tuple to '{f}'", .{dest_ty.fmt(pt)}); |
| 28293 | 28379 | errdefer err_msg.destroy(sema.gpa); |
| ... | ... | @@ -28383,6 +28469,7 @@ fn coerceExtra( |
| 28383 | 28469 | if (maybe_inst_val) |val| { |
| 28384 | 28470 | const result_val = try val.floatCast(dest_ty, pt); |
| 28385 | 28471 | if (!val.eql(try result_val.floatCast(inst_ty, pt), inst_ty, zcu)) { |
| 28472 | if (!opts.report_err) return error.NotCoercible; |
| 28386 | 28473 | return sema.fail( |
| 28387 | 28474 | block, |
| 28388 | 28475 | inst_src, |
| ... | ... | @@ -28440,12 +28527,15 @@ fn coerceExtra( |
| 28440 | 28527 | break :fits result_big_int.toConst().eql(operand_big_int); |
| 28441 | 28528 | }, |
| 28442 | 28529 | }; |
| 28443 | | if (!fits) return sema.fail( |
| 28444 | | block, |
| 28445 | | inst_src, |
| 28446 | | "type '{f}' cannot represent integer value '{f}'", |
| 28447 | | .{ dest_ty.fmt(pt), val.fmtValue(pt) }, |
| 28448 | | ); |
| 28530 | if (!fits) { |
| 28531 | if (!opts.report_err) return error.NotCoercible; |
| 28532 | return sema.fail( |
| 28533 | block, |
| 28534 | inst_src, |
| 28535 | "type '{f}' cannot represent integer value '{f}'", |
| 28536 | .{ dest_ty.fmt(pt), val.fmtValue(pt) }, |
| 28537 | ); |
| 28538 | } |
| 28449 | 28539 | return .fromValue(result_val); |
| 28450 | 28540 | }, |
| 28451 | 28541 | else => {}, |
| ... | ... | @@ -28456,6 +28546,7 @@ fn coerceExtra( |
| 28456 | 28546 | const val = sema.resolveValue(inst).?; |
| 28457 | 28547 | const string = zcu.intern_pool.indexToKey(val.toIntern()).enum_literal; |
| 28458 | 28548 | const field_index = dest_ty.enumFieldIndex(string, zcu) orelse { |
| 28549 | if (!opts.report_err) return error.NotCoercible; |
| 28459 | 28550 | return sema.fail(block, inst_src, "no field named '{f}' in enum '{f}'", .{ |
| 28460 | 28551 | string.fmt(&zcu.intern_pool), dest_ty.fmt(pt), |
| 28461 | 28552 | }); |