authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-23 23:30:20-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-23 23:30:20-05:00
log32d8686da80d282e8cd6d84a0e5c331d269a1f69
tree889c1f634f4ff2e7b9d8cb078f11dbb41c4a1b2a
parent17cb85dfb837949cd3a559fe8e99dee1f72463a4

various fixes

* comptime expression is a block expression as it should be * fix var args when number of args passed is 0 * implement const value equality for structs * fix indent when rendering container decl AST * IR: prevent duplicate generation of code when it is partially compile-time evaluated * implement compile time struct field pointer evaluation * fix compile time evaluation of slicing

10 files changed, 84 insertions(+), 42 deletions(-)

doc/langref.md+4-4
...@@ -69,7 +69,9 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un...@@ -69,7 +69,9 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un
6969
70AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "&&=" | "||=" | "*%=" | "+%=" | "-%=" | "<<%="70AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | "&=" | "^=" | "|=" | "&&=" | "||=" | "*%=" | "+%=" | "-%=" | "<<%="
7171
72BlockExpression = IfExpression | Block | WhileExpression | ForExpression | SwitchExpression72BlockExpression = IfExpression | Block | WhileExpression | ForExpression | SwitchExpression | CompTimeExpression
73
74CompTimeExpression = option("comptime") Expression
7375
74SwitchExpression = option("inline") "switch" "(" Expression ")" "{" many(SwitchProng) "}"76SwitchExpression = option("inline") "switch" "(" Expression ")" "{" many(SwitchProng) "}"
7577
...@@ -141,14 +143,12 @@ StructLiteralField = "." Symbol "=" Expression...@@ -141,14 +143,12 @@ StructLiteralField = "." Symbol "=" Expression
141143
142PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" | "%%" | "??" | "-%"144PrefixOp = "!" | "-" | "~" | "*" | ("&" option("const")) | "?" | "%" | "%%" | "??" | "-%"
143145
144PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | CompTimeExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl146PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
145147
146ArrayType = "[" option(Expression) "]" option("const") TypeExpr148ArrayType = "[" option(Expression) "]" option("const") TypeExpr
147149
148GotoExpression = "goto" Symbol150GotoExpression = "goto" Symbol
149151
150CompTimeExpression = option("comptime") Expression
151
152GroupedExpression = "(" Expression ")"152GroupedExpression = "(" Expression ")"
153153
154KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this"154KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this"
example/cat/main.zig+4-12
...@@ -16,9 +16,7 @@ pub fn main(args: [][]u8) -> %void {...@@ -16,9 +16,7 @@ pub fn main(args: [][]u8) -> %void {
16 } else {16 } else {
17 var is: io.InStream = undefined;17 var is: io.InStream = undefined;
18 is.open(arg) %% |err| {18 is.open(arg) %% |err| {
19 %%io.stderr.printf("Unable to open file: ");19 %%io.stderr.printf("Unable to open file: {}\n", @errorName(err));
20 %%io.stderr.printf(@errorName(err));
21 %%io.stderr.printf("\n");
22 return err;20 return err;
23 };21 };
24 defer %%is.close();22 defer %%is.close();
...@@ -34,9 +32,7 @@ pub fn main(args: [][]u8) -> %void {...@@ -34,9 +32,7 @@ pub fn main(args: [][]u8) -> %void {
34}32}
3533
36fn usage(exe: []u8) -> %void {34fn usage(exe: []u8) -> %void {
37 %%io.stderr.printf("Usage: ");35 %%io.stderr.printf("Usage: {} [FILE]...\n", exe);
38 %%io.stderr.printf(exe);
39 %%io.stderr.printf(" [FILE]...\n");
40 return error.Invalid;36 return error.Invalid;
41}37}
4238
...@@ -45,9 +41,7 @@ fn cat_stream(is: &io.InStream) -> %void {...@@ -45,9 +41,7 @@ fn cat_stream(is: &io.InStream) -> %void {
4541
46 while (true) {42 while (true) {
47 const bytes_read = is.read(buf) %% |err| {43 const bytes_read = is.read(buf) %% |err| {
48 %%io.stderr.printf("Unable to read from stream: ");44 %%io.stderr.printf("Unable to read from stream: {}\n", @errorName(err));
49 %%io.stderr.printf(@errorName(err));
50 %%io.stderr.printf("\n");
51 return err;45 return err;
52 };46 };
5347
...@@ -56,9 +50,7 @@ fn cat_stream(is: &io.InStream) -> %void {...@@ -56,9 +50,7 @@ fn cat_stream(is: &io.InStream) -> %void {
56 }50 }
5751
58 io.stdout.write(buf[0...bytes_read]) %% |err| {52 io.stdout.write(buf[0...bytes_read]) %% |err| {
59 %%io.stderr.printf("Unable to write to stdout: ");53 %%io.stderr.printf("Unable to write to stdout: {}\n", @errorName(err));
60 %%io.stderr.printf(@errorName(err));
61 %%io.stderr.printf("\n");
62 return err;54 return err;
63 };55 };
64 }56 }
src/all_types.hpp-2
...@@ -1042,8 +1042,6 @@ struct FnTableEntry {...@@ -1042,8 +1042,6 @@ struct FnTableEntry {
10421042
1043 ZigList<IrInstruction *> alloca_list;1043 ZigList<IrInstruction *> alloca_list;
1044 ZigList<VariableTableEntry *> variable_list;1044 ZigList<VariableTableEntry *> variable_list;
1045
1046 VariableTableEntry *var_args_var;
1047};1045};
10481046
1049uint32_t fn_table_entry_hash(FnTableEntry*);1047uint32_t fn_table_entry_hash(FnTableEntry*);
src/analyze.cpp+7-1
...@@ -3263,7 +3263,13 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {...@@ -3263,7 +3263,13 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) {
3263 case TypeTableEntryIdArray:3263 case TypeTableEntryIdArray:
3264 zig_panic("TODO");3264 zig_panic("TODO");
3265 case TypeTableEntryIdStruct:3265 case TypeTableEntryIdStruct:
3266 zig_panic("TODO");3266 for (size_t i = 0; i < a->type->data.structure.src_field_count; i += 1) {
3267 ConstExprValue *field_a = &a->data.x_struct.fields[i];
3268 ConstExprValue *field_b = &b->data.x_struct.fields[i];
3269 if (!const_values_equal(field_a, field_b))
3270 return false;
3271 }
3272 return true;
3267 case TypeTableEntryIdUnion:3273 case TypeTableEntryIdUnion:
3268 zig_panic("TODO");3274 zig_panic("TODO");
3269 case TypeTableEntryIdUndefLit:3275 case TypeTableEntryIdUndefLit:
src/ast_render.cpp+1
...@@ -600,6 +600,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -600,6 +600,7 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
600 }600 }
601601
602 ar->indent -= ar->indent_size;602 ar->indent -= ar->indent_size;
603 print_indent(ar);
603 fprintf(ar->f, "}");604 fprintf(ar->f, "}");
604 break;605 break;
605 }606 }
src/ir.cpp+46-16
...@@ -5743,6 +5743,8 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {...@@ -5743,6 +5743,8 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb) {
5743 IrInstruction *dep_instruction = ir_instruction_get_dep(instruction, dep_i);5743 IrInstruction *dep_instruction = ir_instruction_get_dep(instruction, dep_i);
5744 if (dep_instruction == nullptr)5744 if (dep_instruction == nullptr)
5745 break;5745 break;
5746 if (dep_instruction->other)
5747 continue;
5746 if (dep_instruction->owner_bb == old_bb)5748 if (dep_instruction->owner_bb == old_bb)
5747 continue;5749 continue;
5748 ir_get_new_bb(ira, dep_instruction->owner_bb);5750 ir_get_new_bb(ira, dep_instruction->owner_bb);
...@@ -7565,19 +7567,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod...@@ -7565,19 +7567,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
7565 }7567 }
75667568
7567 Buf *param_name = param_decl_node->data.param_decl.name;7569 Buf *param_name = param_decl_node->data.param_decl.name;
7568 if (is_var_args) {7570 if (!is_var_args) {
7569 if (!impl_fn->var_args_var) {
7570 ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen,
7571 fn_type_id->param_count, fn_type_id->param_count + 1);
7572 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
7573 *child_scope, param_name, true, var_args_val);
7574 var->value.depends_on_compile_var = true;
7575 *child_scope = var->child_scope;
7576 impl_fn->var_args_var = var;
7577 }
7578 impl_fn->var_args_var->value.data.x_arg_tuple.end_index = fn_type_id->param_count + 1;
7579
7580 } else {
7581 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,7571 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
7582 *child_scope, param_name, true, arg_val);7572 *child_scope, param_name, true, arg_val);
7583 var->value.depends_on_compile_var = true;7573 var->value.depends_on_compile_var = true;
...@@ -7611,7 +7601,8 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -7611,7 +7601,8 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
7611{7601{
7612 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;7602 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
7613 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0;7603 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0;
7614 size_t src_param_count = fn_type_id->param_count;7604 size_t var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0;
7605 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0;
7615 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0;7606 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0;
7616 AstNode *source_node = call_instruction->base.source_node;7607 AstNode *source_node = call_instruction->base.source_node;
76177608
...@@ -7739,11 +7730,22 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -7739,11 +7730,22 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
7739 return ira->codegen->builtin_types.entry_invalid;7730 return ira->codegen->builtin_types.entry_invalid;
7740 }7731 }
7741 }7732 }
7733
7734 bool found_first_var_arg = false;
7735 size_t first_var_arg = inst_fn_type_id.param_count;
7742 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) {7736 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) {
7743 IrInstruction *arg = call_instruction->args[call_i]->other;7737 IrInstruction *arg = call_instruction->args[call_i]->other;
7744 if (arg->value.type->id == TypeTableEntryIdInvalid)7738 if (arg->value.type->id == TypeTableEntryIdInvalid)
7745 return ira->codegen->builtin_types.entry_invalid;7739 return ira->codegen->builtin_types.entry_invalid;
77467740
7741 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
7742 assert(param_decl_node->type == NodeTypeParamDecl);
7743 bool is_var_args = param_decl_node->data.param_decl.is_var_args;
7744 if (is_var_args && !found_first_var_arg) {
7745 first_var_arg = inst_fn_type_id.param_count;
7746 found_first_var_arg = true;
7747 }
7748
7747 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope,7749 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope,
7748 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))7750 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
7749 {7751 {
...@@ -7751,6 +7753,17 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal...@@ -7751,6 +7753,17 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
7751 }7753 }
7752 }7754 }
77537755
7756 if (fn_proto_node->data.fn_proto.is_var_args) {
7757 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
7758 Buf *param_name = param_decl_node->data.param_decl.name;
7759
7760 ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen,
7761 first_var_arg, inst_fn_type_id.param_count);
7762 VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
7763 impl_fn->child_scope, param_name, true, var_args_val);
7764 var->value.depends_on_compile_var = true;
7765 impl_fn->child_scope = var->child_scope;
7766 }
7754 {7767 {
7755 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;7768 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
7756 TypeTableEntry *return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);7769 TypeTableEntry *return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
...@@ -8317,8 +8330,9 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -8317,8 +8330,9 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
8317 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {8330 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
8318 ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone;8331 ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone;
8319 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;8332 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
8333 depends_on_compile_var = mem_slot->depends_on_compile_var || depends_on_compile_var || is_comptime;
8320 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type,8334 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type,
8321 mem_slot->depends_on_compile_var || depends_on_compile_var, ptr_special, is_const);8335 depends_on_compile_var, ptr_special, is_const);
8322 } else {8336 } else {
8323 ir_build_var_ptr_from(&ira->new_irb, instruction, var, false);8337 ir_build_var_ptr_from(&ira->new_irb, instruction, var, false);
8324 type_ensure_zero_bits_known(ira->codegen, var->value.type);8338 type_ensure_zero_bits_known(ira->codegen, var->value.type);
...@@ -8513,6 +8527,22 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field...@@ -8513,6 +8527,22 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field
85138527
8514 TypeStructField *field = find_struct_type_field(bare_type, field_name);8528 TypeStructField *field = find_struct_type_field(bare_type, field_name);
8515 if (field) {8529 if (field) {
8530 if (instr_is_comptime(container_ptr)) {
8531 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
8532 if (!ptr_val)
8533 return ira->codegen->builtin_types.entry_invalid;
8534
8535 ConstExprValue *struct_val = const_ptr_pointee(ptr_val);
8536 if (value_is_comptime(struct_val)) {
8537 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];
8538 if (value_is_comptime(field_val)) {
8539 bool depends_on_compile_var = field_val->depends_on_compile_var ||
8540 struct_val->depends_on_compile_var || ptr_val->depends_on_compile_var;
8541 return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, field_val,
8542 field_val->type, depends_on_compile_var, ConstPtrSpecialNone, is_const);
8543 }
8544 }
8545 }
8516 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);8546 ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field);
8517 return get_pointer_to_type(ira->codegen, field->type_entry, is_const);8547 return get_pointer_to_type(ira->codegen, field->type_entry, is_const);
8518 } else {8548 } else {
...@@ -10937,7 +10967,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio...@@ -10937,7 +10967,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
10937 init_const_ptr(ira->codegen, ptr_val, base_ptr, index, instruction->is_const);10967 init_const_ptr(ira->codegen, ptr_val, base_ptr, index, instruction->is_const);
1093810968
10939 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];10969 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index];
10940 init_const_usize(ira->codegen, len_val, rel_end);10970 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar);
1094110971
10942 return return_type;10972 return return_type;
10943 }10973 }
src/parser.cpp+6-6
...@@ -624,7 +624,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b...@@ -624,7 +624,7 @@ static AstNode *ast_parse_comptime_expr(ParseContext *pc, size_t *token_index, b
624}624}
625625
626/*626/*
627PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | CompTimeExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl627PrimaryExpression = Number | String | CharLiteral | KeywordLiteral | GroupedExpression | GotoExpression | BlockExpression | Symbol | ("@" Symbol FnCallExpression) | ArrayType | (option("extern") FnProto) | AsmExpression | ("error" "." Symbol) | ContainerDecl
628KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this"628KeywordLiteral = "true" | "false" | "null" | "break" | "continue" | "undefined" | "error" | "type" | "this"
629*/629*/
630static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {630static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
...@@ -709,10 +709,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo...@@ -709,10 +709,6 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
709 if (goto_node)709 if (goto_node)
710 return goto_node;710 return goto_node;
711711
712 AstNode *comptime_node = ast_parse_comptime_expr(pc, token_index, false);
713 if (comptime_node)
714 return comptime_node;
715
716 AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false);712 AstNode *grouped_expr_node = ast_parse_grouped_expr(pc, token_index, false);
717 if (grouped_expr_node) {713 if (grouped_expr_node) {
718 return grouped_expr_node;714 return grouped_expr_node;
...@@ -1810,7 +1806,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo...@@ -1810,7 +1806,7 @@ static AstNode *ast_parse_switch_expr(ParseContext *pc, size_t *token_index, boo
1810}1806}
18111807
1812/*1808/*
1813BlockExpression : IfExpression | Block | WhileExpression | ForExpression | SwitchExpression1809BlockExpression = IfExpression | Block | WhileExpression | ForExpression | SwitchExpression | CompTimeExpression
1814*/1810*/
1815static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) {1811static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
1816 Token *token = &pc->tokens->at(*token_index);1812 Token *token = &pc->tokens->at(*token_index);
...@@ -1835,6 +1831,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool...@@ -1835,6 +1831,10 @@ static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool
1835 if (block)1831 if (block)
1836 return block;1832 return block;
18371833
1834 AstNode *comptime_node = ast_parse_comptime_expr(pc, token_index, false);
1835 if (comptime_node)
1836 return comptime_node;
1837
1838 if (mandatory)1838 if (mandatory)
1839 ast_invalid_token_error(pc, token);1839 ast_invalid_token_error(pc, token);
18401840
test/cases/eval.zig+14
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const str = @import("std").str;
23
3fn compileTimeRecursion() {4fn compileTimeRecursion() {
4 @setFnTest(this);5 @setFnTest(this);
...@@ -161,3 +162,16 @@ fn staticallyInitializedArrayLiteral() {...@@ -161,3 +162,16 @@ fn staticallyInitializedArrayLiteral() {
161 assert(y[3] == 4);162 assert(y[3] == 4);
162}163}
163const st_init_arr_lit_x = []u8{1,2,3,4};164const st_init_arr_lit_x = []u8{1,2,3,4};
165
166
167fn constSlice() {
168 @setFnTest(this);
169
170 comptime {
171 const a = "1234567890";
172 assert(a.len == 10);
173 const b = a[1...2];
174 assert(b.len == 1);
175 assert(b[0] == '2');
176 }
177}
test/cases/generics.zig+1-1
...@@ -13,7 +13,7 @@ fn max(comptime T: type, a: T, b: T) -> T {...@@ -13,7 +13,7 @@ fn max(comptime T: type, a: T, b: T) -> T {
13}13}
1414
15fn add(comptime a: i32, b: i32) -> i32 {15fn add(comptime a: i32, b: i32) -> i32 {
16 return comptime {a} + b;16 return (comptime {a}) + b;
17}17}
1818
19const the_max = max(u32, 1234, 5678);19const the_max = max(u32, 1234, 5678);
test/cases/var_args.zig+1
...@@ -13,4 +13,5 @@ fn testAddArbitraryArgs() {...@@ -13,4 +13,5 @@ fn testAddArbitraryArgs() {
1313
14 assert(add(i32(1), i32(2), i32(3), i32(4)) == 10);14 assert(add(i32(1), i32(2), i32(3), i32(4)) == 10);
15 assert(add(i32(1234)) == 1234);15 assert(add(i32(1234)) == 1234);
16 assert(add() == 0);
16}17}