Skip to content

Commit 9f23243

Browse files
authoredJun 19, 2018
Merge pull request #1134 from ziglang/no-explicit-casting
remove "cast harder" casting syntax; add new casting builtins
·
0.15.20.3.0
2 parents 1ca90b5 + a3ddd08 commit 9f23243

24 files changed

+697
-222
lines changed
 

‎doc/langref.html.in‎

Lines changed: 122 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,8 +1456,7 @@ test "pointer array access" {
14561456
// Taking an address of an individual element gives a
14571457
// pointer to a single item. This kind of pointer
14581458
// does not support pointer arithmetic.
1459-
1460-
var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1459+
var array = []u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
14611460
const ptr = &array[2];
14621461
assert(@typeOf(ptr) == *u8);
14631462

@@ -1469,7 +1468,7 @@ test "pointer array access" {
14691468
test "pointer slicing" {
14701469
// In Zig, we prefer using slices over null-terminated pointers.
14711470
// You can turn an array into a slice using slice syntax:
1472-
var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1471+
var array = []u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
14731472
const slice = array[2..4];
14741473
assert(slice.len == 2);
14751474

@@ -1541,13 +1540,13 @@ test "pointer casting" {
15411540
// To convert one pointer type to another, use @ptrCast. This is an unsafe
15421541
// operation that Zig cannot protect you against. Use @ptrCast only when other
15431542
// conversions are not possible.
1544-
const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};
1543+
const bytes align(@alignOf(u32)) = []u8{ 0x12, 0x12, 0x12, 0x12 };
15451544
const u32_ptr = @ptrCast(*const u32, &bytes[0]);
15461545
assert(u32_ptr.* == 0x12121212);
15471546

15481547
// Even this example is contrived - there are better ways to do the above than
15491548
// pointer casting. For example, using a slice narrowing cast:
1550-
const u32_value = ([]const u32)(bytes[0..])[0];
1549+
const u32_value = @bytesToSlice(u32, bytes[0..])[0];
15511550
assert(u32_value == 0x12121212);
15521551

15531552
// And even another way, the most straightforward way to do it:
@@ -1630,13 +1629,13 @@ test "function alignment" {
16301629
const assert = @import("std").debug.assert;
16311630

16321631
test "pointer alignment safety" {
1633-
var array align(4) = []u32{0x11111111, 0x11111111};
1634-
const bytes = ([]u8)(array[0..]);
1632+
var array align(4) = []u32{ 0x11111111, 0x11111111 };
1633+
const bytes = @sliceToBytes(array[0..]);
16351634
assert(foo(bytes) == 0x11111111);
16361635
}
16371636
fn foo(bytes: []u8) u32 {
16381637
const slice4 = bytes[1..5];
1639-
const int_slice = ([]u32)(@alignCast(4, slice4));
1638+
const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
16401639
return int_slice[0];
16411640
}
16421641
{#code_end#}
@@ -1728,8 +1727,8 @@ test "slice pointer" {
17281727
test "slice widening" {
17291728
// Zig supports slice widening and slice narrowing. Cast a slice of u8
17301729
// to a slice of anything else, and Zig will perform the length conversion.
1731-
const array align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13};
1732-
const slice = ([]const u32)(array[0..]);
1730+
const array align(@alignOf(u32)) = []u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 };
1731+
const slice = @bytesToSlice(u32, array[0..]);
17331732
assert(slice.len == 2);
17341733
assert(slice[0] == 0x12121212);
17351734
assert(slice[1] == 0x13131313);
@@ -1901,9 +1900,9 @@ const Value = enum(u2) {
19011900
// Now you can cast between u2 and Value.
19021901
// The ordinal value starts from 0, counting up for each member.
19031902
test "enum ordinal value" {
1904-
assert(u2(Value.Zero) == 0);
1905-
assert(u2(Value.One) == 1);
1906-
assert(u2(Value.Two) == 2);
1903+
assert(@enumToInt(Value.Zero) == 0);
1904+
assert(@enumToInt(Value.One) == 1);
1905+
assert(@enumToInt(Value.Two) == 2);
19071906
}
19081907

19091908
// You can override the ordinal value for an enum.
@@ -1913,9 +1912,9 @@ const Value2 = enum(u32) {
19131912
Million = 1000000,
19141913
};
19151914
test "set enum ordinal value" {
1916-
assert(u32(Value2.Hundred) == 100);
1917-
assert(u32(Value2.Thousand) == 1000);
1918-
assert(u32(Value2.Million) == 1000000);
1915+
assert(@enumToInt(Value2.Hundred) == 100);
1916+
assert(@enumToInt(Value2.Thousand) == 1000);
1917+
assert(@enumToInt(Value2.Million) == 1000000);
19191918
}
19201919

19211920
// Enums can have methods, the same as structs and unions.
@@ -4651,6 +4650,18 @@ comptime {
46514650
</p>
46524651
{#header_close#}
46534652

4653+
{#header_open|@bytesToSlice#}
4654+
<pre><code class="zig">@bytesToSlice(comptime Element: type, bytes: []u8) []Element</code></pre>
4655+
<p>
4656+
Converts a slice of bytes or array of bytes into a slice of <code>Element</code>.
4657+
The resulting slice has the same {#link|pointer|Pointers#} properties as the parameter.
4658+
</p>
4659+
<p>
4660+
Attempting to convert a number of bytes with a length that does not evenly divide into a slice of
4661+
elements results in safety-protected {#link|Undefined Behavior#}.
4662+
</p>
4663+
{#header_close#}
4664+
46544665
{#header_open|@cDefine#}
46554666
<pre><code class="zig">@cDefine(comptime name: []u8, value)</code></pre>
46564667
<p>
@@ -4919,12 +4930,23 @@ test "main" {
49194930
</p>
49204931
{#see_also|@import#}
49214932
{#header_close#}
4922-
{#header_open|@export#}
4923-
<pre><code class="zig">@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8</code></pre>
4933+
4934+
{#header_open|@enumToInt#}
4935+
<pre><code class="zig">@enumToInt(enum_value: var) var</code></pre>
49244936
<p>
4925-
Creates a symbol in the output object file.
4937+
Converts an enumeration value into its integer tag type.
4938+
</p>
4939+
{#see_also|@intToEnum#}
4940+
{#header_close#}
4941+
4942+
{#header_open|@errSetCast#}
4943+
<pre><code class="zig">@errSetCast(comptime T: DestType, value: var) DestType</code></pre>
4944+
<p>
4945+
Converts an error value from one error set to another error set. Attempting to convert an error
4946+
which is not in the destination error set results in safety-protected {#link|Undefined Behavior#}.
49264947
</p>
49274948
{#header_close#}
4949+
49284950
{#header_open|@errorName#}
49294951
<pre><code class="zig">@errorName(err: error) []u8</code></pre>
49304952
<p>
@@ -4941,6 +4963,7 @@ test "main" {
49414963
error name table will be generated.
49424964
</p>
49434965
{#header_close#}
4966+
49444967
{#header_open|@errorReturnTrace#}
49454968
<pre><code class="zig">@errorReturnTrace() ?*builtin.StackTrace</code></pre>
49464969
<p>
@@ -4949,6 +4972,33 @@ test "main" {
49494972
stack trace object. Otherwise returns `null`.
49504973
</p>
49514974
{#header_close#}
4975+
4976+
{#header_open|@errorToInt#}
4977+
<pre><code class="zig">@errorToInt(err: var) @IntType(false, @sizeOf(error) * 8)</code></pre>
4978+
<p>
4979+
Supports the following types:
4980+
</p>
4981+
<ul>
4982+
<li>error unions</li>
4983+
<li><code>E!void</code></li>
4984+
</ul>
4985+
<p>
4986+
Converts an error to the integer representation of an error.
4987+
</p>
4988+
<p>
4989+
It is generally recommended to avoid this
4990+
cast, as the integer representation of an error is not stable across source code changes.
4991+
</p>
4992+
{#see_also|@intToError#}
4993+
{#header_close#}
4994+
4995+
{#header_open|@export#}
4996+
<pre><code class="zig">@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) []const u8</code></pre>
4997+
<p>
4998+
Creates a symbol in the output object file.
4999+
</p>
5000+
{#header_close#}
5001+
49525002
{#header_open|@fence#}
49535003
<pre><code class="zig">@fence(order: AtomicOrder)</code></pre>
49545004
<p>
@@ -5049,8 +5099,36 @@ fn add(a: i32, b: i32) i32 { return a + b; }
50495099
<p>
50505100
Converts an integer to another integer while keeping the same numerical value.
50515101
Attempting to convert a number which is out of range of the destination type results in
5052-
{#link|Undefined Behavior#}.
5102+
safety-protected {#link|Undefined Behavior#}.
5103+
</p>
5104+
{#header_close#}
5105+
5106+
{#header_open|@intToEnum#}
5107+
<pre><code class="zig">@intToEnum(comptime DestType: type, int_value: @TagType(DestType)) DestType</code></pre>
5108+
<p>
5109+
Converts an integer into an {#link|enum#} value.
5110+
</p>
5111+
<p>
5112+
Attempting to convert an integer which represents no value in the chosen enum type invokes
5113+
safety-checked {#link|Undefined Behavior#}.
5114+
</p>
5115+
{#see_also|@enumToInt#}
5116+
{#header_close#}
5117+
5118+
{#header_open|@intToError#}
5119+
<pre><code class="zig">@intToError(value: @IntType(false, @sizeOf(error) * 8)) error</code></pre>
5120+
<p>
5121+
Converts from the integer representation of an error into the global error set type.
50535122
</p>
5123+
<p>
5124+
It is generally recommended to avoid this
5125+
cast, as the integer representation of an error is not stable across source code changes.
5126+
</p>
5127+
<p>
5128+
Attempting to convert an integer that does not correspond to any error results in
5129+
safety-protected {#link|Undefined Behavior#}.
5130+
</p>
5131+
{#see_also|@errorToInt#}
50545132
{#header_close#}
50555133

50565134
{#header_open|@intToFloat#}
@@ -5456,15 +5534,25 @@ pub const FloatMode = enum {
54565534
</p>
54575535
{#see_also|@shlExact|@shlWithOverflow#}
54585536
{#header_close#}
5537+
54595538
{#header_open|@sizeOf#}
5460-
<pre><code class="zig">@sizeOf(comptime T: type) (number literal)</code></pre>
5539+
<pre><code class="zig">@sizeOf(comptime T: type) comptime_int</code></pre>
54615540
<p>
54625541
This function returns the number of bytes it takes to store <code>T</code> in memory.
54635542
</p>
54645543
<p>
54655544
The result is a target-specific compile time constant.
54665545
</p>
54675546
{#header_close#}
5547+
5548+
{#header_open|@sliceToBytes#}
5549+
<pre><code class="zig">@sliceToBytes(value: var) []u8</code></pre>
5550+
<p>
5551+
Converts a slice or array to a slice of <code>u8</code>. The resulting slice has the same
5552+
{#link|pointer|Pointers#} properties as the parameter.
5553+
</p>
5554+
{#header_close#}
5555+
54685556
{#header_open|@sqrt#}
54695557
<pre><code class="zig">@sqrt(comptime T: type, value: T) T</code></pre>
54705558
<p>
@@ -5817,10 +5905,10 @@ pub fn build(b: &Builder) void {
58175905
{#header_open|Undefined Behavior#}
58185906
<p>
58195907
Zig has many instances of undefined behavior. If undefined behavior is
5820-
detected at compile-time, Zig emits an error. Most undefined behavior that
5821-
cannot be detected at compile-time can be detected at runtime. In these cases,
5822-
Zig has safety checks. Safety checks can be disabled on a per-block basis
5823-
with {#link|setRuntimeSafety#}. The {#link|ReleaseFast#}
5908+
detected at compile-time, Zig emits a compile error and refuses to continue.
5909+
Most undefined behavior that cannot be detected at compile-time can be detected
5910+
at runtime. In these cases, Zig has safety checks. Safety checks can be disabled
5911+
on a per-block basis with {#link|setRuntimeSafety#}. The {#link|ReleaseFast#}
58245912
build mode disables all safety checks in order to facilitate optimizations.
58255913
</p>
58265914
<p>
@@ -6091,8 +6179,8 @@ fn getNumberOrFail() !i32 {
60916179
{#code_begin|test_err|integer value 11 represents no error#}
60926180
comptime {
60936181
const err = error.AnError;
6094-
const number = u32(err) + 10;
6095-
const invalid_err = error(number);
6182+
const number = @errorToInt(err) + 10;
6183+
const invalid_err = @intToError(number);
60966184
}
60976185
{#code_end#}
60986186
<p>At runtime crashes with the message <code>invalid error code</code> and a stack trace.</p>
@@ -6101,6 +6189,11 @@ comptime {
61016189
<p>TODO</p>
61026190

61036191
{#header_close#}
6192+
6193+
{#header_open|Invalid Error Set Cast#}
6194+
<p>TODO</p>
6195+
{#header_close#}
6196+
61046197
{#header_open|Incorrect Pointer Alignment#}
61056198
<p>TODO</p>
61066199

@@ -6109,6 +6202,7 @@ comptime {
61096202
<p>TODO</p>
61106203

61116204
{#header_close#}
6205+
61126206
{#header_close#}
61136207
{#header_open|Memory#}
61146208
<p>TODO: explain no default allocator in zig</p>
@@ -6793,7 +6887,7 @@ hljs.registerLanguage("zig", function(t) {
67936887
a = t.IR + "\\s*\\(",
67946888
c = {
67956889
keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong resume cancel await async orelse",
6796-
built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall",
6890+
built_in: "atomicLoad breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic ptrCast intCast floatCast intToFloat floatToInt boolToInt bytesToSlice sliceToBytes errSetCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount memberName memberType typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchgStrong cmpxchgWeak fence divExact truncate atomicRmw sqrt field typeInfo typeName newStackCall errorToInt intToError enumToInt intToEnum",
67976891
literal: "true false null undefined"
67986892
},
67996893
n = [e, t.CLCM, t.CBCM, s, r];

‎src/all_types.hpp‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,16 @@ enum RuntimeHintPtr {
234234
RuntimeHintPtrNonStack,
235235
};
236236

237+
enum RuntimeHintSliceId {
238+
RuntimeHintSliceIdUnknown,
239+
RuntimeHintSliceIdLen,
240+
};
241+
242+
struct RuntimeHintSlice {
243+
enum RuntimeHintSliceId id;
244+
uint64_t len;
245+
};
246+
237247
struct ConstGlobalRefs {
238248
LLVMValueRef llvm_value;
239249
LLVMValueRef llvm_global;
@@ -270,6 +280,7 @@ struct ConstExprValue {
270280
RuntimeHintErrorUnion rh_error_union;
271281
RuntimeHintOptional rh_maybe;
272282
RuntimeHintPtr rh_ptr;
283+
RuntimeHintSlice rh_slice;
273284
} data;
274285
};
275286

@@ -1359,9 +1370,16 @@ enum BuiltinFnId {
13591370
BuiltinFnIdTruncate,
13601371
BuiltinFnIdIntCast,
13611372
BuiltinFnIdFloatCast,
1373+
BuiltinFnIdErrSetCast,
1374+
BuiltinFnIdToBytes,
1375+
BuiltinFnIdFromBytes,
13621376
BuiltinFnIdIntToFloat,
13631377
BuiltinFnIdFloatToInt,
13641378
BuiltinFnIdBoolToInt,
1379+
BuiltinFnIdErrToInt,
1380+
BuiltinFnIdIntToErr,
1381+
BuiltinFnIdEnumToInt,
1382+
BuiltinFnIdIntToEnum,
13651383
BuiltinFnIdIntType,
13661384
BuiltinFnIdSetCold,
13671385
BuiltinFnIdSetRuntimeSafety,
@@ -2076,6 +2094,7 @@ enum IrInstructionId {
20762094
IrInstructionIdIntToPtr,
20772095
IrInstructionIdPtrToInt,
20782096
IrInstructionIdIntToEnum,
2097+
IrInstructionIdEnumToInt,
20792098
IrInstructionIdIntToErr,
20802099
IrInstructionIdErrToInt,
20812100
IrInstructionIdCheckSwitchProngs,
@@ -2121,6 +2140,9 @@ enum IrInstructionId {
21212140
IrInstructionIdMergeErrRetTraces,
21222141
IrInstructionIdMarkErrRetTracePtr,
21232142
IrInstructionIdSqrt,
2143+
IrInstructionIdErrSetCast,
2144+
IrInstructionIdToBytes,
2145+
IrInstructionIdFromBytes,
21242146
};
21252147

21262148
struct IrInstruction {
@@ -2656,6 +2678,26 @@ struct IrInstructionFloatCast {
26562678
IrInstruction *target;
26572679
};
26582680

2681+
struct IrInstructionErrSetCast {
2682+
IrInstruction base;
2683+
2684+
IrInstruction *dest_type;
2685+
IrInstruction *target;
2686+
};
2687+
2688+
struct IrInstructionToBytes {
2689+
IrInstruction base;
2690+
2691+
IrInstruction *target;
2692+
};
2693+
2694+
struct IrInstructionFromBytes {
2695+
IrInstruction base;
2696+
2697+
IrInstruction *dest_child_type;
2698+
IrInstruction *target;
2699+
};
2700+
26592701
struct IrInstructionIntToFloat {
26602702
IrInstruction base;
26612703

@@ -2866,6 +2908,13 @@ struct IrInstructionIntToPtr {
28662908
struct IrInstructionIntToEnum {
28672909
IrInstruction base;
28682910

2911+
IrInstruction *dest_type;
2912+
IrInstruction *target;
2913+
};
2914+
2915+
struct IrInstructionEnumToInt {
2916+
IrInstruction base;
2917+
28692918
IrInstruction *target;
28702919
};
28712920

‎src/codegen.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4727,6 +4727,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
47274727
case IrInstructionIdIntToFloat:
47284728
case IrInstructionIdFloatToInt:
47294729
case IrInstructionIdBoolToInt:
4730+
case IrInstructionIdErrSetCast:
4731+
case IrInstructionIdFromBytes:
4732+
case IrInstructionIdToBytes:
4733+
case IrInstructionIdEnumToInt:
47304734
zig_unreachable();
47314735

47324736
case IrInstructionIdReturn:
@@ -6320,6 +6324,10 @@ static void define_builtin_fns(CodeGen *g) {
63206324
create_builtin_fn(g, BuiltinFnIdIntToFloat, "intToFloat", 2);
63216325
create_builtin_fn(g, BuiltinFnIdFloatToInt, "floatToInt", 2);
63226326
create_builtin_fn(g, BuiltinFnIdBoolToInt, "boolToInt", 1);
6327+
create_builtin_fn(g, BuiltinFnIdErrToInt, "errorToInt", 1);
6328+
create_builtin_fn(g, BuiltinFnIdIntToErr, "intToError", 1);
6329+
create_builtin_fn(g, BuiltinFnIdEnumToInt, "enumToInt", 1);
6330+
create_builtin_fn(g, BuiltinFnIdIntToEnum, "intToEnum", 2);
63236331
create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
63246332
create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
63256333
create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
@@ -6356,6 +6364,9 @@ static void define_builtin_fns(CodeGen *g) {
63566364
create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);
63576365
create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);
63586366
create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
6367+
create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
6368+
create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
6369+
create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
63596370
}
63606371

63616372
static const char *bool_to_str(bool b) {

‎src/ir.cpp‎

Lines changed: 389 additions & 90 deletions
Large diffs are not rendered by default.

‎src/ir_print.cpp‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,28 @@ static void ir_print_float_cast(IrPrint *irp, IrInstructionFloatCast *instructio
664664
fprintf(irp->f, ")");
665665
}
666666

667+
static void ir_print_err_set_cast(IrPrint *irp, IrInstructionErrSetCast *instruction) {
668+
fprintf(irp->f, "@errSetCast(");
669+
ir_print_other_instruction(irp, instruction->dest_type);
670+
fprintf(irp->f, ", ");
671+
ir_print_other_instruction(irp, instruction->target);
672+
fprintf(irp->f, ")");
673+
}
674+
675+
static void ir_print_from_bytes(IrPrint *irp, IrInstructionFromBytes *instruction) {
676+
fprintf(irp->f, "@bytesToSlice(");
677+
ir_print_other_instruction(irp, instruction->dest_child_type);
678+
fprintf(irp->f, ", ");
679+
ir_print_other_instruction(irp, instruction->target);
680+
fprintf(irp->f, ")");
681+
}
682+
683+
static void ir_print_to_bytes(IrPrint *irp, IrInstructionToBytes *instruction) {
684+
fprintf(irp->f, "@sliceToBytes(");
685+
ir_print_other_instruction(irp, instruction->target);
686+
fprintf(irp->f, ")");
687+
}
688+
667689
static void ir_print_int_to_float(IrPrint *irp, IrInstructionIntToFloat *instruction) {
668690
fprintf(irp->f, "@intToFloat(");
669691
ir_print_other_instruction(irp, instruction->dest_type);
@@ -906,6 +928,17 @@ static void ir_print_int_to_ptr(IrPrint *irp, IrInstructionIntToPtr *instruction
906928

907929
static void ir_print_int_to_enum(IrPrint *irp, IrInstructionIntToEnum *instruction) {
908930
fprintf(irp->f, "@intToEnum(");
931+
if (instruction->dest_type == nullptr) {
932+
fprintf(irp->f, "(null)");
933+
} else {
934+
ir_print_other_instruction(irp, instruction->dest_type);
935+
}
936+
ir_print_other_instruction(irp, instruction->target);
937+
fprintf(irp->f, ")");
938+
}
939+
940+
static void ir_print_enum_to_int(IrPrint *irp, IrInstructionEnumToInt *instruction) {
941+
fprintf(irp->f, "@enumToInt(");
909942
ir_print_other_instruction(irp, instruction->target);
910943
fprintf(irp->f, ")");
911944
}
@@ -1461,6 +1494,15 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
14611494
case IrInstructionIdFloatCast:
14621495
ir_print_float_cast(irp, (IrInstructionFloatCast *)instruction);
14631496
break;
1497+
case IrInstructionIdErrSetCast:
1498+
ir_print_err_set_cast(irp, (IrInstructionErrSetCast *)instruction);
1499+
break;
1500+
case IrInstructionIdFromBytes:
1501+
ir_print_from_bytes(irp, (IrInstructionFromBytes *)instruction);
1502+
break;
1503+
case IrInstructionIdToBytes:
1504+
ir_print_to_bytes(irp, (IrInstructionToBytes *)instruction);
1505+
break;
14641506
case IrInstructionIdIntToFloat:
14651507
ir_print_int_to_float(irp, (IrInstructionIntToFloat *)instruction);
14661508
break;
@@ -1686,6 +1728,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
16861728
case IrInstructionIdAtomicLoad:
16871729
ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
16881730
break;
1731+
case IrInstructionIdEnumToInt:
1732+
ir_print_enum_to_int(irp, (IrInstructionEnumToInt *)instruction);
1733+
break;
16891734
}
16901735
fprintf(irp->f, "\n");
16911736
}

‎std/cstr.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub const NullTerminated2DArray = struct {
7979
errdefer allocator.free(buf);
8080

8181
var write_index = index_size;
82-
const index_buf = ([]?[*]u8)(buf);
82+
const index_buf = @bytesToSlice(?[*]u8, buf);
8383

8484
var i: usize = 0;
8585
for (slices) |slice| {

‎std/heap.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ pub const ArenaAllocator = struct {
221221
if (len >= actual_min_size) break;
222222
}
223223
const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
224-
const buf_node_slice = ([]BufNode)(buf[0..@sizeOf(BufNode)]);
224+
const buf_node_slice = @bytesToSlice(BufNode, buf[0..@sizeOf(BufNode)]);
225225
const buf_node = &buf_node_slice[0];
226226
buf_node.* = BufNode{
227227
.data = buf,

‎std/json.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ pub const StreamingParser = struct {
180180
pub fn fromInt(x: var) State {
181181
debug.assert(x == 0 or x == 1);
182182
const T = @TagType(State);
183-
return State(@intCast(T, x));
183+
return @intToEnum(State, @intCast(T, x));
184184
}
185185
};
186186

‎std/macho.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ pub fn loadSymbols(allocator: *mem.Allocator, in: *io.FileInStream) !SymbolTable
161161
}
162162

163163
fn readNoEof(in: *io.FileInStream, comptime T: type, result: []T) !void {
164-
return in.stream.readNoEof(([]u8)(result));
164+
return in.stream.readNoEof(@sliceToBytes(result));
165165
}
166166
fn readOneNoEof(in: *io.FileInStream, comptime T: type, result: *T) !void {
167167
return readNoEof(in, T, (*[1]T)(result)[0..]);

‎std/mem.zig‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub const Allocator = struct {
7070
for (byte_slice) |*byte| {
7171
byte.* = undefined;
7272
}
73-
return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
73+
return @bytesToSlice(T, @alignCast(alignment, byte_slice));
7474
}
7575

7676
pub fn realloc(self: *Allocator, comptime T: type, old_mem: []T, n: usize) ![]T {
@@ -86,7 +86,7 @@ pub const Allocator = struct {
8686
return ([*]align(alignment) T)(undefined)[0..0];
8787
}
8888

89-
const old_byte_slice = ([]u8)(old_mem);
89+
const old_byte_slice = @sliceToBytes(old_mem);
9090
const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
9191
const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment);
9292
assert(byte_slice.len == byte_count);
@@ -96,7 +96,7 @@ pub const Allocator = struct {
9696
byte.* = undefined;
9797
}
9898
}
99-
return ([]T)(@alignCast(alignment, byte_slice));
99+
return @bytesToSlice(T, @alignCast(alignment, byte_slice));
100100
}
101101

102102
/// Reallocate, but `n` must be less than or equal to `old_mem.len`.
@@ -118,13 +118,13 @@ pub const Allocator = struct {
118118
// n <= old_mem.len and the multiplication didn't overflow for that operation.
119119
const byte_count = @sizeOf(T) * n;
120120

121-
const byte_slice = self.reallocFn(self, ([]u8)(old_mem), byte_count, alignment) catch unreachable;
121+
const byte_slice = self.reallocFn(self, @sliceToBytes(old_mem), byte_count, alignment) catch unreachable;
122122
assert(byte_slice.len == byte_count);
123-
return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
123+
return @bytesToSlice(T, @alignCast(alignment, byte_slice));
124124
}
125125

126126
pub fn free(self: *Allocator, memory: var) void {
127-
const bytes = ([]const u8)(memory);
127+
const bytes = @sliceToBytes(memory);
128128
if (bytes.len == 0) return;
129129
const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
130130
self.freeFn(self, non_const_ptr[0..bytes.len]);

‎std/net.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ pub const Address = struct {
6868

6969
pub fn parseIp4(buf: []const u8) !u32 {
7070
var result: u32 = undefined;
71-
const out_ptr = ([]u8)((*[1]u32)(&result)[0..]);
71+
const out_ptr = @sliceToBytes((*[1]u32)(&result)[0..]);
7272

7373
var x: u8 = 0;
7474
var index: u8 = 0;

‎std/os/child_process.zig‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ pub const ChildProcess = struct {
318318
// Here we potentially return the fork child's error
319319
// from the parent pid.
320320
if (err_int != @maxValue(ErrInt)) {
321-
return SpawnError(err_int);
321+
return @errSetCast(SpawnError, @intToError(err_int));
322322
}
323323

324324
return statusToTerm(status);
@@ -756,7 +756,7 @@ fn destroyPipe(pipe: *const [2]i32) void {
756756
// Child of fork calls this to report an error to the fork parent.
757757
// Then the child exits.
758758
fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
759-
_ = writeIntFd(fd, ErrInt(err));
759+
_ = writeIntFd(fd, ErrInt(@errorToInt(err)));
760760
posix.exit(1);
761761
}
762762

‎std/os/index.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1805,7 +1805,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
18051805
const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
18061806
errdefer allocator.free(buf);
18071807

1808-
const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]);
1808+
const result_slice_list = @bytesToSlice([]u8, buf[0..slice_list_bytes]);
18091809
const result_contents = buf[slice_list_bytes..];
18101810
mem.copy(u8, result_contents, contents_slice);
18111811

‎std/os/windows/util.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
7979

8080
const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);
8181
const name_bytes = name_info_bytes[size .. size + usize(name_info.FileNameLength)];
82-
const name_wide = ([]u16)(name_bytes);
82+
const name_wide = @bytesToSlice(u16, name_bytes);
8383
return mem.indexOf(u16, name_wide, []u16{ 'm', 's', 'y', 's', '-' }) != null or
8484
mem.indexOf(u16, name_wide, []u16{ '-', 'p', 't', 'y' }) != null;
8585
}

‎test/cases/align.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn testBytesAlignSlice(b: u8) void {
9090
b,
9191
b,
9292
};
93-
const slice = ([]u32)(bytes[0..]);
93+
const slice: []u32 = @bytesToSlice(u32, bytes[0..]);
9494
assert(slice[0] == 0x33333333);
9595
}
9696

‎test/cases/cast.zig‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ test "explicit cast from integer to error type" {
140140
comptime testCastIntToErr(error.ItBroke);
141141
}
142142
fn testCastIntToErr(err: error) void {
143-
const x = usize(err);
144-
const y = error(x);
143+
const x = @errorToInt(err);
144+
const y = @intToError(x);
145145
assert(error.ItBroke == y);
146146
}
147147

@@ -372,7 +372,7 @@ test "const slice widen cast" {
372372
0x12,
373373
};
374374

375-
const u32_value = ([]const u32)(bytes[0..])[0];
375+
const u32_value = @bytesToSlice(u32, bytes[0..])[0];
376376
assert(u32_value == 0x12121212);
377377

378378
assert(@bitCast(u32, bytes) == 0x12121212);
@@ -420,3 +420,9 @@ test "comptime_int @intToFloat" {
420420
assert(@typeOf(result) == f32);
421421
assert(result == 1234.0);
422422
}
423+
424+
test "@bytesToSlice keeps pointer alignment" {
425+
var bytes = []u8{ 0x01, 0x02, 0x03, 0x04 };
426+
const numbers = @bytesToSlice(u32, bytes[0..]);
427+
comptime assert(@typeOf(numbers) == []align(@alignOf(@typeOf(bytes))) u32);
428+
}

‎test/cases/enum.zig‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,14 @@ test "enum to int" {
9292
}
9393

9494
fn shouldEqual(n: Number, expected: u3) void {
95-
assert(u3(n) == expected);
95+
assert(@enumToInt(n) == expected);
9696
}
9797

9898
test "int to enum" {
9999
testIntToEnumEval(3);
100100
}
101101
fn testIntToEnumEval(x: i32) void {
102-
assert(IntToEnumNumber(@intCast(u3, x)) == IntToEnumNumber.Three);
102+
assert(@intToEnum(IntToEnumNumber, @intCast(u3, x)) == IntToEnumNumber.Three);
103103
}
104104
const IntToEnumNumber = enum {
105105
Zero,
@@ -768,7 +768,7 @@ test "casting enum to its tag type" {
768768
}
769769

770770
fn testCastEnumToTagType(value: Small2) void {
771-
assert(u2(value) == 1);
771+
assert(@enumToInt(value) == 1);
772772
}
773773

774774
const MultipleChoice = enum(u32) {
@@ -784,7 +784,7 @@ test "enum with specified tag values" {
784784
}
785785

786786
fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {
787-
assert(u32(x) == 60);
787+
assert(@enumToInt(x) == 60);
788788
assert(1234 == switch (x) {
789789
MultipleChoice.A => 1,
790790
MultipleChoice.B => 2,
@@ -811,7 +811,7 @@ test "enum with specified and unspecified tag values" {
811811
}
812812

813813
fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
814-
assert(u32(x) == 1000);
814+
assert(@enumToInt(x) == 1000);
815815
assert(1234 == switch (x) {
816816
MultipleChoice2.A => 1,
817817
MultipleChoice2.B => 2,
@@ -826,8 +826,8 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
826826
}
827827

828828
test "cast integer literal to enum" {
829-
assert(MultipleChoice2(0) == MultipleChoice2.Unspecified1);
830-
assert(MultipleChoice2(40) == MultipleChoice2.B);
829+
assert(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1);
830+
assert(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B);
831831
}
832832

833833
const EnumWithOneMember = enum {
@@ -865,7 +865,7 @@ const EnumWithTagValues = enum(u4) {
865865
D = 1 << 3,
866866
};
867867
test "enum with tag values don't require parens" {
868-
assert(u4(EnumWithTagValues.C) == 0b0100);
868+
assert(@enumToInt(EnumWithTagValues.C) == 0b0100);
869869
}
870870

871871
test "enum with 1 field but explicit tag type should still have the tag type" {

‎test/cases/error.zig‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ test "@errorName" {
3131
}
3232

3333
test "error values" {
34-
const a = i32(error.err1);
35-
const b = i32(error.err2);
34+
const a = @errorToInt(error.err1);
35+
const b = @errorToInt(error.err2);
3636
assert(a != b);
3737
}
3838

@@ -124,8 +124,8 @@ const Set2 = error{
124124
};
125125

126126
fn testExplicitErrorSetCast(set1: Set1) void {
127-
var x = Set2(set1);
128-
var y = Set1(x);
127+
var x = @errSetCast(Set2, set1);
128+
var y = @errSetCast(Set1, x);
129129
assert(y == error.A);
130130
}
131131

@@ -147,14 +147,14 @@ test "syntax: optional operator in front of error union operator" {
147147
}
148148

149149
test "comptime err to int of error set with only 1 possible value" {
150-
testErrToIntWithOnePossibleValue(error.A, u32(error.A));
151-
comptime testErrToIntWithOnePossibleValue(error.A, u32(error.A));
150+
testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
151+
comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
152152
}
153153
fn testErrToIntWithOnePossibleValue(
154154
x: error{A},
155155
comptime value: u32,
156156
) void {
157-
if (u32(x) != value) {
157+
if (@errorToInt(x) != value) {
158158
@compileError("bad");
159159
}
160160
}

‎test/cases/misc.zig‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,14 +422,14 @@ test "cast slice to u8 slice" {
422422
4,
423423
};
424424
const big_thing_slice: []i32 = big_thing_array[0..];
425-
const bytes = ([]u8)(big_thing_slice);
425+
const bytes = @sliceToBytes(big_thing_slice);
426426
assert(bytes.len == 4 * 4);
427427
bytes[4] = 0;
428428
bytes[5] = 0;
429429
bytes[6] = 0;
430430
bytes[7] = 0;
431431
assert(big_thing_slice[1] == 0);
432-
const big_thing_again = ([]align(1) i32)(bytes);
432+
const big_thing_again = @bytesToSlice(i32, bytes);
433433
assert(big_thing_again[2] == 3);
434434
big_thing_again[2] = -1;
435435
assert(bytes[8] == @maxValue(u8));

‎test/cases/struct.zig‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ test "packed array 24bits" {
302302

303303
var bytes = []u8{0} ** (@sizeOf(FooArray24Bits) + 1);
304304
bytes[bytes.len - 1] = 0xaa;
305-
const ptr = &([]FooArray24Bits)(bytes[0 .. bytes.len - 1])[0];
305+
const ptr = &@bytesToSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
306306
assert(ptr.a == 0);
307307
assert(ptr.b[0].field == 0);
308308
assert(ptr.b[1].field == 0);
@@ -351,7 +351,7 @@ test "aligned array of packed struct" {
351351
}
352352

353353
var bytes = []u8{0xbb} ** @sizeOf(FooArrayOfAligned);
354-
const ptr = &([]FooArrayOfAligned)(bytes[0..bytes.len])[0];
354+
const ptr = &@bytesToSlice(FooArrayOfAligned, bytes[0..bytes.len])[0];
355355

356356
assert(ptr.a[0].a == 0xbb);
357357
assert(ptr.a[0].b == 0xbb);

‎test/cases/type_info.zig‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ fn testErrorSet() void {
130130
assert(TypeId(error_set_info) == TypeId.ErrorSet);
131131
assert(error_set_info.ErrorSet.errors.len == 3);
132132
assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));
133-
assert(error_set_info.ErrorSet.errors[2].value == usize(TestErrorSet.Third));
133+
assert(error_set_info.ErrorSet.errors[2].value == @errorToInt(TestErrorSet.Third));
134134

135135
const error_union_info = @typeInfo(TestErrorSet!usize);
136136
assert(TypeId(error_union_info) == TypeId.ErrorUnion);

‎test/cases/union.zig‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ const MultipleChoice = union(enum(u32)) {
126126
test "simple union(enum(u32))" {
127127
var x = MultipleChoice.C;
128128
assert(x == MultipleChoice.C);
129-
assert(u32(@TagType(MultipleChoice)(x)) == 60);
129+
assert(@enumToInt(@TagType(MultipleChoice)(x)) == 60);
130130
}
131131

132132
const MultipleChoice2 = union(enum(u32)) {
@@ -148,7 +148,7 @@ test "union(enum(u32)) with specified and unspecified tag values" {
148148
}
149149

150150
fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: *const MultipleChoice2) void {
151-
assert(u32(@TagType(MultipleChoice2)(x.*)) == 60);
151+
assert(@enumToInt(@TagType(MultipleChoice2)(x.*)) == 60);
152152
assert(1123 == switch (x.*) {
153153
MultipleChoice2.A => 1,
154154
MultipleChoice2.B => 2,

‎test/compile_errors.zig‎

Lines changed: 27 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
404404
\\const Set2 = error {A, C};
405405
\\comptime {
406406
\\ var x = Set1.B;
407-
\\ var y = Set2(x);
407+
\\ var y = @errSetCast(Set2, x);
408408
\\}
409409
,
410-
".tmp_source.zig:5:17: error: error.B not a member of error set 'Set2'",
410+
".tmp_source.zig:5:13: error: error.B not a member of error set 'Set2'",
411411
);
412412

413413
cases.add(
@@ -467,25 +467,34 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
467467

468468
cases.add(
469469
"int to err global invalid number",
470-
\\const Set1 = error{A, B};
470+
\\const Set1 = error{
471+
\\ A,
472+
\\ B,
473+
\\};
471474
\\comptime {
472-
\\ var x: usize = 3;
473-
\\ var y = error(x);
475+
\\ var x: u16 = 3;
476+
\\ var y = @intToError(x);
474477
\\}
475478
,
476-
".tmp_source.zig:4:18: error: integer value 3 represents no error",
479+
".tmp_source.zig:7:13: error: integer value 3 represents no error",
477480
);
478481

479482
cases.add(
480483
"int to err non global invalid number",
481-
\\const Set1 = error{A, B};
482-
\\const Set2 = error{A, C};
484+
\\const Set1 = error{
485+
\\ A,
486+
\\ B,
487+
\\};
488+
\\const Set2 = error{
489+
\\ A,
490+
\\ C,
491+
\\};
483492
\\comptime {
484-
\\ var x = usize(Set1.B);
485-
\\ var y = Set2(x);
493+
\\ var x = @errorToInt(Set1.B);
494+
\\ var y = @errSetCast(Set2, @intToError(x));
486495
\\}
487496
,
488-
".tmp_source.zig:5:17: error: integer value 2 represents no error in 'Set2'",
497+
".tmp_source.zig:11:13: error: error.B not a member of error set 'Set2'",
489498
);
490499

491500
cases.add(
@@ -2086,10 +2095,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
20862095
"convert fixed size array to slice with invalid size",
20872096
\\export fn f() void {
20882097
\\ var array: [5]u8 = undefined;
2089-
\\ var foo = ([]const u32)(array)[0];
2098+
\\ var foo = @bytesToSlice(u32, array)[0];
20902099
\\}
20912100
,
2092-
".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch",
2101+
".tmp_source.zig:3:15: error: unable to convert [5]u8 to []align(1) const u32: size mismatch",
2102+
".tmp_source.zig:3:29: note: u32 has size 4; remaining bytes: 1",
20932103
);
20942104

20952105
cases.add(
@@ -2611,17 +2621,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
26112621
".tmp_source.zig:2:21: error: expected pointer, found 'usize'",
26122622
);
26132623

2614-
cases.add(
2615-
"too many error values to cast to small integer",
2616-
\\const Error = error { A, B, C, D, E, F, G, H };
2617-
\\fn foo(e: Error) u2 {
2618-
\\ return u2(e);
2619-
\\}
2620-
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
2621-
,
2622-
".tmp_source.zig:3:14: error: too many error values to fit in 'u2'",
2623-
);
2624-
26252624
cases.add(
26262625
"asm at compile time",
26272626
\\comptime {
@@ -3239,18 +3238,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
32393238
".tmp_source.zig:3:26: note: '*u32' has alignment 4",
32403239
);
32413240

3242-
cases.add(
3243-
"increase pointer alignment in slice resize",
3244-
\\export fn entry() u32 {
3245-
\\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};
3246-
\\ return ([]u32)(bytes[0..])[0];
3247-
\\}
3248-
,
3249-
".tmp_source.zig:3:19: error: cast increases pointer alignment",
3250-
".tmp_source.zig:3:19: note: '[]u8' has alignment 1",
3251-
".tmp_source.zig:3:19: note: '[]u32' has alignment 4",
3252-
);
3253-
32543241
cases.add(
32553242
"@alignCast expects pointer or slice",
32563243
\\export fn entry() void {
@@ -3722,22 +3709,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37223709
".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'",
37233710
);
37243711

3725-
cases.add(
3726-
"explicitly casting enum to non tag type",
3727-
\\const Small = enum(u2) {
3728-
\\ One,
3729-
\\ Two,
3730-
\\ Three,
3731-
\\ Four,
3732-
\\};
3733-
\\
3734-
\\export fn entry() void {
3735-
\\ var x = u3(Small.Two);
3736-
\\}
3737-
,
3738-
".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'",
3739-
);
3740-
37413712
cases.add(
37423713
"explicitly casting non tag type to enum",
37433714
\\const Small = enum(u2) {
@@ -3749,10 +3720,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
37493720
\\
37503721
\\export fn entry() void {
37513722
\\ var y = u3(3);
3752-
\\ var x = Small(y);
3723+
\\ var x = @intToEnum(Small, y);
37533724
\\}
37543725
,
3755-
".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'",
3726+
".tmp_source.zig:10:31: error: expected type 'u2', found 'u3'",
37563727
);
37573728

37583729
cases.add(
@@ -4033,10 +4004,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
40334004
\\ B = 11,
40344005
\\};
40354006
\\export fn entry() void {
4036-
\\ var x = Foo(0);
4007+
\\ var x = @intToEnum(Foo, 0);
40374008
\\}
40384009
,
4039-
".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0",
4010+
".tmp_source.zig:6:13: error: enum 'Foo' has no tag matching integer value 0",
40404011
".tmp_source.zig:1:13: note: 'Foo' declared here",
40414012
);
40424013

‎test/runtime_safety.zig‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
175175
\\ if (x.len == 0) return error.Whatever;
176176
\\}
177177
\\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
178-
\\ return ([]align(1) const i32)(slice);
178+
\\ return @bytesToSlice(i32, slice);
179179
\\}
180180
);
181181

@@ -227,12 +227,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
227227
\\pub fn main() void {
228228
\\ _ = bar(9999);
229229
\\}
230-
\\fn bar(x: u32) error {
231-
\\ return error(x);
230+
\\fn bar(x: u16) error {
231+
\\ return @intToError(x);
232232
\\}
233233
);
234234

235-
cases.addRuntimeSafety("cast integer to non-global error set and no match",
235+
cases.addRuntimeSafety("@errSetCast error not present in destination",
236236
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
237237
\\ @import("std").os.exit(126);
238238
\\}
@@ -242,7 +242,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
242242
\\ _ = foo(Set1.B);
243243
\\}
244244
\\fn foo(set1: Set1) Set2 {
245-
\\ return Set2(set1);
245+
\\ return @errSetCast(Set2, set1);
246246
\\}
247247
);
248248

@@ -252,12 +252,12 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
252252
\\}
253253
\\pub fn main() !void {
254254
\\ var array align(4) = []u32{0x11111111, 0x11111111};
255-
\\ const bytes = ([]u8)(array[0..]);
255+
\\ const bytes = @sliceToBytes(array[0..]);
256256
\\ if (foo(bytes) != 0x11111111) return error.Wrong;
257257
\\}
258258
\\fn foo(bytes: []u8) u32 {
259259
\\ const slice4 = bytes[1..5];
260-
\\ const int_slice = ([]u32)(@alignCast(4, slice4));
260+
\\ const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
261261
\\ return int_slice[0];
262262
\\}
263263
);

0 commit comments

Comments
 (0)
Please sign in to comment.