| ... | @@ -29385,14 +29385,18 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -29385,14 +29385,18 @@ const InMemoryCoercionResult = union(enum) { |
| 29385 | break; | 29385 | break; |
| 29386 | }, | 29386 | }, |
| 29387 | .array_sentinel => |sentinel| { | 29387 | .array_sentinel => |sentinel| { |
| 29388 | if (sentinel.actual.toIntern() != .unreachable_value) { | 29388 | if (sentinel.wanted.toIntern() == .unreachable_value) { |
| 29389 | try sema.errNote(src, msg, "array sentinel '{f}' cannot cast into array sentinel '{f}'", .{ | 29389 | try sema.errNote(src, msg, "source array cannot be guaranteed to maintain '{f}' sentinel", .{ |
| 29390 | sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema), | 29390 | sentinel.actual.fmtValueSema(pt, sema), |
| 29391 | }); | 29391 | }); |
| 29392 | } else { | 29392 | } else if (sentinel.actual.toIntern() == .unreachable_value) { |
| 29393 | try sema.errNote(src, msg, "destination array requires '{f}' sentinel", .{ | 29393 | try sema.errNote(src, msg, "destination array requires '{f}' sentinel", .{ |
| 29394 | sentinel.wanted.fmtValueSema(pt, sema), | 29394 | sentinel.wanted.fmtValueSema(pt, sema), |
| 29395 | }); | 29395 | }); |
| | 29396 | } else { |
| | 29397 | try sema.errNote(src, msg, "array sentinel '{f}' cannot cast into array sentinel '{f}'", .{ |
| | 29398 | sentinel.actual.fmtValueSema(pt, sema), sentinel.wanted.fmtValueSema(pt, sema), |
| | 29399 | }); |
| 29396 | } | 29400 | } |
| 29397 | break; | 29401 | break; |
| 29398 | }, | 29402 | }, |
| ... | @@ -30179,10 +30183,14 @@ fn coerceInMemoryAllowedPtrs( | ... | @@ -30179,10 +30183,14 @@ fn coerceInMemoryAllowedPtrs( |
| 30179 | src_src, | 30183 | src_src, |
| 30180 | null, | 30184 | null, |
| 30181 | ); | 30185 | ); |
| 30182 | if (child != .ok and !dest_is_mut) allow: { | 30186 | if (child != .ok) allow: { |
| 30183 | // As a special case, we also allow coercing `*[n:s]T` to `*[n]T`, akin to dropping the sentinel from a slice. | 30187 | // As a special case, we also allow coercing `*[n:s]T` to `*[n]T`, akin to dropping the sentinel from a slice. |
| 30184 | // `*[n:s]T` cannot coerce in memory to `*[n]T` since they have different sizes. | 30188 | // `*[n:s]T` cannot coerce in memory to `*[n]T` since they have different sizes. |
| 30185 | if (src_child.zigTypeTag(zcu) == .array and dest_child.zigTypeTag(zcu) == .array and | 30189 | // |
| | 30190 | // We must once again include `dest_is_mut` because `**[n:s]T -> **[n]T` |
| | 30191 | // is not allowed, as it would make it possible to assign an illegal value |
| | 30192 | // to the sentinel-terminated side. |
| | 30193 | if (!dest_is_mut and src_child.zigTypeTag(zcu) == .array and dest_child.zigTypeTag(zcu) == .array and |
| 30186 | src_child.arrayLen(zcu) == dest_child.arrayLen(zcu) and | 30194 | src_child.arrayLen(zcu) == dest_child.arrayLen(zcu) and |
| 30187 | src_child.sentinel(zcu) != null and dest_child.sentinel(zcu) == null and | 30195 | src_child.sentinel(zcu) != null and dest_child.sentinel(zcu) == null and |
| 30188 | .ok == try sema.coerceInMemoryAllowed(block, dest_child.childType(zcu), src_child.childType(zcu), !dest_info.flags.is_const, target, dest_src, src_src, null)) | 30196 | .ok == try sema.coerceInMemoryAllowed(block, dest_child.childType(zcu), src_child.childType(zcu), !dest_info.flags.is_const, target, dest_src, src_src, null)) |