From a9785fe8eef564011b4266e8a1b9aa15b7e37189 Mon Sep 17 00:00:00 2001
From: Veikka Tuominen
Date: Fri, 27 Jan 2023 16:03:51 +0200
Subject: [PATCH] Sema: add helpful notes to invalid `@ptrCast` operations
Closes #14474
---
doc/langref.html.in | 9 +++++++++
src/Sema.zig | 11 ++++++++++-
.../increase_pointer_alignment_in_ptrCast.zig | 1 +
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/doc/langref.html.in b/doc/langref.html.in
index fd4aa8ae76..e1521795ca 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -8799,6 +8799,15 @@ pub const PrefetchOptions = struct {
{#link|Optional Pointers#} are allowed. Casting an optional pointer which is {#link|null#}
to a non-optional pointer invokes safety-checked {#link|Undefined Behavior#}.
+
+ {#syntax#}@ptrCast{#endsyntax#} cannot be used for:
+
+
+ - Removing {#syntax#}const{#endsyntax#} or {#syntax#}volatile{#endsyntax#} qualifier. TODO add a {#syntax#}@qualCast{#endsyntax#} builtin.
+ - Changing pointer address space, use {#link|@addrSpaceCast#}
+ - Increasing pointer alignment, use {#link|@alignCast#}
+ - Casting a non-slice pointer to a slice, use slicing syntax {#syntax#}ptr[start..end]{#endsyntax#}
+
{#header_close#}
{#header_open|@ptrToInt#}
diff --git a/src/Sema.zig b/src/Sema.zig
index 3b744a4f78..712a684bf8 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -19535,7 +19535,14 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
return sema.fail(block, src, "cast discards volatile qualifier", .{});
}
if (operand_info.@"addrspace" != dest_info.@"addrspace") {
- return sema.fail(block, src, "cast changes pointer address space", .{});
+ const msg = msg: {
+ const msg = try sema.errMsg(block, src, "cast changes pointer address space", .{});
+ errdefer msg.destroy(sema.gpa);
+
+ try sema.errNote(block, src, msg, "consider using '@addrSpaceCast'", .{});
+ break :msg msg;
+ };
+ return sema.failWithOwnedErrorMsg(msg);
}
const dest_is_slice = dest_ty.isSlice();
@@ -19590,6 +19597,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
try sema.errNote(block, dest_ty_src, msg, "'{}' has alignment '{d}'", .{
dest_ty.fmt(sema.mod), dest_align,
});
+
+ try sema.errNote(block, src, msg, "consider using '@alignCast'", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(msg);
diff --git a/test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig b/test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig
index 9cc5ed3a42..242454e859 100644
--- a/test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig
+++ b/test/cases/compile_errors/increase_pointer_alignment_in_ptrCast.zig
@@ -11,3 +11,4 @@ export fn entry() u32 {
// :3:17: error: cast increases pointer alignment
// :3:32: note: '*u8' has alignment '1'
// :3:26: note: '*u32' has alignment '4'
+// :3:17: note: consider using '@alignCast'