authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-05 10:29:54-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-06-05 10:29:54-04:00
log7dd18294b7988062461430d431eaad2ad7b19daa
tree8ce835394267efdf369948f0438de35a29db3b9f
parent58ce79f9352a6139c873df6d99d1531101350e9f
parent677eaf29b10df9b1dc461b37e7be78734b11ef19

Merge remote-tracking branch 'origin/master' into llvm7


34 files changed, 954 insertions(+), 636 deletions(-)

doc/langref.html.in+24-21
...@@ -1565,7 +1565,7 @@ var foo: u8 align(4) = 100;...@@ -1565,7 +1565,7 @@ var foo: u8 align(4) = 100;
1565test "global variable alignment" {1565test "global variable alignment" {
1566 assert(@typeOf(&foo).alignment == 4);1566 assert(@typeOf(&foo).alignment == 4);
1567 assert(@typeOf(&foo) == *align(4) u8);1567 assert(@typeOf(&foo) == *align(4) u8);
1568 const slice = (&foo)[0..1];1568 const slice = (*[1]u8)(&foo)[0..];
1569 assert(@typeOf(slice) == []align(4) u8);1569 assert(@typeOf(slice) == []align(4) u8);
1570}1570}
15711571
...@@ -1671,7 +1671,7 @@ test "using slices for strings" {...@@ -1671,7 +1671,7 @@ test "using slices for strings" {
16711671
1672test "slice pointer" {1672test "slice pointer" {
1673 var array: [10]u8 = undefined;1673 var array: [10]u8 = undefined;
1674 const ptr = &array[0];1674 const ptr = &array;
16751675
1676 // You can use slicing syntax to convert a pointer into a slice:1676 // You can use slicing syntax to convert a pointer into a slice:
1677 const slice = ptr[0..5];1677 const slice = ptr[0..5];
...@@ -4893,10 +4893,10 @@ pub const TypeId = enum {...@@ -4893,10 +4893,10 @@ pub const TypeId = enum {
4893 Pointer,4893 Pointer,
4894 Array,4894 Array,
4895 Struct,4895 Struct,
4896 FloatLiteral,4896 ComptimeFloat,
4897 IntLiteral,4897 ComptimeInt,
4898 UndefinedLiteral,4898 Undefined,
4899 NullLiteral,4899 Null,
4900 Nullable,4900 Nullable,
4901 ErrorUnion,4901 ErrorUnion,
4902 Error,4902 Error,
...@@ -4927,10 +4927,10 @@ pub const TypeInfo = union(TypeId) {...@@ -4927,10 +4927,10 @@ pub const TypeInfo = union(TypeId) {
4927 Pointer: Pointer,4927 Pointer: Pointer,
4928 Array: Array,4928 Array: Array,
4929 Struct: Struct,4929 Struct: Struct,
4930 FloatLiteral: void,4930 ComptimeFloat: void,
4931 IntLiteral: void,4931 ComptimeInt: void,
4932 UndefinedLiteral: void,4932 Undefined: void,
4933 NullLiteral: void,4933 Null: void,
4934 Nullable: Nullable,4934 Nullable: Nullable,
4935 ErrorUnion: ErrorUnion,4935 ErrorUnion: ErrorUnion,
4936 ErrorSet: ErrorSet,4936 ErrorSet: ErrorSet,
...@@ -5685,10 +5685,10 @@ pub const TypeId = enum {...@@ -5685,10 +5685,10 @@ pub const TypeId = enum {
5685 Pointer,5685 Pointer,
5686 Array,5686 Array,
5687 Struct,5687 Struct,
5688 FloatLiteral,5688 ComptimeFloat,
5689 IntLiteral,5689 ComptimeInt,
5690 UndefinedLiteral,5690 Undefined,
5691 NullLiteral,5691 Null,
5692 Nullable,5692 Nullable,
5693 ErrorUnion,5693 ErrorUnion,
5694 ErrorSet,5694 ErrorSet,
...@@ -5713,10 +5713,10 @@ pub const TypeInfo = union(TypeId) {...@@ -5713,10 +5713,10 @@ pub const TypeInfo = union(TypeId) {
5713 Pointer: Pointer,5713 Pointer: Pointer,
5714 Array: Array,5714 Array: Array,
5715 Struct: Struct,5715 Struct: Struct,
5716 FloatLiteral: void,5716 ComptimeFloat: void,
5717 IntLiteral: void,5717 ComptimeInt: void,
5718 UndefinedLiteral: void,5718 Undefined: void,
5719 NullLiteral: void,5719 Null: void,
5720 Nullable: Nullable,5720 Nullable: Nullable,
5721 ErrorUnion: ErrorUnion,5721 ErrorUnion: ErrorUnion,
5722 ErrorSet: ErrorSet,5722 ErrorSet: ErrorSet,
...@@ -6004,9 +6004,12 @@ const c = @cImport({...@@ -6004,9 +6004,12 @@ const c = @cImport({
6004 {#code_begin|syntax#}6004 {#code_begin|syntax#}
6005const base64 = @import("std").base64;6005const base64 = @import("std").base64;
60066006
6007export fn decode_base_64(dest_ptr: *u8, dest_len: usize,6007export fn decode_base_64(
6008 source_ptr: *const u8, source_len: usize) usize6008 dest_ptr: [*]u8,
6009{6009 dest_len: usize,
6010 source_ptr: [*]const u8,
6011 source_len: usize,
6012) usize {
6010 const src = source_ptr[0..source_len];6013 const src = source_ptr[0..source_len];
6011 const dest = dest_ptr[0..dest_len];6014 const dest = dest_ptr[0..dest_len];
6012 const base64_decoder = base64.standard_decoder_unsafe;6015 const base64_decoder = base64.standard_decoder_unsafe;
example/mix_o_files/base64.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const base64 = @import("std").base64;1const base64 = @import("std").base64;
22
3export fn decode_base_64(dest_ptr: *u8, dest_len: usize, source_ptr: *const u8, source_len: usize) usize {3export fn decode_base_64(dest_ptr: [*]u8, dest_len: usize, source_ptr: [*]const u8, source_len: usize) usize {
4 const src = source_ptr[0..source_len];4 const src = source_ptr[0..source_len];
5 const dest = dest_ptr[0..dest_len];5 const dest = dest_ptr[0..dest_len];
6 const base64_decoder = base64.standard_decoder_unsafe;6 const base64_decoder = base64.standard_decoder_unsafe;
src/all_types.hpp+9-4
...@@ -83,6 +83,7 @@ enum ConstParentId {...@@ -83,6 +83,7 @@ enum ConstParentId {
83 ConstParentIdStruct,83 ConstParentIdStruct,
84 ConstParentIdArray,84 ConstParentIdArray,
85 ConstParentIdUnion,85 ConstParentIdUnion,
86 ConstParentIdScalar,
86};87};
8788
88struct ConstParent {89struct ConstParent {
...@@ -100,6 +101,9 @@ struct ConstParent {...@@ -100,6 +101,9 @@ struct ConstParent {
100 struct {101 struct {
101 ConstExprValue *union_val;102 ConstExprValue *union_val;
102 } p_union;103 } p_union;
104 struct {
105 ConstExprValue *scalar_val;
106 } p_scalar;
103 } data;107 } data;
104};108};
105109
...@@ -578,6 +582,7 @@ enum CastOp {...@@ -578,6 +582,7 @@ enum CastOp {
578 CastOpBytesToSlice,582 CastOpBytesToSlice,
579 CastOpNumLitToConcrete,583 CastOpNumLitToConcrete,
580 CastOpErrSet,584 CastOpErrSet,
585 CastOpBitCast,
581};586};
582587
583struct AstNodeFnCallExpr {588struct AstNodeFnCallExpr {
...@@ -1154,10 +1159,10 @@ enum TypeTableEntryId {...@@ -1154,10 +1159,10 @@ enum TypeTableEntryId {
1154 TypeTableEntryIdPointer,1159 TypeTableEntryIdPointer,
1155 TypeTableEntryIdArray,1160 TypeTableEntryIdArray,
1156 TypeTableEntryIdStruct,1161 TypeTableEntryIdStruct,
1157 TypeTableEntryIdNumLitFloat,1162 TypeTableEntryIdComptimeFloat,
1158 TypeTableEntryIdNumLitInt,1163 TypeTableEntryIdComptimeInt,
1159 TypeTableEntryIdUndefLit,1164 TypeTableEntryIdUndefined,
1160 TypeTableEntryIdNullLit,1165 TypeTableEntryIdNull,
1161 TypeTableEntryIdMaybe,1166 TypeTableEntryIdMaybe,
1162 TypeTableEntryIdErrorUnion,1167 TypeTableEntryIdErrorUnion,
1163 TypeTableEntryIdErrorSet,1168 TypeTableEntryIdErrorSet,
src/analyze.cpp+103-99
...@@ -232,10 +232,10 @@ bool type_is_complete(TypeTableEntry *type_entry) {...@@ -232,10 +232,10 @@ bool type_is_complete(TypeTableEntry *type_entry) {
232 case TypeTableEntryIdFloat:232 case TypeTableEntryIdFloat:
233 case TypeTableEntryIdPointer:233 case TypeTableEntryIdPointer:
234 case TypeTableEntryIdArray:234 case TypeTableEntryIdArray:
235 case TypeTableEntryIdNumLitFloat:235 case TypeTableEntryIdComptimeFloat:
236 case TypeTableEntryIdNumLitInt:236 case TypeTableEntryIdComptimeInt:
237 case TypeTableEntryIdUndefLit:237 case TypeTableEntryIdUndefined:
238 case TypeTableEntryIdNullLit:238 case TypeTableEntryIdNull:
239 case TypeTableEntryIdMaybe:239 case TypeTableEntryIdMaybe:
240 case TypeTableEntryIdErrorUnion:240 case TypeTableEntryIdErrorUnion:
241 case TypeTableEntryIdErrorSet:241 case TypeTableEntryIdErrorSet:
...@@ -268,10 +268,10 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {...@@ -268,10 +268,10 @@ bool type_has_zero_bits_known(TypeTableEntry *type_entry) {
268 case TypeTableEntryIdFloat:268 case TypeTableEntryIdFloat:
269 case TypeTableEntryIdPointer:269 case TypeTableEntryIdPointer:
270 case TypeTableEntryIdArray:270 case TypeTableEntryIdArray:
271 case TypeTableEntryIdNumLitFloat:271 case TypeTableEntryIdComptimeFloat:
272 case TypeTableEntryIdNumLitInt:272 case TypeTableEntryIdComptimeInt:
273 case TypeTableEntryIdUndefLit:273 case TypeTableEntryIdUndefined:
274 case TypeTableEntryIdNullLit:274 case TypeTableEntryIdNull:
275 case TypeTableEntryIdMaybe:275 case TypeTableEntryIdMaybe:
276 case TypeTableEntryIdErrorUnion:276 case TypeTableEntryIdErrorUnion:
277 case TypeTableEntryIdErrorSet:277 case TypeTableEntryIdErrorSet:
...@@ -1333,10 +1333,10 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {...@@ -1333,10 +1333,10 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
1333 zig_unreachable();1333 zig_unreachable();
1334 case TypeTableEntryIdMetaType:1334 case TypeTableEntryIdMetaType:
1335 case TypeTableEntryIdUnreachable:1335 case TypeTableEntryIdUnreachable:
1336 case TypeTableEntryIdNumLitFloat:1336 case TypeTableEntryIdComptimeFloat:
1337 case TypeTableEntryIdNumLitInt:1337 case TypeTableEntryIdComptimeInt:
1338 case TypeTableEntryIdUndefLit:1338 case TypeTableEntryIdUndefined:
1339 case TypeTableEntryIdNullLit:1339 case TypeTableEntryIdNull:
1340 case TypeTableEntryIdErrorUnion:1340 case TypeTableEntryIdErrorUnion:
1341 case TypeTableEntryIdErrorSet:1341 case TypeTableEntryIdErrorSet:
1342 case TypeTableEntryIdNamespace:1342 case TypeTableEntryIdNamespace:
...@@ -1374,10 +1374,10 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {...@@ -1374,10 +1374,10 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1374 case TypeTableEntryIdInvalid:1374 case TypeTableEntryIdInvalid:
1375 zig_unreachable();1375 zig_unreachable();
1376 case TypeTableEntryIdMetaType:1376 case TypeTableEntryIdMetaType:
1377 case TypeTableEntryIdNumLitFloat:1377 case TypeTableEntryIdComptimeFloat:
1378 case TypeTableEntryIdNumLitInt:1378 case TypeTableEntryIdComptimeInt:
1379 case TypeTableEntryIdUndefLit:1379 case TypeTableEntryIdUndefined:
1380 case TypeTableEntryIdNullLit:1380 case TypeTableEntryIdNull:
1381 case TypeTableEntryIdErrorUnion:1381 case TypeTableEntryIdErrorUnion:
1382 case TypeTableEntryIdErrorSet:1382 case TypeTableEntryIdErrorSet:
1383 case TypeTableEntryIdNamespace:1383 case TypeTableEntryIdNamespace:
...@@ -1511,15 +1511,15 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1511,15 +1511,15 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1511 case TypeTableEntryIdInvalid:1511 case TypeTableEntryIdInvalid:
1512 return g->builtin_types.entry_invalid;1512 return g->builtin_types.entry_invalid;
1513 case TypeTableEntryIdUnreachable:1513 case TypeTableEntryIdUnreachable:
1514 case TypeTableEntryIdUndefLit:1514 case TypeTableEntryIdUndefined:
1515 case TypeTableEntryIdNullLit:1515 case TypeTableEntryIdNull:
1516 case TypeTableEntryIdArgTuple:1516 case TypeTableEntryIdArgTuple:
1517 case TypeTableEntryIdOpaque:1517 case TypeTableEntryIdOpaque:
1518 add_node_error(g, param_node->data.param_decl.type,1518 add_node_error(g, param_node->data.param_decl.type,
1519 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));1519 buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
1520 return g->builtin_types.entry_invalid;1520 return g->builtin_types.entry_invalid;
1521 case TypeTableEntryIdNumLitFloat:1521 case TypeTableEntryIdComptimeFloat:
1522 case TypeTableEntryIdNumLitInt:1522 case TypeTableEntryIdComptimeInt:
1523 case TypeTableEntryIdNamespace:1523 case TypeTableEntryIdNamespace:
1524 case TypeTableEntryIdBlock:1524 case TypeTableEntryIdBlock:
1525 case TypeTableEntryIdBoundFn:1525 case TypeTableEntryIdBoundFn:
...@@ -1599,16 +1599,16 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1599,16 +1599,16 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1599 case TypeTableEntryIdInvalid:1599 case TypeTableEntryIdInvalid:
1600 zig_unreachable();1600 zig_unreachable();
16011601
1602 case TypeTableEntryIdUndefLit:1602 case TypeTableEntryIdUndefined:
1603 case TypeTableEntryIdNullLit:1603 case TypeTableEntryIdNull:
1604 case TypeTableEntryIdArgTuple:1604 case TypeTableEntryIdArgTuple:
1605 case TypeTableEntryIdOpaque:1605 case TypeTableEntryIdOpaque:
1606 add_node_error(g, fn_proto->return_type,1606 add_node_error(g, fn_proto->return_type,
1607 buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name)));1607 buf_sprintf("return type '%s' not allowed", buf_ptr(&fn_type_id.return_type->name)));
1608 return g->builtin_types.entry_invalid;1608 return g->builtin_types.entry_invalid;
16091609
1610 case TypeTableEntryIdNumLitFloat:1610 case TypeTableEntryIdComptimeFloat:
1611 case TypeTableEntryIdNumLitInt:1611 case TypeTableEntryIdComptimeInt:
1612 case TypeTableEntryIdNamespace:1612 case TypeTableEntryIdNamespace:
1613 case TypeTableEntryIdBlock:1613 case TypeTableEntryIdBlock:
1614 case TypeTableEntryIdBoundFn:1614 case TypeTableEntryIdBoundFn:
...@@ -1860,7 +1860,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {...@@ -1860,7 +1860,7 @@ static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
1860 }1860 }
18611861
1862 assert(!struct_type->data.structure.zero_bits_loop_flag);1862 assert(!struct_type->data.structure.zero_bits_loop_flag);
1863 assert(struct_type->data.structure.fields);1863 assert(struct_type->data.structure.fields || struct_type->data.structure.src_field_count == 0);
1864 assert(decl_node->type == NodeTypeContainerDecl);1864 assert(decl_node->type == NodeTypeContainerDecl);
18651865
1866 size_t field_count = struct_type->data.structure.src_field_count;1866 size_t field_count = struct_type->data.structure.src_field_count;
...@@ -2677,8 +2677,8 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2677,8 +2677,8 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
2677 return;2677 return;
2678 }2678 }
2679 tag_type = enum_type;2679 tag_type = enum_type;
2680 abi_alignment_so_far = get_abi_alignment(g, enum_type); // this populates src_field_count
2680 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);2681 covered_enum_fields = allocate<bool>(enum_type->data.enumeration.src_field_count);
2681 abi_alignment_so_far = get_abi_alignment(g, enum_type);
2682 } else {2682 } else {
2683 tag_type = nullptr;2683 tag_type = nullptr;
2684 abi_alignment_so_far = 0;2684 abi_alignment_so_far = 0;
...@@ -3337,16 +3337,16 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt...@@ -3337,16 +3337,16 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt
3337 case TypeTableEntryIdInvalid:3337 case TypeTableEntryIdInvalid:
3338 return g->builtin_types.entry_invalid;3338 return g->builtin_types.entry_invalid;
3339 case TypeTableEntryIdUnreachable:3339 case TypeTableEntryIdUnreachable:
3340 case TypeTableEntryIdNumLitFloat:3340 case TypeTableEntryIdUndefined:
3341 case TypeTableEntryIdNumLitInt:3341 case TypeTableEntryIdNull:
3342 case TypeTableEntryIdUndefLit:
3343 case TypeTableEntryIdNullLit:
3344 case TypeTableEntryIdBlock:3342 case TypeTableEntryIdBlock:
3345 case TypeTableEntryIdArgTuple:3343 case TypeTableEntryIdArgTuple:
3346 case TypeTableEntryIdOpaque:3344 case TypeTableEntryIdOpaque:
3347 add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed",3345 add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed",
3348 buf_ptr(&type_entry->name)));3346 buf_ptr(&type_entry->name)));
3349 return g->builtin_types.entry_invalid;3347 return g->builtin_types.entry_invalid;
3348 case TypeTableEntryIdComptimeFloat:
3349 case TypeTableEntryIdComptimeInt:
3350 case TypeTableEntryIdNamespace:3350 case TypeTableEntryIdNamespace:
3351 case TypeTableEntryIdMetaType:3351 case TypeTableEntryIdMetaType:
3352 case TypeTableEntryIdVoid:3352 case TypeTableEntryIdVoid:
...@@ -3480,12 +3480,12 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {...@@ -3480,12 +3480,12 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) {
3480 add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable"));3480 add_node_error(g, source_node, buf_sprintf("variable initialization is unreachable"));
3481 implicit_type = g->builtin_types.entry_invalid;3481 implicit_type = g->builtin_types.entry_invalid;
3482 } else if ((!is_const || linkage == VarLinkageExternal) &&3482 } else if ((!is_const || linkage == VarLinkageExternal) &&
3483 (implicit_type->id == TypeTableEntryIdNumLitFloat ||3483 (implicit_type->id == TypeTableEntryIdComptimeFloat ||
3484 implicit_type->id == TypeTableEntryIdNumLitInt))3484 implicit_type->id == TypeTableEntryIdComptimeInt))
3485 {3485 {
3486 add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));3486 add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));
3487 implicit_type = g->builtin_types.entry_invalid;3487 implicit_type = g->builtin_types.entry_invalid;
3488 } else if (implicit_type->id == TypeTableEntryIdNullLit) {3488 } else if (implicit_type->id == TypeTableEntryIdNull) {
3489 add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));3489 add_node_error(g, source_node, buf_sprintf("unable to infer variable type"));
3490 implicit_type = g->builtin_types.entry_invalid;3490 implicit_type = g->builtin_types.entry_invalid;
3491 } else if (implicit_type->id == TypeTableEntryIdMetaType && !is_const) {3491 } else if (implicit_type->id == TypeTableEntryIdMetaType && !is_const) {
...@@ -3730,10 +3730,10 @@ static bool is_container(TypeTableEntry *type_entry) {...@@ -3730,10 +3730,10 @@ static bool is_container(TypeTableEntry *type_entry) {
3730 case TypeTableEntryIdInt:3730 case TypeTableEntryIdInt:
3731 case TypeTableEntryIdFloat:3731 case TypeTableEntryIdFloat:
3732 case TypeTableEntryIdArray:3732 case TypeTableEntryIdArray:
3733 case TypeTableEntryIdNumLitFloat:3733 case TypeTableEntryIdComptimeFloat:
3734 case TypeTableEntryIdNumLitInt:3734 case TypeTableEntryIdComptimeInt:
3735 case TypeTableEntryIdUndefLit:3735 case TypeTableEntryIdUndefined:
3736 case TypeTableEntryIdNullLit:3736 case TypeTableEntryIdNull:
3737 case TypeTableEntryIdMaybe:3737 case TypeTableEntryIdMaybe:
3738 case TypeTableEntryIdErrorUnion:3738 case TypeTableEntryIdErrorUnion:
3739 case TypeTableEntryIdErrorSet:3739 case TypeTableEntryIdErrorSet:
...@@ -3779,10 +3779,10 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {...@@ -3779,10 +3779,10 @@ void resolve_container_type(CodeGen *g, TypeTableEntry *type_entry) {
3779 case TypeTableEntryIdInt:3779 case TypeTableEntryIdInt:
3780 case TypeTableEntryIdFloat:3780 case TypeTableEntryIdFloat:
3781 case TypeTableEntryIdArray:3781 case TypeTableEntryIdArray:
3782 case TypeTableEntryIdNumLitFloat:3782 case TypeTableEntryIdComptimeFloat:
3783 case TypeTableEntryIdNumLitInt:3783 case TypeTableEntryIdComptimeInt:
3784 case TypeTableEntryIdUndefLit:3784 case TypeTableEntryIdUndefined:
3785 case TypeTableEntryIdNullLit:3785 case TypeTableEntryIdNull:
3786 case TypeTableEntryIdMaybe:3786 case TypeTableEntryIdMaybe:
3787 case TypeTableEntryIdErrorUnion:3787 case TypeTableEntryIdErrorUnion:
3788 case TypeTableEntryIdErrorSet:3788 case TypeTableEntryIdErrorSet:
...@@ -4283,10 +4283,10 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -4283,10 +4283,10 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
4283 switch (type_entry->id) {4283 switch (type_entry->id) {
4284 case TypeTableEntryIdInvalid:4284 case TypeTableEntryIdInvalid:
4285 case TypeTableEntryIdMetaType:4285 case TypeTableEntryIdMetaType:
4286 case TypeTableEntryIdNumLitFloat:4286 case TypeTableEntryIdComptimeFloat:
4287 case TypeTableEntryIdNumLitInt:4287 case TypeTableEntryIdComptimeInt:
4288 case TypeTableEntryIdUndefLit:4288 case TypeTableEntryIdUndefined:
4289 case TypeTableEntryIdNullLit:4289 case TypeTableEntryIdNull:
4290 case TypeTableEntryIdNamespace:4290 case TypeTableEntryIdNamespace:
4291 case TypeTableEntryIdBlock:4291 case TypeTableEntryIdBlock:
4292 case TypeTableEntryIdBoundFn:4292 case TypeTableEntryIdBoundFn:
...@@ -4568,7 +4568,7 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -4568,7 +4568,7 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
4568 case TypeTableEntryIdVoid:4568 case TypeTableEntryIdVoid:
4569 return (uint32_t)4149439618;4569 return (uint32_t)4149439618;
4570 case TypeTableEntryIdInt:4570 case TypeTableEntryIdInt:
4571 case TypeTableEntryIdNumLitInt:4571 case TypeTableEntryIdComptimeInt:
4572 {4572 {
4573 uint32_t result = 1331471175;4573 uint32_t result = 1331471175;
4574 for (size_t i = 0; i < const_val->data.x_bigint.digit_count; i += 1) {4574 for (size_t i = 0; i < const_val->data.x_bigint.digit_count; i += 1) {
...@@ -4609,7 +4609,7 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -4609,7 +4609,7 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
4609 default:4609 default:
4610 zig_unreachable();4610 zig_unreachable();
4611 }4611 }
4612 case TypeTableEntryIdNumLitFloat:4612 case TypeTableEntryIdComptimeFloat:
4613 {4613 {
4614 float128_t f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);4614 float128_t f128 = bigfloat_to_f128(&const_val->data.x_bigfloat);
4615 uint32_t ints[4];4615 uint32_t ints[4];
...@@ -4672,9 +4672,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {...@@ -4672,9 +4672,9 @@ static uint32_t hash_const_val(ConstExprValue *const_val) {
4672 case TypeTableEntryIdPromise:4672 case TypeTableEntryIdPromise:
4673 // TODO better hashing algorithm4673 // TODO better hashing algorithm
4674 return 223048345;4674 return 223048345;
4675 case TypeTableEntryIdUndefLit:4675 case TypeTableEntryIdUndefined:
4676 return 162837799;4676 return 162837799;
4677 case TypeTableEntryIdNullLit:4677 case TypeTableEntryIdNull:
4678 return 844854567;4678 return 844854567;
4679 case TypeTableEntryIdArray:4679 case TypeTableEntryIdArray:
4680 // TODO better hashing algorithm4680 // TODO better hashing algorithm
...@@ -4754,10 +4754,10 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {...@@ -4754,10 +4754,10 @@ static bool can_mutate_comptime_var_state(ConstExprValue *value) {
4754 case TypeTableEntryIdUnreachable:4754 case TypeTableEntryIdUnreachable:
4755 case TypeTableEntryIdInt:4755 case TypeTableEntryIdInt:
4756 case TypeTableEntryIdFloat:4756 case TypeTableEntryIdFloat:
4757 case TypeTableEntryIdNumLitFloat:4757 case TypeTableEntryIdComptimeFloat:
4758 case TypeTableEntryIdNumLitInt:4758 case TypeTableEntryIdComptimeInt:
4759 case TypeTableEntryIdUndefLit:4759 case TypeTableEntryIdUndefined:
4760 case TypeTableEntryIdNullLit:4760 case TypeTableEntryIdNull:
4761 case TypeTableEntryIdNamespace:4761 case TypeTableEntryIdNamespace:
4762 case TypeTableEntryIdBoundFn:4762 case TypeTableEntryIdBoundFn:
4763 case TypeTableEntryIdFn:4763 case TypeTableEntryIdFn:
...@@ -4819,10 +4819,10 @@ static bool return_type_is_cacheable(TypeTableEntry *return_type) {...@@ -4819,10 +4819,10 @@ static bool return_type_is_cacheable(TypeTableEntry *return_type) {
4819 case TypeTableEntryIdUnreachable:4819 case TypeTableEntryIdUnreachable:
4820 case TypeTableEntryIdInt:4820 case TypeTableEntryIdInt:
4821 case TypeTableEntryIdFloat:4821 case TypeTableEntryIdFloat:
4822 case TypeTableEntryIdNumLitFloat:4822 case TypeTableEntryIdComptimeFloat:
4823 case TypeTableEntryIdNumLitInt:4823 case TypeTableEntryIdComptimeInt:
4824 case TypeTableEntryIdUndefLit:4824 case TypeTableEntryIdUndefined:
4825 case TypeTableEntryIdNullLit:4825 case TypeTableEntryIdNull:
4826 case TypeTableEntryIdNamespace:4826 case TypeTableEntryIdNamespace:
4827 case TypeTableEntryIdBoundFn:4827 case TypeTableEntryIdBoundFn:
4828 case TypeTableEntryIdFn:4828 case TypeTableEntryIdFn:
...@@ -4930,10 +4930,10 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {...@@ -4930,10 +4930,10 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
4930 case TypeTableEntryIdInvalid:4930 case TypeTableEntryIdInvalid:
4931 case TypeTableEntryIdOpaque:4931 case TypeTableEntryIdOpaque:
4932 zig_unreachable();4932 zig_unreachable();
4933 case TypeTableEntryIdNumLitFloat:4933 case TypeTableEntryIdComptimeFloat:
4934 case TypeTableEntryIdNumLitInt:4934 case TypeTableEntryIdComptimeInt:
4935 case TypeTableEntryIdUndefLit:4935 case TypeTableEntryIdUndefined:
4936 case TypeTableEntryIdNullLit:4936 case TypeTableEntryIdNull:
4937 case TypeTableEntryIdMetaType:4937 case TypeTableEntryIdMetaType:
4938 case TypeTableEntryIdNamespace:4938 case TypeTableEntryIdNamespace:
4939 case TypeTableEntryIdBlock:4939 case TypeTableEntryIdBlock:
...@@ -5070,7 +5070,7 @@ ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) {...@@ -5070,7 +5070,7 @@ ConstExprValue *create_const_signed(TypeTableEntry *type, int64_t x) {
5070void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value) {5070void init_const_float(ConstExprValue *const_val, TypeTableEntry *type, double value) {
5071 const_val->special = ConstValSpecialStatic;5071 const_val->special = ConstValSpecialStatic;
5072 const_val->type = type;5072 const_val->type = type;
5073 if (type->id == TypeTableEntryIdNumLitFloat) {5073 if (type->id == TypeTableEntryIdComptimeFloat) {
5074 bigfloat_init_64(&const_val->data.x_bigfloat, value);5074 bigfloat_init_64(&const_val->data.x_bigfloat, value);
5075 } else if (type->id == TypeTableEntryIdFloat) {5075 } else if (type->id == TypeTableEntryIdFloat) {
5076 switch (type->data.floating.bit_count) {5076 switch (type->data.floating.bit_count) {
...@@ -5158,7 +5158,8 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr...@@ -5158,7 +5158,8 @@ void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *arr
5158 const_val->type = get_slice_type(g, ptr_type);5158 const_val->type = get_slice_type(g, ptr_type);
5159 const_val->data.x_struct.fields = create_const_vals(2);5159 const_val->data.x_struct.fields = create_const_vals(2);
51605160
5161 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const);5161 init_const_ptr_array(g, &const_val->data.x_struct.fields[slice_ptr_index], array_val, start, is_const,
5162 PtrLenUnknown);
5162 init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);5163 init_const_usize(g, &const_val->data.x_struct.fields[slice_len_index], len);
5163}5164}
51645165
...@@ -5169,21 +5170,24 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t...@@ -5169,21 +5170,24 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t
5169}5170}
51705171
5171void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,5172void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,
5172 size_t elem_index, bool is_const)5173 size_t elem_index, bool is_const, PtrLen ptr_len)
5173{5174{
5174 assert(array_val->type->id == TypeTableEntryIdArray);5175 assert(array_val->type->id == TypeTableEntryIdArray);
5175 TypeTableEntry *child_type = array_val->type->data.array.child_type;5176 TypeTableEntry *child_type = array_val->type->data.array.child_type;
51765177
5177 const_val->special = ConstValSpecialStatic;5178 const_val->special = ConstValSpecialStatic;
5178 const_val->type = get_pointer_to_type(g, child_type, is_const);5179 const_val->type = get_pointer_to_type_extra(g, child_type, is_const, false,
5180 ptr_len, get_abi_alignment(g, child_type), 0, 0);
5179 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray;5181 const_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
5180 const_val->data.x_ptr.data.base_array.array_val = array_val;5182 const_val->data.x_ptr.data.base_array.array_val = array_val;
5181 const_val->data.x_ptr.data.base_array.elem_index = elem_index;5183 const_val->data.x_ptr.data.base_array.elem_index = elem_index;
5182}5184}
51835185
5184ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const) {5186ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const,
5187 PtrLen ptr_len)
5188{
5185 ConstExprValue *const_val = create_const_vals(1);5189 ConstExprValue *const_val = create_const_vals(1);
5186 init_const_ptr_array(g, const_val, array_val, elem_index, is_const);5190 init_const_ptr_array(g, const_val, array_val, elem_index, is_const, ptr_len);
5187 return const_val;5191 return const_val;
5188}5192}
51895193
...@@ -5346,10 +5350,10 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -5346,10 +5350,10 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
5346 default:5350 default:
5347 zig_unreachable();5351 zig_unreachable();
5348 }5352 }
5349 case TypeTableEntryIdNumLitFloat:5353 case TypeTableEntryIdComptimeFloat:
5350 return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;5354 return bigfloat_cmp(&a->data.x_bigfloat, &b->data.x_bigfloat) == CmpEQ;
5351 case TypeTableEntryIdInt:5355 case TypeTableEntryIdInt:
5352 case TypeTableEntryIdNumLitInt:5356 case TypeTableEntryIdComptimeInt:
5353 return bigint_cmp(&a->data.x_bigint, &b->data.x_bigint) == CmpEQ;5357 return bigint_cmp(&a->data.x_bigint, &b->data.x_bigint) == CmpEQ;
5354 case TypeTableEntryIdPointer:5358 case TypeTableEntryIdPointer:
5355 case TypeTableEntryIdFn:5359 case TypeTableEntryIdFn:
...@@ -5406,9 +5410,9 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -5406,9 +5410,9 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
5406 return false;5410 return false;
5407 }5411 }
5408 return true;5412 return true;
5409 case TypeTableEntryIdUndefLit:5413 case TypeTableEntryIdUndefined:
5410 zig_panic("TODO");5414 zig_panic("TODO");
5411 case TypeTableEntryIdNullLit:5415 case TypeTableEntryIdNull:
5412 zig_panic("TODO");5416 zig_panic("TODO");
5413 case TypeTableEntryIdMaybe:5417 case TypeTableEntryIdMaybe:
5414 if (a->data.x_maybe == nullptr || b->data.x_maybe == nullptr) {5418 if (a->data.x_maybe == nullptr || b->data.x_maybe == nullptr) {
...@@ -5510,7 +5514,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5510,7 +5514,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5510 case TypeTableEntryIdVoid:5514 case TypeTableEntryIdVoid:
5511 buf_appendf(buf, "{}");5515 buf_appendf(buf, "{}");
5512 return;5516 return;
5513 case TypeTableEntryIdNumLitFloat:5517 case TypeTableEntryIdComptimeFloat:
5514 bigfloat_append_buf(buf, &const_val->data.x_bigfloat);5518 bigfloat_append_buf(buf, &const_val->data.x_bigfloat);
5515 return;5519 return;
5516 case TypeTableEntryIdFloat:5520 case TypeTableEntryIdFloat:
...@@ -5538,7 +5542,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5538,7 +5542,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5538 default:5542 default:
5539 zig_unreachable();5543 zig_unreachable();
5540 }5544 }
5541 case TypeTableEntryIdNumLitInt:5545 case TypeTableEntryIdComptimeInt:
5542 case TypeTableEntryIdInt:5546 case TypeTableEntryIdInt:
5543 bigint_append_buf(buf, &const_val->data.x_bigint, 10);5547 bigint_append_buf(buf, &const_val->data.x_bigint, 10);
5544 return;5548 return;
...@@ -5642,12 +5646,12 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {...@@ -5642,12 +5646,12 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
5642 buf_appendf(buf, "}");5646 buf_appendf(buf, "}");
5643 return;5647 return;
5644 }5648 }
5645 case TypeTableEntryIdNullLit:5649 case TypeTableEntryIdNull:
5646 {5650 {
5647 buf_appendf(buf, "null");5651 buf_appendf(buf, "null");
5648 return;5652 return;
5649 }5653 }
5650 case TypeTableEntryIdUndefLit:5654 case TypeTableEntryIdUndefined:
5651 {5655 {
5652 buf_appendf(buf, "undefined");5656 buf_appendf(buf, "undefined");
5653 return;5657 return;
...@@ -5757,10 +5761,10 @@ uint32_t type_id_hash(TypeId x) {...@@ -5757,10 +5761,10 @@ uint32_t type_id_hash(TypeId x) {
5757 case TypeTableEntryIdUnreachable:5761 case TypeTableEntryIdUnreachable:
5758 case TypeTableEntryIdFloat:5762 case TypeTableEntryIdFloat:
5759 case TypeTableEntryIdStruct:5763 case TypeTableEntryIdStruct:
5760 case TypeTableEntryIdNumLitFloat:5764 case TypeTableEntryIdComptimeFloat:
5761 case TypeTableEntryIdNumLitInt:5765 case TypeTableEntryIdComptimeInt:
5762 case TypeTableEntryIdUndefLit:5766 case TypeTableEntryIdUndefined:
5763 case TypeTableEntryIdNullLit:5767 case TypeTableEntryIdNull:
5764 case TypeTableEntryIdMaybe:5768 case TypeTableEntryIdMaybe:
5765 case TypeTableEntryIdErrorSet:5769 case TypeTableEntryIdErrorSet:
5766 case TypeTableEntryIdEnum:5770 case TypeTableEntryIdEnum:
...@@ -5803,10 +5807,10 @@ bool type_id_eql(TypeId a, TypeId b) {...@@ -5803,10 +5807,10 @@ bool type_id_eql(TypeId a, TypeId b) {
5803 case TypeTableEntryIdUnreachable:5807 case TypeTableEntryIdUnreachable:
5804 case TypeTableEntryIdFloat:5808 case TypeTableEntryIdFloat:
5805 case TypeTableEntryIdStruct:5809 case TypeTableEntryIdStruct:
5806 case TypeTableEntryIdNumLitFloat:5810 case TypeTableEntryIdComptimeFloat:
5807 case TypeTableEntryIdNumLitInt:5811 case TypeTableEntryIdComptimeInt:
5808 case TypeTableEntryIdUndefLit:5812 case TypeTableEntryIdUndefined:
5809 case TypeTableEntryIdNullLit:5813 case TypeTableEntryIdNull:
5810 case TypeTableEntryIdMaybe:5814 case TypeTableEntryIdMaybe:
5811 case TypeTableEntryIdPromise:5815 case TypeTableEntryIdPromise:
5812 case TypeTableEntryIdErrorSet:5816 case TypeTableEntryIdErrorSet:
...@@ -5925,10 +5929,10 @@ static const TypeTableEntryId all_type_ids[] = {...@@ -5925,10 +5929,10 @@ static const TypeTableEntryId all_type_ids[] = {
5925 TypeTableEntryIdPointer,5929 TypeTableEntryIdPointer,
5926 TypeTableEntryIdArray,5930 TypeTableEntryIdArray,
5927 TypeTableEntryIdStruct,5931 TypeTableEntryIdStruct,
5928 TypeTableEntryIdNumLitFloat,5932 TypeTableEntryIdComptimeFloat,
5929 TypeTableEntryIdNumLitInt,5933 TypeTableEntryIdComptimeInt,
5930 TypeTableEntryIdUndefLit,5934 TypeTableEntryIdUndefined,
5931 TypeTableEntryIdNullLit,5935 TypeTableEntryIdNull,
5932 TypeTableEntryIdMaybe,5936 TypeTableEntryIdMaybe,
5933 TypeTableEntryIdErrorUnion,5937 TypeTableEntryIdErrorUnion,
5934 TypeTableEntryIdErrorSet,5938 TypeTableEntryIdErrorSet,
...@@ -5976,13 +5980,13 @@ size_t type_id_index(TypeTableEntry *entry) {...@@ -5976,13 +5980,13 @@ size_t type_id_index(TypeTableEntry *entry) {
5976 if (entry->data.structure.is_slice)5980 if (entry->data.structure.is_slice)
5977 return 25;5981 return 25;
5978 return 8;5982 return 8;
5979 case TypeTableEntryIdNumLitFloat:5983 case TypeTableEntryIdComptimeFloat:
5980 return 9;5984 return 9;
5981 case TypeTableEntryIdNumLitInt:5985 case TypeTableEntryIdComptimeInt:
5982 return 10;5986 return 10;
5983 case TypeTableEntryIdUndefLit:5987 case TypeTableEntryIdUndefined:
5984 return 11;5988 return 11;
5985 case TypeTableEntryIdNullLit:5989 case TypeTableEntryIdNull:
5986 return 12;5990 return 12;
5987 case TypeTableEntryIdMaybe:5991 case TypeTableEntryIdMaybe:
5988 return 13;5992 return 13;
...@@ -6034,14 +6038,14 @@ const char *type_id_name(TypeTableEntryId id) {...@@ -6034,14 +6038,14 @@ const char *type_id_name(TypeTableEntryId id) {
6034 return "Array";6038 return "Array";
6035 case TypeTableEntryIdStruct:6039 case TypeTableEntryIdStruct:
6036 return "Struct";6040 return "Struct";
6037 case TypeTableEntryIdNumLitFloat:6041 case TypeTableEntryIdComptimeFloat:
6038 return "FloatLiteral";6042 return "ComptimeFloat";
6039 case TypeTableEntryIdNumLitInt:6043 case TypeTableEntryIdComptimeInt:
6040 return "IntLiteral";6044 return "ComptimeInt";
6041 case TypeTableEntryIdUndefLit:6045 case TypeTableEntryIdUndefined:
6042 return "UndefinedLiteral";6046 return "Undefined";
6043 case TypeTableEntryIdNullLit:6047 case TypeTableEntryIdNull:
6044 return "NullLiteral";6048 return "Null";
6045 case TypeTableEntryIdMaybe:6049 case TypeTableEntryIdMaybe:
6046 return "Nullable";6050 return "Nullable";
6047 case TypeTableEntryIdErrorUnion:6051 case TypeTableEntryIdErrorUnion:
src/analyze.hpp+3-2
...@@ -152,8 +152,9 @@ ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *poi...@@ -152,8 +152,9 @@ ConstExprValue *create_const_ptr_hard_coded_addr(CodeGen *g, TypeTableEntry *poi
152 size_t addr, bool is_const);152 size_t addr, bool is_const);
153153
154void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,154void init_const_ptr_array(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,
155 size_t elem_index, bool is_const);155 size_t elem_index, bool is_const, PtrLen ptr_len);
156ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index, bool is_const);156ConstExprValue *create_const_ptr_array(CodeGen *g, ConstExprValue *array_val, size_t elem_index,
157 bool is_const, PtrLen ptr_len);
157158
158void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,159void init_const_slice(CodeGen *g, ConstExprValue *const_val, ConstExprValue *array_val,
159 size_t start, size_t len, bool is_const);160 size_t start, size_t len, bool is_const);
src/codegen.cpp+57-36
...@@ -2541,6 +2541,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -2541,6 +2541,8 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
2541 add_error_range_check(g, wanted_type, g->err_tag_type, expr_val);2541 add_error_range_check(g, wanted_type, g->err_tag_type, expr_val);
2542 }2542 }
2543 return expr_val;2543 return expr_val;
2544 case CastOpBitCast:
2545 return LLVMBuildBitCast(g->builder, expr_val, wanted_type->type_ref, "");
2544 }2546 }
2545 zig_unreachable();2547 zig_unreachable();
2546}2548}
...@@ -2823,7 +2825,13 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -2823,7 +2825,13 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
28232825
2824 bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on;2826 bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on;
28252827
2826 if (array_type->id == TypeTableEntryIdArray) {2828 if (array_type->id == TypeTableEntryIdArray ||
2829 (array_type->id == TypeTableEntryIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle))
2830 {
2831 if (array_type->id == TypeTableEntryIdPointer) {
2832 assert(array_type->data.pointer.child_type->id == TypeTableEntryIdArray);
2833 array_type = array_type->data.pointer.child_type;
2834 }
2827 if (safety_check_on) {2835 if (safety_check_on) {
2828 LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,2836 LLVMValueRef end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
2829 array_type->data.array.len, false);2837 array_type->data.array.len, false);
...@@ -3709,7 +3717,12 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3709,7 +3717,12 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
37093717
3710 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);3718 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
37113719
3712 if (array_type->id == TypeTableEntryIdArray) {3720 if (array_type->id == TypeTableEntryIdArray ||
3721 (array_type->id == TypeTableEntryIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle))
3722 {
3723 if (array_type->id == TypeTableEntryIdPointer) {
3724 array_type = array_type->data.pointer.child_type;
3725 }
3713 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);3726 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
3714 LLVMValueRef end_val;3727 LLVMValueRef end_val;
3715 if (instruction->end) {3728 if (instruction->end) {
...@@ -3750,6 +3763,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3750,6 +3763,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
37503763
3751 return tmp_struct_ptr;3764 return tmp_struct_ptr;
3752 } else if (array_type->id == TypeTableEntryIdPointer) {3765 } else if (array_type->id == TypeTableEntryIdPointer) {
3766 assert(array_type->data.pointer.ptr_len == PtrLenUnknown);
3753 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);3767 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
3754 LLVMValueRef end_val = ir_llvm_value(g, instruction->end);3768 LLVMValueRef end_val = ir_llvm_value(g, instruction->end);
37553769
...@@ -4727,7 +4741,7 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {...@@ -4727,7 +4741,7 @@ static void ir_render(CodeGen *g, FnTableEntry *fn_entry) {
47274741
4728static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *struct_const_val, size_t field_index);4742static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ConstExprValue *struct_const_val, size_t field_index);
4729static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index);4743static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index);
4730static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *array_const_val);4744static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ConstExprValue *union_const_val);
47314745
4732static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent *parent) {4746static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent *parent) {
4733 switch (parent->id) {4747 switch (parent->id) {
...@@ -4743,6 +4757,10 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent...@@ -4743,6 +4757,10 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
4743 parent->data.p_array.elem_index);4757 parent->data.p_array.elem_index);
4744 case ConstParentIdUnion:4758 case ConstParentIdUnion:
4745 return gen_const_ptr_union_recursive(g, parent->data.p_union.union_val);4759 return gen_const_ptr_union_recursive(g, parent->data.p_union.union_val);
4760 case ConstParentIdScalar:
4761 render_const_val(g, parent->data.p_scalar.scalar_val, "");
4762 render_const_val_global(g, parent->data.p_scalar.scalar_val, "");
4763 return parent->data.p_scalar.scalar_val->global_refs->llvm_global;
4746 }4764 }
4747 zig_unreachable();4765 zig_unreachable();
4748}4766}
...@@ -4768,7 +4786,8 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar...@@ -4768,7 +4786,8 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *ar
4768 };4786 };
4769 return LLVMConstInBoundsGEP(base_ptr, indices, 2);4787 return LLVMConstInBoundsGEP(base_ptr, indices, 2);
4770 } else {4788 } else {
4771 zig_unreachable();4789 assert(parent->id == ConstParentIdScalar);
4790 return base_ptr;
4772 }4791 }
4773}4792}
47744793
...@@ -4812,10 +4831,10 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con...@@ -4812,10 +4831,10 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Con
4812 case TypeTableEntryIdInvalid:4831 case TypeTableEntryIdInvalid:
4813 case TypeTableEntryIdMetaType:4832 case TypeTableEntryIdMetaType:
4814 case TypeTableEntryIdUnreachable:4833 case TypeTableEntryIdUnreachable:
4815 case TypeTableEntryIdNumLitFloat:4834 case TypeTableEntryIdComptimeFloat:
4816 case TypeTableEntryIdNumLitInt:4835 case TypeTableEntryIdComptimeInt:
4817 case TypeTableEntryIdUndefLit:4836 case TypeTableEntryIdUndefined:
4818 case TypeTableEntryIdNullLit:4837 case TypeTableEntryIdNull:
4819 case TypeTableEntryIdErrorUnion:4838 case TypeTableEntryIdErrorUnion:
4820 case TypeTableEntryIdErrorSet:4839 case TypeTableEntryIdErrorSet:
4821 case TypeTableEntryIdNamespace:4840 case TypeTableEntryIdNamespace:
...@@ -5258,10 +5277,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c...@@ -5258,10 +5277,10 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val, const c
5258 case TypeTableEntryIdInvalid:5277 case TypeTableEntryIdInvalid:
5259 case TypeTableEntryIdMetaType:5278 case TypeTableEntryIdMetaType:
5260 case TypeTableEntryIdUnreachable:5279 case TypeTableEntryIdUnreachable:
5261 case TypeTableEntryIdNumLitFloat:5280 case TypeTableEntryIdComptimeFloat:
5262 case TypeTableEntryIdNumLitInt:5281 case TypeTableEntryIdComptimeInt:
5263 case TypeTableEntryIdUndefLit:5282 case TypeTableEntryIdUndefined:
5264 case TypeTableEntryIdNullLit:5283 case TypeTableEntryIdNull:
5265 case TypeTableEntryIdNamespace:5284 case TypeTableEntryIdNamespace:
5266 case TypeTableEntryIdBlock:5285 case TypeTableEntryIdBlock:
5267 case TypeTableEntryIdBoundFn:5286 case TypeTableEntryIdBoundFn:
...@@ -5500,7 +5519,7 @@ static void do_code_gen(CodeGen *g) {...@@ -5500,7 +5519,7 @@ static void do_code_gen(CodeGen *g) {
5500 TldVar *tld_var = g->global_vars.at(i);5519 TldVar *tld_var = g->global_vars.at(i);
5501 VariableTableEntry *var = tld_var->var;5520 VariableTableEntry *var = tld_var->var;
55025521
5503 if (var->value->type->id == TypeTableEntryIdNumLitFloat) {5522 if (var->value->type->id == TypeTableEntryIdComptimeFloat) {
5504 // Generate debug info for it but that's it.5523 // Generate debug info for it but that's it.
5505 ConstExprValue *const_val = var->value;5524 ConstExprValue *const_val = var->value;
5506 assert(const_val->special != ConstValSpecialRuntime);5525 assert(const_val->special != ConstValSpecialRuntime);
...@@ -5514,7 +5533,7 @@ static void do_code_gen(CodeGen *g) {...@@ -5514,7 +5533,7 @@ static void do_code_gen(CodeGen *g) {
5514 continue;5533 continue;
5515 }5534 }
55165535
5517 if (var->value->type->id == TypeTableEntryIdNumLitInt) {5536 if (var->value->type->id == TypeTableEntryIdComptimeInt) {
5518 // Generate debug info for it but that's it.5537 // Generate debug info for it but that's it.
5519 ConstExprValue *const_val = var->value;5538 ConstExprValue *const_val = var->value;
5520 assert(const_val->special != ConstValSpecialRuntime);5539 assert(const_val->special != ConstValSpecialRuntime);
...@@ -5908,25 +5927,27 @@ static void define_builtin_types(CodeGen *g) {...@@ -5908,25 +5927,27 @@ static void define_builtin_types(CodeGen *g) {
5908 g->builtin_types.entry_block = entry;5927 g->builtin_types.entry_block = entry;
5909 }5928 }
5910 {5929 {
5911 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitFloat);5930 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdComptimeFloat);
5912 buf_init_from_str(&entry->name, "(float literal)");5931 buf_init_from_str(&entry->name, "comptime_float");
5913 entry->zero_bits = true;5932 entry->zero_bits = true;
5914 g->builtin_types.entry_num_lit_float = entry;5933 g->builtin_types.entry_num_lit_float = entry;
5934 g->primitive_type_table.put(&entry->name, entry);
5915 }5935 }
5916 {5936 {
5917 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNumLitInt);5937 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdComptimeInt);
5918 buf_init_from_str(&entry->name, "(integer literal)");5938 buf_init_from_str(&entry->name, "comptime_int");
5919 entry->zero_bits = true;5939 entry->zero_bits = true;
5920 g->builtin_types.entry_num_lit_int = entry;5940 g->builtin_types.entry_num_lit_int = entry;
5941 g->primitive_type_table.put(&entry->name, entry);
5921 }5942 }
5922 {5943 {
5923 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefLit);5944 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdUndefined);
5924 buf_init_from_str(&entry->name, "(undefined)");5945 buf_init_from_str(&entry->name, "(undefined)");
5925 entry->zero_bits = true;5946 entry->zero_bits = true;
5926 g->builtin_types.entry_undef = entry;5947 g->builtin_types.entry_undef = entry;
5927 }5948 }
5928 {5949 {
5929 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNullLit);5950 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNull);
5930 buf_init_from_str(&entry->name, "(null)");5951 buf_init_from_str(&entry->name, "(null)");
5931 entry->zero_bits = true;5952 entry->zero_bits = true;
5932 g->builtin_types.entry_null = entry;5953 g->builtin_types.entry_null = entry;
...@@ -6391,10 +6412,10 @@ static void define_builtin_compile_vars(CodeGen *g) {...@@ -6391,10 +6412,10 @@ static void define_builtin_compile_vars(CodeGen *g) {
6391 " Slice: Slice,\n"6412 " Slice: Slice,\n"
6392 " Array: Array,\n"6413 " Array: Array,\n"
6393 " Struct: Struct,\n"6414 " Struct: Struct,\n"
6394 " FloatLiteral: void,\n"6415 " ComptimeFloat: void,\n"
6395 " IntLiteral: void,\n"6416 " ComptimeInt: void,\n"
6396 " UndefinedLiteral: void,\n"6417 " Undefined: void,\n"
6397 " NullLiteral: void,\n"6418 " Null: void,\n"
6398 " Nullable: Nullable,\n"6419 " Nullable: Nullable,\n"
6399 " ErrorUnion: ErrorUnion,\n"6420 " ErrorUnion: ErrorUnion,\n"
6400 " ErrorSet: ErrorSet,\n"6421 " ErrorSet: ErrorSet,\n"
...@@ -6966,10 +6987,10 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry...@@ -6966,10 +6987,10 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry
6966 switch (type_entry->id) {6987 switch (type_entry->id) {
6967 case TypeTableEntryIdInvalid:6988 case TypeTableEntryIdInvalid:
6968 case TypeTableEntryIdMetaType:6989 case TypeTableEntryIdMetaType:
6969 case TypeTableEntryIdNumLitFloat:6990 case TypeTableEntryIdComptimeFloat:
6970 case TypeTableEntryIdNumLitInt:6991 case TypeTableEntryIdComptimeInt:
6971 case TypeTableEntryIdUndefLit:6992 case TypeTableEntryIdUndefined:
6972 case TypeTableEntryIdNullLit:6993 case TypeTableEntryIdNull:
6973 case TypeTableEntryIdNamespace:6994 case TypeTableEntryIdNamespace:
6974 case TypeTableEntryIdBlock:6995 case TypeTableEntryIdBlock:
6975 case TypeTableEntryIdBoundFn:6996 case TypeTableEntryIdBoundFn:
...@@ -7151,10 +7172,10 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf...@@ -7151,10 +7172,10 @@ static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf
7151 case TypeTableEntryIdBoundFn:7172 case TypeTableEntryIdBoundFn:
7152 case TypeTableEntryIdNamespace:7173 case TypeTableEntryIdNamespace:
7153 case TypeTableEntryIdBlock:7174 case TypeTableEntryIdBlock:
7154 case TypeTableEntryIdNumLitFloat:7175 case TypeTableEntryIdComptimeFloat:
7155 case TypeTableEntryIdNumLitInt:7176 case TypeTableEntryIdComptimeInt:
7156 case TypeTableEntryIdUndefLit:7177 case TypeTableEntryIdUndefined:
7157 case TypeTableEntryIdNullLit:7178 case TypeTableEntryIdNull:
7158 case TypeTableEntryIdArgTuple:7179 case TypeTableEntryIdArgTuple:
7159 case TypeTableEntryIdPromise:7180 case TypeTableEntryIdPromise:
7160 zig_unreachable();7181 zig_unreachable();
...@@ -7303,11 +7324,11 @@ static void gen_h_file(CodeGen *g) {...@@ -7303,11 +7324,11 @@ static void gen_h_file(CodeGen *g) {
7303 case TypeTableEntryIdInt:7324 case TypeTableEntryIdInt:
7304 case TypeTableEntryIdFloat:7325 case TypeTableEntryIdFloat:
7305 case TypeTableEntryIdPointer:7326 case TypeTableEntryIdPointer:
7306 case TypeTableEntryIdNumLitFloat:7327 case TypeTableEntryIdComptimeFloat:
7307 case TypeTableEntryIdNumLitInt:7328 case TypeTableEntryIdComptimeInt:
7308 case TypeTableEntryIdArray:7329 case TypeTableEntryIdArray:
7309 case TypeTableEntryIdUndefLit:7330 case TypeTableEntryIdUndefined:
7310 case TypeTableEntryIdNullLit:7331 case TypeTableEntryIdNull:
7311 case TypeTableEntryIdErrorUnion:7332 case TypeTableEntryIdErrorUnion:
7312 case TypeTableEntryIdErrorSet:7333 case TypeTableEntryIdErrorSet:
7313 case TypeTableEntryIdNamespace:7334 case TypeTableEntryIdNamespace:
src/ir.cpp+305-192
...@@ -107,6 +107,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -107,6 +107,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
107static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var);107static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var);
108static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);108static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);
109static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);109static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
110static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align);
110111
111ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {112ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
112 assert(const_val->type->id == TypeTableEntryIdPointer);113 assert(const_val->type->id == TypeTableEntryIdPointer);
...@@ -6849,7 +6850,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -6849,7 +6850,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
6849 IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr);6850 IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr);
6850 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);6851 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
6851 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);6852 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
6852 IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_mem_ptr_maybe);6853 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
6854 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
6855 false, false, PtrLenUnknown, get_abi_alignment(irb->codegen, irb->codegen->builtin_types.entry_u8),
6856 0, 0));
6857 IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, coro_mem_ptr_maybe);
6853 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);6858 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
6854 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);6859 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
6855 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);6860 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
...@@ -6940,14 +6945,14 @@ static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *so...@@ -6940,14 +6945,14 @@ static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *so
6940}6945}
69416946
6942static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry *num_lit_type) {6947static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry *num_lit_type) {
6943 return ((num_lit_type->id == TypeTableEntryIdNumLitFloat &&6948 return ((num_lit_type->id == TypeTableEntryIdComptimeFloat &&
6944 (const_val->type->id == TypeTableEntryIdFloat || const_val->type->id == TypeTableEntryIdNumLitFloat)) ||6949 (const_val->type->id == TypeTableEntryIdFloat || const_val->type->id == TypeTableEntryIdComptimeFloat)) ||
6945 (num_lit_type->id == TypeTableEntryIdNumLitInt &&6950 (num_lit_type->id == TypeTableEntryIdComptimeInt &&
6946 (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt)));6951 (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdComptimeInt)));
6947}6952}
69486953
6949static bool float_has_fraction(ConstExprValue *const_val) {6954static bool float_has_fraction(ConstExprValue *const_val) {
6950 if (const_val->type->id == TypeTableEntryIdNumLitFloat) {6955 if (const_val->type->id == TypeTableEntryIdComptimeFloat) {
6951 return bigfloat_has_fraction(&const_val->data.x_bigfloat);6956 return bigfloat_has_fraction(&const_val->data.x_bigfloat);
6952 } else if (const_val->type->id == TypeTableEntryIdFloat) {6957 } else if (const_val->type->id == TypeTableEntryIdFloat) {
6953 switch (const_val->type->data.floating.bit_count) {6958 switch (const_val->type->data.floating.bit_count) {
...@@ -6970,7 +6975,7 @@ static bool float_has_fraction(ConstExprValue *const_val) {...@@ -6970,7 +6975,7 @@ static bool float_has_fraction(ConstExprValue *const_val) {
6970}6975}
69716976
6972static void float_append_buf(Buf *buf, ConstExprValue *const_val) {6977static void float_append_buf(Buf *buf, ConstExprValue *const_val) {
6973 if (const_val->type->id == TypeTableEntryIdNumLitFloat) {6978 if (const_val->type->id == TypeTableEntryIdComptimeFloat) {
6974 bigfloat_append_buf(buf, &const_val->data.x_bigfloat);6979 bigfloat_append_buf(buf, &const_val->data.x_bigfloat);
6975 } else if (const_val->type->id == TypeTableEntryIdFloat) {6980 } else if (const_val->type->id == TypeTableEntryIdFloat) {
6976 switch (const_val->type->data.floating.bit_count) {6981 switch (const_val->type->data.floating.bit_count) {
...@@ -7005,7 +7010,7 @@ static void float_append_buf(Buf *buf, ConstExprValue *const_val) {...@@ -7005,7 +7010,7 @@ static void float_append_buf(Buf *buf, ConstExprValue *const_val) {
7005}7010}
70067011
7007static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {7012static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {
7008 if (const_val->type->id == TypeTableEntryIdNumLitFloat) {7013 if (const_val->type->id == TypeTableEntryIdComptimeFloat) {
7009 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat);7014 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat);
7010 } else if (const_val->type->id == TypeTableEntryIdFloat) {7015 } else if (const_val->type->id == TypeTableEntryIdFloat) {
7011 switch (const_val->type->data.floating.bit_count) {7016 switch (const_val->type->data.floating.bit_count) {
...@@ -7041,7 +7046,7 @@ static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {...@@ -7041,7 +7046,7 @@ static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) {
7041}7046}
70427047
7043static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) {7048static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) {
7044 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {7049 if (dest_val->type->id == TypeTableEntryIdComptimeFloat) {
7045 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat);7050 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat);
7046 } else if (dest_val->type->id == TypeTableEntryIdFloat) {7051 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
7047 switch (dest_val->type->data.floating.bit_count) {7052 switch (dest_val->type->data.floating.bit_count) {
...@@ -7063,7 +7068,7 @@ static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) {...@@ -7063,7 +7068,7 @@ static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) {
7063}7068}
70647069
7065static void float_init_f32(ConstExprValue *dest_val, float x) {7070static void float_init_f32(ConstExprValue *dest_val, float x) {
7066 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {7071 if (dest_val->type->id == TypeTableEntryIdComptimeFloat) {
7067 bigfloat_init_32(&dest_val->data.x_bigfloat, x);7072 bigfloat_init_32(&dest_val->data.x_bigfloat, x);
7068 } else if (dest_val->type->id == TypeTableEntryIdFloat) {7073 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
7069 switch (dest_val->type->data.floating.bit_count) {7074 switch (dest_val->type->data.floating.bit_count) {
...@@ -7089,7 +7094,7 @@ static void float_init_f32(ConstExprValue *dest_val, float x) {...@@ -7089,7 +7094,7 @@ static void float_init_f32(ConstExprValue *dest_val, float x) {
7089}7094}
70907095
7091static void float_init_f64(ConstExprValue *dest_val, double x) {7096static void float_init_f64(ConstExprValue *dest_val, double x) {
7092 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {7097 if (dest_val->type->id == TypeTableEntryIdComptimeFloat) {
7093 bigfloat_init_64(&dest_val->data.x_bigfloat, x);7098 bigfloat_init_64(&dest_val->data.x_bigfloat, x);
7094 } else if (dest_val->type->id == TypeTableEntryIdFloat) {7099 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
7095 switch (dest_val->type->data.floating.bit_count) {7100 switch (dest_val->type->data.floating.bit_count) {
...@@ -7115,7 +7120,7 @@ static void float_init_f64(ConstExprValue *dest_val, double x) {...@@ -7115,7 +7120,7 @@ static void float_init_f64(ConstExprValue *dest_val, double x) {
7115}7120}
71167121
7117static void float_init_f128(ConstExprValue *dest_val, float128_t x) {7122static void float_init_f128(ConstExprValue *dest_val, float128_t x) {
7118 if (dest_val->type->id == TypeTableEntryIdNumLitFloat) {7123 if (dest_val->type->id == TypeTableEntryIdComptimeFloat) {
7119 bigfloat_init_128(&dest_val->data.x_bigfloat, x);7124 bigfloat_init_128(&dest_val->data.x_bigfloat, x);
7120 } else if (dest_val->type->id == TypeTableEntryIdFloat) {7125 } else if (dest_val->type->id == TypeTableEntryIdFloat) {
7121 switch (dest_val->type->data.floating.bit_count) {7126 switch (dest_val->type->data.floating.bit_count) {
...@@ -7145,7 +7150,7 @@ static void float_init_f128(ConstExprValue *dest_val, float128_t x) {...@@ -7145,7 +7150,7 @@ static void float_init_f128(ConstExprValue *dest_val, float128_t x) {
7145}7150}
71467151
7147static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) {7152static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) {
7148 if (src_val->type->id == TypeTableEntryIdNumLitFloat) {7153 if (src_val->type->id == TypeTableEntryIdComptimeFloat) {
7149 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat);7154 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat);
7150 } else if (src_val->type->id == TypeTableEntryIdFloat) {7155 } else if (src_val->type->id == TypeTableEntryIdFloat) {
7151 switch (src_val->type->data.floating.bit_count) {7156 switch (src_val->type->data.floating.bit_count) {
...@@ -7168,7 +7173,7 @@ static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val)...@@ -7168,7 +7173,7 @@ static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val)
71687173
7169static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) {7174static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) {
7170 assert(op1->type == op2->type);7175 assert(op1->type == op2->type);
7171 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7176 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7172 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat);7177 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat);
7173 } else if (op1->type->id == TypeTableEntryIdFloat) {7178 } else if (op1->type->id == TypeTableEntryIdFloat) {
7174 switch (op1->type->data.floating.bit_count) {7179 switch (op1->type->data.floating.bit_count) {
...@@ -7205,7 +7210,7 @@ static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) {...@@ -7205,7 +7210,7 @@ static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) {
7205}7210}
72067211
7207static Cmp float_cmp_zero(ConstExprValue *op) {7212static Cmp float_cmp_zero(ConstExprValue *op) {
7208 if (op->type->id == TypeTableEntryIdNumLitFloat) {7213 if (op->type->id == TypeTableEntryIdComptimeFloat) {
7209 return bigfloat_cmp_zero(&op->data.x_bigfloat);7214 return bigfloat_cmp_zero(&op->data.x_bigfloat);
7210 } else if (op->type->id == TypeTableEntryIdFloat) {7215 } else if (op->type->id == TypeTableEntryIdFloat) {
7211 switch (op->type->data.floating.bit_count) {7216 switch (op->type->data.floating.bit_count) {
...@@ -7246,7 +7251,7 @@ static Cmp float_cmp_zero(ConstExprValue *op) {...@@ -7246,7 +7251,7 @@ static Cmp float_cmp_zero(ConstExprValue *op) {
7246static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7251static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7247 assert(op1->type == op2->type);7252 assert(op1->type == op2->type);
7248 out_val->type = op1->type;7253 out_val->type = op1->type;
7249 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7254 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7250 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7255 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7251 } else if (op1->type->id == TypeTableEntryIdFloat) {7256 } else if (op1->type->id == TypeTableEntryIdFloat) {
7252 switch (op1->type->data.floating.bit_count) {7257 switch (op1->type->data.floating.bit_count) {
...@@ -7270,7 +7275,7 @@ static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal...@@ -7270,7 +7275,7 @@ static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
7270static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7275static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7271 assert(op1->type == op2->type);7276 assert(op1->type == op2->type);
7272 out_val->type = op1->type;7277 out_val->type = op1->type;
7273 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7278 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7274 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7279 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7275 } else if (op1->type->id == TypeTableEntryIdFloat) {7280 } else if (op1->type->id == TypeTableEntryIdFloat) {
7276 switch (op1->type->data.floating.bit_count) {7281 switch (op1->type->data.floating.bit_count) {
...@@ -7294,7 +7299,7 @@ static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal...@@ -7294,7 +7299,7 @@ static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
7294static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7299static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7295 assert(op1->type == op2->type);7300 assert(op1->type == op2->type);
7296 out_val->type = op1->type;7301 out_val->type = op1->type;
7297 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7302 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7298 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7303 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7299 } else if (op1->type->id == TypeTableEntryIdFloat) {7304 } else if (op1->type->id == TypeTableEntryIdFloat) {
7300 switch (op1->type->data.floating.bit_count) {7305 switch (op1->type->data.floating.bit_count) {
...@@ -7318,7 +7323,7 @@ static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal...@@ -7318,7 +7323,7 @@ static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
7318static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7323static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7319 assert(op1->type == op2->type);7324 assert(op1->type == op2->type);
7320 out_val->type = op1->type;7325 out_val->type = op1->type;
7321 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7326 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7322 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7327 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7323 } else if (op1->type->id == TypeTableEntryIdFloat) {7328 } else if (op1->type->id == TypeTableEntryIdFloat) {
7324 switch (op1->type->data.floating.bit_count) {7329 switch (op1->type->data.floating.bit_count) {
...@@ -7342,7 +7347,7 @@ static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal...@@ -7342,7 +7347,7 @@ static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
7342static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7347static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7343 assert(op1->type == op2->type);7348 assert(op1->type == op2->type);
7344 out_val->type = op1->type;7349 out_val->type = op1->type;
7345 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7350 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7346 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7351 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7347 } else if (op1->type->id == TypeTableEntryIdFloat) {7352 } else if (op1->type->id == TypeTableEntryIdFloat) {
7348 switch (op1->type->data.floating.bit_count) {7353 switch (op1->type->data.floating.bit_count) {
...@@ -7377,7 +7382,7 @@ static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstE...@@ -7377,7 +7382,7 @@ static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstE
7377static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7382static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7378 assert(op1->type == op2->type);7383 assert(op1->type == op2->type);
7379 out_val->type = op1->type;7384 out_val->type = op1->type;
7380 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7385 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7381 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7386 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7382 } else if (op1->type->id == TypeTableEntryIdFloat) {7387 } else if (op1->type->id == TypeTableEntryIdFloat) {
7383 switch (op1->type->data.floating.bit_count) {7388 switch (op1->type->data.floating.bit_count) {
...@@ -7402,7 +7407,7 @@ static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstE...@@ -7402,7 +7407,7 @@ static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstE
7402static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7407static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7403 assert(op1->type == op2->type);7408 assert(op1->type == op2->type);
7404 out_val->type = op1->type;7409 out_val->type = op1->type;
7405 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7410 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7406 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7411 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7407 } else if (op1->type->id == TypeTableEntryIdFloat) {7412 } else if (op1->type->id == TypeTableEntryIdFloat) {
7408 switch (op1->type->data.floating.bit_count) {7413 switch (op1->type->data.floating.bit_count) {
...@@ -7426,7 +7431,7 @@ static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal...@@ -7426,7 +7431,7 @@ static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
7426static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {7431static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) {
7427 assert(op1->type == op2->type);7432 assert(op1->type == op2->type);
7428 out_val->type = op1->type;7433 out_val->type = op1->type;
7429 if (op1->type->id == TypeTableEntryIdNumLitFloat) {7434 if (op1->type->id == TypeTableEntryIdComptimeFloat) {
7430 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);7435 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat);
7431 } else if (op1->type->id == TypeTableEntryIdFloat) {7436 } else if (op1->type->id == TypeTableEntryIdFloat) {
7432 switch (op1->type->data.floating.bit_count) {7437 switch (op1->type->data.floating.bit_count) {
...@@ -7451,7 +7456,7 @@ static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal...@@ -7451,7 +7456,7 @@ static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprVal
74517456
7452static void float_negate(ConstExprValue *out_val, ConstExprValue *op) {7457static void float_negate(ConstExprValue *out_val, ConstExprValue *op) {
7453 out_val->type = op->type;7458 out_val->type = op->type;
7454 if (op->type->id == TypeTableEntryIdNumLitFloat) {7459 if (op->type->id == TypeTableEntryIdComptimeFloat) {
7455 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat);7460 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat);
7456 } else if (op->type->id == TypeTableEntryIdFloat) {7461 } else if (op->type->id == TypeTableEntryIdFloat) {
7457 switch (op->type->data.floating.bit_count) {7462 switch (op->type->data.floating.bit_count) {
...@@ -7525,9 +7530,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -7525,9 +7530,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
7525 assert(const_val->special != ConstValSpecialRuntime);7530 assert(const_val->special != ConstValSpecialRuntime);
75267531
7527 bool const_val_is_int = (const_val->type->id == TypeTableEntryIdInt ||7532 bool const_val_is_int = (const_val->type->id == TypeTableEntryIdInt ||
7528 const_val->type->id == TypeTableEntryIdNumLitInt);7533 const_val->type->id == TypeTableEntryIdComptimeInt);
7529 bool const_val_is_float = (const_val->type->id == TypeTableEntryIdFloat ||7534 bool const_val_is_float = (const_val->type->id == TypeTableEntryIdFloat ||
7530 const_val->type->id == TypeTableEntryIdNumLitFloat);7535 const_val->type->id == TypeTableEntryIdComptimeFloat);
7531 if (other_type->id == TypeTableEntryIdFloat) {7536 if (other_type->id == TypeTableEntryIdFloat) {
7532 return true;7537 return true;
7533 } else if (other_type->id == TypeTableEntryIdInt && const_val_is_int) {7538 } else if (other_type->id == TypeTableEntryIdInt && const_val_is_int) {
...@@ -7571,7 +7576,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -7571,7 +7576,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
7571 return true;7576 return true;
7572 }7577 }
7573 }7578 }
7574 if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdNumLitInt) &&7579 if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdComptimeInt) &&
7575 const_val_is_float)7580 const_val_is_float)
7576 {7581 {
7577 if (float_has_fraction(const_val)) {7582 if (float_has_fraction(const_val)) {
...@@ -7584,7 +7589,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -7584,7 +7589,7 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
7584 buf_ptr(&other_type->name)));7589 buf_ptr(&other_type->name)));
7585 return false;7590 return false;
7586 } else {7591 } else {
7587 if (other_type->id == TypeTableEntryIdNumLitInt) {7592 if (other_type->id == TypeTableEntryIdComptimeInt) {
7588 return true;7593 return true;
7589 } else {7594 } else {
7590 BigInt bigint;7595 BigInt bigint;
...@@ -7955,7 +7960,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -7955,7 +7960,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
79557960
7956 // implicit conversion from null literal to maybe type7961 // implicit conversion from null literal to maybe type
7957 if (expected_type->id == TypeTableEntryIdMaybe &&7962 if (expected_type->id == TypeTableEntryIdMaybe &&
7958 actual_type->id == TypeTableEntryIdNullLit)7963 actual_type->id == TypeTableEntryIdNull)
7959 {7964 {
7960 return ImplicitCastMatchResultYes;7965 return ImplicitCastMatchResultYes;
7961 }7966 }
...@@ -8073,8 +8078,8 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -8073,8 +8078,8 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
80738078
8074 // implicit number literal to typed number8079 // implicit number literal to typed number
8075 // implicit number literal to &const integer8080 // implicit number literal to &const integer
8076 if (actual_type->id == TypeTableEntryIdNumLitFloat ||8081 if (actual_type->id == TypeTableEntryIdComptimeFloat ||
8077 actual_type->id == TypeTableEntryIdNumLitInt)8082 actual_type->id == TypeTableEntryIdComptimeInt)
8078 {8083 {
8079 if (expected_type->id == TypeTableEntryIdPointer &&8084 if (expected_type->id == TypeTableEntryIdPointer &&
8080 expected_type->data.pointer.is_const)8085 expected_type->data.pointer.is_const)
...@@ -8094,9 +8099,9 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -8094,9 +8099,9 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
8094 // implicit typed number to integer or float literal.8099 // implicit typed number to integer or float literal.
8095 // works when the number is known8100 // works when the number is known
8096 if (value->value.special == ConstValSpecialStatic) {8101 if (value->value.special == ConstValSpecialStatic) {
8097 if (actual_type->id == TypeTableEntryIdInt && expected_type->id == TypeTableEntryIdNumLitInt) {8102 if (actual_type->id == TypeTableEntryIdInt && expected_type->id == TypeTableEntryIdComptimeInt) {
8098 return ImplicitCastMatchResultYes;8103 return ImplicitCastMatchResultYes;
8099 } else if (actual_type->id == TypeTableEntryIdFloat && expected_type->id == TypeTableEntryIdNumLitFloat) {8104 } else if (actual_type->id == TypeTableEntryIdFloat && expected_type->id == TypeTableEntryIdComptimeFloat) {
8100 return ImplicitCastMatchResultYes;8105 return ImplicitCastMatchResultYes;
8101 }8106 }
8102 }8107 }
...@@ -8137,7 +8142,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -8137,7 +8142,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
8137 }8142 }
81388143
8139 // implicit undefined literal to anything8144 // implicit undefined literal to anything
8140 if (actual_type->id == TypeTableEntryIdUndefLit) {8145 if (actual_type->id == TypeTableEntryIdUndefined) {
8141 return ImplicitCastMatchResultYes;8146 return ImplicitCastMatchResultYes;
8142 }8147 }
81438148
...@@ -8185,7 +8190,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8185,7 +8190,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8185 }8190 }
8186 }8191 }
81878192
8188 bool any_are_null = (prev_inst->value.type->id == TypeTableEntryIdNullLit);8193 bool any_are_null = (prev_inst->value.type->id == TypeTableEntryIdNull);
8189 bool convert_to_const_slice = false;8194 bool convert_to_const_slice = false;
8190 for (size_t i = 1; i < instruction_count; i += 1) {8195 for (size_t i = 1; i < instruction_count; i += 1) {
8191 IrInstruction *cur_inst = instructions[i];8196 IrInstruction *cur_inst = instructions[i];
...@@ -8464,12 +8469,12 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8464,12 +8469,12 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8464 }8469 }
8465 }8470 }
84668471
8467 if (prev_type->id == TypeTableEntryIdNullLit) {8472 if (prev_type->id == TypeTableEntryIdNull) {
8468 prev_inst = cur_inst;8473 prev_inst = cur_inst;
8469 continue;8474 continue;
8470 }8475 }
84718476
8472 if (cur_type->id == TypeTableEntryIdNullLit) {8477 if (cur_type->id == TypeTableEntryIdNull) {
8473 any_are_null = true;8478 any_are_null = true;
8474 continue;8479 continue;
8475 }8480 }
...@@ -8541,17 +8546,17 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8541,17 +8546,17 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8541 continue;8546 continue;
8542 }8547 }
85438548
8544 if (cur_type->id == TypeTableEntryIdUndefLit) {8549 if (cur_type->id == TypeTableEntryIdUndefined) {
8545 continue;8550 continue;
8546 }8551 }
85478552
8548 if (prev_type->id == TypeTableEntryIdUndefLit) {8553 if (prev_type->id == TypeTableEntryIdUndefined) {
8549 prev_inst = cur_inst;8554 prev_inst = cur_inst;
8550 continue;8555 continue;
8551 }8556 }
85528557
8553 if (prev_type->id == TypeTableEntryIdNumLitInt ||8558 if (prev_type->id == TypeTableEntryIdComptimeInt ||
8554 prev_type->id == TypeTableEntryIdNumLitFloat)8559 prev_type->id == TypeTableEntryIdComptimeFloat)
8555 {8560 {
8556 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) {8561 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) {
8557 prev_inst = cur_inst;8562 prev_inst = cur_inst;
...@@ -8561,8 +8566,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8561,8 +8566,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8561 }8566 }
8562 }8567 }
85638568
8564 if (cur_type->id == TypeTableEntryIdNumLitInt ||8569 if (cur_type->id == TypeTableEntryIdComptimeInt ||
8565 cur_type->id == TypeTableEntryIdNumLitFloat)8570 cur_type->id == TypeTableEntryIdComptimeFloat)
8566 {8571 {
8567 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) {8572 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) {
8568 continue;8573 continue;
...@@ -8666,13 +8671,13 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8666,13 +8671,13 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8666 } else if (expected_type != nullptr && expected_type->id == TypeTableEntryIdErrorUnion) {8671 } else if (expected_type != nullptr && expected_type->id == TypeTableEntryIdErrorUnion) {
8667 return get_error_union_type(ira->codegen, err_set_type, expected_type->data.error_union.payload_type);8672 return get_error_union_type(ira->codegen, err_set_type, expected_type->data.error_union.payload_type);
8668 } else {8673 } else {
8669 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||8674 if (prev_inst->value.type->id == TypeTableEntryIdComptimeInt ||
8670 prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)8675 prev_inst->value.type->id == TypeTableEntryIdComptimeFloat)
8671 {8676 {
8672 ir_add_error_node(ira, source_node,8677 ir_add_error_node(ira, source_node,
8673 buf_sprintf("unable to make error union out of number literal"));8678 buf_sprintf("unable to make error union out of number literal"));
8674 return ira->codegen->builtin_types.entry_invalid;8679 return ira->codegen->builtin_types.entry_invalid;
8675 } else if (prev_inst->value.type->id == TypeTableEntryIdNullLit) {8680 } else if (prev_inst->value.type->id == TypeTableEntryIdNull) {
8676 ir_add_error_node(ira, source_node,8681 ir_add_error_node(ira, source_node,
8677 buf_sprintf("unable to make error union out of null literal"));8682 buf_sprintf("unable to make error union out of null literal"));
8678 return ira->codegen->builtin_types.entry_invalid;8683 return ira->codegen->builtin_types.entry_invalid;
...@@ -8680,9 +8685,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod...@@ -8680,9 +8685,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
8680 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type);8685 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type);
8681 }8686 }
8682 }8687 }
8683 } else if (any_are_null && prev_inst->value.type->id != TypeTableEntryIdNullLit) {8688 } else if (any_are_null && prev_inst->value.type->id != TypeTableEntryIdNull) {
8684 if (prev_inst->value.type->id == TypeTableEntryIdNumLitInt ||8689 if (prev_inst->value.type->id == TypeTableEntryIdComptimeInt ||
8685 prev_inst->value.type->id == TypeTableEntryIdNumLitFloat)8690 prev_inst->value.type->id == TypeTableEntryIdComptimeFloat)
8686 {8691 {
8687 ir_add_error_node(ira, source_node,8692 ir_add_error_node(ira, source_node,
8688 buf_sprintf("unable to make maybe out of number literal"));8693 buf_sprintf("unable to make maybe out of number literal"));
...@@ -8729,6 +8734,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -8729,6 +8734,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
8729 case CastOpNoCast:8734 case CastOpNoCast:
8730 zig_unreachable();8735 zig_unreachable();
8731 case CastOpErrSet:8736 case CastOpErrSet:
8737 case CastOpBitCast:
8732 zig_panic("TODO");8738 zig_panic("TODO");
8733 case CastOpNoop:8739 case CastOpNoop:
8734 {8740 {
...@@ -8737,7 +8743,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -8737,7 +8743,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
8737 break;8743 break;
8738 }8744 }
8739 case CastOpNumLitToConcrete:8745 case CastOpNumLitToConcrete:
8740 if (other_val->type->id == TypeTableEntryIdNumLitFloat) {8746 if (other_val->type->id == TypeTableEntryIdComptimeFloat) {
8741 assert(new_type->id == TypeTableEntryIdFloat);8747 assert(new_type->id == TypeTableEntryIdFloat);
8742 switch (new_type->data.floating.bit_count) {8748 switch (new_type->data.floating.bit_count) {
8743 case 32:8749 case 32:
...@@ -8752,7 +8758,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -8752,7 +8758,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
8752 default:8758 default:
8753 zig_unreachable();8759 zig_unreachable();
8754 }8760 }
8755 } else if (other_val->type->id == TypeTableEntryIdNumLitInt) {8761 } else if (other_val->type->id == TypeTableEntryIdComptimeInt) {
8756 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint);8762 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint);
8757 } else {8763 } else {
8758 zig_unreachable();8764 zig_unreachable();
...@@ -9595,9 +9601,9 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction...@@ -9595,9 +9601,9 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction
95959601
9596 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,9602 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope,
9597 source_instr->source_node, wanted_type);9603 source_instr->source_node, wanted_type);
9598 if (wanted_type->id == TypeTableEntryIdNumLitFloat) {9604 if (wanted_type->id == TypeTableEntryIdComptimeFloat) {
9599 float_init_float(&result->value, val);9605 float_init_float(&result->value, val);
9600 } else if (wanted_type->id == TypeTableEntryIdNumLitInt) {9606 } else if (wanted_type->id == TypeTableEntryIdComptimeInt) {
9601 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);9607 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint);
9602 } else {9608 } else {
9603 zig_unreachable();9609 zig_unreachable();
...@@ -9750,6 +9756,49 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc...@@ -9750,6 +9756,49 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc
9750 return result;9756 return result;
9751}9757}
97529758
9759static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
9760 TypeTableEntry *wanted_type)
9761{
9762 assert(wanted_type->id == TypeTableEntryIdPointer);
9763 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, target->value.type->data.pointer.alignment);
9764 TypeTableEntry *array_type = wanted_type->data.pointer.child_type;
9765 assert(array_type->id == TypeTableEntryIdArray);
9766 assert(array_type->data.array.len == 1);
9767
9768 if (instr_is_comptime(target)) {
9769 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
9770 if (!val)
9771 return ira->codegen->invalid_instruction;
9772
9773 assert(val->type->id == TypeTableEntryIdPointer);
9774 ConstExprValue *pointee = const_ptr_pointee(ira->codegen, val);
9775 if (pointee->special != ConstValSpecialRuntime) {
9776 ConstExprValue *array_val = create_const_vals(1);
9777 array_val->special = ConstValSpecialStatic;
9778 array_val->type = array_type;
9779 array_val->data.x_array.special = ConstArraySpecialNone;
9780 array_val->data.x_array.s_none.elements = pointee;
9781 array_val->data.x_array.s_none.parent.id = ConstParentIdScalar;
9782 array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee;
9783
9784 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
9785 source_instr->scope, source_instr->source_node);
9786 const_instruction->base.value.type = wanted_type;
9787 const_instruction->base.value.special = ConstValSpecialStatic;
9788 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef;
9789 const_instruction->base.value.data.x_ptr.data.ref.pointee = array_val;
9790 const_instruction->base.value.data.x_ptr.mut = val->data.x_ptr.mut;
9791 return &const_instruction->base;
9792 }
9793 }
9794
9795 // pointer to array and pointer to single item are represented the same way at runtime
9796 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node,
9797 wanted_type, target, CastOpBitCast);
9798 result->value.type = wanted_type;
9799 return result;
9800}
9801
9753static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,9802static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
9754 TypeTableEntry *wanted_type, IrInstruction *value)9803 TypeTableEntry *wanted_type, IrInstruction *value)
9755{9804{
...@@ -9929,8 +9978,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -9929,8 +9978,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
9929 TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type;9978 TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type;
9930 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node).id == ConstCastResultIdOk) {9979 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node).id == ConstCastResultIdOk) {
9931 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);9980 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
9932 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||9981 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||
9933 actual_type->id == TypeTableEntryIdNumLitFloat)9982 actual_type->id == TypeTableEntryIdComptimeFloat)
9934 {9983 {
9935 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {9984 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) {
9936 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);9985 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type);
...@@ -9955,7 +10004,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -9955,7 +10004,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
995510004
9956 // explicit cast from null literal to maybe type10005 // explicit cast from null literal to maybe type
9957 if (wanted_type->id == TypeTableEntryIdMaybe &&10006 if (wanted_type->id == TypeTableEntryIdMaybe &&
9958 actual_type->id == TypeTableEntryIdNullLit)10007 actual_type->id == TypeTableEntryIdNull)
9959 {10008 {
9960 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type);10009 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type);
9961 }10010 }
...@@ -9964,8 +10013,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -9964,8 +10013,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
9964 if (wanted_type->id == TypeTableEntryIdErrorUnion) {10013 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
9965 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, source_node).id == ConstCastResultIdOk) {10014 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, source_node).id == ConstCastResultIdOk) {
9966 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);10015 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
9967 } else if (actual_type->id == TypeTableEntryIdNumLitInt ||10016 } else if (actual_type->id == TypeTableEntryIdComptimeInt ||
9968 actual_type->id == TypeTableEntryIdNumLitFloat)10017 actual_type->id == TypeTableEntryIdComptimeFloat)
9969 {10018 {
9970 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {10019 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) {
9971 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);10020 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type);
...@@ -10012,9 +10061,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10012,9 +10061,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10012 {10061 {
10013 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;10062 TypeTableEntry *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type;
10014 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node).id == ConstCastResultIdOk ||10063 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node).id == ConstCastResultIdOk ||
10015 actual_type->id == TypeTableEntryIdNullLit ||10064 actual_type->id == TypeTableEntryIdNull ||
10016 actual_type->id == TypeTableEntryIdNumLitInt ||10065 actual_type->id == TypeTableEntryIdComptimeInt ||
10017 actual_type->id == TypeTableEntryIdNumLitFloat)10066 actual_type->id == TypeTableEntryIdComptimeFloat)
10018 {10067 {
10019 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);10068 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value);
10020 if (type_is_invalid(cast1->value.type))10069 if (type_is_invalid(cast1->value.type))
...@@ -10030,8 +10079,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10030,8 +10079,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1003010079
10031 // explicit cast from number literal to another type10080 // explicit cast from number literal to another type
10032 // explicit cast from number literal to &const integer10081 // explicit cast from number literal to &const integer
10033 if (actual_type->id == TypeTableEntryIdNumLitFloat ||10082 if (actual_type->id == TypeTableEntryIdComptimeFloat ||
10034 actual_type->id == TypeTableEntryIdNumLitInt)10083 actual_type->id == TypeTableEntryIdComptimeInt)
10035 {10084 {
10036 ensure_complete_type(ira->codegen, wanted_type);10085 ensure_complete_type(ira->codegen, wanted_type);
10037 if (type_is_invalid(wanted_type))10086 if (type_is_invalid(wanted_type))
...@@ -10060,9 +10109,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10060,9 +10109,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10060 return cast2;10109 return cast2;
10061 } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) {10110 } else if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) {
10062 CastOp op;10111 CastOp op;
10063 if ((actual_type->id == TypeTableEntryIdNumLitFloat &&10112 if ((actual_type->id == TypeTableEntryIdComptimeFloat &&
10064 wanted_type->id == TypeTableEntryIdFloat) ||10113 wanted_type->id == TypeTableEntryIdFloat) ||
10065 (actual_type->id == TypeTableEntryIdNumLitInt &&10114 (actual_type->id == TypeTableEntryIdComptimeInt &&
10066 wanted_type->id == TypeTableEntryIdInt))10115 wanted_type->id == TypeTableEntryIdInt))
10067 {10116 {
10068 op = CastOpNumLitToConcrete;10117 op = CastOpNumLitToConcrete;
...@@ -10082,8 +10131,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10082,8 +10131,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10082 // explicit cast from typed number to integer or float literal.10131 // explicit cast from typed number to integer or float literal.
10083 // works when the number is known at compile time10132 // works when the number is known at compile time
10084 if (instr_is_comptime(value) &&10133 if (instr_is_comptime(value) &&
10085 ((actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdNumLitInt) ||10134 ((actual_type->id == TypeTableEntryIdInt && wanted_type->id == TypeTableEntryIdComptimeInt) ||
10086 (actual_type->id == TypeTableEntryIdFloat && wanted_type->id == TypeTableEntryIdNumLitFloat)))10135 (actual_type->id == TypeTableEntryIdFloat && wanted_type->id == TypeTableEntryIdComptimeFloat)))
10087 {10136 {
10088 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type);10137 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type);
10089 }10138 }
...@@ -10156,8 +10205,32 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -10156,8 +10205,32 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
10156 }10205 }
10157 }10206 }
1015810207
10208 // explicit cast from *T to *[1]T
10209 if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
10210 actual_type->id == TypeTableEntryIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle)
10211 {
10212 TypeTableEntry *array_type = wanted_type->data.pointer.child_type;
10213 if (array_type->id == TypeTableEntryIdArray && array_type->data.array.len == 1 &&
10214 types_match_const_cast_only(ira, array_type->data.array.child_type,
10215 actual_type->data.pointer.child_type, source_node).id == ConstCastResultIdOk)
10216 {
10217 if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) {
10218 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment"));
10219 add_error_note(ira->codegen, msg, value->source_node,
10220 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name),
10221 actual_type->data.pointer.alignment));
10222 add_error_note(ira->codegen, msg, source_instr->source_node,
10223 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name),
10224 wanted_type->data.pointer.alignment));
10225 return ira->codegen->invalid_instruction;
10226 }
10227 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type);
10228 }
10229 }
10230
10231
10159 // explicit cast from undefined to anything10232 // explicit cast from undefined to anything
10160 if (actual_type->id == TypeTableEntryIdUndefLit) {10233 if (actual_type->id == TypeTableEntryIdUndefined) {
10161 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);10234 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
10162 }10235 }
1016310236
...@@ -10554,19 +10627,19 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -10554,19 +10627,19 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
10554 IrBinOp op_id = bin_op_instruction->op_id;10627 IrBinOp op_id = bin_op_instruction->op_id;
10555 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq);10628 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq);
10556 if (is_equality_cmp &&10629 if (is_equality_cmp &&
10557 ((op1->value.type->id == TypeTableEntryIdNullLit && op2->value.type->id == TypeTableEntryIdMaybe) ||10630 ((op1->value.type->id == TypeTableEntryIdNull && op2->value.type->id == TypeTableEntryIdMaybe) ||
10558 (op2->value.type->id == TypeTableEntryIdNullLit && op1->value.type->id == TypeTableEntryIdMaybe) ||10631 (op2->value.type->id == TypeTableEntryIdNull && op1->value.type->id == TypeTableEntryIdMaybe) ||
10559 (op1->value.type->id == TypeTableEntryIdNullLit && op2->value.type->id == TypeTableEntryIdNullLit)))10632 (op1->value.type->id == TypeTableEntryIdNull && op2->value.type->id == TypeTableEntryIdNull)))
10560 {10633 {
10561 if (op1->value.type->id == TypeTableEntryIdNullLit && op2->value.type->id == TypeTableEntryIdNullLit) {10634 if (op1->value.type->id == TypeTableEntryIdNull && op2->value.type->id == TypeTableEntryIdNull) {
10562 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base);10635 ConstExprValue *out_val = ir_build_const_from(ira, &bin_op_instruction->base);
10563 out_val->data.x_bool = (op_id == IrBinOpCmpEq);10636 out_val->data.x_bool = (op_id == IrBinOpCmpEq);
10564 return ira->codegen->builtin_types.entry_bool;10637 return ira->codegen->builtin_types.entry_bool;
10565 }10638 }
10566 IrInstruction *maybe_op;10639 IrInstruction *maybe_op;
10567 if (op1->value.type->id == TypeTableEntryIdNullLit) {10640 if (op1->value.type->id == TypeTableEntryIdNull) {
10568 maybe_op = op2;10641 maybe_op = op2;
10569 } else if (op2->value.type->id == TypeTableEntryIdNullLit) {10642 } else if (op2->value.type->id == TypeTableEntryIdNull) {
10570 maybe_op = op1;10643 maybe_op = op1;
10571 } else {10644 } else {
10572 zig_unreachable();10645 zig_unreachable();
...@@ -10686,8 +10759,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -10686,8 +10759,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
10686 case TypeTableEntryIdInvalid:10759 case TypeTableEntryIdInvalid:
10687 zig_unreachable(); // handled above10760 zig_unreachable(); // handled above
1068810761
10689 case TypeTableEntryIdNumLitFloat:10762 case TypeTableEntryIdComptimeFloat:
10690 case TypeTableEntryIdNumLitInt:10763 case TypeTableEntryIdComptimeInt:
10691 case TypeTableEntryIdInt:10764 case TypeTableEntryIdInt:
10692 case TypeTableEntryIdFloat:10765 case TypeTableEntryIdFloat:
10693 break;10766 break;
...@@ -10722,8 +10795,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -10722,8 +10795,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
10722 case TypeTableEntryIdUnreachable:10795 case TypeTableEntryIdUnreachable:
10723 case TypeTableEntryIdArray:10796 case TypeTableEntryIdArray:
10724 case TypeTableEntryIdStruct:10797 case TypeTableEntryIdStruct:
10725 case TypeTableEntryIdUndefLit:10798 case TypeTableEntryIdUndefined:
10726 case TypeTableEntryIdNullLit:10799 case TypeTableEntryIdNull:
10727 case TypeTableEntryIdMaybe:10800 case TypeTableEntryIdMaybe:
10728 case TypeTableEntryIdErrorUnion:10801 case TypeTableEntryIdErrorUnion:
10729 case TypeTableEntryIdUnion:10802 case TypeTableEntryIdUnion:
...@@ -10745,10 +10818,10 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -10745,10 +10818,10 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
10745 bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type);10818 bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type);
10746 if (one_possible_value || (value_is_comptime(op1_val) && value_is_comptime(op2_val))) {10819 if (one_possible_value || (value_is_comptime(op1_val) && value_is_comptime(op2_val))) {
10747 bool answer;10820 bool answer;
10748 if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) {10821 if (resolved_type->id == TypeTableEntryIdComptimeFloat || resolved_type->id == TypeTableEntryIdFloat) {
10749 Cmp cmp_result = float_cmp(op1_val, op2_val);10822 Cmp cmp_result = float_cmp(op1_val, op2_val);
10750 answer = resolve_cmp_op_id(op_id, cmp_result);10823 answer = resolve_cmp_op_id(op_id, cmp_result);
10751 } else if (resolved_type->id == TypeTableEntryIdNumLitInt || resolved_type->id == TypeTableEntryIdInt) {10824 } else if (resolved_type->id == TypeTableEntryIdComptimeInt || resolved_type->id == TypeTableEntryIdInt) {
10752 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);10825 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
10753 answer = resolve_cmp_op_id(op_id, cmp_result);10826 answer = resolve_cmp_op_id(op_id, cmp_result);
10754 } else {10827 } else {
...@@ -10812,12 +10885,12 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,...@@ -10812,12 +10885,12 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val,
10812 bool is_int;10885 bool is_int;
10813 bool is_float;10886 bool is_float;
10814 Cmp op2_zcmp;10887 Cmp op2_zcmp;
10815 if (type_entry->id == TypeTableEntryIdInt || type_entry->id == TypeTableEntryIdNumLitInt) {10888 if (type_entry->id == TypeTableEntryIdInt || type_entry->id == TypeTableEntryIdComptimeInt) {
10816 is_int = true;10889 is_int = true;
10817 is_float = false;10890 is_float = false;
10818 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint);10891 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint);
10819 } else if (type_entry->id == TypeTableEntryIdFloat ||10892 } else if (type_entry->id == TypeTableEntryIdFloat ||
10820 type_entry->id == TypeTableEntryIdNumLitFloat)10893 type_entry->id == TypeTableEntryIdComptimeFloat)
10821 {10894 {
10822 is_int = false;10895 is_int = false;
10823 is_float = true;10896 is_float = true;
...@@ -10991,7 +11064,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *...@@ -10991,7 +11064,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
10991 if (type_is_invalid(op1->value.type))11064 if (type_is_invalid(op1->value.type))
10992 return ira->codegen->builtin_types.entry_invalid;11065 return ira->codegen->builtin_types.entry_invalid;
1099311066
10994 if (op1->value.type->id != TypeTableEntryIdInt && op1->value.type->id != TypeTableEntryIdNumLitInt) {11067 if (op1->value.type->id != TypeTableEntryIdInt && op1->value.type->id != TypeTableEntryIdComptimeInt) {
10995 ir_add_error(ira, &bin_op_instruction->base,11068 ir_add_error(ira, &bin_op_instruction->base,
10996 buf_sprintf("bit shifting operation expected integer type, found '%s'",11069 buf_sprintf("bit shifting operation expected integer type, found '%s'",
10997 buf_ptr(&op1->value.type->name)));11070 buf_ptr(&op1->value.type->name)));
...@@ -11004,7 +11077,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *...@@ -11004,7 +11077,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
1100411077
11005 IrInstruction *casted_op2;11078 IrInstruction *casted_op2;
11006 IrBinOp op_id = bin_op_instruction->op_id;11079 IrBinOp op_id = bin_op_instruction->op_id;
11007 if (op1->value.type->id == TypeTableEntryIdNumLitInt) {11080 if (op1->value.type->id == TypeTableEntryIdComptimeInt) {
11008 casted_op2 = op2;11081 casted_op2 = op2;
1100911082
11010 if (op_id == IrBinOpBitShiftLeftLossy) {11083 if (op_id == IrBinOpBitShiftLeftLossy) {
...@@ -11049,7 +11122,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *...@@ -11049,7 +11122,7 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
1104911122
11050 ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false);11123 ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false);
11051 return op1->value.type;11124 return op1->value.type;
11052 } else if (op1->value.type->id == TypeTableEntryIdNumLitInt) {11125 } else if (op1->value.type->id == TypeTableEntryIdComptimeInt) {
11053 ir_add_error(ira, &bin_op_instruction->base,11126 ir_add_error(ira, &bin_op_instruction->base,
11054 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known"));11127 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known"));
11055 return ira->codegen->builtin_types.entry_invalid;11128 return ira->codegen->builtin_types.entry_invalid;
...@@ -11085,15 +11158,15 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp...@@ -11085,15 +11158,15 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
11085 if (type_is_invalid(resolved_type))11158 if (type_is_invalid(resolved_type))
11086 return resolved_type;11159 return resolved_type;
1108711160
11088 bool is_int = resolved_type->id == TypeTableEntryIdInt || resolved_type->id == TypeTableEntryIdNumLitInt;11161 bool is_int = resolved_type->id == TypeTableEntryIdInt || resolved_type->id == TypeTableEntryIdComptimeInt;
11089 bool is_float = resolved_type->id == TypeTableEntryIdFloat || resolved_type->id == TypeTableEntryIdNumLitFloat;11162 bool is_float = resolved_type->id == TypeTableEntryIdFloat || resolved_type->id == TypeTableEntryIdComptimeFloat;
11090 bool is_signed_div = (11163 bool is_signed_div = (
11091 (resolved_type->id == TypeTableEntryIdInt && resolved_type->data.integral.is_signed) ||11164 (resolved_type->id == TypeTableEntryIdInt && resolved_type->data.integral.is_signed) ||
11092 resolved_type->id == TypeTableEntryIdFloat ||11165 resolved_type->id == TypeTableEntryIdFloat ||
11093 (resolved_type->id == TypeTableEntryIdNumLitFloat &&11166 (resolved_type->id == TypeTableEntryIdComptimeFloat &&
11094 ((bigfloat_cmp_zero(&op1->value.data.x_bigfloat) != CmpGT) !=11167 ((bigfloat_cmp_zero(&op1->value.data.x_bigfloat) != CmpGT) !=
11095 (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) != CmpGT))) ||11168 (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) != CmpGT))) ||
11096 (resolved_type->id == TypeTableEntryIdNumLitInt &&11169 (resolved_type->id == TypeTableEntryIdComptimeInt &&
11097 ((bigint_cmp_zero(&op1->value.data.x_bigint) != CmpGT) !=11170 ((bigint_cmp_zero(&op1->value.data.x_bigint) != CmpGT) !=
11098 (bigint_cmp_zero(&op2->value.data.x_bigint) != CmpGT)))11171 (bigint_cmp_zero(&op2->value.data.x_bigint) != CmpGT)))
11099 );11172 );
...@@ -11194,7 +11267,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp...@@ -11194,7 +11267,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
11194 return ira->codegen->builtin_types.entry_invalid;11267 return ira->codegen->builtin_types.entry_invalid;
11195 }11268 }
1119611269
11197 if (resolved_type->id == TypeTableEntryIdNumLitInt) {11270 if (resolved_type->id == TypeTableEntryIdComptimeInt) {
11198 if (op_id == IrBinOpAddWrap) {11271 if (op_id == IrBinOpAddWrap) {
11199 op_id = IrBinOpAdd;11272 op_id = IrBinOpAdd;
11200 } else if (op_id == IrBinOpSubWrap) {11273 } else if (op_id == IrBinOpSubWrap) {
...@@ -11568,11 +11641,11 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {...@@ -11568,11 +11641,11 @@ static VarClassRequired get_var_class_required(TypeTableEntry *type_entry) {
11568 case TypeTableEntryIdFn:11641 case TypeTableEntryIdFn:
11569 case TypeTableEntryIdPromise:11642 case TypeTableEntryIdPromise:
11570 return VarClassRequiredAny;11643 return VarClassRequiredAny;
11571 case TypeTableEntryIdNumLitFloat:11644 case TypeTableEntryIdComptimeFloat:
11572 case TypeTableEntryIdNumLitInt:11645 case TypeTableEntryIdComptimeInt:
11573 case TypeTableEntryIdUndefLit:11646 case TypeTableEntryIdUndefined:
11574 case TypeTableEntryIdBlock:11647 case TypeTableEntryIdBlock:
11575 case TypeTableEntryIdNullLit:11648 case TypeTableEntryIdNull:
11576 case TypeTableEntryIdOpaque:11649 case TypeTableEntryIdOpaque:
11577 case TypeTableEntryIdMetaType:11650 case TypeTableEntryIdMetaType:
11578 case TypeTableEntryIdNamespace:11651 case TypeTableEntryIdNamespace:
...@@ -11837,10 +11910,10 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi...@@ -11837,10 +11910,10 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
11837 case TypeTableEntryIdMetaType:11910 case TypeTableEntryIdMetaType:
11838 case TypeTableEntryIdVoid:11911 case TypeTableEntryIdVoid:
11839 case TypeTableEntryIdUnreachable:11912 case TypeTableEntryIdUnreachable:
11840 case TypeTableEntryIdNumLitFloat:11913 case TypeTableEntryIdComptimeFloat:
11841 case TypeTableEntryIdNumLitInt:11914 case TypeTableEntryIdComptimeInt:
11842 case TypeTableEntryIdUndefLit:11915 case TypeTableEntryIdUndefined:
11843 case TypeTableEntryIdNullLit:11916 case TypeTableEntryIdNull:
11844 case TypeTableEntryIdMaybe:11917 case TypeTableEntryIdMaybe:
11845 case TypeTableEntryIdErrorUnion:11918 case TypeTableEntryIdErrorUnion:
11846 case TypeTableEntryIdErrorSet:11919 case TypeTableEntryIdErrorSet:
...@@ -11861,10 +11934,10 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi...@@ -11861,10 +11934,10 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi
11861 case TypeTableEntryIdFloat:11934 case TypeTableEntryIdFloat:
11862 case TypeTableEntryIdPointer:11935 case TypeTableEntryIdPointer:
11863 case TypeTableEntryIdArray:11936 case TypeTableEntryIdArray:
11864 case TypeTableEntryIdNumLitFloat:11937 case TypeTableEntryIdComptimeFloat:
11865 case TypeTableEntryIdNumLitInt:11938 case TypeTableEntryIdComptimeInt:
11866 case TypeTableEntryIdUndefLit:11939 case TypeTableEntryIdUndefined:
11867 case TypeTableEntryIdNullLit:11940 case TypeTableEntryIdNull:
11868 case TypeTableEntryIdMaybe:11941 case TypeTableEntryIdMaybe:
11869 case TypeTableEntryIdErrorUnion:11942 case TypeTableEntryIdErrorUnion:
11870 case TypeTableEntryIdErrorSet:11943 case TypeTableEntryIdErrorSet:
...@@ -12076,7 +12149,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -12076,7 +12149,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
12076 }12149 }
1207712150
12078 bool comptime_arg = param_decl_node->data.param_decl.is_inline ||12151 bool comptime_arg = param_decl_node->data.param_decl.is_inline ||
12079 casted_arg->value.type->id == TypeTableEntryIdNumLitInt || casted_arg->value.type->id == TypeTableEntryIdNumLitFloat;12152 casted_arg->value.type->id == TypeTableEntryIdComptimeInt || casted_arg->value.type->id == TypeTableEntryIdComptimeFloat;
1208012153
12081 ConstExprValue *arg_val;12154 ConstExprValue *arg_val;
1208212155
...@@ -12101,8 +12174,8 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -12101,8 +12174,8 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
12101 var->shadowable = !comptime_arg;12174 var->shadowable = !comptime_arg;
1210212175
12103 *next_proto_i += 1;12176 *next_proto_i += 1;
12104 } else if (casted_arg->value.type->id == TypeTableEntryIdNumLitInt ||12177 } else if (casted_arg->value.type->id == TypeTableEntryIdComptimeInt ||
12105 casted_arg->value.type->id == TypeTableEntryIdNumLitFloat)12178 casted_arg->value.type->id == TypeTableEntryIdComptimeFloat)
12106 {12179 {
12107 ir_add_error(ira, casted_arg,12180 ir_add_error(ira, casted_arg,
12108 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557"));12181 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557"));
...@@ -12825,10 +12898,10 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op...@@ -12825,10 +12898,10 @@ static TypeTableEntry *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op
12825 case TypeTableEntryIdPointer:12898 case TypeTableEntryIdPointer:
12826 case TypeTableEntryIdArray:12899 case TypeTableEntryIdArray:
12827 case TypeTableEntryIdStruct:12900 case TypeTableEntryIdStruct:
12828 case TypeTableEntryIdNumLitFloat:12901 case TypeTableEntryIdComptimeFloat:
12829 case TypeTableEntryIdNumLitInt:12902 case TypeTableEntryIdComptimeInt:
12830 case TypeTableEntryIdUndefLit:12903 case TypeTableEntryIdUndefined:
12831 case TypeTableEntryIdNullLit:12904 case TypeTableEntryIdNull:
12832 case TypeTableEntryIdMaybe:12905 case TypeTableEntryIdMaybe:
12833 case TypeTableEntryIdErrorUnion:12906 case TypeTableEntryIdErrorUnion:
12834 case TypeTableEntryIdErrorSet:12907 case TypeTableEntryIdErrorSet:
...@@ -12862,10 +12935,10 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un...@@ -12862,10 +12935,10 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un
1286212935
12863 bool is_wrap_op = (un_op_instruction->op_id == IrUnOpNegationWrap);12936 bool is_wrap_op = (un_op_instruction->op_id == IrUnOpNegationWrap);
1286412937
12865 bool is_float = (expr_type->id == TypeTableEntryIdFloat || expr_type->id == TypeTableEntryIdNumLitFloat);12938 bool is_float = (expr_type->id == TypeTableEntryIdFloat || expr_type->id == TypeTableEntryIdComptimeFloat);
1286612939
12867 if ((expr_type->id == TypeTableEntryIdInt && expr_type->data.integral.is_signed) ||12940 if ((expr_type->id == TypeTableEntryIdInt && expr_type->data.integral.is_signed) ||
12868 expr_type->id == TypeTableEntryIdNumLitInt || (is_float && !is_wrap_op))12941 expr_type->id == TypeTableEntryIdComptimeInt || (is_float && !is_wrap_op))
12869 {12942 {
12870 if (instr_is_comptime(value)) {12943 if (instr_is_comptime(value)) {
12871 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad);12944 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad);
...@@ -12881,7 +12954,7 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un...@@ -12881,7 +12954,7 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un
12881 } else {12954 } else {
12882 bigint_negate(&out_val->data.x_bigint, &target_const_val->data.x_bigint);12955 bigint_negate(&out_val->data.x_bigint, &target_const_val->data.x_bigint);
12883 }12956 }
12884 if (is_wrap_op || is_float || expr_type->id == TypeTableEntryIdNumLitInt) {12957 if (is_wrap_op || is_float || expr_type->id == TypeTableEntryIdComptimeInt) {
12885 return expr_type;12958 return expr_type;
12886 }12959 }
1288712960
...@@ -13077,10 +13150,10 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -13077,10 +13150,10 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
13077 if (type_is_invalid(resolved_type))13150 if (type_is_invalid(resolved_type))
13078 return resolved_type;13151 return resolved_type;
1307913152
13080 if (resolved_type->id == TypeTableEntryIdNumLitFloat ||13153 if (resolved_type->id == TypeTableEntryIdComptimeFloat ||
13081 resolved_type->id == TypeTableEntryIdNumLitInt ||13154 resolved_type->id == TypeTableEntryIdComptimeInt ||
13082 resolved_type->id == TypeTableEntryIdNullLit ||13155 resolved_type->id == TypeTableEntryIdNull ||
13083 resolved_type->id == TypeTableEntryIdUndefLit)13156 resolved_type->id == TypeTableEntryIdUndefined)
13084 {13157 {
13085 ir_add_error_node(ira, phi_instruction->base.source_node,13158 ir_add_error_node(ira, phi_instruction->base.source_node,
13086 buf_sprintf("unable to infer expression type"));13159 buf_sprintf("unable to infer expression type"));
...@@ -13162,11 +13235,13 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13162,11 +13235,13 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
13162 if (type_is_invalid(array_ptr->value.type))13235 if (type_is_invalid(array_ptr->value.type))
13163 return ira->codegen->builtin_types.entry_invalid;13236 return ira->codegen->builtin_types.entry_invalid;
1316413237
13238 ConstExprValue *orig_array_ptr_val = &array_ptr->value;
13239
13165 IrInstruction *elem_index = elem_ptr_instruction->elem_index->other;13240 IrInstruction *elem_index = elem_ptr_instruction->elem_index->other;
13166 if (type_is_invalid(elem_index->value.type))13241 if (type_is_invalid(elem_index->value.type))
13167 return ira->codegen->builtin_types.entry_invalid;13242 return ira->codegen->builtin_types.entry_invalid;
1316813243
13169 TypeTableEntry *ptr_type = array_ptr->value.type;13244 TypeTableEntry *ptr_type = orig_array_ptr_val->type;
13170 assert(ptr_type->id == TypeTableEntryIdPointer);13245 assert(ptr_type->id == TypeTableEntryIdPointer);
1317113246
13172 TypeTableEntry *array_type = ptr_type->data.pointer.child_type;13247 TypeTableEntry *array_type = ptr_type->data.pointer.child_type;
...@@ -13177,7 +13252,18 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13177,7 +13252,18 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1317713252
13178 if (type_is_invalid(array_type)) {13253 if (type_is_invalid(array_type)) {
13179 return array_type;13254 return array_type;
13180 } else if (array_type->id == TypeTableEntryIdArray) {13255 } else if (array_type->id == TypeTableEntryIdArray ||
13256 (array_type->id == TypeTableEntryIdPointer &&
13257 array_type->data.pointer.ptr_len == PtrLenSingle &&
13258 array_type->data.pointer.child_type->id == TypeTableEntryIdArray))
13259 {
13260 if (array_type->id == TypeTableEntryIdPointer) {
13261 array_type = array_type->data.pointer.child_type;
13262 ptr_type = ptr_type->data.pointer.child_type;
13263 if (orig_array_ptr_val->special != ConstValSpecialRuntime) {
13264 orig_array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val);
13265 }
13266 }
13181 if (array_type->data.array.len == 0) {13267 if (array_type->data.array.len == 0) {
13182 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,13268 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
13183 buf_sprintf("index 0 outside array of size 0"));13269 buf_sprintf("index 0 outside array of size 0"));
...@@ -13205,7 +13291,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13205,7 +13291,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
13205 } else if (array_type->id == TypeTableEntryIdPointer) {13291 } else if (array_type->id == TypeTableEntryIdPointer) {
13206 if (array_type->data.pointer.ptr_len == PtrLenSingle) {13292 if (array_type->data.pointer.ptr_len == PtrLenSingle) {
13207 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,13293 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
13208 buf_sprintf("indexing not allowed on pointer to single item"));13294 buf_sprintf("index of single-item pointer"));
13209 return ira->codegen->builtin_types.entry_invalid;13295 return ira->codegen->builtin_types.entry_invalid;
13210 }13296 }
13211 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len);13297 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len);
...@@ -13294,9 +13380,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13294,9 +13380,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
13294 }13380 }
1329513381
13296 ConstExprValue *array_ptr_val;13382 ConstExprValue *array_ptr_val;
13297 if (array_ptr->value.special != ConstValSpecialRuntime &&13383 if (orig_array_ptr_val->special != ConstValSpecialRuntime &&
13298 (array_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) &&13384 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) &&
13299 (array_ptr_val = const_ptr_pointee(ira->codegen, &array_ptr->value)) &&13385 (array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val)) &&
13300 array_ptr_val->special != ConstValSpecialRuntime &&13386 array_ptr_val->special != ConstValSpecialRuntime &&
13301 (array_type->id != TypeTableEntryIdPointer ||13387 (array_type->id != TypeTableEntryIdPointer ||
13302 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))13388 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))
...@@ -13401,7 +13487,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -13401,7 +13487,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
13401 } else if (array_type->id == TypeTableEntryIdArray) {13487 } else if (array_type->id == TypeTableEntryIdArray) {
13402 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);13488 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
13403 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;13489 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
13404 out_val->data.x_ptr.mut = array_ptr->value.data.x_ptr.mut;13490 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut;
13405 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val;13491 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val;
13406 out_val->data.x_ptr.data.base_array.elem_index = index;13492 out_val->data.x_ptr.data.base_array.elem_index = index;
13407 return return_type;13493 return return_type;
...@@ -14127,10 +14213,10 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi...@@ -14127,10 +14213,10 @@ static TypeTableEntry *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructi
14127 switch (type_entry->id) {14213 switch (type_entry->id) {
14128 case TypeTableEntryIdInvalid:14214 case TypeTableEntryIdInvalid:
14129 zig_unreachable(); // handled above14215 zig_unreachable(); // handled above
14130 case TypeTableEntryIdNumLitFloat:14216 case TypeTableEntryIdComptimeFloat:
14131 case TypeTableEntryIdNumLitInt:14217 case TypeTableEntryIdComptimeInt:
14132 case TypeTableEntryIdUndefLit:14218 case TypeTableEntryIdUndefined:
14133 case TypeTableEntryIdNullLit:14219 case TypeTableEntryIdNull:
14134 case TypeTableEntryIdNamespace:14220 case TypeTableEntryIdNamespace:
14135 case TypeTableEntryIdBlock:14221 case TypeTableEntryIdBlock:
14136 case TypeTableEntryIdBoundFn:14222 case TypeTableEntryIdBoundFn:
...@@ -14393,8 +14479,8 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -14393,8 +14479,8 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
14393 case TypeTableEntryIdInvalid: // handled above14479 case TypeTableEntryIdInvalid: // handled above
14394 zig_unreachable();14480 zig_unreachable();
14395 case TypeTableEntryIdUnreachable:14481 case TypeTableEntryIdUnreachable:
14396 case TypeTableEntryIdUndefLit:14482 case TypeTableEntryIdUndefined:
14397 case TypeTableEntryIdNullLit:14483 case TypeTableEntryIdNull:
14398 case TypeTableEntryIdBlock:14484 case TypeTableEntryIdBlock:
14399 case TypeTableEntryIdArgTuple:14485 case TypeTableEntryIdArgTuple:
14400 case TypeTableEntryIdOpaque:14486 case TypeTableEntryIdOpaque:
...@@ -14409,8 +14495,8 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,...@@ -14409,8 +14495,8 @@ static TypeTableEntry *ir_analyze_instruction_slice_type(IrAnalyze *ira,
14409 case TypeTableEntryIdPointer:14495 case TypeTableEntryIdPointer:
14410 case TypeTableEntryIdArray:14496 case TypeTableEntryIdArray:
14411 case TypeTableEntryIdStruct:14497 case TypeTableEntryIdStruct:
14412 case TypeTableEntryIdNumLitFloat:14498 case TypeTableEntryIdComptimeFloat:
14413 case TypeTableEntryIdNumLitInt:14499 case TypeTableEntryIdComptimeInt:
14414 case TypeTableEntryIdMaybe:14500 case TypeTableEntryIdMaybe:
14415 case TypeTableEntryIdErrorUnion:14501 case TypeTableEntryIdErrorUnion:
14416 case TypeTableEntryIdErrorSet:14502 case TypeTableEntryIdErrorSet:
...@@ -14501,8 +14587,8 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -14501,8 +14587,8 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
14501 case TypeTableEntryIdInvalid: // handled above14587 case TypeTableEntryIdInvalid: // handled above
14502 zig_unreachable();14588 zig_unreachable();
14503 case TypeTableEntryIdUnreachable:14589 case TypeTableEntryIdUnreachable:
14504 case TypeTableEntryIdUndefLit:14590 case TypeTableEntryIdUndefined:
14505 case TypeTableEntryIdNullLit:14591 case TypeTableEntryIdNull:
14506 case TypeTableEntryIdBlock:14592 case TypeTableEntryIdBlock:
14507 case TypeTableEntryIdArgTuple:14593 case TypeTableEntryIdArgTuple:
14508 case TypeTableEntryIdOpaque:14594 case TypeTableEntryIdOpaque:
...@@ -14517,8 +14603,8 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,...@@ -14517,8 +14603,8 @@ static TypeTableEntry *ir_analyze_instruction_array_type(IrAnalyze *ira,
14517 case TypeTableEntryIdPointer:14603 case TypeTableEntryIdPointer:
14518 case TypeTableEntryIdArray:14604 case TypeTableEntryIdArray:
14519 case TypeTableEntryIdStruct:14605 case TypeTableEntryIdStruct:
14520 case TypeTableEntryIdNumLitFloat:14606 case TypeTableEntryIdComptimeFloat:
14521 case TypeTableEntryIdNumLitInt:14607 case TypeTableEntryIdComptimeInt:
14522 case TypeTableEntryIdMaybe:14608 case TypeTableEntryIdMaybe:
14523 case TypeTableEntryIdErrorUnion:14609 case TypeTableEntryIdErrorUnion:
14524 case TypeTableEntryIdErrorSet:14610 case TypeTableEntryIdErrorSet:
...@@ -14570,11 +14656,11 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,...@@ -14570,11 +14656,11 @@ static TypeTableEntry *ir_analyze_instruction_size_of(IrAnalyze *ira,
14570 case TypeTableEntryIdInvalid: // handled above14656 case TypeTableEntryIdInvalid: // handled above
14571 zig_unreachable();14657 zig_unreachable();
14572 case TypeTableEntryIdUnreachable:14658 case TypeTableEntryIdUnreachable:
14573 case TypeTableEntryIdUndefLit:14659 case TypeTableEntryIdUndefined:
14574 case TypeTableEntryIdNullLit:14660 case TypeTableEntryIdNull:
14575 case TypeTableEntryIdBlock:14661 case TypeTableEntryIdBlock:
14576 case TypeTableEntryIdNumLitFloat:14662 case TypeTableEntryIdComptimeFloat:
14577 case TypeTableEntryIdNumLitInt:14663 case TypeTableEntryIdComptimeInt:
14578 case TypeTableEntryIdBoundFn:14664 case TypeTableEntryIdBoundFn:
14579 case TypeTableEntryIdMetaType:14665 case TypeTableEntryIdMetaType:
14580 case TypeTableEntryIdNamespace:14666 case TypeTableEntryIdNamespace:
...@@ -14627,7 +14713,7 @@ static TypeTableEntry *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIn...@@ -14627,7 +14713,7 @@ static TypeTableEntry *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrIn
1462714713
14628 ir_build_test_nonnull_from(&ira->new_irb, &instruction->base, value);14714 ir_build_test_nonnull_from(&ira->new_irb, &instruction->base, value);
14629 return ira->codegen->builtin_types.entry_bool;14715 return ira->codegen->builtin_types.entry_bool;
14630 } else if (type_entry->id == TypeTableEntryIdNullLit) {14716 } else if (type_entry->id == TypeTableEntryIdNull) {
14631 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);14717 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
14632 out_val->data.x_bool = false;14718 out_val->data.x_bool = false;
14633 return ira->codegen->builtin_types.entry_bool;14719 return ira->codegen->builtin_types.entry_bool;
...@@ -14934,8 +15020,8 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -14934,8 +15020,8 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
14934 case TypeTableEntryIdBool:15020 case TypeTableEntryIdBool:
14935 case TypeTableEntryIdInt:15021 case TypeTableEntryIdInt:
14936 case TypeTableEntryIdFloat:15022 case TypeTableEntryIdFloat:
14937 case TypeTableEntryIdNumLitFloat:15023 case TypeTableEntryIdComptimeFloat:
14938 case TypeTableEntryIdNumLitInt:15024 case TypeTableEntryIdComptimeInt:
14939 case TypeTableEntryIdPointer:15025 case TypeTableEntryIdPointer:
14940 case TypeTableEntryIdPromise:15026 case TypeTableEntryIdPromise:
14941 case TypeTableEntryIdFn:15027 case TypeTableEntryIdFn:
...@@ -15013,8 +15099,8 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -15013,8 +15099,8 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
15013 case TypeTableEntryIdUnreachable:15099 case TypeTableEntryIdUnreachable:
15014 case TypeTableEntryIdArray:15100 case TypeTableEntryIdArray:
15015 case TypeTableEntryIdStruct:15101 case TypeTableEntryIdStruct:
15016 case TypeTableEntryIdUndefLit:15102 case TypeTableEntryIdUndefined:
15017 case TypeTableEntryIdNullLit:15103 case TypeTableEntryIdNull:
15018 case TypeTableEntryIdMaybe:15104 case TypeTableEntryIdMaybe:
15019 case TypeTableEntryIdBlock:15105 case TypeTableEntryIdBlock:
15020 case TypeTableEntryIdBoundFn:15106 case TypeTableEntryIdBoundFn:
...@@ -15532,10 +15618,10 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_...@@ -15532,10 +15618,10 @@ static TypeTableEntry *ir_analyze_min_max(IrAnalyze *ira, IrInstruction *source_
15532 case TypeTableEntryIdPromise:15618 case TypeTableEntryIdPromise:
15533 case TypeTableEntryIdArray:15619 case TypeTableEntryIdArray:
15534 case TypeTableEntryIdStruct:15620 case TypeTableEntryIdStruct:
15535 case TypeTableEntryIdNumLitFloat:15621 case TypeTableEntryIdComptimeFloat:
15536 case TypeTableEntryIdNumLitInt:15622 case TypeTableEntryIdComptimeInt:
15537 case TypeTableEntryIdUndefLit:15623 case TypeTableEntryIdUndefined:
15538 case TypeTableEntryIdNullLit:15624 case TypeTableEntryIdNull:
15539 case TypeTableEntryIdMaybe:15625 case TypeTableEntryIdMaybe:
15540 case TypeTableEntryIdErrorUnion:15626 case TypeTableEntryIdErrorUnion:
15541 case TypeTableEntryIdErrorSet:15627 case TypeTableEntryIdErrorSet:
...@@ -16194,10 +16280,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t...@@ -16194,10 +16280,10 @@ static ConstExprValue *ir_make_type_info_value(IrAnalyze *ira, TypeTableEntry *t
16194 case TypeTableEntryIdVoid:16280 case TypeTableEntryIdVoid:
16195 case TypeTableEntryIdBool:16281 case TypeTableEntryIdBool:
16196 case TypeTableEntryIdUnreachable:16282 case TypeTableEntryIdUnreachable:
16197 case TypeTableEntryIdNumLitFloat:16283 case TypeTableEntryIdComptimeFloat:
16198 case TypeTableEntryIdNumLitInt:16284 case TypeTableEntryIdComptimeInt:
16199 case TypeTableEntryIdUndefLit:16285 case TypeTableEntryIdUndefined:
16200 case TypeTableEntryIdNullLit:16286 case TypeTableEntryIdNull:
16201 case TypeTableEntryIdNamespace:16287 case TypeTableEntryIdNamespace:
16202 case TypeTableEntryIdBlock:16288 case TypeTableEntryIdBlock:
16203 case TypeTableEntryIdArgTuple:16289 case TypeTableEntryIdArgTuple:
...@@ -17057,7 +17143,7 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc...@@ -17057,7 +17143,7 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc
17057 return ira->codegen->builtin_types.entry_invalid;17143 return ira->codegen->builtin_types.entry_invalid;
1705817144
17059 if (dest_type->id != TypeTableEntryIdInt &&17145 if (dest_type->id != TypeTableEntryIdInt &&
17060 dest_type->id != TypeTableEntryIdNumLitInt)17146 dest_type->id != TypeTableEntryIdComptimeInt)
17061 {17147 {
17062 ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name)));17148 ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name)));
17063 return ira->codegen->builtin_types.entry_invalid;17149 return ira->codegen->builtin_types.entry_invalid;
...@@ -17069,7 +17155,7 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc...@@ -17069,7 +17155,7 @@ static TypeTableEntry *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstruc
17069 return ira->codegen->builtin_types.entry_invalid;17155 return ira->codegen->builtin_types.entry_invalid;
1707017156
17071 if (src_type->id != TypeTableEntryIdInt &&17157 if (src_type->id != TypeTableEntryIdInt &&
17072 src_type->id != TypeTableEntryIdNumLitInt)17158 src_type->id != TypeTableEntryIdComptimeInt)
17073 {17159 {
17074 ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name)));17160 ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name)));
17075 return ira->codegen->builtin_types.entry_invalid;17161 return ira->codegen->builtin_types.entry_invalid;
...@@ -17406,14 +17492,29 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -17406,14 +17492,29 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
17406 byte_alignment, 0, 0);17492 byte_alignment, 0, 0);
17407 return_type = get_slice_type(ira->codegen, slice_ptr_type);17493 return_type = get_slice_type(ira->codegen, slice_ptr_type);
17408 } else if (array_type->id == TypeTableEntryIdPointer) {17494 } else if (array_type->id == TypeTableEntryIdPointer) {
17409 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,17495 if (array_type->data.pointer.ptr_len == PtrLenSingle) {
17410 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,17496 TypeTableEntry *main_type = array_type->data.pointer.child_type;
17411 PtrLenUnknown,17497 if (main_type->id == TypeTableEntryIdArray) {
17412 array_type->data.pointer.alignment, 0, 0);17498 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen,
17413 return_type = get_slice_type(ira->codegen, slice_ptr_type);17499 main_type->data.pointer.child_type,
17414 if (!end) {17500 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
17415 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value"));17501 PtrLenUnknown,
17416 return ira->codegen->builtin_types.entry_invalid;17502 array_type->data.pointer.alignment, 0, 0);
17503 return_type = get_slice_type(ira->codegen, slice_ptr_type);
17504 } else {
17505 ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer"));
17506 return ira->codegen->builtin_types.entry_invalid;
17507 }
17508 } else {
17509 TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,
17510 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
17511 PtrLenUnknown,
17512 array_type->data.pointer.alignment, 0, 0);
17513 return_type = get_slice_type(ira->codegen, slice_ptr_type);
17514 if (!end) {
17515 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value"));
17516 return ira->codegen->builtin_types.entry_invalid;
17517 }
17417 }17518 }
17418 } else if (is_slice(array_type)) {17519 } else if (is_slice(array_type)) {
17419 TypeTableEntry *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry;17520 TypeTableEntry *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry;
...@@ -17433,12 +17534,24 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -17433,12 +17534,24 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
17433 size_t abs_offset;17534 size_t abs_offset;
17434 size_t rel_end;17535 size_t rel_end;
17435 bool ptr_is_undef = false;17536 bool ptr_is_undef = false;
17436 if (array_type->id == TypeTableEntryIdArray) {17537 if (array_type->id == TypeTableEntryIdArray ||
17437 array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value);17538 (array_type->id == TypeTableEntryIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle))
17438 abs_offset = 0;17539 {
17439 rel_end = array_type->data.array.len;17540 if (array_type->id == TypeTableEntryIdPointer) {
17440 parent_ptr = nullptr;17541 TypeTableEntry *child_array_type = array_type->data.pointer.child_type;
17542 assert(child_array_type->id == TypeTableEntryIdArray);
17543 parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
17544 array_val = const_ptr_pointee(ira->codegen, parent_ptr);
17545 rel_end = child_array_type->data.array.len;
17546 abs_offset = 0;
17547 } else {
17548 array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
17549 rel_end = array_type->data.array.len;
17550 parent_ptr = nullptr;
17551 abs_offset = 0;
17552 }
17441 } else if (array_type->id == TypeTableEntryIdPointer) {17553 } else if (array_type->id == TypeTableEntryIdPointer) {
17554 assert(array_type->data.pointer.ptr_len == PtrLenUnknown);
17442 parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);17555 parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
17443 if (parent_ptr->special == ConstValSpecialUndef) {17556 if (parent_ptr->special == ConstValSpecialUndef) {
17444 array_val = nullptr;17557 array_val = nullptr;
...@@ -17537,7 +17650,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -17537,7 +17650,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
17537 if (array_val) {17650 if (array_val) {
17538 size_t index = abs_offset + start_scalar;17651 size_t index = abs_offset + start_scalar;
17539 bool is_const = slice_is_const(return_type);17652 bool is_const = slice_is_const(return_type);
17540 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const);17653 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown);
17541 if (array_type->id == TypeTableEntryIdArray) {17654 if (array_type->id == TypeTableEntryIdArray) {
17542 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut;17655 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut;
17543 } else if (is_slice(array_type)) {17656 } else if (is_slice(array_type)) {
...@@ -17763,10 +17876,10 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc...@@ -17763,10 +17876,10 @@ static TypeTableEntry *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruc
17763 zig_unreachable();17876 zig_unreachable();
17764 case TypeTableEntryIdMetaType:17877 case TypeTableEntryIdMetaType:
17765 case TypeTableEntryIdUnreachable:17878 case TypeTableEntryIdUnreachable:
17766 case TypeTableEntryIdNumLitFloat:17879 case TypeTableEntryIdComptimeFloat:
17767 case TypeTableEntryIdNumLitInt:17880 case TypeTableEntryIdComptimeInt:
17768 case TypeTableEntryIdUndefLit:17881 case TypeTableEntryIdUndefined:
17769 case TypeTableEntryIdNullLit:17882 case TypeTableEntryIdNull:
17770 case TypeTableEntryIdNamespace:17883 case TypeTableEntryIdNamespace:
17771 case TypeTableEntryIdBlock:17884 case TypeTableEntryIdBlock:
17772 case TypeTableEntryIdBoundFn:17885 case TypeTableEntryIdBoundFn:
...@@ -18264,8 +18377,8 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira...@@ -18264,8 +18377,8 @@ static TypeTableEntry *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira
18264 if (!end_val)18377 if (!end_val)
18265 return ira->codegen->builtin_types.entry_invalid;18378 return ira->codegen->builtin_types.entry_invalid;
1826618379
18267 assert(start_val->type->id == TypeTableEntryIdInt || start_val->type->id == TypeTableEntryIdNumLitInt);18380 assert(start_val->type->id == TypeTableEntryIdInt || start_val->type->id == TypeTableEntryIdComptimeInt);
18268 assert(end_val->type->id == TypeTableEntryIdInt || end_val->type->id == TypeTableEntryIdNumLitInt);18381 assert(end_val->type->id == TypeTableEntryIdInt || end_val->type->id == TypeTableEntryIdComptimeInt);
18269 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint,18382 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint,
18270 start_value->source_node);18383 start_value->source_node);
18271 if (prev_node != nullptr) {18384 if (prev_node != nullptr) {
...@@ -18497,10 +18610,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -18497,10 +18610,10 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
18497 case TypeTableEntryIdNamespace:18610 case TypeTableEntryIdNamespace:
18498 case TypeTableEntryIdBlock:18611 case TypeTableEntryIdBlock:
18499 case TypeTableEntryIdUnreachable:18612 case TypeTableEntryIdUnreachable:
18500 case TypeTableEntryIdNumLitFloat:18613 case TypeTableEntryIdComptimeFloat:
18501 case TypeTableEntryIdNumLitInt:18614 case TypeTableEntryIdComptimeInt:
18502 case TypeTableEntryIdUndefLit:18615 case TypeTableEntryIdUndefined:
18503 case TypeTableEntryIdNullLit:18616 case TypeTableEntryIdNull:
18504 case TypeTableEntryIdPromise:18617 case TypeTableEntryIdPromise:
18505 zig_unreachable();18618 zig_unreachable();
18506 case TypeTableEntryIdVoid:18619 case TypeTableEntryIdVoid:
...@@ -18564,10 +18677,10 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -18564,10 +18677,10 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
18564 case TypeTableEntryIdNamespace:18677 case TypeTableEntryIdNamespace:
18565 case TypeTableEntryIdBlock:18678 case TypeTableEntryIdBlock:
18566 case TypeTableEntryIdUnreachable:18679 case TypeTableEntryIdUnreachable:
18567 case TypeTableEntryIdNumLitFloat:18680 case TypeTableEntryIdComptimeFloat:
18568 case TypeTableEntryIdNumLitInt:18681 case TypeTableEntryIdComptimeInt:
18569 case TypeTableEntryIdUndefLit:18682 case TypeTableEntryIdUndefined:
18570 case TypeTableEntryIdNullLit:18683 case TypeTableEntryIdNull:
18571 case TypeTableEntryIdPromise:18684 case TypeTableEntryIdPromise:
18572 zig_unreachable();18685 zig_unreachable();
18573 case TypeTableEntryIdVoid:18686 case TypeTableEntryIdVoid:
...@@ -18645,10 +18758,10 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc...@@ -18645,10 +18758,10 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
18645 case TypeTableEntryIdNamespace:18758 case TypeTableEntryIdNamespace:
18646 case TypeTableEntryIdBlock:18759 case TypeTableEntryIdBlock:
18647 case TypeTableEntryIdUnreachable:18760 case TypeTableEntryIdUnreachable:
18648 case TypeTableEntryIdNumLitFloat:18761 case TypeTableEntryIdComptimeFloat:
18649 case TypeTableEntryIdNumLitInt:18762 case TypeTableEntryIdComptimeInt:
18650 case TypeTableEntryIdUndefLit:18763 case TypeTableEntryIdUndefined:
18651 case TypeTableEntryIdNullLit:18764 case TypeTableEntryIdNull:
18652 ir_add_error(ira, dest_type_value,18765 ir_add_error(ira, dest_type_value,
18653 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));18766 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name)));
18654 return ira->codegen->builtin_types.entry_invalid;18767 return ira->codegen->builtin_types.entry_invalid;
...@@ -18671,10 +18784,10 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc...@@ -18671,10 +18784,10 @@ static TypeTableEntry *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruc
18671 case TypeTableEntryIdNamespace:18784 case TypeTableEntryIdNamespace:
18672 case TypeTableEntryIdBlock:18785 case TypeTableEntryIdBlock:
18673 case TypeTableEntryIdUnreachable:18786 case TypeTableEntryIdUnreachable:
18674 case TypeTableEntryIdNumLitFloat:18787 case TypeTableEntryIdComptimeFloat:
18675 case TypeTableEntryIdNumLitInt:18788 case TypeTableEntryIdComptimeInt:
18676 case TypeTableEntryIdUndefLit:18789 case TypeTableEntryIdUndefined:
18677 case TypeTableEntryIdNullLit:18790 case TypeTableEntryIdNull:
18678 ir_add_error(ira, dest_type_value,18791 ir_add_error(ira, dest_type_value,
18679 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));18792 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name)));
18680 return ira->codegen->builtin_types.entry_invalid;18793 return ira->codegen->builtin_types.entry_invalid;
...@@ -19447,7 +19560,7 @@ static TypeTableEntry *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstruction...@@ -19447,7 +19560,7 @@ static TypeTableEntry *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstruction
19447 if (type_is_invalid(op->value.type))19560 if (type_is_invalid(op->value.type))
19448 return ira->codegen->builtin_types.entry_invalid;19561 return ira->codegen->builtin_types.entry_invalid;
1944919562
19450 bool ok_type = float_type->id == TypeTableEntryIdNumLitFloat || float_type->id == TypeTableEntryIdFloat;19563 bool ok_type = float_type->id == TypeTableEntryIdComptimeFloat || float_type->id == TypeTableEntryIdFloat;
19451 if (!ok_type) {19564 if (!ok_type) {
19452 ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name)));19565 ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name)));
19453 return ira->codegen->builtin_types.entry_invalid;19566 return ira->codegen->builtin_types.entry_invalid;
...@@ -19464,7 +19577,7 @@ static TypeTableEntry *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstruction...@@ -19464,7 +19577,7 @@ static TypeTableEntry *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstruction
1946419577
19465 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);19578 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
1946619579
19467 if (float_type->id == TypeTableEntryIdNumLitFloat) {19580 if (float_type->id == TypeTableEntryIdComptimeFloat) {
19468 bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat);19581 bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat);
19469 } else if (float_type->id == TypeTableEntryIdFloat) {19582 } else if (float_type->id == TypeTableEntryIdFloat) {
19470 switch (float_type->data.floating.bit_count) {19583 switch (float_type->data.floating.bit_count) {
src/util.hpp+16-3
...@@ -65,6 +65,11 @@ static inline int clzll(unsigned long long mask) {...@@ -65,6 +65,11 @@ static inline int clzll(unsigned long long mask) {
6565
66template<typename T>66template<typename T>
67ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {67ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
68#ifndef NDEBUG
69 // make behavior when size == 0 portable
70 if (count == 0)
71 return nullptr;
72#endif
68 T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));73 T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
69 if (!ptr)74 if (!ptr)
70 zig_panic("allocation failed");75 zig_panic("allocation failed");
...@@ -73,6 +78,11 @@ ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {...@@ -73,6 +78,11 @@ ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate_nonzero(size_t count) {
7378
74template<typename T>79template<typename T>
75ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) {80ATTRIBUTE_RETURNS_NOALIAS static inline T *allocate(size_t count) {
81#ifndef NDEBUG
82 // make behavior when size == 0 portable
83 if (count == 0)
84 return nullptr;
85#endif
76 T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));86 T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
77 if (!ptr)87 if (!ptr)
78 zig_panic("allocation failed");88 zig_panic("allocation failed");
...@@ -93,9 +103,7 @@ static inline void safe_memcpy(T *dest, const T *src, size_t count) {...@@ -93,9 +103,7 @@ static inline void safe_memcpy(T *dest, const T *src, size_t count) {
93103
94template<typename T>104template<typename T>
95static inline T *reallocate(T *old, size_t old_count, size_t new_count) {105static inline T *reallocate(T *old, size_t old_count, size_t new_count) {
96 T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));106 T *ptr = reallocate_nonzero(old, old_count, new_count);
97 if (!ptr)
98 zig_panic("allocation failed");
99 if (new_count > old_count) {107 if (new_count > old_count) {
100 memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T));108 memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T));
101 }109 }
...@@ -104,6 +112,11 @@ static inline T *reallocate(T *old, size_t old_count, size_t new_count) {...@@ -104,6 +112,11 @@ static inline T *reallocate(T *old, size_t old_count, size_t new_count) {
104112
105template<typename T>113template<typename T>
106static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count) {114static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count) {
115#ifndef NDEBUG
116 // make behavior when size == 0 portable
117 if (new_count == 0 && old == nullptr)
118 return nullptr;
119#endif
107 T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));120 T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
108 if (!ptr)121 if (!ptr)
109 zig_panic("allocation failed");122 zig_panic("allocation failed");
std/fmt/errol/index.zig+1-1
...@@ -59,7 +59,7 @@ pub fn roundToPrecision(float_decimal: *FloatDecimal, precision: usize, mode: Ro...@@ -59,7 +59,7 @@ pub fn roundToPrecision(float_decimal: *FloatDecimal, precision: usize, mode: Ro
59 float_decimal.exp += 1;59 float_decimal.exp += 1;
6060
61 // Re-size the buffer to use the reserved leading byte.61 // Re-size the buffer to use the reserved leading byte.
62 const one_before = @intToPtr(*u8, @ptrToInt(&float_decimal.digits[0]) - 1);62 const one_before = @intToPtr([*]u8, @ptrToInt(&float_decimal.digits[0]) - 1);
63 float_decimal.digits = one_before[0 .. float_decimal.digits.len + 1];63 float_decimal.digits = one_before[0 .. float_decimal.digits.len + 1];
64 float_decimal.digits[0] = '1';64 float_decimal.digits[0] = '1';
65 return;65 return;
std/fmt/index.zig+246-212
...@@ -16,27 +16,12 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),...@@ -16,27 +16,12 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),
16 Start,16 Start,
17 OpenBrace,17 OpenBrace,
18 CloseBrace,18 CloseBrace,
19 Integer,19 FormatString,
20 IntegerWidth,
21 Float,
22 FloatWidth,
23 FloatScientific,
24 FloatScientificWidth,
25 Character,
26 Buf,
27 BufWidth,
28 Bytes,
29 BytesBase,
30 BytesWidth,
31 };20 };
3221
33 comptime var start_index = 0;22 comptime var start_index = 0;
34 comptime var state = State.Start;23 comptime var state = State.Start;
35 comptime var next_arg = 0;24 comptime var next_arg = 0;
36 comptime var radix = 0;
37 comptime var uppercase = false;
38 comptime var width = 0;
39 comptime var width_start = 0;
4025
41 inline for (fmt) |c, i| {26 inline for (fmt) |c, i| {
42 switch (state) {27 switch (state) {
...@@ -45,8 +30,10 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),...@@ -45,8 +30,10 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),
45 if (start_index < i) {30 if (start_index < i) {
46 try output(context, fmt[start_index..i]);31 try output(context, fmt[start_index..i]);
47 }32 }
33 start_index = i;
48 state = State.OpenBrace;34 state = State.OpenBrace;
49 },35 },
36
50 '}' => {37 '}' => {
51 if (start_index < i) {38 if (start_index < i) {
52 try output(context, fmt[start_index..i]);39 try output(context, fmt[start_index..i]);
...@@ -61,57 +48,14 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),...@@ -61,57 +48,14 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),
61 start_index = i;48 start_index = i;
62 },49 },
63 '}' => {50 '}' => {
64 try formatValue(args[next_arg], context, Errors, output);51 try formatType(args[next_arg], fmt[0..0], context, Errors, output);
65 next_arg += 1;52 next_arg += 1;
66 state = State.Start;53 state = State.Start;
67 start_index = i + 1;54 start_index = i + 1;
68 },55 },
69 'd' => {56 else => {
70 radix = 10;57 state = State.FormatString;
71 uppercase = false;
72 width = 0;
73 state = State.Integer;
74 },
75 'x' => {
76 radix = 16;
77 uppercase = false;
78 width = 0;
79 state = State.Integer;
80 },
81 'X' => {
82 radix = 16;
83 uppercase = true;
84 width = 0;
85 state = State.Integer;
86 },
87 'c' => {
88 state = State.Character;
89 },
90 's' => {
91 state = State.Buf;
92 },
93 'e' => {
94 state = State.FloatScientific;
95 },
96 '.' => {
97 state = State.Float;
98 },
99 'B' => {
100 width = 0;
101 radix = 1000;
102 state = State.Bytes;
103 },
104 else => @compileError("Unknown format character: " ++ []u8{c}),
105 },
106 State.Buf => switch (c) {
107 '}' => {
108 return output(context, args[next_arg]);
109 },
110 '0'...'9' => {
111 width_start = i;
112 state = State.BufWidth;
113 },58 },
114 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
115 },59 },
116 State.CloseBrace => switch (c) {60 State.CloseBrace => switch (c) {
117 '}' => {61 '}' => {
...@@ -120,138 +64,15 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),...@@ -120,138 +64,15 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),
120 },64 },
121 else => @compileError("Single '}' encountered in format string"),65 else => @compileError("Single '}' encountered in format string"),
122 },66 },
123 State.Integer => switch (c) {67 State.FormatString => switch (c) {
124 '}' => {
125 try formatInt(args[next_arg], radix, uppercase, width, context, Errors, output);
126 next_arg += 1;
127 state = State.Start;
128 start_index = i + 1;
129 },
130 '0'...'9' => {
131 width_start = i;
132 state = State.IntegerWidth;
133 },
134 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
135 },
136 State.IntegerWidth => switch (c) {
137 '}' => {68 '}' => {
138 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);69 const s = start_index + 1;
139 try formatInt(args[next_arg], radix, uppercase, width, context, Errors, output);70 try formatType(args[next_arg], fmt[s..i], context, Errors, output);
140 next_arg += 1;71 next_arg += 1;
141 state = State.Start;72 state = State.Start;
142 start_index = i + 1;73 start_index = i + 1;
143 },74 },
144 '0'...'9' => {},75 else => {},
145 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
146 },
147 State.FloatScientific => switch (c) {
148 '}' => {
149 try formatFloatScientific(args[next_arg], null, context, Errors, output);
150 next_arg += 1;
151 state = State.Start;
152 start_index = i + 1;
153 },
154 '0'...'9' => {
155 width_start = i;
156 state = State.FloatScientificWidth;
157 },
158 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
159 },
160 State.FloatScientificWidth => switch (c) {
161 '}' => {
162 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
163 try formatFloatScientific(args[next_arg], width, context, Errors, output);
164 next_arg += 1;
165 state = State.Start;
166 start_index = i + 1;
167 },
168 '0'...'9' => {},
169 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
170 },
171 State.Float => switch (c) {
172 '}' => {
173 try formatFloatDecimal(args[next_arg], null, context, Errors, output);
174 next_arg += 1;
175 state = State.Start;
176 start_index = i + 1;
177 },
178 '0'...'9' => {
179 width_start = i;
180 state = State.FloatWidth;
181 },
182 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
183 },
184 State.FloatWidth => switch (c) {
185 '}' => {
186 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
187 try formatFloatDecimal(args[next_arg], width, context, Errors, output);
188 next_arg += 1;
189 state = State.Start;
190 start_index = i + 1;
191 },
192 '0'...'9' => {},
193 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
194 },
195 State.BufWidth => switch (c) {
196 '}' => {
197 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
198 try formatBuf(args[next_arg], width, context, Errors, output);
199 next_arg += 1;
200 state = State.Start;
201 start_index = i + 1;
202 },
203 '0'...'9' => {},
204 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
205 },
206 State.Character => switch (c) {
207 '}' => {
208 try formatAsciiChar(args[next_arg], context, Errors, output);
209 next_arg += 1;
210 state = State.Start;
211 start_index = i + 1;
212 },
213 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
214 },
215 State.Bytes => switch (c) {
216 '}' => {
217 try formatBytes(args[next_arg], 0, radix, context, Errors, output);
218 next_arg += 1;
219 state = State.Start;
220 start_index = i + 1;
221 },
222 'i' => {
223 radix = 1024;
224 state = State.BytesBase;
225 },
226 '0'...'9' => {
227 width_start = i;
228 state = State.BytesWidth;
229 },
230 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
231 },
232 State.BytesBase => switch (c) {
233 '}' => {
234 try formatBytes(args[next_arg], 0, radix, context, Errors, output);
235 next_arg += 1;
236 state = State.Start;
237 start_index = i + 1;
238 },
239 '0'...'9' => {
240 width_start = i;
241 state = State.BytesWidth;
242 },
243 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
244 },
245 State.BytesWidth => switch (c) {
246 '}' => {
247 width = comptime (parseUnsigned(usize, fmt[width_start..i], 10) catch unreachable);
248 try formatBytes(args[next_arg], width, radix, context, Errors, output);
249 next_arg += 1;
250 state = State.Start;
251 start_index = i + 1;
252 },
253 '0'...'9' => {},
254 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
255 },76 },
256 }77 }
257 }78 }
...@@ -268,14 +89,17 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),...@@ -268,14 +89,17 @@ pub fn format(context: var, comptime Errors: type, output: fn (@typeOf(context),
268 }89 }
269}90}
27091
271pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn (@typeOf(context), []const u8) Errors!void) Errors!void {92pub fn formatType(
93 value: var,
94 comptime fmt: []const u8,
95 context: var,
96 comptime Errors: type,
97 output: fn (@typeOf(context), []const u8) Errors!void,
98) Errors!void {
272 const T = @typeOf(value);99 const T = @typeOf(value);
273 switch (@typeId(T)) {100 switch (@typeId(T)) {
274 builtin.TypeId.Int => {101 builtin.TypeId.Int, builtin.TypeId.Float => {
275 return formatInt(value, 10, false, 0, context, Errors, output);102 return formatValue(value, fmt, context, Errors, output);
276 },
277 builtin.TypeId.Float => {
278 return formatFloatScientific(value, null, context, Errors, output);
279 },103 },
280 builtin.TypeId.Void => {104 builtin.TypeId.Void => {
281 return output(context, "void");105 return output(context, "void");
...@@ -285,16 +109,16 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn (...@@ -285,16 +109,16 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn (
285 },109 },
286 builtin.TypeId.Nullable => {110 builtin.TypeId.Nullable => {
287 if (value) |payload| {111 if (value) |payload| {
288 return formatValue(payload, context, Errors, output);112 return formatType(payload, fmt, context, Errors, output);
289 } else {113 } else {
290 return output(context, "null");114 return output(context, "null");
291 }115 }
292 },116 },
293 builtin.TypeId.ErrorUnion => {117 builtin.TypeId.ErrorUnion => {
294 if (value) |payload| {118 if (value) |payload| {
295 return formatValue(payload, context, Errors, output);119 return formatType(payload, fmt, context, Errors, output);
296 } else |err| {120 } else |err| {
297 return formatValue(err, context, Errors, output);121 return formatType(err, fmt, context, Errors, output);
298 }122 }
299 },123 },
300 builtin.TypeId.ErrorSet => {124 builtin.TypeId.ErrorSet => {
...@@ -302,10 +126,34 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn (...@@ -302,10 +126,34 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn (
302 return output(context, @errorName(value));126 return output(context, @errorName(value));
303 },127 },
304 builtin.TypeId.Pointer => {128 builtin.TypeId.Pointer => {
305 if (@typeId(T.Child) == builtin.TypeId.Array and T.Child.Child == u8) {129 switch (@typeId(T.Child)) {
306 return output(context, (value.*)[0..]);130 builtin.TypeId.Array => {
307 } else {131 if (T.Child.Child == u8) {
308 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));132 return formatText(value, fmt, context, Errors, output);
133 }
134 },
135 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {
136 const has_cust_fmt = comptime cf: {
137 const info = @typeInfo(T.Child);
138 const defs = switch (info) {
139 builtin.TypeId.Struct => |s| s.defs,
140 builtin.TypeId.Union => |u| u.defs,
141 builtin.TypeId.Enum => |e| e.defs,
142 else => unreachable,
143 };
144
145 for (defs) |def| {
146 if (mem.eql(u8, def.name, "format")) {
147 break :cf true;
148 }
149 }
150 break :cf false;
151 };
152
153 if (has_cust_fmt) return value.format(fmt, context, Errors, output);
154 return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value));
155 },
156 else => return format(context, Errors, output, "{}@{x}", @typeName(T.Child), @ptrToInt(value)),
309 }157 }
310 },158 },
311 else => if (@canImplicitCast([]const u8, value)) {159 else => if (@canImplicitCast([]const u8, value)) {
...@@ -317,11 +165,129 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn (...@@ -317,11 +165,129 @@ pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn (
317 }165 }
318}166}
319167
320pub fn formatAsciiChar(c: u8, context: var, comptime Errors: type, output: fn (@typeOf(context), []const u8) Errors!void) Errors!void {168fn formatValue(
321 return output(context, (&c)[0..1]);169 value: var,
170 comptime fmt: []const u8,
171 context: var,
172 comptime Errors: type,
173 output: fn (@typeOf(context), []const u8) Errors!void,
174) Errors!void {
175 if (fmt.len > 0) {
176 if (fmt[0] == 'B') {
177 comptime var width: ?usize = null;
178 if (fmt.len > 1) {
179 if (fmt[1] == 'i') {
180 if (fmt.len > 2) width = comptime (parseUnsigned(usize, fmt[2..], 10) catch unreachable);
181 return formatBytes(value, width, 1024, context, Errors, output);
182 }
183 width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
184 }
185 return formatBytes(value, width, 1000, context, Errors, output);
186 }
187 }
188
189 comptime var T = @typeOf(value);
190 switch (@typeId(T)) {
191 builtin.TypeId.Float => return formatFloatValue(value, fmt, context, Errors, output),
192 builtin.TypeId.Int => return formatIntValue(value, fmt, context, Errors, output),
193 else => unreachable,
194 }
195}
196
197pub fn formatIntValue(
198 value: var,
199 comptime fmt: []const u8,
200 context: var,
201 comptime Errors: type,
202 output: fn (@typeOf(context), []const u8) Errors!void,
203) Errors!void {
204 comptime var radix = 10;
205 comptime var uppercase = false;
206 comptime var width = 0;
207 if (fmt.len > 0) {
208 switch (fmt[0]) {
209 'c' => {
210 if (@typeOf(value) == u8) {
211 if (fmt.len > 1) @compileError("Unknown format character: " ++ []u8{fmt[1]});
212 return formatAsciiChar(value, context, Errors, output);
213 }
214 },
215 'd' => {
216 radix = 10;
217 uppercase = false;
218 width = 0;
219 },
220 'x' => {
221 radix = 16;
222 uppercase = false;
223 width = 0;
224 },
225 'X' => {
226 radix = 16;
227 uppercase = true;
228 width = 0;
229 },
230 else => @compileError("Unknown format character: " ++ []u8{fmt[0]}),
231 }
232 if (fmt.len > 1) width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
233 }
234 return formatInt(value, radix, uppercase, width, context, Errors, output);
235}
236
237fn formatFloatValue(
238 value: var,
239 comptime fmt: []const u8,
240 context: var,
241 comptime Errors: type,
242 output: fn (@typeOf(context), []const u8) Errors!void,
243) Errors!void {
244 comptime var width: ?usize = null;
245 comptime var float_fmt = 'e';
246 if (fmt.len > 0) {
247 float_fmt = fmt[0];
248 if (fmt.len > 1) width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
249 }
250
251 switch (float_fmt) {
252 'e' => try formatFloatScientific(value, width, context, Errors, output),
253 '.' => try formatFloatDecimal(value, width, context, Errors, output),
254 else => @compileError("Unknown format character: " ++ []u8{float_fmt}),
255 }
256}
257
258pub fn formatText(
259 bytes: []const u8,
260 comptime fmt: []const u8,
261 context: var,
262 comptime Errors: type,
263 output: fn (@typeOf(context), []const u8) Errors!void,
264) Errors!void {
265 if (fmt.len > 0) {
266 if (fmt[0] == 's') {
267 comptime var width = 0;
268 if (fmt.len > 1) width = comptime (parseUnsigned(usize, fmt[1..], 10) catch unreachable);
269 return formatBuf(bytes, width, context, Errors, output);
270 } else @compileError("Unknown format character: " ++ []u8{fmt[0]});
271 }
272 return output(context, bytes);
273}
274
275pub fn formatAsciiChar(
276 c: u8,
277 context: var,
278 comptime Errors: type,
279 output: fn (@typeOf(context), []const u8) Errors!void,
280) Errors!void {
281 return output(context, (*[1]u8)(&c)[0..]);
322}282}
323283
324pub fn formatBuf(buf: []const u8, width: usize, context: var, comptime Errors: type, output: fn (@typeOf(context), []const u8) Errors!void) Errors!void {284pub fn formatBuf(
285 buf: []const u8,
286 width: usize,
287 context: var,
288 comptime Errors: type,
289 output: fn (@typeOf(context), []const u8) Errors!void,
290) Errors!void {
325 try output(context, buf);291 try output(context, buf);
326292
327 var leftover_padding = if (width > buf.len) (width - buf.len) else return;293 var leftover_padding = if (width > buf.len) (width - buf.len) else return;
...@@ -334,7 +300,13 @@ pub fn formatBuf(buf: []const u8, width: usize, context: var, comptime Errors: t...@@ -334,7 +300,13 @@ pub fn formatBuf(buf: []const u8, width: usize, context: var, comptime Errors: t
334// Print a float in scientific notation to the specified precision. Null uses full precision.300// Print a float in scientific notation to the specified precision. Null uses full precision.
335// It should be the case that every full precision, printed value can be re-parsed back to the301// It should be the case that every full precision, printed value can be re-parsed back to the
336// same type unambiguously.302// same type unambiguously.
337pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var, comptime Errors: type, output: fn (@typeOf(context), []const u8) Errors!void) Errors!void {303pub fn formatFloatScientific(
304 value: var,
305 maybe_precision: ?usize,
306 context: var,
307 comptime Errors: type,
308 output: fn (@typeOf(context), []const u8) Errors!void,
309) Errors!void {
338 var x = f64(value);310 var x = f64(value);
339311
340 // Errol doesn't handle these special cases.312 // Errol doesn't handle these special cases.
...@@ -423,7 +395,13 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,...@@ -423,7 +395,13 @@ pub fn formatFloatScientific(value: var, maybe_precision: ?usize, context: var,
423395
424// Print a float of the format x.yyyyy where the number of y is specified by the precision argument.396// Print a float of the format x.yyyyy where the number of y is specified by the precision argument.
425// By default floats are printed at full precision (no rounding).397// By default floats are printed at full precision (no rounding).
426pub fn formatFloatDecimal(value: var, maybe_precision: ?usize, context: var, comptime Errors: type, output: fn (@typeOf(context), []const u8) Errors!void) Errors!void {398pub fn formatFloatDecimal(
399 value: var,
400 maybe_precision: ?usize,
401 context: var,
402 comptime Errors: type,
403 output: fn (@typeOf(context), []const u8) Errors!void,
404) Errors!void {
427 var x = f64(value);405 var x = f64(value);
428406
429 // Errol doesn't handle these special cases.407 // Errol doesn't handle these special cases.
...@@ -613,11 +591,19 @@ pub fn formatInt(...@@ -613,11 +591,19 @@ pub fn formatInt(
613 }591 }
614}592}
615593
616fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, context: var, comptime Errors: type, output: fn (@typeOf(context), []const u8) Errors!void) Errors!void {594fn formatIntSigned(
595 value: var,
596 base: u8,
597 uppercase: bool,
598 width: usize,
599 context: var,
600 comptime Errors: type,
601 output: fn (@typeOf(context), []const u8) Errors!void,
602) Errors!void {
617 const uint = @IntType(false, @typeOf(value).bit_count);603 const uint = @IntType(false, @typeOf(value).bit_count);
618 if (value < 0) {604 if (value < 0) {
619 const minus_sign: u8 = '-';605 const minus_sign: u8 = '-';
620 try output(context, (&minus_sign)[0..1]);606 try output(context, (*[1]u8)(&minus_sign)[0..]);
621 const new_value = uint(-(value + 1)) + 1;607 const new_value = uint(-(value + 1)) + 1;
622 const new_width = if (width == 0) 0 else (width - 1);608 const new_width = if (width == 0) 0 else (width - 1);
623 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);609 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);
...@@ -625,14 +611,22 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, context:...@@ -625,14 +611,22 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize, context:
625 return formatIntUnsigned(uint(value), base, uppercase, width, context, Errors, output);611 return formatIntUnsigned(uint(value), base, uppercase, width, context, Errors, output);
626 } else {612 } else {
627 const plus_sign: u8 = '+';613 const plus_sign: u8 = '+';
628 try output(context, (&plus_sign)[0..1]);614 try output(context, (*[1]u8)(&plus_sign)[0..]);
629 const new_value = uint(value);615 const new_value = uint(value);
630 const new_width = if (width == 0) 0 else (width - 1);616 const new_width = if (width == 0) 0 else (width - 1);
631 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);617 return formatIntUnsigned(new_value, base, uppercase, new_width, context, Errors, output);
632 }618 }
633}619}
634620
635fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize, context: var, comptime Errors: type, output: fn (@typeOf(context), []const u8) Errors!void) Errors!void {621fn formatIntUnsigned(
622 value: var,
623 base: u8,
624 uppercase: bool,
625 width: usize,
626 context: var,
627 comptime Errors: type,
628 output: fn (@typeOf(context), []const u8) Errors!void,
629) Errors!void {
636 // max_int_digits accounts for the minus sign. when printing an unsigned630 // max_int_digits accounts for the minus sign. when printing an unsigned
637 // number we don't need to do that.631 // number we don't need to do that.
638 var buf: [max_int_digits - 1]u8 = undefined;632 var buf: [max_int_digits - 1]u8 = undefined;
...@@ -654,7 +648,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize, contex...@@ -654,7 +648,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize, contex
654 const zero_byte: u8 = '0';648 const zero_byte: u8 = '0';
655 var leftover_padding = padding - index;649 var leftover_padding = padding - index;
656 while (true) {650 while (true) {
657 try output(context, (&zero_byte)[0..1]);651 try output(context, (*[1]u8)(&zero_byte)[0..]);
658 leftover_padding -= 1;652 leftover_padding -= 1;
659 if (leftover_padding == 0) break;653 if (leftover_padding == 0) break;
660 }654 }
...@@ -831,6 +825,10 @@ test "fmt.format" {...@@ -831,6 +825,10 @@ test "fmt.format" {
831 const value: u3 = 0b101;825 const value: u3 = 0b101;
832 try testFmt("u3: 5\n", "u3: {}\n", value);826 try testFmt("u3: 5\n", "u3: {}\n", value);
833 }827 }
828 {
829 const value: u8 = 'a';
830 try testFmt("u8: a\n", "u8: {c}\n", value);
831 }
834 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024));832 try testFmt("file size: 63MiB\n", "file size: {Bi}\n", usize(63 * 1024 * 1024));
835 try testFmt("file size: 66.06MB\n", "file size: {B2}\n", usize(63 * 1024 * 1024));833 try testFmt("file size: 66.06MB\n", "file size: {B2}\n", usize(63 * 1024 * 1024));
836 {834 {
...@@ -1048,6 +1046,42 @@ test "fmt.format" {...@@ -1048,6 +1046,42 @@ test "fmt.format" {
1048 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);1046 const result = try bufPrint(buf1[0..], "f64: {.5}\n", value);
1049 assert(mem.eql(u8, result, "f64: 18014400656965630.00000\n"));1047 assert(mem.eql(u8, result, "f64: 18014400656965630.00000\n"));
1050 }1048 }
1049 //custom type format
1050 {
1051 const Vec2 = struct {
1052 const SelfType = this;
1053 x: f32,
1054 y: f32,
1055
1056 pub fn format(
1057 self: *SelfType,
1058 comptime fmt: []const u8,
1059 context: var,
1060 comptime Errors: type,
1061 output: fn (@typeOf(context), []const u8) Errors!void,
1062 ) Errors!void {
1063 if (fmt.len > 0) {
1064 if (fmt.len > 1) unreachable;
1065 switch (fmt[0]) {
1066 //point format
1067 'p' => return std.fmt.format(context, Errors, output, "({.3},{.3})", self.x, self.y),
1068 //dimension format
1069 'd' => return std.fmt.format(context, Errors, output, "{.3}x{.3}", self.x, self.y),
1070 else => unreachable,
1071 }
1072 }
1073 return std.fmt.format(context, Errors, output, "({.3},{.3})", self.x, self.y);
1074 }
1075 };
1076
1077 var buf1: [32]u8 = undefined;
1078 var value = Vec2{
1079 .x = 10.2,
1080 .y = 2.22,
1081 };
1082 try testFmt("point: (10.200,2.220)\n", "point: {}\n", &value);
1083 try testFmt("dim: 10.200x2.220\n", "dim: {d}\n", &value);
1084 }
1051}1085}
10521086
1053fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void {1087fn testFmt(expected: []const u8, comptime template: []const u8, args: ...) !void {
std/heap.zig+1-1
...@@ -24,7 +24,7 @@ fn cAlloc(self: *Allocator, n: usize, alignment: u29) ![]u8 {...@@ -24,7 +24,7 @@ fn cAlloc(self: *Allocator, n: usize, alignment: u29) ![]u8 {
24fn cRealloc(self: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {24fn cRealloc(self: *Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
25 const old_ptr = @ptrCast([*]c_void, old_mem.ptr);25 const old_ptr = @ptrCast([*]c_void, old_mem.ptr);
26 if (c.realloc(old_ptr, new_size)) |buf| {26 if (c.realloc(old_ptr, new_size)) |buf| {
27 return @ptrCast(*u8, buf)[0..new_size];27 return @ptrCast([*]u8, buf)[0..new_size];
28 } else if (new_size <= old_mem.len) {28 } else if (new_size <= old_mem.len) {
29 return old_mem[0..new_size];29 return old_mem[0..new_size];
30 } else {30 } else {
std/io.zig+2-2
...@@ -219,12 +219,12 @@ pub fn OutStream(comptime WriteError: type) type {...@@ -219,12 +219,12 @@ pub fn OutStream(comptime WriteError: type) type {
219 }219 }
220220
221 pub fn writeByte(self: *Self, byte: u8) !void {221 pub fn writeByte(self: *Self, byte: u8) !void {
222 const slice = (&byte)[0..1];222 const slice = (*[1]u8)(&byte)[0..];
223 return self.writeFn(self, slice);223 return self.writeFn(self, slice);
224 }224 }
225225
226 pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) !void {226 pub fn writeByteNTimes(self: *Self, byte: u8, n: usize) !void {
227 const slice = (&byte)[0..1];227 const slice = (*[1]u8)(&byte)[0..];
228 var i: usize = 0;228 var i: usize = 0;
229 while (i < n) : (i += 1) {229 while (i < n) : (i += 1) {
230 try self.writeFn(self, slice);230 try self.writeFn(self, slice);
std/macho.zig+1-1
...@@ -164,7 +164,7 @@ fn readNoEof(in: *io.FileInStream, comptime T: type, result: []T) !void {...@@ -164,7 +164,7 @@ fn readNoEof(in: *io.FileInStream, comptime T: type, result: []T) !void {
164 return in.stream.readNoEof(([]u8)(result));164 return in.stream.readNoEof(([]u8)(result));
165}165}
166fn readOneNoEof(in: *io.FileInStream, comptime T: type, result: *T) !void {166fn readOneNoEof(in: *io.FileInStream, comptime T: type, result: *T) !void {
167 return readNoEof(in, T, result[0..1]);167 return readNoEof(in, T, (*[1]T)(result)[0..]);
168}168}
169169
170fn isSymbol(sym: *const Nlist64) bool {170fn isSymbol(sym: *const Nlist64) bool {
std/math/ln.zig+2-2
...@@ -14,7 +14,7 @@ const TypeId = builtin.TypeId;...@@ -14,7 +14,7 @@ const TypeId = builtin.TypeId;
14pub fn ln(x: var) @typeOf(x) {14pub fn ln(x: var) @typeOf(x) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.ComptimeFloat => {
18 return @typeOf(1.0)(ln_64(x));18 return @typeOf(1.0)(ln_64(x));
19 },19 },
20 TypeId.Float => {20 TypeId.Float => {
...@@ -24,7 +24,7 @@ pub fn ln(x: var) @typeOf(x) {...@@ -24,7 +24,7 @@ pub fn ln(x: var) @typeOf(x) {
24 else => @compileError("ln not implemented for " ++ @typeName(T)),24 else => @compileError("ln not implemented for " ++ @typeName(T)),
25 };25 };
26 },26 },
27 TypeId.IntLiteral => {27 TypeId.ComptimeInt => {
28 return @typeOf(1)(math.floor(ln_64(f64(x))));28 return @typeOf(1)(math.floor(ln_64(f64(x))));
29 },29 },
30 TypeId.Int => {30 TypeId.Int => {
std/math/log.zig+3-3
...@@ -9,15 +9,15 @@ pub fn log(comptime T: type, base: T, x: T) T {...@@ -9,15 +9,15 @@ pub fn log(comptime T: type, base: T, x: T) T {
9 return math.log2(x);9 return math.log2(x);
10 } else if (base == 10) {10 } else if (base == 10) {
11 return math.log10(x);11 return math.log10(x);
12 } else if ((@typeId(T) == TypeId.Float or @typeId(T) == TypeId.FloatLiteral) and base == math.e) {12 } else if ((@typeId(T) == TypeId.Float or @typeId(T) == TypeId.ComptimeFloat) and base == math.e) {
13 return math.ln(x);13 return math.ln(x);
14 }14 }
1515
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.ComptimeFloat => {
18 return @typeOf(1.0)(math.ln(f64(x)) / math.ln(f64(base)));18 return @typeOf(1.0)(math.ln(f64(x)) / math.ln(f64(base)));
19 },19 },
20 TypeId.IntLiteral => {20 TypeId.ComptimeInt => {
21 return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(f64(base))));21 return @typeOf(1)(math.floor(math.ln(f64(x)) / math.ln(f64(base))));
22 },22 },
23 builtin.TypeId.Int => {23 builtin.TypeId.Int => {
std/math/log10.zig+2-2
...@@ -14,7 +14,7 @@ const TypeId = builtin.TypeId;...@@ -14,7 +14,7 @@ const TypeId = builtin.TypeId;
14pub fn log10(x: var) @typeOf(x) {14pub fn log10(x: var) @typeOf(x) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.ComptimeFloat => {
18 return @typeOf(1.0)(log10_64(x));18 return @typeOf(1.0)(log10_64(x));
19 },19 },
20 TypeId.Float => {20 TypeId.Float => {
...@@ -24,7 +24,7 @@ pub fn log10(x: var) @typeOf(x) {...@@ -24,7 +24,7 @@ pub fn log10(x: var) @typeOf(x) {
24 else => @compileError("log10 not implemented for " ++ @typeName(T)),24 else => @compileError("log10 not implemented for " ++ @typeName(T)),
25 };25 };
26 },26 },
27 TypeId.IntLiteral => {27 TypeId.ComptimeInt => {
28 return @typeOf(1)(math.floor(log10_64(f64(x))));28 return @typeOf(1)(math.floor(log10_64(f64(x))));
29 },29 },
30 TypeId.Int => {30 TypeId.Int => {
std/math/log2.zig+2-2
...@@ -14,7 +14,7 @@ const TypeId = builtin.TypeId;...@@ -14,7 +14,7 @@ const TypeId = builtin.TypeId;
14pub fn log2(x: var) @typeOf(x) {14pub fn log2(x: var) @typeOf(x) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.ComptimeFloat => {
18 return @typeOf(1.0)(log2_64(x));18 return @typeOf(1.0)(log2_64(x));
19 },19 },
20 TypeId.Float => {20 TypeId.Float => {
...@@ -24,7 +24,7 @@ pub fn log2(x: var) @typeOf(x) {...@@ -24,7 +24,7 @@ pub fn log2(x: var) @typeOf(x) {
24 else => @compileError("log2 not implemented for " ++ @typeName(T)),24 else => @compileError("log2 not implemented for " ++ @typeName(T)),
25 };25 };
26 },26 },
27 TypeId.IntLiteral => comptime {27 TypeId.ComptimeInt => comptime {
28 var result = 0;28 var result = 0;
29 var x_shifted = x;29 var x_shifted = x;
30 while (b: {30 while (b: {
std/math/sqrt.zig+2-2
...@@ -14,9 +14,9 @@ const TypeId = builtin.TypeId;...@@ -14,9 +14,9 @@ const TypeId = builtin.TypeId;
14pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {14pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => return T(@sqrt(f64, x)), // TODO upgrade to f12817 TypeId.ComptimeFloat => return T(@sqrt(f64, x)), // TODO upgrade to f128
18 TypeId.Float => return @sqrt(T, x),18 TypeId.Float => return @sqrt(T, x),
19 TypeId.IntLiteral => comptime {19 TypeId.ComptimeInt => comptime {
20 if (x > @maxValue(u128)) {20 if (x > @maxValue(u128)) {
21 @compileError("sqrt not implemented for comptime_int greater than 128 bits");21 @compileError("sqrt not implemented for comptime_int greater than 128 bits");
22 }22 }
std/mem.zig+19-15
...@@ -31,14 +31,16 @@ pub const Allocator = struct {...@@ -31,14 +31,16 @@ pub const Allocator = struct {
31 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`31 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
32 freeFn: fn (self: *Allocator, old_mem: []u8) void,32 freeFn: fn (self: *Allocator, old_mem: []u8) void,
3333
34 fn create(self: *Allocator, comptime T: type) !*T {34 /// Call destroy with the result
35 pub fn create(self: *Allocator, comptime T: type) !*T {
35 if (@sizeOf(T) == 0) return *{};36 if (@sizeOf(T) == 0) return *{};
36 const slice = try self.alloc(T, 1);37 const slice = try self.alloc(T, 1);
37 return &slice[0];38 return &slice[0];
38 }39 }
3940
40 // TODO once #733 is solved, this will replace create41 /// Call destroy with the result
41 fn construct(self: *Allocator, init: var) t: {42 /// TODO once #733 is solved, this will replace create
43 pub fn construct(self: *Allocator, init: var) t: {
42 // TODO this is a workaround for type getting parsed as Error!&const T44 // TODO this is a workaround for type getting parsed as Error!&const T
43 const T = @typeOf(init).Child;45 const T = @typeOf(init).Child;
44 break :t Error!*T;46 break :t Error!*T;
...@@ -51,17 +53,19 @@ pub const Allocator = struct {...@@ -51,17 +53,19 @@ pub const Allocator = struct {
51 return ptr;53 return ptr;
52 }54 }
5355
54 fn destroy(self: *Allocator, ptr: var) void {56 /// `ptr` should be the return value of `construct` or `create`
55 self.free(ptr[0..1]);57 pub fn destroy(self: *Allocator, ptr: var) void {
58 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(ptr));
59 self.freeFn(self, non_const_ptr[0..@sizeOf(@typeOf(ptr).Child)]);
56 }60 }
5761
58 fn alloc(self: *Allocator, comptime T: type, n: usize) ![]T {62 pub fn alloc(self: *Allocator, comptime T: type, n: usize) ![]T {
59 return self.alignedAlloc(T, @alignOf(T), n);63 return self.alignedAlloc(T, @alignOf(T), n);
60 }64 }
6165
62 fn alignedAlloc(self: *Allocator, comptime T: type, comptime alignment: u29, n: usize) ![]align(alignment) T {66 pub fn alignedAlloc(self: *Allocator, comptime T: type, comptime alignment: u29, n: usize) ![]align(alignment) T {
63 if (n == 0) {67 if (n == 0) {
64 return (*align(alignment) T)(undefined)[0..0];68 return ([*]align(alignment) T)(undefined)[0..0];
65 }69 }
66 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;70 const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
67 const byte_slice = try self.allocFn(self, byte_count, alignment);71 const byte_slice = try self.allocFn(self, byte_count, alignment);
...@@ -73,17 +77,17 @@ pub const Allocator = struct {...@@ -73,17 +77,17 @@ pub const Allocator = struct {
73 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));77 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
74 }78 }
7579
76 fn realloc(self: *Allocator, comptime T: type, old_mem: []T, n: usize) ![]T {80 pub fn realloc(self: *Allocator, comptime T: type, old_mem: []T, n: usize) ![]T {
77 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);81 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
78 }82 }
7983
80 fn alignedRealloc(self: *Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) ![]align(alignment) T {84 pub fn alignedRealloc(self: *Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) ![]align(alignment) T {
81 if (old_mem.len == 0) {85 if (old_mem.len == 0) {
82 return self.alloc(T, n);86 return self.alloc(T, n);
83 }87 }
84 if (n == 0) {88 if (n == 0) {
85 self.free(old_mem);89 self.free(old_mem);
86 return (*align(alignment) T)(undefined)[0..0];90 return ([*]align(alignment) T)(undefined)[0..0];
87 }91 }
8892
89 const old_byte_slice = ([]u8)(old_mem);93 const old_byte_slice = ([]u8)(old_mem);
...@@ -102,11 +106,11 @@ pub const Allocator = struct {...@@ -102,11 +106,11 @@ pub const Allocator = struct {
102 /// Reallocate, but `n` must be less than or equal to `old_mem.len`.106 /// Reallocate, but `n` must be less than or equal to `old_mem.len`.
103 /// Unlike `realloc`, this function cannot fail.107 /// Unlike `realloc`, this function cannot fail.
104 /// Shrinking to 0 is the same as calling `free`.108 /// Shrinking to 0 is the same as calling `free`.
105 fn shrink(self: *Allocator, comptime T: type, old_mem: []T, n: usize) []T {109 pub fn shrink(self: *Allocator, comptime T: type, old_mem: []T, n: usize) []T {
106 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);110 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
107 }111 }
108112
109 fn alignedShrink(self: *Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) []align(alignment) T {113 pub fn alignedShrink(self: *Allocator, comptime T: type, comptime alignment: u29, old_mem: []align(alignment) T, n: usize) []align(alignment) T {
110 if (n == 0) {114 if (n == 0) {
111 self.free(old_mem);115 self.free(old_mem);
112 return old_mem[0..0];116 return old_mem[0..0];
...@@ -123,10 +127,10 @@ pub const Allocator = struct {...@@ -123,10 +127,10 @@ pub const Allocator = struct {
123 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));127 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
124 }128 }
125129
126 fn free(self: *Allocator, memory: var) void {130 pub fn free(self: *Allocator, memory: var) void {
127 const bytes = ([]const u8)(memory);131 const bytes = ([]const u8)(memory);
128 if (bytes.len == 0) return;132 if (bytes.len == 0) return;
129 const non_const_ptr = @intToPtr(*u8, @ptrToInt(bytes.ptr));133 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
130 self.freeFn(self, non_const_ptr[0..bytes.len]);134 self.freeFn(self, non_const_ptr[0..bytes.len]);
131 }135 }
132};136};
std/net.zig+1-1
...@@ -68,7 +68,7 @@ pub const Address = struct {...@@ -68,7 +68,7 @@ pub const Address = struct {
6868
69pub fn parseIp4(buf: []const u8) !u32 {69pub fn parseIp4(buf: []const u8) !u32 {
70 var result: u32 = undefined;70 var result: u32 = undefined;
71 const out_ptr = ([]u8)((&result)[0..1]);71 const out_ptr = ([]u8)((*[1]u32)(&result)[0..]);
7272
73 var x: u8 = 0;73 var x: u8 = 0;
74 var index: u8 = 0;74 var index: u8 = 0;
std/os/index.zig+2-2
...@@ -1240,7 +1240,7 @@ pub const Dir = struct {...@@ -1240,7 +1240,7 @@ pub const Dir = struct {
1240 const next_index = self.index + darwin_entry.d_reclen;1240 const next_index = self.index + darwin_entry.d_reclen;
1241 self.index = next_index;1241 self.index = next_index;
12421242
1243 const name = (&darwin_entry.d_name)[0..darwin_entry.d_namlen];1243 const name = @ptrCast([*]u8, &darwin_entry.d_name)[0..darwin_entry.d_namlen];
12441244
1245 // skip . and .. entries1245 // skip . and .. entries
1246 if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) {1246 if (mem.eql(u8, name, ".") or mem.eql(u8, name, "..")) {
...@@ -1704,7 +1704,7 @@ pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {...@@ -1704,7 +1704,7 @@ pub fn argsFree(allocator: *mem.Allocator, args_alloc: []const []u8) void {
1704 for (args_alloc) |arg| {1704 for (args_alloc) |arg| {
1705 total_bytes += @sizeOf([]u8) + arg.len;1705 total_bytes += @sizeOf([]u8) + arg.len;
1706 }1706 }
1707 const unaligned_allocated_buf = @ptrCast(*const u8, args_alloc.ptr)[0..total_bytes];1707 const unaligned_allocated_buf = @ptrCast([*]const u8, args_alloc.ptr)[0..total_bytes];
1708 const aligned_allocated_buf = @alignCast(@alignOf([]u8), unaligned_allocated_buf);1708 const aligned_allocated_buf = @alignCast(@alignOf([]u8), unaligned_allocated_buf);
1709 return allocator.free(aligned_allocated_buf);1709 return allocator.free(aligned_allocated_buf);
1710}1710}
std/os/time.zig+1-1
...@@ -266,7 +266,7 @@ test "os.time.timestamp" {...@@ -266,7 +266,7 @@ test "os.time.timestamp" {
266266
267test "os.time.Timer" {267test "os.time.Timer" {
268 const ns_per_ms = (ns_per_s / ms_per_s);268 const ns_per_ms = (ns_per_s / ms_per_s);
269 const margin = ns_per_ms * 50;269 const margin = ns_per_ms * 150;
270270
271 var timer = try Timer.start();271 var timer = try Timer.start();
272 sleep(0, 10 * ns_per_ms);272 sleep(0, 10 * ns_per_ms);
std/special/compiler_rt/udivmoddi4_test.zig+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1// Disable formatting to avoid unnecessary source repository bloat.
2// zig fmt: off
1const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;3const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
2const assert = @import("std").debug.assert;4const assert = @import("std").debug.assert;
35
std/special/compiler_rt/udivmodti4_test.zig+2
...@@ -1,3 +1,5 @@...@@ -1,3 +1,5 @@
1// Disable formatting to avoid unnecessary source repository bloat.
2// zig fmt: off
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;3const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const assert = @import("std").debug.assert;4const assert = @import("std").debug.assert;
35
std/zig/parser_test.zig+26
...@@ -1,3 +1,29 @@...@@ -1,3 +1,29 @@
1test "zig fmt: comment to disable/enable zig fmt first" {
2 try testCanonical(
3 \\// Test trailing comma syntax
4 \\// zig fmt: off
5 \\
6 \\const struct_trailing_comma = struct { x: i32, y: i32, };
7 );
8}
9
10test "zig fmt: comment to disable/enable zig fmt" {
11 try testTransform(
12 \\const a = b;
13 \\// zig fmt: off
14 \\const c = d;
15 \\// zig fmt: on
16 \\const e = f;
17 ,
18 \\const a = b;
19 \\// zig fmt: off
20 \\const c = d;
21 \\// zig fmt: on
22 \\const e = f;
23 \\
24 );
25}
26
1test "zig fmt: pointer of unknown length" {27test "zig fmt: pointer of unknown length" {
2 try testCanonical(28 try testCanonical(
3 \\fn foo(ptr: [*]u8) void {}29 \\fn foo(ptr: [*]u8) void {}
std/zig/render.zig+39-2
...@@ -82,8 +82,45 @@ fn renderRoot(...@@ -82,8 +82,45 @@ fn renderRoot(
8282
83 var start_col: usize = 0;83 var start_col: usize = 0;
84 var it = tree.root_node.decls.iterator(0);84 var it = tree.root_node.decls.iterator(0);
85 while (it.next()) |decl| {85 while (true) {
86 try renderTopLevelDecl(allocator, stream, tree, 0, &start_col, decl.*);86 var decl = (it.next() ?? return).*;
87 // look for zig fmt: off comment
88 var start_token_index = decl.firstToken();
89 zig_fmt_loop: while (start_token_index != 0) {
90 start_token_index -= 1;
91 const start_token = tree.tokens.at(start_token_index);
92 switch (start_token.id) {
93 Token.Id.LineComment => {},
94 Token.Id.DocComment => continue,
95 else => break,
96 }
97 if (mem.eql(u8, mem.trim(u8, tree.tokenSlicePtr(start_token)[2..], " "), "zig fmt: off")) {
98 var end_token_index = start_token_index;
99 while (true) {
100 end_token_index += 1;
101 const end_token = tree.tokens.at(end_token_index);
102 switch (end_token.id) {
103 Token.Id.LineComment => {},
104 Token.Id.Eof => {
105 const start = tree.tokens.at(start_token_index + 1).start;
106 try stream.write(tree.source[start..]);
107 return;
108 },
109 else => continue,
110 }
111 if (mem.eql(u8, mem.trim(u8, tree.tokenSlicePtr(end_token)[2..], " "), "zig fmt: on")) {
112 const start = tree.tokens.at(start_token_index + 1).start;
113 try stream.print("{}\n", tree.source[start..end_token.end]);
114 while (tree.tokens.at(decl.firstToken()).start < end_token.end) {
115 decl = (it.next() ?? return).*;
116 }
117 break :zig_fmt_loop;
118 }
119 }
120 }
121 }
122
123 try renderTopLevelDecl(allocator, stream, tree, 0, &start_col, decl);
87 if (it.peek()) |next_decl| {124 if (it.peek()) |next_decl| {
88 try renderExtraNewline(tree, stream, &start_col, next_decl.*);125 try renderExtraNewline(tree, stream, &start_col, next_decl.*);
89 }126 }
test/cases/align.zig+2-2
...@@ -6,7 +6,7 @@ var foo: u8 align(4) = 100;...@@ -6,7 +6,7 @@ var foo: u8 align(4) = 100;
6test "global variable alignment" {6test "global variable alignment" {
7 assert(@typeOf(&foo).alignment == 4);7 assert(@typeOf(&foo).alignment == 4);
8 assert(@typeOf(&foo) == *align(4) u8);8 assert(@typeOf(&foo) == *align(4) u8);
9 const slice = (&foo)[0..1];9 const slice = (*[1]u8)(&foo)[0..];
10 assert(@typeOf(slice) == []align(4) u8);10 assert(@typeOf(slice) == []align(4) u8);
11}11}
1212
...@@ -60,7 +60,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {...@@ -60,7 +60,7 @@ fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
60test "implicitly decreasing slice alignment" {60test "implicitly decreasing slice alignment" {
61 const a: u32 align(4) = 3;61 const a: u32 align(4) = 3;
62 const b: u32 align(8) = 4;62 const b: u32 align(8) = 4;
63 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);63 assert(addUnalignedSlice((*[1]u32)(&a)[0..], (*[1]u32)(&b)[0..]) == 7);
64}64}
65fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {65fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
66 return a[0] + b[0];66 return a[0] + b[0];
test/cases/array.zig+29
...@@ -115,3 +115,32 @@ test "array len property" {...@@ -115,3 +115,32 @@ test "array len property" {
115 var x: [5]i32 = undefined;115 var x: [5]i32 = undefined;
116 assert(@typeOf(x).len == 5);116 assert(@typeOf(x).len == 5);
117}117}
118
119test "single-item pointer to array indexing and slicing" {
120 testSingleItemPtrArrayIndexSlice();
121 comptime testSingleItemPtrArrayIndexSlice();
122}
123
124fn testSingleItemPtrArrayIndexSlice() void {
125 var array = "aaaa";
126 doSomeMangling(&array);
127 assert(mem.eql(u8, "azya", array));
128}
129
130fn doSomeMangling(array: *[4]u8) void {
131 array[1] = 'z';
132 array[2..3][0] = 'y';
133}
134
135test "implicit cast single-item pointer" {
136 testImplicitCastSingleItemPtr();
137 comptime testImplicitCastSingleItemPtr();
138}
139
140fn testImplicitCastSingleItemPtr() void {
141 var byte: u8 = 100;
142 const slice = (*[1]u8)(&byte)[0..];
143 slice[0] += 1;
144 assert(byte == 101);
145}
146
test/cases/eval.zig+3-3
...@@ -418,9 +418,9 @@ test "string literal used as comptime slice is memoized" {...@@ -418,9 +418,9 @@ test "string literal used as comptime slice is memoized" {
418}418}
419419
420test "comptime slice of undefined pointer of length 0" {420test "comptime slice of undefined pointer of length 0" {
421 const slice1 = (*i32)(undefined)[0..0];421 const slice1 = ([*]i32)(undefined)[0..0];
422 assert(slice1.len == 0);422 assert(slice1.len == 0);
423 const slice2 = (*i32)(undefined)[100..100];423 const slice2 = ([*]i32)(undefined)[100..100];
424 assert(slice2.len == 0);424 assert(slice2.len == 0);
425}425}
426426
...@@ -508,7 +508,7 @@ test "comptime slice of slice preserves comptime var" {...@@ -508,7 +508,7 @@ test "comptime slice of slice preserves comptime var" {
508test "comptime slice of pointer preserves comptime var" {508test "comptime slice of pointer preserves comptime var" {
509 comptime {509 comptime {
510 var buff: [10]u8 = undefined;510 var buff: [10]u8 = undefined;
511 var a = &buff[0];511 var a = buff[0..].ptr;
512 a[0..1][0] = 1;512 a[0..1][0] = 1;
513 assert(buff[0..][0..][0] == 1);513 assert(buff[0..][0..][0] == 1);
514 }514 }
test/cases/math.zig+18-6
...@@ -329,14 +329,14 @@ fn testShrExact(x: u8) void {...@@ -329,14 +329,14 @@ fn testShrExact(x: u8) void {
329 assert(shifted == 0b00101101);329 assert(shifted == 0b00101101);
330}330}
331331
332test "big number addition" {332test "comptime_int addition" {
333 comptime {333 comptime {
334 assert(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);334 assert(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
335 assert(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);335 assert(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
336 }336 }
337}337}
338338
339test "big number multiplication" {339test "comptime_int multiplication" {
340 comptime {340 comptime {
341 assert(341 assert(
342 45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567,342 45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567,
...@@ -347,13 +347,13 @@ test "big number multiplication" {...@@ -347,13 +347,13 @@ test "big number multiplication" {
347 }347 }
348}348}
349349
350test "big number shifting" {350test "comptime_int shifting" {
351 comptime {351 comptime {
352 assert((u128(1) << 127) == 0x80000000000000000000000000000000);352 assert((u128(1) << 127) == 0x80000000000000000000000000000000);
353 }353 }
354}354}
355355
356test "big number multi-limb shift and mask" {356test "comptime_int multi-limb shift and mask" {
357 comptime {357 comptime {
358 var a = 0xefffffffa0000001eeeeeeefaaaaaaab;358 var a = 0xefffffffa0000001eeeeeeefaaaaaaab;
359359
...@@ -370,7 +370,7 @@ test "big number multi-limb shift and mask" {...@@ -370,7 +370,7 @@ test "big number multi-limb shift and mask" {
370 }370 }
371}371}
372372
373test "big number multi-limb partial shift right" {373test "comptime_int multi-limb partial shift right" {
374 comptime {374 comptime {
375 var a = 0x1ffffffffeeeeeeee;375 var a = 0x1ffffffffeeeeeeee;
376 a >>= 16;376 a >>= 16;
...@@ -391,7 +391,7 @@ fn test_xor() void {...@@ -391,7 +391,7 @@ fn test_xor() void {
391 assert(0xFF ^ 0xFF == 0x00);391 assert(0xFF ^ 0xFF == 0x00);
392}392}
393393
394test "big number xor" {394test "comptime_int xor" {
395 comptime {395 comptime {
396 assert(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);396 assert(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
397 assert(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);397 assert(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
...@@ -449,3 +449,15 @@ test "@sqrt" {...@@ -449,3 +449,15 @@ test "@sqrt" {
449fn testSqrt(comptime T: type, x: T) void {449fn testSqrt(comptime T: type, x: T) void {
450 assert(@sqrt(T, x * x) == x);450 assert(@sqrt(T, x * x) == x);
451}451}
452
453test "comptime_int param and return" {
454 const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);
455 assert(a == 137114567242441932203689521744947848950);
456
457 const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768);
458 assert(b == 985095453608931032642182098849559179469148836107390954364380);
459}
460
461fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int {
462 return a + b;
463}
test/cases/misc.zig+6-6
...@@ -274,7 +274,7 @@ test "generic malloc free" {...@@ -274,7 +274,7 @@ test "generic malloc free" {
274}274}
275var some_mem: [100]u8 = undefined;275var some_mem: [100]u8 = undefined;
276fn memAlloc(comptime T: type, n: usize) error![]T {276fn memAlloc(comptime T: type, n: usize) error![]T {
277 return @ptrCast(*T, &some_mem[0])[0..n];277 return @ptrCast([*]T, &some_mem[0])[0..n];
278}278}
279fn memFree(comptime T: type, memory: []T) void {}279fn memFree(comptime T: type, memory: []T) void {}
280280
...@@ -501,10 +501,10 @@ test "@typeId" {...@@ -501,10 +501,10 @@ test "@typeId" {
501 assert(@typeId(*f32) == Tid.Pointer);501 assert(@typeId(*f32) == Tid.Pointer);
502 assert(@typeId([2]u8) == Tid.Array);502 assert(@typeId([2]u8) == Tid.Array);
503 assert(@typeId(AStruct) == Tid.Struct);503 assert(@typeId(AStruct) == Tid.Struct);
504 assert(@typeId(@typeOf(1)) == Tid.IntLiteral);504 assert(@typeId(@typeOf(1)) == Tid.ComptimeInt);
505 assert(@typeId(@typeOf(1.0)) == Tid.FloatLiteral);505 assert(@typeId(@typeOf(1.0)) == Tid.ComptimeFloat);
506 assert(@typeId(@typeOf(undefined)) == Tid.UndefinedLiteral);506 assert(@typeId(@typeOf(undefined)) == Tid.Undefined);
507 assert(@typeId(@typeOf(null)) == Tid.NullLiteral);507 assert(@typeId(@typeOf(null)) == Tid.Null);
508 assert(@typeId(?i32) == Tid.Nullable);508 assert(@typeId(?i32) == Tid.Nullable);
509 assert(@typeId(error!i32) == Tid.ErrorUnion);509 assert(@typeId(error!i32) == Tid.ErrorUnion);
510 assert(@typeId(error) == Tid.ErrorSet);510 assert(@typeId(error) == Tid.ErrorSet);
...@@ -588,7 +588,7 @@ var global_ptr = &gdt[0];...@@ -588,7 +588,7 @@ var global_ptr = &gdt[0];
588588
589// can't really run this test but we can make sure it has no compile error589// can't really run this test but we can make sure it has no compile error
590// and generates code590// and generates code
591const vram = @intToPtr(*volatile u8, 0x20000000)[0..0x8000];591const vram = @intToPtr([*]volatile u8, 0x20000000)[0..0x8000];
592export fn writeToVRam() void {592export fn writeToVRam() void {
593 vram[0] = 'X';593 vram[0] = 'X';
594}594}
test/cases/slice.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4const x = @intToPtr(*i32, 0x1000)[0..0x500];4const x = @intToPtr([*]i32, 0x1000)[0..0x500];
5const y = x[0x100..];5const y = x[0x100..];
6test "compile time slice of pointer to hard coded address" {6test "compile time slice of pointer to hard coded address" {
7 assert(@ptrToInt(x.ptr) == 0x1000);7 assert(@ptrToInt(x.ptr) == 0x1000);
test/cases/syntax.zig+1
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1// Test trailing comma syntax1// Test trailing comma syntax
2// zig fmt: off
23
3const struct_trailing_comma = struct { x: i32, y: i32, };4const struct_trailing_comma = struct { x: i32, y: i32, };
4const struct_no_comma = struct { x: i32, y: i32 };5const struct_no_comma = struct { x: i32, y: i32 };
test/compile_errors.zig+22-11
...@@ -1,13 +1,22 @@...@@ -1,13 +1,22 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.add(
5 "slicing single-item pointer",
6 \\export fn entry(ptr: *i32) void {
7 \\ const slice = ptr[0..2];
8 \\}
9 ,
10 ".tmp_source.zig:2:22: error: slice of single-item pointer",
11 );
12
4 cases.add(13 cases.add(
5 "indexing single-item pointer",14 "indexing single-item pointer",
6 \\export fn entry(ptr: *i32) i32 {15 \\export fn entry(ptr: *i32) i32 {
7 \\ return ptr[1];16 \\ return ptr[1];
8 \\}17 \\}
9 ,18 ,
10 ".tmp_source.zig:2:15: error: indexing not allowed on pointer to single item",19 ".tmp_source.zig:2:15: error: index of single-item pointer",
11 );20 );
1221
13 cases.add(22 cases.add(
...@@ -144,10 +153,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -144,10 +153,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
144 cases.add(153 cases.add(
145 "comptime slice of undefined pointer non-zero len",154 "comptime slice of undefined pointer non-zero len",
146 \\export fn entry() void {155 \\export fn entry() void {
147 \\ const slice = (*i32)(undefined)[0..1];156 \\ const slice = ([*]i32)(undefined)[0..1];
148 \\}157 \\}
149 ,158 ,
150 ".tmp_source.zig:2:36: error: non-zero length slice of undefined pointer",159 ".tmp_source.zig:2:38: error: non-zero length slice of undefined pointer",
151 );160 );
152161
153 cases.add(162 cases.add(
...@@ -1530,7 +1539,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1530,7 +1539,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1530 \\fn foo() *const i32 { return y; }1539 \\fn foo() *const i32 { return y; }
1531 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }1540 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1532 ,1541 ,
1533 ".tmp_source.zig:3:30: error: expected type '*const i32', found '*const (integer literal)'",1542 ".tmp_source.zig:3:30: error: expected type '*const i32', found '*const comptime_int'",
1534 );1543 );
15351544
1536 cases.add(1545 cases.add(
...@@ -1546,7 +1555,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1546,7 +1555,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1546 \\const x = 2 == 2.0;1555 \\const x = 2 == 2.0;
1547 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }1556 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
1548 ,1557 ,
1549 ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'",1558 ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type 'comptime_float'",
1550 );1559 );
15511560
1552 cases.add(1561 cases.add(
...@@ -2180,7 +2189,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2180,7 +2189,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2180 \\2189 \\
2181 \\export fn entry() usize { return @sizeOf(@typeOf(block_aligned_stuff)); }2190 \\export fn entry() usize { return @sizeOf(@typeOf(block_aligned_stuff)); }
2182 ,2191 ,
2183 ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'",2192 ".tmp_source.zig:3:60: error: unable to perform binary not operation on type 'comptime_int'",
2184 );2193 );
21852194
2186 cases.addCase(x: {2195 cases.addCase(x: {
...@@ -3129,14 +3138,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3129,14 +3138,16 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3129 \\export fn entry() void {3138 \\export fn entry() void {
3130 \\ var foo = Foo { .a = 1, .b = 10 };3139 \\ var foo = Foo { .a = 1, .b = 10 };
3131 \\ foo.b += 1;3140 \\ foo.b += 1;
3132 \\ bar((&foo.b)[0..1]);3141 \\ bar((*[1]u32)(&foo.b)[0..]);
3133 \\}3142 \\}
3134 \\3143 \\
3135 \\fn bar(x: []u32) void {3144 \\fn bar(x: []u32) void {
3136 \\ x[0] += 1;3145 \\ x[0] += 1;
3137 \\}3146 \\}
3138 ,3147 ,
3139 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'",3148 ".tmp_source.zig:9:18: error: cast increases pointer alignment",
3149 ".tmp_source.zig:9:23: note: '*align(1) u32' has alignment 1",
3150 ".tmp_source.zig:9:18: note: '*[1]u32' has alignment 4",
3140 );3151 );
31413152
3142 cases.add(3153 cases.add(
...@@ -3258,10 +3269,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3258,10 +3269,10 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3258 \\ fn bar(self: *const Foo) void {}3269 \\ fn bar(self: *const Foo) void {}
3259 \\};3270 \\};
3260 ,3271 ,
3261 ".tmp_source.zig:4:4: error: variable of type '*(integer literal)' must be const or comptime",3272 ".tmp_source.zig:4:4: error: variable of type '*comptime_int' must be const or comptime",
3262 ".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime",3273 ".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime",
3263 ".tmp_source.zig:8:4: error: variable of type '(integer literal)' must be const or comptime",3274 ".tmp_source.zig:8:4: error: variable of type 'comptime_int' must be const or comptime",
3264 ".tmp_source.zig:9:4: error: variable of type '(float literal)' must be const or comptime",3275 ".tmp_source.zig:9:4: error: variable of type 'comptime_float' must be const or comptime",
3265 ".tmp_source.zig:10:4: error: variable of type '(block)' must be const or comptime",3276 ".tmp_source.zig:10:4: error: variable of type '(block)' must be const or comptime",
3266 ".tmp_source.zig:11:4: error: variable of type '(null)' must be const or comptime",3277 ".tmp_source.zig:11:4: error: variable of type '(null)' must be const or comptime",
3267 ".tmp_source.zig:12:4: error: variable of type 'Opaque' must be const or comptime",3278 ".tmp_source.zig:12:4: error: variable of type 'Opaque' must be const or comptime",