authorgravatar for will.lillis24@gmail.comWill Lillis <will.lillis24@gmail.com> 2024-07-16 12:42:13-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-16 16:42:13+00:00
loga9d544575d5bd2a939b09b8f088bee5d8ff7b0d9
tree0b8f7a3dc25261d88ea412399104ca291060ec9f
parent9356cb1475606a7afd2e722af60f87ce2b39f9f8
signaturebadge-check Signed by PGP key B5690EEEBB952194

Sema: add error note for failed coercions to optional types and error unions


4 files changed, 87 insertions(+), 29 deletions(-)

src/Sema.zig+61-28
...@@ -11312,7 +11312,7 @@ const SwitchProngAnalysis = struct {...@@ -11312,7 +11312,7 @@ const SwitchProngAnalysis = struct {
11312 const first_non_imc = in_mem: {11312 const first_non_imc = in_mem: {
11313 for (field_indices, 0..) |field_idx, i| {11313 for (field_indices, 0..) |field_idx, i| {
11314 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);11314 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
11315 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded)) {11315 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) {
11316 break :in_mem i;11316 break :in_mem i;
11317 }11317 }
11318 }11318 }
...@@ -11335,7 +11335,7 @@ const SwitchProngAnalysis = struct {...@@ -11335,7 +11335,7 @@ const SwitchProngAnalysis = struct {
11335 const next = first_non_imc + 1;11335 const next = first_non_imc + 1;
11336 for (field_indices[next..], next..) |field_idx, i| {11336 for (field_indices[next..], next..) |field_idx, i| {
11337 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);11337 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_idx]);
11338 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded)) {11338 if (.ok != try sema.coerceInMemoryAllowed(block, capture_ty, field_ty, false, zcu.getTarget(), LazySrcLoc.unneeded, LazySrcLoc.unneeded, null)) {
11339 in_mem_coercible.unset(i);11339 in_mem_coercible.unset(i);
11340 }11340 }
11341 }11341 }
...@@ -23162,6 +23162,7 @@ fn ptrCastFull(...@@ -23162,6 +23162,7 @@ fn ptrCastFull(
23162 mod.getTarget(),23162 mod.getTarget(),
23163 src,23163 src,
23164 operand_src,23164 operand_src,
23165 null,
23165 );23166 );
23166 if (imc_res == .ok) break :check_child;23167 if (imc_res == .ok) break :check_child;
23167 return sema.failWithOwnedErrorMsg(block, msg: {23168 return sema.failWithOwnedErrorMsg(block, msg: {
...@@ -25772,7 +25773,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -25772,7 +25773,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
2577225773
25773 const dest_elem_ty = dest_ty.elemType2(mod);25774 const dest_elem_ty = dest_ty.elemType2(mod);
25774 const src_elem_ty = src_ty.elemType2(mod);25775 const src_elem_ty = src_ty.elemType2(mod);
25775 if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src)) {25776 if (.ok != try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, true, target, dest_src, src_src, null)) {
25776 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{});25777 return sema.fail(block, src, "TODO: lower @memcpy to a for loop because the element types have different ABI sizes", .{});
25777 }25778 }
2577825779
...@@ -29188,7 +29189,7 @@ fn coerceExtra(...@@ -29188,7 +29189,7 @@ fn coerceExtra(
2918829189
29189 const maybe_inst_val = try sema.resolveValue(inst);29190 const maybe_inst_val = try sema.resolveValue(inst);
2919029191
29191 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);29192 var in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
29192 if (in_memory_result == .ok) {29193 if (in_memory_result == .ok) {
29193 if (maybe_inst_val) |val| {29194 if (maybe_inst_val) |val| {
29194 return sema.coerceInMemory(val, dest_ty);29195 return sema.coerceInMemory(val, dest_ty);
...@@ -29243,7 +29244,7 @@ fn coerceExtra(...@@ -29243,7 +29244,7 @@ fn coerceExtra(
29243 error.NotCoercible => {29244 error.NotCoercible => {
29244 if (in_memory_result == .no_match) {29245 if (in_memory_result == .no_match) {
29245 // Try to give more useful notes29246 // Try to give more useful notes
29246 in_memory_result = try sema.coerceInMemoryAllowed(block, child_type, inst_ty, false, target, dest_ty_src, inst_src);29247 in_memory_result = try sema.coerceInMemoryAllowed(block, child_type, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
29247 }29248 }
29248 break :optional;29249 break :optional;
29249 },29250 },
...@@ -29273,7 +29274,7 @@ fn coerceExtra(...@@ -29273,7 +29274,7 @@ fn coerceExtra(
29273 const array_elem_ty = array_ty.childType(zcu);29274 const array_elem_ty = array_ty.childType(zcu);
29274 if (array_ty.arrayLen(zcu) != 1) break :single_item;29275 if (array_ty.arrayLen(zcu) != 1) break :single_item;
29275 const dest_is_mut = !dest_info.flags.is_const;29276 const dest_is_mut = !dest_info.flags.is_const;
29276 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {29277 switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val)) {
29277 .ok => {},29278 .ok => {},
29278 else => break :single_item,29279 else => break :single_item,
29279 }29280 }
...@@ -29290,7 +29291,7 @@ fn coerceExtra(...@@ -29290,7 +29291,7 @@ fn coerceExtra(
29290 const dest_is_mut = !dest_info.flags.is_const;29291 const dest_is_mut = !dest_info.flags.is_const;
2929129292
29292 const dst_elem_type = Type.fromInterned(dest_info.child);29293 const dst_elem_type = Type.fromInterned(dest_info.child);
29293 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src);29294 const elem_res = try sema.coerceInMemoryAllowed(block, dst_elem_type, array_elem_type, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val);
29294 switch (elem_res) {29295 switch (elem_res) {
29295 .ok => {},29296 .ok => {},
29296 else => {29297 else => {
...@@ -29351,7 +29352,7 @@ fn coerceExtra(...@@ -29351,7 +29352,7 @@ fn coerceExtra(
29351 const src_elem_ty = inst_ty.childType(zcu);29352 const src_elem_ty = inst_ty.childType(zcu);
29352 const dest_is_mut = !dest_info.flags.is_const;29353 const dest_is_mut = !dest_info.flags.is_const;
29353 const dst_elem_type = Type.fromInterned(dest_info.child);29354 const dst_elem_type = Type.fromInterned(dest_info.child);
29354 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) {29355 switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src, maybe_inst_val)) {
29355 .ok => {},29356 .ok => {},
29356 else => break :src_c_ptr,29357 else => break :src_c_ptr,
29357 }29358 }
...@@ -29404,7 +29405,7 @@ fn coerceExtra(...@@ -29404,7 +29405,7 @@ fn coerceExtra(
29404 const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {29405 const addr = sema.coerceExtra(block, ptr_size_ty, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) {
29405 error.NotCoercible => {29406 error.NotCoercible => {
29406 // Try to give more useful notes29407 // Try to give more useful notes
29407 in_memory_result = try sema.coerceInMemoryAllowed(block, ptr_size_ty, inst_ty, false, target, dest_ty_src, inst_src);29408 in_memory_result = try sema.coerceInMemoryAllowed(block, ptr_size_ty, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
29408 break :pointer;29409 break :pointer;
29409 },29410 },
29410 else => |e| return e,29411 else => |e| return e,
...@@ -29422,6 +29423,7 @@ fn coerceExtra(...@@ -29422,6 +29423,7 @@ fn coerceExtra(
29422 target,29423 target,
29423 dest_ty_src,29424 dest_ty_src,
29424 inst_src,29425 inst_src,
29426 maybe_inst_val,
29425 )) {29427 )) {
29426 .ok => {},29428 .ok => {},
29427 else => break :p,29429 else => break :p,
...@@ -29526,6 +29528,7 @@ fn coerceExtra(...@@ -29526,6 +29528,7 @@ fn coerceExtra(
29526 target,29528 target,
29527 dest_ty_src,29529 dest_ty_src,
29528 inst_src,29530 inst_src,
29531 maybe_inst_val,
29529 )) {29532 )) {
29530 .ok => {},29533 .ok => {},
29531 else => break :p,29534 else => break :p,
...@@ -29705,7 +29708,14 @@ fn coerceExtra(...@@ -29705,7 +29708,14 @@ fn coerceExtra(
29705 else => eu: {29708 else => eu: {
29706 // T to E!T29709 // T to E!T
29707 return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) {29710 return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) {
29708 error.NotCoercible => break :eu,29711 error.NotCoercible => {
29712 if (in_memory_result == .no_match) {
29713 const payload_type = dest_ty.errorUnionPayload(zcu);
29714 // Try to give more useful notes
29715 in_memory_result = try sema.coerceInMemoryAllowed(block, payload_type, inst_ty, false, target, dest_ty_src, inst_src, maybe_inst_val);
29716 }
29717 break :eu;
29718 },
29709 else => |e| return e,29719 else => |e| return e,
29710 };29720 };
29711 },29721 },
...@@ -29730,6 +29740,7 @@ fn coerceExtra(...@@ -29730,6 +29740,7 @@ fn coerceExtra(
29730 target,29740 target,
29731 dest_ty_src,29741 dest_ty_src,
29732 inst_src,29742 inst_src,
29743 maybe_inst_val,
29733 )) {29744 )) {
29734 break :array_to_array;29745 break :array_to_array;
29735 }29746 }
...@@ -29805,7 +29816,7 @@ fn coerceExtra(...@@ -29805,7 +29816,7 @@ fn coerceExtra(
2980529816
29806 // E!T to T29817 // E!T to T
29807 if (inst_ty.zigTypeTag(zcu) == .ErrorUnion and29818 if (inst_ty.zigTypeTag(zcu) == .ErrorUnion and
29808 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)29819 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)
29809 {29820 {
29810 try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{});29821 try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{});
29811 try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});29822 try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
...@@ -29813,7 +29824,7 @@ fn coerceExtra(...@@ -29813,7 +29824,7 @@ fn coerceExtra(
2981329824
29814 // ?T to T29825 // ?T to T
29815 if (inst_ty.zigTypeTag(zcu) == .Optional and29826 if (inst_ty.zigTypeTag(zcu) == .Optional and
29816 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src)) == .ok)29827 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)
29817 {29828 {
29818 try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{});29829 try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{});
29819 try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});29830 try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});
...@@ -29859,6 +29870,7 @@ const InMemoryCoercionResult = union(enum) {...@@ -29859,6 +29870,7 @@ const InMemoryCoercionResult = union(enum) {
29859 ok,29870 ok,
29860 no_match: Pair,29871 no_match: Pair,
29861 int_not_coercible: Int,29872 int_not_coercible: Int,
29873 comptime_int_not_coercible: TypeValuePair,
29862 error_union_payload: PairAndChild,29874 error_union_payload: PairAndChild,
29863 array_len: IntPair,29875 array_len: IntPair,
29864 array_sentinel: Sentinel,29876 array_sentinel: Sentinel,
...@@ -29895,6 +29907,11 @@ const InMemoryCoercionResult = union(enum) {...@@ -29895,6 +29907,11 @@ const InMemoryCoercionResult = union(enum) {
29895 wanted: Type,29907 wanted: Type,
29896 };29908 };
2989729909
29910 const TypeValuePair = struct {
29911 actual: Value,
29912 wanted: Type,
29913 };
29914
29898 const PairAndChild = struct {29915 const PairAndChild = struct {
29899 child: *InMemoryCoercionResult,29916 child: *InMemoryCoercionResult,
29900 actual: Type,29917 actual: Type,
...@@ -29988,6 +30005,12 @@ const InMemoryCoercionResult = union(enum) {...@@ -29988,6 +30005,12 @@ const InMemoryCoercionResult = union(enum) {
29988 });30005 });
29989 break;30006 break;
29990 },30007 },
30008 .comptime_int_not_coercible => |int| {
30009 try sema.errNote(src, msg, "type '{}' cannot represent value '{}'", .{
30010 int.wanted.fmt(pt), int.actual.fmtValue(pt, sema),
30011 });
30012 break;
30013 },
29991 .error_union_payload => |pair| {30014 .error_union_payload => |pair| {
29992 try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{30015 try sema.errNote(src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{
29993 pair.actual.fmt(pt), pair.wanted.fmt(pt),30016 pair.actual.fmt(pt), pair.wanted.fmt(pt),
...@@ -30229,6 +30252,7 @@ pub fn coerceInMemoryAllowed(...@@ -30229,6 +30252,7 @@ pub fn coerceInMemoryAllowed(
30229 target: std.Target,30252 target: std.Target,
30230 dest_src: LazySrcLoc,30253 dest_src: LazySrcLoc,
30231 src_src: LazySrcLoc,30254 src_src: LazySrcLoc,
30255 src_val: ?Value,
30232) CompileError!InMemoryCoercionResult {30256) CompileError!InMemoryCoercionResult {
30233 const pt = sema.pt;30257 const pt = sema.pt;
30234 const mod = pt.zcu;30258 const mod = pt.zcu;
...@@ -30264,6 +30288,15 @@ pub fn coerceInMemoryAllowed(...@@ -30264,6 +30288,15 @@ pub fn coerceInMemoryAllowed(
30264 }30288 }
30265 }30289 }
3026630290
30291 // Comptime int to regular int.
30292 if (dest_tag == .Int and src_tag == .ComptimeInt) {
30293 if (src_val) |val| {
30294 if (!(try sema.intFitsInType(val, dest_ty, null))) {
30295 return .{ .comptime_int_not_coercible = .{ .wanted = dest_ty, .actual = val } };
30296 }
30297 }
30298 }
30299
30267 // Differently-named floats with the same number of bits.30300 // Differently-named floats with the same number of bits.
30268 if (dest_tag == .Float and src_tag == .Float) {30301 if (dest_tag == .Float and src_tag == .Float) {
30269 const dest_bits = dest_ty.floatBits(target);30302 const dest_bits = dest_ty.floatBits(target);
...@@ -30296,7 +30329,7 @@ pub fn coerceInMemoryAllowed(...@@ -30296,7 +30329,7 @@ pub fn coerceInMemoryAllowed(
30296 if (dest_tag == .ErrorUnion and src_tag == .ErrorUnion) {30329 if (dest_tag == .ErrorUnion and src_tag == .ErrorUnion) {
30297 const dest_payload = dest_ty.errorUnionPayload(mod);30330 const dest_payload = dest_ty.errorUnionPayload(mod);
30298 const src_payload = src_ty.errorUnionPayload(mod);30331 const src_payload = src_ty.errorUnionPayload(mod);
30299 const child = try sema.coerceInMemoryAllowed(block, dest_payload, src_payload, dest_is_mut, target, dest_src, src_src);30332 const child = try sema.coerceInMemoryAllowed(block, dest_payload, src_payload, dest_is_mut, target, dest_src, src_src, null);
30300 if (child != .ok) {30333 if (child != .ok) {
30301 return InMemoryCoercionResult{ .error_union_payload = .{30334 return InMemoryCoercionResult{ .error_union_payload = .{
30302 .child = try child.dupe(sema.arena),30335 .child = try child.dupe(sema.arena),
...@@ -30304,7 +30337,7 @@ pub fn coerceInMemoryAllowed(...@@ -30304,7 +30337,7 @@ pub fn coerceInMemoryAllowed(
30304 .wanted = dest_payload,30337 .wanted = dest_payload,
30305 } };30338 } };
30306 }30339 }
30307 return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(mod), src_ty.errorUnionSet(mod), dest_is_mut, target, dest_src, src_src);30340 return try sema.coerceInMemoryAllowed(block, dest_ty.errorUnionSet(mod), src_ty.errorUnionSet(mod), dest_is_mut, target, dest_src, src_src, null);
30308 }30341 }
3030930342
30310 // Error Sets30343 // Error Sets
...@@ -30323,7 +30356,7 @@ pub fn coerceInMemoryAllowed(...@@ -30323,7 +30356,7 @@ pub fn coerceInMemoryAllowed(
30323 } };30356 } };
30324 }30357 }
3032530358
30326 const child = try sema.coerceInMemoryAllowed(block, dest_info.elem_type, src_info.elem_type, dest_is_mut, target, dest_src, src_src);30359 const child = try sema.coerceInMemoryAllowed(block, dest_info.elem_type, src_info.elem_type, dest_is_mut, target, dest_src, src_src, null);
30327 if (child != .ok) {30360 if (child != .ok) {
30328 return InMemoryCoercionResult{ .array_elem = .{30361 return InMemoryCoercionResult{ .array_elem = .{
30329 .child = try child.dupe(sema.arena),30362 .child = try child.dupe(sema.arena),
...@@ -30362,7 +30395,7 @@ pub fn coerceInMemoryAllowed(...@@ -30362,7 +30395,7 @@ pub fn coerceInMemoryAllowed(
3036230395
30363 const dest_elem_ty = dest_ty.scalarType(mod);30396 const dest_elem_ty = dest_ty.scalarType(mod);
30364 const src_elem_ty = src_ty.scalarType(mod);30397 const src_elem_ty = src_ty.scalarType(mod);
30365 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src);30398 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src, null);
30366 if (child != .ok) {30399 if (child != .ok) {
30367 return InMemoryCoercionResult{ .vector_elem = .{30400 return InMemoryCoercionResult{ .vector_elem = .{
30368 .child = try child.dupe(sema.arena),30401 .child = try child.dupe(sema.arena),
...@@ -30389,7 +30422,7 @@ pub fn coerceInMemoryAllowed(...@@ -30389,7 +30422,7 @@ pub fn coerceInMemoryAllowed(
3038930422
30390 const dest_elem_ty = dest_ty.childType(mod);30423 const dest_elem_ty = dest_ty.childType(mod);
30391 const src_elem_ty = src_ty.childType(mod);30424 const src_elem_ty = src_ty.childType(mod);
30392 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src);30425 const child = try sema.coerceInMemoryAllowed(block, dest_elem_ty, src_elem_ty, dest_is_mut, target, dest_src, src_src, null);
30393 if (child != .ok) {30426 if (child != .ok) {
30394 return InMemoryCoercionResult{ .array_elem = .{30427 return InMemoryCoercionResult{ .array_elem = .{
30395 .child = try child.dupe(sema.arena),30428 .child = try child.dupe(sema.arena),
...@@ -30429,7 +30462,7 @@ pub fn coerceInMemoryAllowed(...@@ -30429,7 +30462,7 @@ pub fn coerceInMemoryAllowed(
30429 const dest_child_type = dest_ty.optionalChild(mod);30462 const dest_child_type = dest_ty.optionalChild(mod);
30430 const src_child_type = src_ty.optionalChild(mod);30463 const src_child_type = src_ty.optionalChild(mod);
3043130464
30432 const child = try sema.coerceInMemoryAllowed(block, dest_child_type, src_child_type, dest_is_mut, target, dest_src, src_src);30465 const child = try sema.coerceInMemoryAllowed(block, dest_child_type, src_child_type, dest_is_mut, target, dest_src, src_src, null);
30433 if (child != .ok) {30466 if (child != .ok) {
30434 return InMemoryCoercionResult{ .optional_child = .{30467 return InMemoryCoercionResult{ .optional_child = .{
30435 .child = try child.dupe(sema.arena),30468 .child = try child.dupe(sema.arena),
...@@ -30451,7 +30484,7 @@ pub fn coerceInMemoryAllowed(...@@ -30451,7 +30484,7 @@ pub fn coerceInMemoryAllowed(
30451 if (dest_ty.structFieldAlign(field_idx, pt) != src_ty.structFieldAlign(field_idx, pt)) break :tuple;30484 if (dest_ty.structFieldAlign(field_idx, pt) != src_ty.structFieldAlign(field_idx, pt)) break :tuple;
30452 const dest_field_ty = dest_ty.structFieldType(field_idx, mod);30485 const dest_field_ty = dest_ty.structFieldType(field_idx, mod);
30453 const src_field_ty = src_ty.structFieldType(field_idx, mod);30486 const src_field_ty = src_ty.structFieldType(field_idx, mod);
30454 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src);30487 const field = try sema.coerceInMemoryAllowed(block, dest_field_ty, src_field_ty, dest_is_mut, target, dest_src, src_src, null);
30455 if (field != .ok) break :tuple;30488 if (field != .ok) break :tuple;
30456 }30489 }
30457 return .ok;30490 return .ok;
...@@ -30598,7 +30631,7 @@ fn coerceInMemoryAllowedFns(...@@ -30598,7 +30631,7 @@ fn coerceInMemoryAllowedFns(
30598 else => {30631 else => {
30599 const dest_return_type = Type.fromInterned(dest_info.return_type);30632 const dest_return_type = Type.fromInterned(dest_info.return_type);
30600 const src_return_type = Type.fromInterned(src_info.return_type);30633 const src_return_type = Type.fromInterned(src_info.return_type);
30601 const rt = try sema.coerceInMemoryAllowed(block, dest_return_type, src_return_type, false, target, dest_src, src_src);30634 const rt = try sema.coerceInMemoryAllowed(block, dest_return_type, src_return_type, false, target, dest_src, src_src, null);
30602 if (rt != .ok) {30635 if (rt != .ok) {
30603 return InMemoryCoercionResult{ .fn_return_type = .{30636 return InMemoryCoercionResult{ .fn_return_type = .{
30604 .child = try rt.dupe(sema.arena),30637 .child = try rt.dupe(sema.arena),
...@@ -30644,7 +30677,7 @@ fn coerceInMemoryAllowedFns(...@@ -30644,7 +30677,7 @@ fn coerceInMemoryAllowedFns(
30644 .generic_poison_type => {},30677 .generic_poison_type => {},
30645 else => {30678 else => {
30646 // Note: Cast direction is reversed here.30679 // Note: Cast direction is reversed here.
30647 const param = try sema.coerceInMemoryAllowed(block, src_param_ty, dest_param_ty, false, target, dest_src, src_src);30680 const param = try sema.coerceInMemoryAllowed(block, src_param_ty, dest_param_ty, false, target, dest_src, src_src, null);
30648 if (param != .ok) {30681 if (param != .ok) {
30649 return InMemoryCoercionResult{ .fn_param = .{30682 return InMemoryCoercionResult{ .fn_param = .{
30650 .child = try param.dupe(sema.arena),30683 .child = try param.dupe(sema.arena),
...@@ -30708,13 +30741,13 @@ fn coerceInMemoryAllowedPtrs(...@@ -30708,13 +30741,13 @@ fn coerceInMemoryAllowedPtrs(
3070830741
30709 const dest_child = Type.fromInterned(dest_info.child);30742 const dest_child = Type.fromInterned(dest_info.child);
30710 const src_child = Type.fromInterned(src_info.child);30743 const src_child = Type.fromInterned(src_info.child);
30711 const child = try sema.coerceInMemoryAllowed(block, dest_child, src_child, !dest_info.flags.is_const, target, dest_src, src_src);30744 const child = try sema.coerceInMemoryAllowed(block, dest_child, src_child, !dest_info.flags.is_const, target, dest_src, src_src, null);
30712 if (child != .ok) allow: {30745 if (child != .ok) allow: {
30713 // As a special case, we also allow coercing `*[n:s]T` to `*[n]T`, akin to dropping the sentinel from a slice.30746 // As a special case, we also allow coercing `*[n:s]T` to `*[n]T`, akin to dropping the sentinel from a slice.
30714 // `*[n:s]T` cannot coerce in memory to `*[n]T` since they have different sizes.30747 // `*[n:s]T` cannot coerce in memory to `*[n]T` since they have different sizes.
30715 if (src_child.zigTypeTag(zcu) == .Array and dest_child.zigTypeTag(zcu) == .Array and30748 if (src_child.zigTypeTag(zcu) == .Array and dest_child.zigTypeTag(zcu) == .Array and
30716 src_child.sentinel(zcu) != null and dest_child.sentinel(zcu) == null and30749 src_child.sentinel(zcu) != null and dest_child.sentinel(zcu) == null and
30717 .ok == try sema.coerceInMemoryAllowed(block, dest_child.childType(zcu), src_child.childType(zcu), !dest_info.flags.is_const, target, dest_src, src_src))30750 .ok == try sema.coerceInMemoryAllowed(block, dest_child.childType(zcu), src_child.childType(zcu), !dest_info.flags.is_const, target, dest_src, src_src, null))
30718 {30751 {
30719 break :allow;30752 break :allow;
30720 }30753 }
...@@ -31593,7 +31626,7 @@ fn coerceArrayLike(...@@ -31593,7 +31626,7 @@ fn coerceArrayLike(
31593 const target = mod.getTarget();31626 const target = mod.getTarget();
3159431627
31595 // try coercion of the whole array31628 // try coercion of the whole array
31596 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src);31629 const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty, false, target, dest_ty_src, inst_src, null);
31597 if (in_memory_result == .ok) {31630 if (in_memory_result == .ok) {
31598 if (try sema.resolveValue(inst)) |inst_val| {31631 if (try sema.resolveValue(inst)) |inst_val| {
31599 // These types share the same comptime value representation.31632 // These types share the same comptime value representation.
...@@ -34108,13 +34141,13 @@ fn resolvePeerTypesInner(...@@ -34108,13 +34141,13 @@ fn resolvePeerTypesInner(
34108 const peer_elem_ty = ty.childType(mod);34141 const peer_elem_ty = ty.childType(mod);
34109 if (!peer_elem_ty.eql(elem_ty, mod)) coerce: {34142 if (!peer_elem_ty.eql(elem_ty, mod)) coerce: {
34110 const peer_elem_coerces_to_elem =34143 const peer_elem_coerces_to_elem =
34111 try sema.coerceInMemoryAllowed(block, elem_ty, peer_elem_ty, false, mod.getTarget(), src, src);34144 try sema.coerceInMemoryAllowed(block, elem_ty, peer_elem_ty, false, mod.getTarget(), src, src, null);
34112 if (peer_elem_coerces_to_elem == .ok) {34145 if (peer_elem_coerces_to_elem == .ok) {
34113 break :coerce;34146 break :coerce;
34114 }34147 }
3411534148
34116 const elem_coerces_to_peer_elem =34149 const elem_coerces_to_peer_elem =
34117 try sema.coerceInMemoryAllowed(block, peer_elem_ty, elem_ty, false, mod.getTarget(), src, src);34150 try sema.coerceInMemoryAllowed(block, peer_elem_ty, elem_ty, false, mod.getTarget(), src, src, null);
34118 if (elem_coerces_to_peer_elem == .ok) {34151 if (elem_coerces_to_peer_elem == .ok) {
34119 elem_ty = peer_elem_ty;34152 elem_ty = peer_elem_ty;
34120 break :coerce;34153 break :coerce;
...@@ -35039,12 +35072,12 @@ fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_...@@ -35039,12 +35072,12 @@ fn resolvePairInMemoryCoercible(sema: *Sema, block: *Block, src: LazySrcLoc, ty_
35039 const target = sema.pt.zcu.getTarget();35072 const target = sema.pt.zcu.getTarget();
3504035073
35041 // ty_b -> ty_a35074 // ty_b -> ty_a
35042 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, target, src, src)) {35075 if (.ok == try sema.coerceInMemoryAllowed(block, ty_a, ty_b, true, target, src, src, null)) {
35043 return ty_a;35076 return ty_a;
35044 }35077 }
3504535078
35046 // ty_a -> ty_b35079 // ty_a -> ty_b
35047 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, target, src, src)) {35080 if (.ok == try sema.coerceInMemoryAllowed(block, ty_b, ty_a, true, target, src, src, null)) {
35048 return ty_b;35081 return ty_b;
35049 }35082 }
3505035083
src/Sema/comptime_ptr_access.zig+4-1
...@@ -321,6 +321,7 @@ fn loadComptimePtrInner(...@@ -321,6 +321,7 @@ fn loadComptimePtrInner(
321 zcu.getTarget(),321 zcu.getTarget(),
322 src,322 src,
323 src,323 src,
324 null,
324 )) {325 )) {
325 // We already have a value which is IMC to the desired type.326 // We already have a value which is IMC to the desired type.
326 return .{ .success = base_val };327 return .{ .success = base_val };
...@@ -353,6 +354,7 @@ fn loadComptimePtrInner(...@@ -353,6 +354,7 @@ fn loadComptimePtrInner(
353 zcu.getTarget(),354 zcu.getTarget(),
354 src,355 src,
355 src,356 src,
357 null,
356 )) {358 )) {
357 // Changing the length of an array.359 // Changing the length of an array.
358 const skip_base: u64 = extra_base_index + if (load_ty.zigTypeTag(zcu) == .Array) skip: {360 const skip_base: u64 = extra_base_index + if (load_ty.zigTypeTag(zcu) == .Array) skip: {
...@@ -721,6 +723,7 @@ fn prepareComptimePtrStore(...@@ -721,6 +723,7 @@ fn prepareComptimePtrStore(
721 zcu.getTarget(),723 zcu.getTarget(),
722 src,724 src,
723 src,725 src,
726 null,
724 )) {727 )) {
725 // The base strategy already gets us a value which the desired type is IMC to.728 // The base strategy already gets us a value which the desired type is IMC to.
726 return base_strat;729 return base_strat;
...@@ -753,7 +756,7 @@ fn prepareComptimePtrStore(...@@ -753,7 +756,7 @@ fn prepareComptimePtrStore(
753 else => unreachable,756 else => unreachable,
754 };757 };
755 const val_one_ty, const val_count = base_val.typeOf(zcu).arrayBase(zcu);758 const val_one_ty, const val_count = base_val.typeOf(zcu).arrayBase(zcu);
756 if (.ok != try sema.coerceInMemoryAllowed(block, val_one_ty, store_one_ty, true, zcu.getTarget(), src, src)) {759 if (.ok != try sema.coerceInMemoryAllowed(block, val_one_ty, store_one_ty, true, zcu.getTarget(), src, src, null)) {
757 break :restructure_array;760 break :restructure_array;
758 }761 }
759 if (base_elem_offset + extra_base_index + store_count > val_count) return .{ .out_of_bounds = oob_ty };762 if (base_elem_offset + extra_base_index + store_count > val_count) return .{ .out_of_bounds = oob_ty };
test/cases/compile_errors/coercion_to_error_union.zig created+11
...@@ -0,0 +1,11 @@
1export fn b() void {
2 const x: anyerror!u8 = 256;
3 _ = x;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// 2:28: error: expected type 'anyerror!u8', found 'comptime_int'
11// 2:28: note: type 'u8' cannot represent value '256'
test/cases/compile_errors/coercion_to_optional.zig created+11
...@@ -0,0 +1,11 @@
1export fn a() void {
2 const x: ?u8 = 256;
3 _ = x;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// 2:20: error: expected type '?u8', found 'comptime_int'
11// 2:20: note: type 'u8' cannot represent value '256'