master
1//! This file contains pointer coercions which are invalid because the element types are only
2//! in-memory coercible *in one direction*. When casting a mutable pointer, the element type
3//! must coerce in both directions for the pointer to coerce. Otherwise, you could do something
4//! like this, where `A` coerces to `B` but not vice-versa:
5//!
6//! ```
7//! var x: A = undefined;
8//! const p: *B = &x; // `*A` -> `*B`
9//! p.* = some_b;
10//! const some_b_as_a = x;
11//! ```
12
13export fn error_set_to_larger() void {
14 var x: error{Foo} = undefined;
15 _ = @as(*const error{ Foo, Bar }, &x); // this is ok
16 _ = @as(*error{ Foo, Bar }, &x); // compile error
17}
18
19export fn error_set_to_anyerror() void {
20 var x: error{Foo} = undefined;
21 _ = @as(*const anyerror, &x); // this is ok
22 _ = @as(*anyerror, &x); // compile error
23}
24
25export fn error_union_to_anyerror_union() void {
26 var x: error{Foo}!u32 = undefined;
27 _ = @as(*const anyerror!u32, &x); // this is ok
28 _ = @as(*anyerror!u32, &x); // compile error
29}
30
31export fn ptr_to_const_ptr() void {
32 var x: *u32 = undefined;
33 _ = @as(*const *const u32, &x); // this is ok
34 _ = @as(**const u32, &x); // compile error
35}
36
37export fn ptr_to_allowzero_ptr() void {
38 var x: *u32 = undefined;
39 _ = @as(*const *allowzero u32, &x); // this is ok
40 _ = @as(**allowzero u32, &x); // compile error
41}
42
43export fn ptr_to_volatile_ptr() void {
44 var x: *u32 = undefined;
45 _ = @as(*const *volatile u32, &x); // this is ok
46 _ = @as(**volatile u32, &x); // compile error
47}
48
49export fn ptr_to_underaligned_ptr() void {
50 var x: *u32 = undefined;
51 _ = @as(*const *align(1) u32, &x); // this is ok
52 _ = @as(**align(1) u32, &x); // compile error
53}
54
55// error
56//
57// :16:33: error: expected type '*error{Bar,Foo}', found '*error{Foo}'
58// :16:33: note: pointer type child 'error{Foo}' cannot cast into pointer type child 'error{Bar,Foo}'
59// :16:33: note: 'error.Bar' not a member of destination error set
60// :22:24: error: expected type '*anyerror', found '*error{Foo}'
61// :22:24: note: pointer type child 'error{Foo}' cannot cast into pointer type child 'anyerror'
62// :22:24: note: global error set cannot cast into a smaller set
63// :28:28: error: expected type '*anyerror!u32', found '*error{Foo}!u32'
64// :28:28: note: pointer type child 'error{Foo}!u32' cannot cast into pointer type child 'anyerror!u32'
65// :28:28: note: global error set cannot cast into a smaller set
66// :34:26: error: expected type '**const u32', found '**u32'
67// :34:26: note: pointer type child '*u32' cannot cast into pointer type child '*const u32'
68// :34:26: note: mutable '*const u32' would allow illegal const pointers stored to type '*u32'
69// :40:30: error: expected type '**allowzero u32', found '**u32'
70// :40:30: note: pointer type child '*u32' cannot cast into pointer type child '*allowzero u32'
71// :40:30: note: mutable '*allowzero u32' would allow illegal null values stored to type '*u32'
72// :46:29: error: expected type '**volatile u32', found '**u32'
73// :46:29: note: pointer type child '*u32' cannot cast into pointer type child '*volatile u32'
74// :46:29: note: mutable '*volatile u32' would allow illegal volatile pointers stored to type '*u32'
75// :52:29: error: expected type '**align(1) u32', found '**u32'
76// :52:29: note: pointer type child '*u32' cannot cast into pointer type child '*align(1) u32'
77// :52:29: note: pointer alignment '4' cannot cast into pointer alignment '1'