authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-27 16:03:51+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-01-30 15:20:16+02:00
loga9785fe8eef564011b4266e8a1b9aa15b7e37189
tree6f350d82c03043356608001c9a3bed2ae68fe59b
parentb129350cb5de2251d50b142a50d8d74ccd92ae73

Sema: add helpful notes to invalid `@ptrCast` operations

Closes #14474

3 files changed, 20 insertions(+), 1 deletions(-)

doc/langref.html.in+9
......@@ -8799,6 +8799,15 @@ pub const PrefetchOptions = struct {
87998799 {#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
88008800 to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.
88018801 </p>
8802 <p>
8803 {#syntax#}@ptrCast{#endsyntax#} cannot be used for:
8804 </p>
8805 <ul>
8806 <li>Removing {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier. TODO add a {#syntax#}@qualCast{#endsyntax#} builtin.</li>
8807 <li>Changing pointer address space, use {#link|@addrSpaceCast#}</li>
8808 <li>Increasing pointer alignment, use {#link|@alignCast#}</li>
8809 <li>Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}</li>
8810 </ul>
88028811 {#header_close#}
88038812
88048813 {#header_open|@ptrToInt#}
src/Sema.zig+10-1
......@@ -19535,7 +19535,14 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1953519535 return sema.fail(block, src, "cast discards volatile qualifier", .{});
1953619536 }
1953719537 if (operand_info.@"addrspace" != dest_info.@"addrspace") {
19538 return sema.fail(block, src, "cast changes pointer address space", .{});
19538 const msg = msg: {
19539 const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
19540 errdefer msg.destroy(sema.gpa);
19541
19542 try sema.errNote(block, src, msg, "consider using '@addrSpaceCast'", .{});
19543 break :msg msg;
19544 };
19545 return sema.failWithOwnedErrorMsg(msg);
1953919546 }
1954019547
1954119548 const dest_is_slice = dest_ty.isSlice();
......@@ -19590,6 +19597,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1959019597 try sema.errNote(block, dest_ty_src, msg, "'{}' has alignment '{d}'", .{
1959119598 dest_ty.fmt(sema.mod), dest_align,
1959219599 });
19600
19601 try sema.errNote(block, src, msg, "consider using '@alignCast'", .{});
1959319602 break :msg msg;
1959419603 };
1959519604 return sema.failWithOwnedErrorMsg(msg);
test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig+1
......@@ -11,3 +11,4 @@ export fn entry() u32 {
1111// :3:17: error: cast increases pointer alignment
1212// :3:32: note: '*u8' has alignment '1'
1313// :3:26: note: '*u32' has alignment '4'
14// :3:17: note: consider using '@alignCast'