| author | |
| committer | |
| log | 2029601cb2ad4a6e9c8b260eec68de881d46735b |
| tree | 1c8573a9b47a9432a8e3f8d7574355243309b064 |
| parent | a6bf8c2593ae6e60d4c4804d4e9fd87fe29885ed |
28 files changed, 212 insertions(+), 209 deletions(-)
src/AstGen.zig+13-12| ... | @@ -5154,16 +5154,14 @@ fn arrayAccess( | ... | @@ -5154,16 +5154,14 @@ fn arrayAccess( |
| 5154 | const tree = astgen.tree; | 5154 | const tree = astgen.tree; |
| 5155 | const node_datas = tree.nodes.items(.data); | 5155 | const node_datas = tree.nodes.items(.data); |
| 5156 | switch (rl) { | 5156 | switch (rl) { |
| 5157 | .ref => return gz.addBin( | 5157 | .ref => return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ |
| 5158 | .elem_ptr, | 5158 | .lhs = try expr(gz, scope, .ref, node_datas[node].lhs), |
| 5159 | try expr(gz, scope, .ref, node_datas[node].lhs), | 5159 | .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), |
| 5160 | try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), | 5160 | }), |
| 5161 | ), | 5161 | else => return rvalue(gz, rl, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ |
| 5162 | else => return rvalue(gz, rl, try gz.addBin( | 5162 | .lhs = try expr(gz, scope, .none, node_datas[node].lhs), |
| 5163 | .elem_val, | 5163 | .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), |
| 5164 | try expr(gz, scope, .none, node_datas[node].lhs), | 5164 | }), node), |
| 5165 | try expr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs), | ||
| 5166 | ), node), | ||
| 5167 | } | 5165 | } |
| 5168 | } | 5166 | } |
| 5169 | 5167 | ||
| ... | @@ -5685,7 +5683,7 @@ fn whileExpr( | ... | @@ -5685,7 +5683,7 @@ fn whileExpr( |
| 5685 | try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst); | 5683 | try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst); |
| 5686 | } | 5684 | } |
| 5687 | if (while_full.ast.cont_expr != 0) { | 5685 | if (while_full.ast.cont_expr != 0) { |
| 5688 | _ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr); | 5686 | _ = try unusedResultExpr(&loop_scope, then_sub_scope, while_full.ast.cont_expr); |
| 5689 | } | 5687 | } |
| 5690 | try then_scope.addDbgBlockEnd(); | 5688 | try then_scope.addDbgBlockEnd(); |
| 5691 | const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat; | 5689 | const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat; |
| ... | @@ -5890,7 +5888,10 @@ fn forExpr( | ... | @@ -5890,7 +5888,10 @@ fn forExpr( |
| 5890 | if (!mem.eql(u8, value_name, "_")) { | 5888 | if (!mem.eql(u8, value_name, "_")) { |
| 5891 | const name_str_index = try astgen.identAsString(ident); | 5889 | const name_str_index = try astgen.identAsString(ident); |
| 5892 | const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; | 5890 | const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val; |
| 5893 | const payload_inst = try then_scope.addBin(tag, array_ptr, index); | 5891 | const payload_inst = try then_scope.addPlNode(tag, for_full.ast.cond_expr, Zir.Inst.Bin{ |
| 5892 | .lhs = array_ptr, | ||
| 5893 | .rhs = index, | ||
| 5894 | }); | ||
| 5894 | try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name); | 5895 | try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name); |
| 5895 | payload_val_scope = .{ | 5896 | payload_val_scope = .{ |
| 5896 | .parent = &then_scope.base, | 5897 | .parent = &then_scope.base, |
src/Sema.zig+21-18| ... | @@ -2738,6 +2738,7 @@ fn ensureResultUsed( | ... | @@ -2738,6 +2738,7 @@ fn ensureResultUsed( |
| 2738 | const operand_ty = sema.typeOf(operand); | 2738 | const operand_ty = sema.typeOf(operand); |
| 2739 | switch (operand_ty.zigTypeTag()) { | 2739 | switch (operand_ty.zigTypeTag()) { |
| 2740 | .Void, .NoReturn => return, | 2740 | .Void, .NoReturn => return, |
| 2741 | .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is ignored. consider using `try`, `catch`, or `if`", .{}), | ||
| 2741 | else => return sema.fail(block, src, "expression value is ignored", .{}), | 2742 | else => return sema.fail(block, src, "expression value is ignored", .{}), |
| 2742 | } | 2743 | } |
| 2743 | } | 2744 | } |
| ... | @@ -2751,7 +2752,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -2751,7 +2752,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 2751 | const src = inst_data.src(); | 2752 | const src = inst_data.src(); |
| 2752 | const operand_ty = sema.typeOf(operand); | 2753 | const operand_ty = sema.typeOf(operand); |
| 2753 | switch (operand_ty.zigTypeTag()) { | 2754 | switch (operand_ty.zigTypeTag()) { |
| 2754 | .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discardederror is discarded. consider using `try`, `catch`, or `if`", .{}), | 2755 | .ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded. consider using `try`, `catch`, or `if`", .{}), |
| 2755 | else => return, | 2756 | else => return, |
| 2756 | } | 2757 | } |
| 2757 | } | 2758 | } |
| ... | @@ -7092,7 +7093,7 @@ fn funcCommon( | ... | @@ -7092,7 +7093,7 @@ fn funcCommon( |
| 7092 | const param_types = try sema.arena.alloc(Type, block.params.items.len); | 7093 | const param_types = try sema.arena.alloc(Type, block.params.items.len); |
| 7093 | const comptime_params = try sema.arena.alloc(bool, block.params.items.len); | 7094 | const comptime_params = try sema.arena.alloc(bool, block.params.items.len); |
| 7094 | for (block.params.items) |param, i| { | 7095 | for (block.params.items) |param, i| { |
| 7095 | const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better src | 7096 | const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location |
| 7096 | param_types[i] = param.ty; | 7097 | param_types[i] = param.ty; |
| 7097 | comptime_params[i] = param.is_comptime or | 7098 | comptime_params[i] = param.is_comptime or |
| 7098 | try sema.typeRequiresComptime(block, param_src, param.ty); | 7099 | try sema.typeRequiresComptime(block, param_src, param.ty); |
| ... | @@ -7798,12 +7799,12 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -7798,12 +7799,12 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 7798 | const tracy = trace(@src()); | 7799 | const tracy = trace(@src()); |
| 7799 | defer tracy.end(); | 7800 | defer tracy.end(); |
| 7800 | 7801 | ||
| 7801 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; | 7802 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 7802 | const src = sema.src; // TODO better source location | 7803 | const src = inst_data.src(); |
| 7803 | const elem_index_src = sema.src; // TODO better source location | 7804 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 7804 | const array = try sema.resolveInst(bin_inst.lhs); | 7805 | const array = try sema.resolveInst(extra.lhs); |
| 7805 | const elem_index = try sema.resolveInst(bin_inst.rhs); | 7806 | const elem_index = try sema.resolveInst(extra.rhs); |
| 7806 | return sema.elemVal(block, src, array, elem_index, elem_index_src); | 7807 | return sema.elemVal(block, src, array, elem_index, src); |
| 7807 | } | 7808 | } |
| 7808 | 7809 | ||
| 7809 | fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 7810 | fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -7823,10 +7824,12 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -7823,10 +7824,12 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 7823 | const tracy = trace(@src()); | 7824 | const tracy = trace(@src()); |
| 7824 | defer tracy.end(); | 7825 | defer tracy.end(); |
| 7825 | 7826 | ||
| 7826 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; | 7827 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 7827 | const array_ptr = try sema.resolveInst(bin_inst.lhs); | 7828 | const src = inst_data.src(); |
| 7828 | const elem_index = try sema.resolveInst(bin_inst.rhs); | 7829 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 7829 | return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src, false); | 7830 | const array_ptr = try sema.resolveInst(extra.lhs); |
| 7831 | const elem_index = try sema.resolveInst(extra.rhs); | ||
| 7832 | return sema.elemPtr(block, src, array_ptr, elem_index, src, false); | ||
| 7830 | } | 7833 | } |
| 7831 | 7834 | ||
| 7832 | fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 7835 | fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -19454,7 +19457,7 @@ fn tupleFieldPtr( | ... | @@ -19454,7 +19457,7 @@ fn tupleFieldPtr( |
| 19454 | const tuple_fields = tuple_ty.tupleFields(); | 19457 | const tuple_fields = tuple_ty.tupleFields(); |
| 19455 | 19458 | ||
| 19456 | if (tuple_fields.types.len == 0) { | 19459 | if (tuple_fields.types.len == 0) { |
| 19457 | return sema.fail(block, field_index_src, "indexing into empty tuple", .{}); | 19460 | return sema.fail(block, tuple_ptr_src, "indexing into empty tuple is not allowed", .{}); |
| 19458 | } | 19461 | } |
| 19459 | 19462 | ||
| 19460 | if (field_index >= tuple_fields.types.len) { | 19463 | if (field_index >= tuple_fields.types.len) { |
| ... | @@ -19497,7 +19500,7 @@ fn tupleField( | ... | @@ -19497,7 +19500,7 @@ fn tupleField( |
| 19497 | const tuple_fields = tuple_ty.tupleFields(); | 19500 | const tuple_fields = tuple_ty.tupleFields(); |
| 19498 | 19501 | ||
| 19499 | if (tuple_fields.types.len == 0) { | 19502 | if (tuple_fields.types.len == 0) { |
| 19500 | return sema.fail(block, field_index_src, "indexing into empty tuple", .{}); | 19503 | return sema.fail(block, tuple_src, "indexing into empty tuple is not allowed", .{}); |
| 19501 | } | 19504 | } |
| 19502 | 19505 | ||
| 19503 | if (field_index >= tuple_fields.types.len) { | 19506 | if (field_index >= tuple_fields.types.len) { |
| ... | @@ -19538,7 +19541,7 @@ fn elemValArray( | ... | @@ -19538,7 +19541,7 @@ fn elemValArray( |
| 19538 | const elem_ty = array_ty.childType(); | 19541 | const elem_ty = array_ty.childType(); |
| 19539 | 19542 | ||
| 19540 | if (array_len_s == 0) { | 19543 | if (array_len_s == 0) { |
| 19541 | return sema.fail(block, elem_index_src, "indexing into empty array", .{}); | 19544 | return sema.fail(block, array_src, "indexing into empty array is not allowed", .{}); |
| 19542 | } | 19545 | } |
| 19543 | 19546 | ||
| 19544 | const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array); | 19547 | const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array); |
| ... | @@ -19618,7 +19621,7 @@ fn elemPtrArray( | ... | @@ -19618,7 +19621,7 @@ fn elemPtrArray( |
| 19618 | const array_len_s = array_len + @boolToInt(array_sent); | 19621 | const array_len_s = array_len + @boolToInt(array_sent); |
| 19619 | 19622 | ||
| 19620 | if (array_len_s == 0) { | 19623 | if (array_len_s == 0) { |
| 19621 | return sema.fail(block, elem_index_src, "indexing into empty array", .{}); | 19624 | return sema.fail(block, array_ptr_src, "indexing into empty array is not allowed", .{}); |
| 19622 | } | 19625 | } |
| 19623 | 19626 | ||
| 19624 | const maybe_undef_array_ptr_val = try sema.resolveMaybeUndefVal(block, array_ptr_src, array_ptr); | 19627 | const maybe_undef_array_ptr_val = try sema.resolveMaybeUndefVal(block, array_ptr_src, array_ptr); |
| ... | @@ -19700,7 +19703,7 @@ fn elemValSlice( | ... | @@ -19700,7 +19703,7 @@ fn elemValSlice( |
| 19700 | const slice_len = slice_val.sliceLen(sema.mod); | 19703 | const slice_len = slice_val.sliceLen(sema.mod); |
| 19701 | const slice_len_s = slice_len + @boolToInt(slice_sent); | 19704 | const slice_len_s = slice_len + @boolToInt(slice_sent); |
| 19702 | if (slice_len_s == 0) { | 19705 | if (slice_len_s == 0) { |
| 19703 | return sema.fail(block, elem_index_src, "indexing into empty slice", .{}); | 19706 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); |
| 19704 | } | 19707 | } |
| 19705 | if (maybe_index_val) |index_val| { | 19708 | if (maybe_index_val) |index_val| { |
| 19706 | const index = @intCast(usize, index_val.toUnsignedInt(target)); | 19709 | const index = @intCast(usize, index_val.toUnsignedInt(target)); |
| ... | @@ -19757,7 +19760,7 @@ fn elemPtrSlice( | ... | @@ -19757,7 +19760,7 @@ fn elemPtrSlice( |
| 19757 | const slice_len = slice_val.sliceLen(sema.mod); | 19760 | const slice_len = slice_val.sliceLen(sema.mod); |
| 19758 | const slice_len_s = slice_len + @boolToInt(slice_sent); | 19761 | const slice_len_s = slice_len + @boolToInt(slice_sent); |
| 19759 | if (slice_len_s == 0) { | 19762 | if (slice_len_s == 0) { |
| 19760 | return sema.fail(block, elem_index_src, "indexing into empty slice", .{}); | 19763 | return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{}); |
| 19761 | } | 19764 | } |
| 19762 | if (offset) |index| { | 19765 | if (offset) |index| { |
| 19763 | if (index >= slice_len_s) { | 19766 | if (index >= slice_len_s) { |
src/Zir.zig+9-10| ... | @@ -370,24 +370,23 @@ pub const Inst = struct { | ... | @@ -370,24 +370,23 @@ pub const Inst = struct { |
| 370 | /// Uses the `pl_node` union field. Payload is `Bin`. | 370 | /// Uses the `pl_node` union field. Payload is `Bin`. |
| 371 | div, | 371 | div, |
| 372 | /// Given a pointer to an array, slice, or pointer, returns a pointer to the element at | 372 | /// Given a pointer to an array, slice, or pointer, returns a pointer to the element at |
| 373 | /// the provided index. Uses the `bin` union field. Source location is implied | 373 | /// the provided index. |
| 374 | /// to be the same as the previous instruction. | ||
| 375 | elem_ptr, | ||
| 376 | /// Same as `elem_ptr` except also stores a source location node. | ||
| 377 | /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. | 374 | /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. |
| 378 | elem_ptr_node, | 375 | elem_ptr_node, |
| 376 | /// Same as `elem_ptr_node` but used only for for loop. | ||
| 377 | /// Uses the `pl_node` union field. AST node is the condition of a for loop. Payload is `Bin`. | ||
| 378 | elem_ptr, | ||
| 379 | /// Same as `elem_ptr_node` except the index is stored immediately rather than | 379 | /// Same as `elem_ptr_node` except the index is stored immediately rather than |
| 380 | /// as a reference to another ZIR instruction. | 380 | /// as a reference to another ZIR instruction. |
| 381 | /// Uses the `pl_node` union field. AST node is an element inside array initialization | 381 | /// Uses the `pl_node` union field. AST node is an element inside array initialization |
| 382 | /// syntax. Payload is `ElemPtrImm`. | 382 | /// syntax. Payload is `ElemPtrImm`. |
| 383 | elem_ptr_imm, | 383 | elem_ptr_imm, |
| 384 | /// Given an array, slice, or pointer, returns the element at the provided index. | 384 | /// Given an array, slice, or pointer, returns the element at the provided index. |
| 385 | /// Uses the `bin` union field. Source location is implied to be the same | ||
| 386 | /// as the previous instruction. | ||
| 387 | elem_val, | ||
| 388 | /// Same as `elem_val` except also stores a source location node. | ||
| 389 | /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. | 385 | /// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`. |
| 390 | elem_val_node, | 386 | elem_val_node, |
| 387 | /// Same as `elem_val_node` but used only for for loop. | ||
| 388 | /// Uses the `pl_node` union field. AST node is the condition of a for loop. Payload is `Bin`. | ||
| 389 | elem_val, | ||
| 391 | /// Emits a compile error if the operand is not `void`. | 390 | /// Emits a compile error if the operand is not `void`. |
| 392 | /// Uses the `un_node` field. | 391 | /// Uses the `un_node` field. |
| 393 | ensure_result_used, | 392 | ensure_result_used, |
| ... | @@ -1627,10 +1626,10 @@ pub const Inst = struct { | ... | @@ -1627,10 +1626,10 @@ pub const Inst = struct { |
| 1627 | .decl_val = .str_tok, | 1626 | .decl_val = .str_tok, |
| 1628 | .load = .un_node, | 1627 | .load = .un_node, |
| 1629 | .div = .pl_node, | 1628 | .div = .pl_node, |
| 1630 | .elem_ptr = .bin, | 1629 | .elem_ptr = .pl_node, |
| 1631 | .elem_ptr_node = .pl_node, | 1630 | .elem_ptr_node = .pl_node, |
| 1632 | .elem_ptr_imm = .pl_node, | 1631 | .elem_ptr_imm = .pl_node, |
| 1633 | .elem_val = .bin, | 1632 | .elem_val = .pl_node, |
| 1634 | .elem_val_node = .pl_node, | 1633 | .elem_val_node = .pl_node, |
| 1635 | .ensure_result_used = .un_node, | 1634 | .ensure_result_used = .un_node, |
| 1636 | .ensure_result_non_error = .un_node, | 1635 | .ensure_result_non_error = .un_node, |
src/print_zir.zig+2-2| ... | @@ -144,8 +144,6 @@ const Writer = struct { | ... | @@ -144,8 +144,6 @@ const Writer = struct { |
| 144 | switch (tag) { | 144 | switch (tag) { |
| 145 | .array_type, | 145 | .array_type, |
| 146 | .as, | 146 | .as, |
| 147 | .elem_ptr, | ||
| 148 | .elem_val, | ||
| 149 | .store, | 147 | .store, |
| 150 | .store_to_block_ptr, | 148 | .store_to_block_ptr, |
| 151 | .store_to_inferred_ptr, | 149 | .store_to_inferred_ptr, |
| ... | @@ -355,6 +353,8 @@ const Writer = struct { | ... | @@ -355,6 +353,8 @@ const Writer = struct { |
| 355 | .minimum, | 353 | .minimum, |
| 356 | .elem_ptr_node, | 354 | .elem_ptr_node, |
| 357 | .elem_val_node, | 355 | .elem_val_node, |
| 356 | .elem_ptr, | ||
| 357 | .elem_val, | ||
| 358 | .coerce_result_ptr, | 358 | .coerce_result_ptr, |
| 359 | => try self.writePlNodeBin(stream, inst), | 359 | => try self.writePlNodeBin(stream, inst), |
| 360 | 360 |
src/type.zig+1-1| ... | @@ -189,7 +189,7 @@ pub const Type = extern union { | ... | @@ -189,7 +189,7 @@ pub const Type = extern union { |
| 189 | .Frame, | 189 | .Frame, |
| 190 | => false, | 190 | => false, |
| 191 | 191 | ||
| 192 | .Pointer => is_equality_cmp or ty.isCPtr(), | 192 | .Pointer => !ty.isSlice() and (is_equality_cmp or ty.isCPtr()), |
| 193 | .Optional => { | 193 | .Optional => { |
| 194 | if (!is_equality_cmp) return false; | 194 | if (!is_equality_cmp) return false; |
| 195 | var buf: Payload.ElemType = undefined; | 195 | var buf: Payload.ElemType = undefined; |
test/cases/compile_errors/ignored_deferred_function_call.zig created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | export fn foo() void { | ||
| 2 | defer bar(); | ||
| 3 | } | ||
| 4 | fn bar() anyerror!i32 { return 0; } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage2 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // :2:14: error: error is ignored. consider using `try`, `catch`, or `if` | ||
test/cases/compile_errors/ignored_expression_in_while_continuation.zig created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | export fn a() void { | ||
| 2 | while (true) : (bad()) {} | ||
| 3 | } | ||
| 4 | export fn b() void { | ||
| 5 | var x: anyerror!i32 = 1234; | ||
| 6 | while (x) |_| : (bad()) {} else |_| {} | ||
| 7 | } | ||
| 8 | export fn c() void { | ||
| 9 | var x: ?i32 = 1234; | ||
| 10 | while (x) |_| : (bad()) {} | ||
| 11 | } | ||
| 12 | fn bad() anyerror!void { | ||
| 13 | return error.Bad; | ||
| 14 | } | ||
| 15 | |||
| 16 | // error | ||
| 17 | // backend=stage2 | ||
| 18 | // target=native | ||
| 19 | // | ||
| 20 | // :2:24: error: error is ignored. consider using `try`, `catch`, or `if` | ||
| 21 | // :6:25: error: error is ignored. consider using `try`, `catch`, or `if` | ||
| 22 | // :10:25: error: error is ignored. consider using `try`, `catch`, or `if` | ||
test/cases/compile_errors/illegal_comparison_of_types.zig created+20| ... | @@ -0,0 +1,20 @@ | ||
| 1 | fn bad_eql_1(a: []u8, b: []u8) bool { | ||
| 2 | return a == b; | ||
| 3 | } | ||
| 4 | const EnumWithData = union(enum) { | ||
| 5 | One: void, | ||
| 6 | Two: i32, | ||
| 7 | }; | ||
| 8 | fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool { | ||
| 9 | return a.* == b.*; | ||
| 10 | } | ||
| 11 | |||
| 12 | export fn entry1() usize { return @sizeOf(@TypeOf(&bad_eql_1)); } | ||
| 13 | export fn entry2() usize { return @sizeOf(@TypeOf(&bad_eql_2)); } | ||
| 14 | |||
| 15 | // error | ||
| 16 | // backend=stage2 | ||
| 17 | // target=native | ||
| 18 | // | ||
| 19 | // :2:14: error: operator == not allowed for type '[]u8' | ||
| 20 | // :9:16: error: operator == not allowed for type 'tmp.EnumWithData' | ||
test/cases/compile_errors/implicitly_casting_enum_to_tag_type.zig created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | const Small = enum(u2) { | ||
| 2 | One, | ||
| 3 | Two, | ||
| 4 | Three, | ||
| 5 | Four, | ||
| 6 | }; | ||
| 7 | |||
| 8 | export fn entry() void { | ||
| 9 | var x: u2 = Small.Two; | ||
| 10 | _ = x; | ||
| 11 | } | ||
| 12 | |||
| 13 | // error | ||
| 14 | // backend=stage2 | ||
| 15 | // target=native | ||
| 16 | // | ||
| 17 | // :9:22: error: expected type 'u2', found 'tmp.Small' | ||
test/cases/compile_errors/incorrect_return_type.zig created+21| ... | @@ -0,0 +1,21 @@ | ||
| 1 | pub export fn entry() void{ | ||
| 2 | _ = foo(); | ||
| 3 | } | ||
| 4 | const A = struct { | ||
| 5 | a: u32, | ||
| 6 | }; | ||
| 7 | fn foo() A { | ||
| 8 | return bar(); | ||
| 9 | } | ||
| 10 | const B = struct { | ||
| 11 | a: u32, | ||
| 12 | }; | ||
| 13 | fn bar() B { | ||
| 14 | unreachable; | ||
| 15 | } | ||
| 16 | |||
| 17 | // error | ||
| 18 | // backend=stage2 | ||
| 19 | // target=native | ||
| 20 | // | ||
| 21 | // :8:16: error: expected type 'tmp.A', found 'tmp.B' | ||
test/cases/compile_errors/indexing_an_array_of_size_zero.zig created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | const array = [_]u8{}; | ||
| 2 | export fn foo() void { | ||
| 3 | const pointer = &array[0]; | ||
| 4 | _ = pointer; | ||
| 5 | } | ||
| 6 | |||
| 7 | // error | ||
| 8 | // backend=stage2 | ||
| 9 | // target=native | ||
| 10 | // | ||
| 11 | // :3:27: error: indexing into empty array is not allowed | ||
test/cases/compile_errors/indexing_an_array_of_size_zero_with_runtime_index.zig created+12| ... | @@ -0,0 +1,12 @@ | ||
| 1 | const array = [_]u8{}; | ||
| 2 | export fn foo() void { | ||
| 3 | var index: usize = 0; | ||
| 4 | const pointer = &array[index]; | ||
| 5 | _ = pointer; | ||
| 6 | } | ||
| 7 | |||
| 8 | // error | ||
| 9 | // backend=stage2 | ||
| 10 | // target=native | ||
| 11 | // | ||
| 12 | // :4:27: error: indexing into empty array is not allowed | ||
test/cases/compile_errors/indexing_single-item_pointer.zig created+9| ... | @@ -0,0 +1,9 @@ | ||
| 1 | export fn entry(ptr: *i32) i32 { | ||
| 2 | return ptr[1]; | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // backend=stage2 | ||
| 7 | // target=native | ||
| 8 | // | ||
| 9 | // :2:15: error: element access of non-indexable type '*i32' | ||
test/cases/compile_errors/invalid_cast_from_integral_type_to_enum.zig created+17| ... | @@ -0,0 +1,17 @@ | ||
| 1 | const E = enum(usize) { One, Two }; | ||
| 2 | |||
| 3 | export fn entry() void { | ||
| 4 | foo(1); | ||
| 5 | } | ||
| 6 | |||
| 7 | fn foo(x: usize) void { | ||
| 8 | switch (x) { | ||
| 9 | E.One => {}, | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | // error | ||
| 14 | // backend=stage2 | ||
| 15 | // target=native | ||
| 16 | // | ||
| 17 | // :9:10: error: expected type 'usize', found 'tmp.E' | ||
test/cases/compile_errors/runtime_indexing_comptime_array.zig+6-6| ... | @@ -24,9 +24,9 @@ pub export fn entry3() void { | ... | @@ -24,9 +24,9 @@ pub export fn entry3() void { |
| 24 | // target=native | 24 | // target=native |
| 25 | // backend=stage2 | 25 | // backend=stage2 |
| 26 | // | 26 | // |
| 27 | // :6:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known | 27 | // :7:10: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known |
| 28 | // :6:5: note: use '*const fn() void' for a function pointer type | 28 | // :7:10: note: use '*const fn() void' for a function pointer type |
| 29 | // :13:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known | 29 | // :15:18: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known |
| 30 | // :13:5: note: use '*const fn() void' for a function pointer type | 30 | // :15:17: note: use '*const fn() void' for a function pointer type |
| 31 | // :19:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known | 31 | // :21:19: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known |
| 32 | // :19:5: note: use '*const fn() void' for a function pointer type | 32 | // :21:18: note: use '*const fn() void' for a function pointer type |
test/cases/compile_errors/stage1/implicit_cast_from_f64_to_f32.zig created+10| ... | @@ -0,0 +1,10 @@ | ||
| 1 | var x: f64 = 1.0; | ||
| 2 | var y: f32 = x; | ||
| 3 | |||
| 4 | export fn entry() usize { return @sizeOf(@TypeOf(y)); } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage1 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // tmp.zig:2:14: error: expected type 'f32', found 'f64' | ||
test/cases/compile_errors/stage1/int_to_ptr_of_0_bits.zig created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | export fn foo() void { | ||
| 2 | var x: usize = 0x1000; | ||
| 3 | var y: *void = @intToPtr(*void, x); | ||
| 4 | _ = y; | ||
| 5 | } | ||
| 6 | |||
| 7 | // error | ||
| 8 | // backend=stage1 | ||
| 9 | // target=native | ||
| 10 | // | ||
| 11 | // tmp.zig:3:30: error: type '*void' has 0 bits and cannot store information | ||
test/cases/compile_errors/stage1/obj/ignored_deferred_function_call.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | export fn foo() void { | ||
| 2 | defer bar(); | ||
| 3 | } | ||
| 4 | fn bar() anyerror!i32 { return 0; } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage1 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // tmp.zig:2:14: error: error is ignored. consider using `try`, `catch`, or `if` | ||
test/cases/compile_errors/stage1/obj/ignored_expression_in_while_continuation.zig deleted-22| ... | @@ -1,22 +0,0 @@ | ||
| 1 | export fn a() void { | ||
| 2 | while (true) : (bad()) {} | ||
| 3 | } | ||
| 4 | export fn b() void { | ||
| 5 | var x: anyerror!i32 = 1234; | ||
| 6 | while (x) |_| : (bad()) {} else |_| {} | ||
| 7 | } | ||
| 8 | export fn c() void { | ||
| 9 | var x: ?i32 = 1234; | ||
| 10 | while (x) |_| : (bad()) {} | ||
| 11 | } | ||
| 12 | fn bad() anyerror!void { | ||
| 13 | return error.Bad; | ||
| 14 | } | ||
| 15 | |||
| 16 | // error | ||
| 17 | // backend=stage1 | ||
| 18 | // target=native | ||
| 19 | // | ||
| 20 | // tmp.zig:2:24: error: error is ignored. consider using `try`, `catch`, or `if` | ||
| 21 | // tmp.zig:6:25: error: error is ignored. consider using `try`, `catch`, or `if` | ||
| 22 | // tmp.zig:10:25: error: error is ignored. consider using `try`, `catch`, or `if` | ||
test/cases/compile_errors/stage1/obj/illegal_comparison_of_types.zig deleted-20| ... | @@ -1,20 +0,0 @@ | ||
| 1 | fn bad_eql_1(a: []u8, b: []u8) bool { | ||
| 2 | return a == b; | ||
| 3 | } | ||
| 4 | const EnumWithData = union(enum) { | ||
| 5 | One: void, | ||
| 6 | Two: i32, | ||
| 7 | }; | ||
| 8 | fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool { | ||
| 9 | return a.* == b.*; | ||
| 10 | } | ||
| 11 | |||
| 12 | export fn entry1() usize { return @sizeOf(@TypeOf(bad_eql_1)); } | ||
| 13 | export fn entry2() usize { return @sizeOf(@TypeOf(bad_eql_2)); } | ||
| 14 | |||
| 15 | // error | ||
| 16 | // backend=stage1 | ||
| 17 | // target=native | ||
| 18 | // | ||
| 19 | // tmp.zig:2:14: error: operator not allowed for type '[]u8' | ||
| 20 | // tmp.zig:9:16: error: operator not allowed for type 'EnumWithData' | ||
test/cases/compile_errors/stage1/obj/implicit_cast_from_f64_to_f32.zig deleted-10| ... | @@ -1,10 +0,0 @@ | ||
| 1 | var x: f64 = 1.0; | ||
| 2 | var y: f32 = x; | ||
| 3 | |||
| 4 | export fn entry() usize { return @sizeOf(@TypeOf(y)); } | ||
| 5 | |||
| 6 | // error | ||
| 7 | // backend=stage1 | ||
| 8 | // target=native | ||
| 9 | // | ||
| 10 | // tmp.zig:2:14: error: expected type 'f32', found 'f64' | ||
test/cases/compile_errors/stage1/obj/implicitly_casting_enum_to_tag_type.zig deleted-17| ... | @@ -1,17 +0,0 @@ | ||
| 1 | const Small = enum(u2) { | ||
| 2 | One, | ||
| 3 | Two, | ||
| 4 | Three, | ||
| 5 | Four, | ||
| 6 | }; | ||
| 7 | |||
| 8 | export fn entry() void { | ||
| 9 | var x: u2 = Small.Two; | ||
| 10 | _ = x; | ||
| 11 | } | ||
| 12 | |||
| 13 | // error | ||
| 14 | // backend=stage1 | ||
| 15 | // target=native | ||
| 16 | // | ||
| 17 | // tmp.zig:9:22: error: expected type 'u2', found 'Small' | ||
test/cases/compile_errors/stage1/obj/incorrect_return_type.zig deleted-21| ... | @@ -1,21 +0,0 @@ | ||
| 1 | pub export fn entry() void{ | ||
| 2 | _ = foo(); | ||
| 3 | } | ||
| 4 | const A = struct { | ||
| 5 | a: u32, | ||
| 6 | }; | ||
| 7 | fn foo() A { | ||
| 8 | return bar(); | ||
| 9 | } | ||
| 10 | const B = struct { | ||
| 11 | a: u32, | ||
| 12 | }; | ||
| 13 | fn bar() B { | ||
| 14 | unreachable; | ||
| 15 | } | ||
| 16 | |||
| 17 | // error | ||
| 18 | // backend=stage1 | ||
| 19 | // target=native | ||
| 20 | // | ||
| 21 | // tmp.zig:8:16: error: expected type 'A', found 'B' | ||
test/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | const array = [_]u8{}; | ||
| 2 | export fn foo() void { | ||
| 3 | const pointer = &array[0]; | ||
| 4 | _ = pointer; | ||
| 5 | } | ||
| 6 | |||
| 7 | // error | ||
| 8 | // backend=stage1 | ||
| 9 | // target=native | ||
| 10 | // | ||
| 11 | // tmp.zig:3:27: error: accessing a zero length array is not allowed | ||
test/cases/compile_errors/stage1/obj/indexing_an_array_of_size_zero_with_runtime_index.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const array = [_]u8{}; | ||
| 2 | export fn foo() void { | ||
| 3 | var index: usize = 0; | ||
| 4 | const pointer = &array[index]; | ||
| 5 | _ = pointer; | ||
| 6 | } | ||
| 7 | |||
| 8 | // error | ||
| 9 | // backend=stage1 | ||
| 10 | // target=native | ||
| 11 | // | ||
| 12 | // tmp.zig:4:27: error: accessing a zero length array is not allowed | ||
test/cases/compile_errors/stage1/obj/indexing_single-item_pointer.zig deleted-9| ... | @@ -1,9 +0,0 @@ | ||
| 1 | export fn entry(ptr: *i32) i32 { | ||
| 2 | return ptr[1]; | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // backend=stage1 | ||
| 7 | // target=native | ||
| 8 | // | ||
| 9 | // tmp.zig:2:15: error: index of single-item pointer | ||
test/cases/compile_errors/stage1/obj/int_to_ptr_of_0_bits.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | export fn foo() void { | ||
| 2 | var x: usize = 0x1000; | ||
| 3 | var y: *void = @intToPtr(*void, x); | ||
| 4 | _ = y; | ||
| 5 | } | ||
| 6 | |||
| 7 | // error | ||
| 8 | // backend=stage1 | ||
| 9 | // target=native | ||
| 10 | // | ||
| 11 | // tmp.zig:3:30: error: type '*void' has 0 bits and cannot store information | ||
test/cases/compile_errors/stage1/obj/invalid_cast_from_integral_type_to_enum.zig deleted-17| ... | @@ -1,17 +0,0 @@ | ||
| 1 | const E = enum(usize) { One, Two }; | ||
| 2 | |||
| 3 | export fn entry() void { | ||
| 4 | foo(1); | ||
| 5 | } | ||
| 6 | |||
| 7 | fn foo(x: usize) void { | ||
| 8 | switch (x) { | ||
| 9 | E.One => {}, | ||
| 10 | } | ||
| 11 | } | ||
| 12 | |||
| 13 | // error | ||
| 14 | // backend=stage1 | ||
| 15 | // target=native | ||
| 16 | // | ||
| 17 | // tmp.zig:9:10: error: expected type 'usize', found 'E' | ||