mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Sema: fix invalid coercion *[n:x]T -> *[m]T for n != m
The change in `Sema.coerceExtra` is just to avoid an unhelpful error message, covered by the added test case. Resolves: #22373
This commit is contained in:
parent
d02c2c76fc
commit
5333d2443a
@ -29736,6 +29736,7 @@ fn coerceExtra(
|
|||||||
// Coercions where the source is a single pointer to an array.
|
// Coercions where the source is a single pointer to an array.
|
||||||
src_array_ptr: {
|
src_array_ptr: {
|
||||||
if (!inst_ty.isSinglePointer(zcu)) break :src_array_ptr;
|
if (!inst_ty.isSinglePointer(zcu)) break :src_array_ptr;
|
||||||
|
if (dest_info.flags.size == .One) break :src_array_ptr; // `*[n]T` -> `*T` isn't valid
|
||||||
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer;
|
||||||
const array_ty = inst_ty.childType(zcu);
|
const array_ty = inst_ty.childType(zcu);
|
||||||
if (array_ty.zigTypeTag(zcu) != .array) break :src_array_ptr;
|
if (array_ty.zigTypeTag(zcu) != .array) break :src_array_ptr;
|
||||||
@ -29791,7 +29792,7 @@ fn coerceExtra(
|
|||||||
// *[N]T to [*]T
|
// *[N]T to [*]T
|
||||||
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
|
||||||
},
|
},
|
||||||
.One => {},
|
.One => unreachable, // early exit at top of block
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31259,6 +31260,7 @@ fn coerceInMemoryAllowedPtrs(
|
|||||||
// As a special case, we also allow coercing `*[n:s]T` to `*[n]T`, akin to dropping the sentinel from a slice.
|
// As a special case, we also allow coercing `*[n:s]T` to `*[n]T`, akin to dropping the sentinel from a slice.
|
||||||
// `*[n:s]T` cannot coerce in memory to `*[n]T` since they have different sizes.
|
// `*[n:s]T` cannot coerce in memory to `*[n]T` since they have different sizes.
|
||||||
if (src_child.zigTypeTag(zcu) == .array and dest_child.zigTypeTag(zcu) == .array and
|
if (src_child.zigTypeTag(zcu) == .array and dest_child.zigTypeTag(zcu) == .array and
|
||||||
|
src_child.arrayLen(zcu) == dest_child.arrayLen(zcu) and
|
||||||
src_child.sentinel(zcu) != null and dest_child.sentinel(zcu) == null and
|
src_child.sentinel(zcu) != null and dest_child.sentinel(zcu) == null and
|
||||||
.ok == try sema.coerceInMemoryAllowed(block, dest_child.childType(zcu), src_child.childType(zcu), !dest_info.flags.is_const, target, dest_src, src_src, null))
|
.ok == try sema.coerceInMemoryAllowed(block, dest_child.childType(zcu), src_child.childType(zcu), !dest_info.flags.is_const, target, dest_src, src_src, null))
|
||||||
{
|
{
|
||||||
|
|||||||
70
test/cases/compile_errors/coerce_array_to_different_size.zig
Normal file
70
test/cases/compile_errors/coerce_array_to_different_size.zig
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
export fn bigger(a: *const [10]u32) void {
|
||||||
|
const b: *const [20]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
const a: *const [10]u32 = &@splat(0);
|
||||||
|
const b: *const [20]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn biggerSentinel(a: *const [10:0]u32) void {
|
||||||
|
const b: *const [20]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
const a: *const [10:0]u32 = &@splat(0);
|
||||||
|
const b: *const [20]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn smaller(a: *const [10]u32) void {
|
||||||
|
const b: *const [5]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
const a: *const [10]u32 = &@splat(0);
|
||||||
|
const b: *const [5]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
export fn smallerSentinel(a: *const [10:0]u32) void {
|
||||||
|
const b: *const [5]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
comptime {
|
||||||
|
const a: *const [10:0]u32 = &@splat(0);
|
||||||
|
const b: *const [5]u32 = a;
|
||||||
|
_ = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error
|
||||||
|
//
|
||||||
|
// :2:31: error: expected type '*const [20]u32', found '*const [10]u32'
|
||||||
|
// :2:31: note: pointer type child '[10]u32' cannot cast into pointer type child '[20]u32'
|
||||||
|
// :2:31: note: array of length 10 cannot cast into an array of length 20
|
||||||
|
// :8:31: error: expected type '*const [20]u32', found '*const [10]u32'
|
||||||
|
// :8:31: note: pointer type child '[10]u32' cannot cast into pointer type child '[20]u32'
|
||||||
|
// :8:31: note: array of length 10 cannot cast into an array of length 20
|
||||||
|
// :13:31: error: expected type '*const [20]u32', found '*const [10:0]u32'
|
||||||
|
// :13:31: note: pointer type child '[10:0]u32' cannot cast into pointer type child '[20]u32'
|
||||||
|
// :13:31: note: array of length 10 cannot cast into an array of length 20
|
||||||
|
// :19:31: error: expected type '*const [20]u32', found '*const [10:0]u32'
|
||||||
|
// :19:31: note: pointer type child '[10:0]u32' cannot cast into pointer type child '[20]u32'
|
||||||
|
// :19:31: note: array of length 10 cannot cast into an array of length 20
|
||||||
|
// :24:30: error: expected type '*const [5]u32', found '*const [10]u32'
|
||||||
|
// :24:30: note: pointer type child '[10]u32' cannot cast into pointer type child '[5]u32'
|
||||||
|
// :24:30: note: array of length 10 cannot cast into an array of length 5
|
||||||
|
// :30:30: error: expected type '*const [5]u32', found '*const [10]u32'
|
||||||
|
// :30:30: note: pointer type child '[10]u32' cannot cast into pointer type child '[5]u32'
|
||||||
|
// :30:30: note: array of length 10 cannot cast into an array of length 5
|
||||||
|
// :35:30: error: expected type '*const [5]u32', found '*const [10:0]u32'
|
||||||
|
// :35:30: note: pointer type child '[10:0]u32' cannot cast into pointer type child '[5]u32'
|
||||||
|
// :35:30: note: array of length 10 cannot cast into an array of length 5
|
||||||
|
// :41:30: error: expected type '*const [5]u32', found '*const [10:0]u32'
|
||||||
|
// :41:30: note: pointer type child '[10:0]u32' cannot cast into pointer type child '[5]u32'
|
||||||
|
// :41:30: note: array of length 10 cannot cast into an array of length 5
|
||||||
Loading…
x
Reference in New Issue
Block a user