diff --git a/src/AstGen.zig b/src/AstGen.zig index a0ff7a0e6ebc..5d6c53768f9c 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -812,7 +812,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr .deref => { const lhs = try expr(gz, scope, .none, node_datas[node].lhs); - _ = try gz.addUnTok(.validate_deref, lhs, main_tokens[node]); + _ = try gz.addUnNode(.validate_deref, lhs, node); switch (rl) { .ref => return lhs, else => { @@ -1320,7 +1320,10 @@ fn arrayInitExpr( const len_inst = try gz.addInt(array_init.ast.elements.len); const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); if (array_type.ast.sentinel == 0) { - const array_type_inst = try gz.addBin(.array_type, len_inst, elem_type); + const array_type_inst = try gz.addPlNode(.array_type, array_init.ast.type_expr, Zir.Inst.Bin{ + .lhs = len_inst, + .rhs = elem_type, + }); break :inst .{ .array = array_type_inst, .elem = elem_type, @@ -1553,7 +1556,10 @@ fn structInitExpr( if (is_inferred_array_len) { const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type); const array_type_inst = if (array_type.ast.sentinel == 0) blk: { - break :blk try gz.addBin(.array_type, .zero_usize, elem_type); + break :blk try gz.addPlNode(.array_type, struct_init.ast.type_expr, Zir.Inst.Bin{ + .lhs = .zero_usize, + .rhs = elem_type, + }); } else blk: { const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); break :blk try gz.addPlNode( @@ -2332,8 +2338,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .error_union_type, .bit_not, .error_value, - .error_to_int, - .int_to_error, .slice_start, .slice_end, .slice_sentinel, @@ -2420,7 +2424,6 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .splat, .reduce, .shuffle, - .select, .atomic_load, .atomic_rmw, .mul_add, @@ -2467,6 +2470,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner .repeat, .repeat_inline, .panic, + .panic_comptime, => { noreturn_src_node = statement; break :b true; @@ -3100,6 +3104,10 @@ fn ptrType( node: Ast.Node.Index, ptr_info: Ast.full.PtrType, ) InnerError!Zir.Inst.Ref { + if (ptr_info.size == .C and ptr_info.allowzero_token != null) { + return gz.astgen.failTok(ptr_info.allowzero_token.?, "C pointers always allow address zero", .{}); + } + const elem_type = try typeExpr(gz, scope, ptr_info.ast.child_type); const simple = ptr_info.ast.align_node == 0 and @@ -3205,7 +3213,10 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Z const len = try expr(gz, scope, .{ .coerced_ty = .usize_type }, len_node); const elem_type = try typeExpr(gz, scope, node_datas[node].rhs); - const result = try gz.addBin(.array_type, len, elem_type); + const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ + .lhs = len, + .rhs = elem_type, + }); return rvalue(gz, rl, result, node); } @@ -7355,15 +7366,13 @@ fn builtinCall( .align_of => return simpleUnOpType(gz, scope, rl, node, params[0], .align_of), .ptr_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .ptr_to_int), - .error_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .error_to_int), - .int_to_error => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .u16_type }, params[0], .int_to_error), .compile_error => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .compile_error), .set_eval_branch_quota => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .u32_type }, params[0], .set_eval_branch_quota), .enum_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .enum_to_int), .bool_to_int => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .bool_to_int), .embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file), .error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name), - .panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .panic), + .panic => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], if (gz.force_comptime) .panic_comptime else .panic), .set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold), .set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety), .sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt), @@ -7396,6 +7405,22 @@ fn builtinCall( .truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate), // zig fmt: on + .error_to_int => { + const operand = try expr(gz, scope, .none, params[0]); + const result = try gz.addExtendedPayload(.error_to_int, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = operand, + }); + return rvalue(gz, rl, result, node); + }, + .int_to_error => { + const operand = try expr(gz, scope, .{ .coerced_ty = .u16_type }, params[0]); + const result = try gz.addExtendedPayload(.int_to_error, Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = operand, + }); + return rvalue(gz, rl, result, node); + }, .align_cast => { const dest_align = try comptimeExpr(gz, scope, align_rl, params[0]); const rhs = try expr(gz, scope, .none, params[1]); @@ -7635,7 +7660,8 @@ fn builtinCall( return rvalue(gz, rl, result, node); }, .select => { - const result = try gz.addPlNode(.select, node, Zir.Inst.Select{ + const result = try gz.addExtendedPayload(.select, Zir.Inst.Select{ + .node = gz.nodeIndexToRelative(node), .elem_type = try typeExpr(gz, scope, params[0]), .pred = try expr(gz, scope, .none, params[1]), .a = try expr(gz, scope, .none, params[2]), diff --git a/src/Module.zig b/src/Module.zig index 1f70a44df5e2..3c4962c58748 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -2171,7 +2171,11 @@ pub const SrcLoc = struct { const token_starts = tree.tokens.items(.start); return token_starts[tok_index]; }, - .node_offset_slice_sentinel => |node_off| { + .node_offset_slice_ptr, + .node_offset_slice_start, + .node_offset_slice_end, + .node_offset_slice_sentinel, + => |node_off| { const tree = try src_loc.file_scope.getTree(gpa); const node_tags = tree.nodes.items(.tag); const node = src_loc.declRelativeToNodeIndex(node_off); @@ -2182,7 +2186,15 @@ pub const SrcLoc = struct { else => unreachable, }; const main_tokens = tree.nodes.items(.main_token); - const tok_index = main_tokens[full.ast.sentinel]; + const tok_index = main_tokens[ + switch (src_loc.lazy) { + .node_offset_slice_ptr => full.ast.sliced, + .node_offset_slice_start => full.ast.start, + .node_offset_slice_end => full.ast.end, + .node_offset_slice_sentinel => full.ast.sentinel, + else => unreachable, + } + ]; const token_starts = tree.tokens.items(.start); return token_starts[tok_index]; }, @@ -2501,6 +2513,16 @@ pub const SrcLoc = struct { const token_starts = tree.tokens.items(.start); return token_starts[tok_index]; }, + .node_offset_un_op => |node_off| { + const tree = try src_loc.file_scope.getTree(gpa); + const node_datas = tree.nodes.items(.data); + const node = src_loc.declRelativeToNodeIndex(node_off); + + const main_tokens = tree.nodes.items(.main_token); + const tok_index = main_tokens[node_datas[node].lhs]; + const token_starts = tree.tokens.items(.start); + return token_starts[tok_index]; + }, } } @@ -2614,6 +2636,24 @@ pub const LazySrcLoc = union(enum) { /// to the index expression. /// The Decl is determined contextually. node_offset_array_access_index: i32, + /// The source location points to the LHS of a slice expression + /// expression, found by taking this AST node index offset from the containing + /// Decl AST node, which points to a slice AST node. Next, navigate + /// to the sentinel expression. + /// The Decl is determined contextually. + node_offset_slice_ptr: i32, + /// The source location points to start expression of a slice expression + /// expression, found by taking this AST node index offset from the containing + /// Decl AST node, which points to a slice AST node. Next, navigate + /// to the sentinel expression. + /// The Decl is determined contextually. + node_offset_slice_start: i32, + /// The source location points to the end expression of a slice + /// expression, found by taking this AST node index offset from the containing + /// Decl AST node, which points to a slice AST node. Next, navigate + /// to the sentinel expression. + /// The Decl is determined contextually. + node_offset_slice_end: i32, /// The source location points to the sentinel expression of a slice /// expression, found by taking this AST node index offset from the containing /// Decl AST node, which points to a slice AST node. Next, navigate @@ -2728,6 +2768,9 @@ pub const LazySrcLoc = union(enum) { /// to the elem expression. /// The Decl is determined contextually. node_offset_array_type_elem: i32, + /// The source location points to the operand of an unary expression. + /// The Decl is determined contextually. + node_offset_un_op: i32, pub const nodeOffset = if (TracedOffset.want_tracing) nodeOffsetDebug else nodeOffsetRelease; @@ -2768,6 +2811,9 @@ pub const LazySrcLoc = union(enum) { .node_offset_builtin_call_arg4, .node_offset_builtin_call_arg5, .node_offset_array_access_index, + .node_offset_slice_ptr, + .node_offset_slice_start, + .node_offset_slice_end, .node_offset_slice_sentinel, .node_offset_call_func, .node_offset_field_name, @@ -2788,6 +2834,7 @@ pub const LazySrcLoc = union(enum) { .node_offset_array_type_len, .node_offset_array_type_sentinel, .node_offset_array_type_elem, + .node_offset_un_op, => .{ .file_scope = decl.getFileScope(), .parent_decl_node = decl.src_node, diff --git a/src/Sema.zig b/src/Sema.zig index a412e288ba9c..054f64523036 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -739,8 +739,6 @@ fn analyzeBodyInner( .err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, false), .error_union_type => try sema.zirErrorUnionType(block, inst), .error_value => try sema.zirErrorValue(block, inst), - .error_to_int => try sema.zirErrorToInt(block, inst), - .int_to_error => try sema.zirIntToError(block, inst), .field_ptr => try sema.zirFieldPtr(block, inst), .field_ptr_named => try sema.zirFieldPtrNamed(block, inst), .field_val => try sema.zirFieldVal(block, inst), @@ -835,7 +833,6 @@ fn analyzeBodyInner( .splat => try sema.zirSplat(block, inst), .reduce => try sema.zirReduce(block, inst), .shuffle => try sema.zirShuffle(block, inst), - .select => try sema.zirSelect(block, inst), .atomic_load => try sema.zirAtomicLoad(block, inst), .atomic_rmw => try sema.zirAtomicRmw(block, inst), .mul_add => try sema.zirMulAdd(block, inst), @@ -906,7 +903,8 @@ fn analyzeBodyInner( .ret_load => break sema.zirRetLoad(block, inst), .ret_err_value => break sema.zirRetErrValue(block, inst), .@"unreachable" => break sema.zirUnreachable(block, inst), - .panic => break sema.zirPanic(block, inst), + .panic => break sema.zirPanic(block, inst, false), + .panic_comptime => break sema.zirPanic(block, inst, true), // zig fmt: on .extended => ext: { @@ -942,6 +940,9 @@ fn analyzeBodyInner( .field_call_bind_named => try sema.zirFieldCallBindNamed(block, extended), .err_set_cast => try sema.zirErrSetCast( block, extended), .await_nosuspend => try sema.zirAwaitNosuspend( block, extended), + .select => try sema.zirSelect( block, extended), + .error_to_int => try sema.zirErrorToInt( block, extended), + .int_to_error => try sema.zirIntToError( block, extended), // zig fmt: on .fence => { try sema.zirFence(block, extended); @@ -1685,7 +1686,9 @@ fn resolveMaybeUndefValAllowVariables( switch (air_tags[i]) { .constant => { const ty_pl = sema.air_instructions.items(.data)[i].ty_pl; - return sema.air_values.items[ty_pl.payload]; + const val = sema.air_values.items[ty_pl.payload]; + if (val.tag() == .runtime_int) return null; + return val; }, .const_ty => { return try sema.air_instructions.items(.data)[i].ty.toValue(sema.arena); @@ -1717,9 +1720,17 @@ fn failWithExpectedOptionalType(sema: *Sema, block: *Block, src: LazySrcLoc, opt } fn failWithArrayInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { - return sema.fail(block, src, "type '{}' does not support array initialization syntax", .{ - ty.fmt(sema.mod), - }); + const msg = msg: { + const msg = try sema.errMsg(block, src, "type '{}' does not support array initialization syntax", .{ + ty.fmt(sema.mod), + }); + errdefer msg.destroy(sema.gpa); + if (ty.isSlice()) { + try sema.errNote(block, src, msg, "inferred array length is specified with an underscore: '[_]{}'", .{ty.elemType2().fmt(sema.mod)}); + } + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); } fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError { @@ -2804,7 +2815,7 @@ fn zirAllocExtended( ) CompileError!Air.Inst.Ref { const extra = sema.code.extraData(Zir.Inst.AllocExtended, extended.operand); const src = LazySrcLoc.nodeOffset(extra.data.src_node); - const ty_src = src; // TODO better source location + const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = extra.data.src_node }; const align_src = src; // TODO better source location const small = @bitCast(Zir.Inst.AllocExtended.Small, extended.small); @@ -3856,9 +3867,9 @@ fn zirValidateArrayInit( } fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { - const inst_data = sema.code.instructions.items(.data)[inst].un_tok; + const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .token_offset = inst_data.src_tok + 1 }; + const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); @@ -3870,10 +3881,26 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}), } + const elem_ty = operand_ty.elemType2(); if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| { if (val.isUndef()) { return sema.fail(block, src, "cannot dereference undefined value", .{}); } + } else if (!(try sema.validateRunTimeType(block, src, elem_ty, false))) { + const msg = msg: { + const msg = try sema.errMsg( + block, + src, + "values of type '{}' must be comptime known, but operand value is runtime known", + .{elem_ty.fmt(sema.mod)}, + ); + errdefer msg.destroy(sema.gpa); + + const src_decl = sema.mod.declPtr(block.src_decl); + try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(src_decl), elem_ty); + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); } } @@ -4308,11 +4335,15 @@ fn zirCompileLog( return Air.Inst.Ref.void_value; } -fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { +fn zirPanic(sema: *Sema, block: *Block, inst: Zir.Inst.Index, force_comptime: bool) CompileError!Zir.Inst.Index { const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src: LazySrcLoc = inst_data.src(); + const src = inst_data.src(); const msg_inst = try sema.resolveInst(inst_data.operand); + if (block.is_comptime or force_comptime) { + return sema.fail(block, src, "encountered @panic at comptime", .{}); + } + try sema.requireRuntimeBlock(block, src); return sema.panicWithMsg(block, src, msg_inst); } @@ -4796,14 +4827,16 @@ fn zirSetAlignStack(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst alignment, }); } - const func = sema.owner_func orelse + const func = sema.func orelse return sema.fail(block, src, "@setAlignStack outside function body", .{}); const fn_owner_decl = sema.mod.declPtr(func.owner_decl); switch (fn_owner_decl.ty.fnCallingConvention()) { .Naked => return sema.fail(block, src, "@setAlignStack in naked function", .{}), .Inline => return sema.fail(block, src, "@setAlignStack in inline function", .{}), - else => {}, + else => if (block.inlining != null) { + return sema.fail(block, src, "@setAlignStack in inline call", .{}); + }, } const gop = try sema.mod.align_stack_fns.getOrPut(sema.mod.gpa, func); @@ -6161,11 +6194,12 @@ fn zirArrayType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const tracy = trace(@src()); defer tracy.end(); - const bin_inst = sema.code.instructions.items(.data)[inst].bin; - const len_src = sema.src; // TODO better source location - const elem_src = sema.src; // TODO better source location - const len = try sema.resolveInt(block, len_src, bin_inst.lhs, Type.usize); - const elem_type = try sema.resolveType(block, elem_src, bin_inst.rhs); + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; + const len_src: LazySrcLoc = .{ .node_offset_array_type_len = inst_data.src_node }; + const elem_src: LazySrcLoc = .{ .node_offset_array_type_elem = inst_data.src_node }; + const len = try sema.resolveInt(block, len_src, extra.lhs, Type.usize); + const elem_type = try sema.resolveType(block, elem_src, extra.rhs); const array_ty = try Type.array(sema.arena, len, null, elem_type, sema.mod); return sema.addType(array_ty); @@ -6240,18 +6274,18 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! ); } -fn zirErrorToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const op = try sema.resolveInst(inst_data.operand); - const op_coerced = try sema.coerce(block, Type.anyerror, op, operand_src); + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const src = LazySrcLoc.nodeOffset(extra.node); + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const uncasted_operand = try sema.resolveInst(extra.operand); + const operand = try sema.coerce(block, Type.anyerror, uncasted_operand, operand_src); const result_ty = Type.u16; - if (try sema.resolveMaybeUndefVal(block, src, op_coerced)) |val| { + if (try sema.resolveMaybeUndefVal(block, src, operand)) |val| { if (val.isUndef()) { return sema.addConstUndef(result_ty); } @@ -6273,7 +6307,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! } } - const op_ty = sema.typeOf(op); + const op_ty = sema.typeOf(uncasted_operand); try sema.resolveInferredErrorSetTy(block, src, op_ty); if (!op_ty.isAnyError()) { const names = op_ty.errorSetNames(); @@ -6285,17 +6319,17 @@ fn zirErrorToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! } try sema.requireRuntimeBlock(block, src); - return block.addBitCast(result_ty, op_coerced); + return block.addBitCast(result_ty, operand); } -fn zirIntToError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src = inst_data.src(); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const uncasted_operand = try sema.resolveInst(inst_data.operand); + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const src = LazySrcLoc.nodeOffset(extra.node); + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const uncasted_operand = try sema.resolveInst(extra.operand); const operand = try sema.coerce(block, Type.u16, uncasted_operand, operand_src); const target = sema.mod.getTarget(); @@ -7432,6 +7466,9 @@ fn analyzeAs( const dest_ty = try sema.resolveType(block, src, zir_dest_type); const operand = try sema.resolveInst(zir_operand); if (dest_ty.tag() == .var_args_param) return operand; + if (dest_ty.zigTypeTag() == .NoReturn) { + return sema.fail(block, src, "cannot cast to noreturn", .{}); + } return sema.coerce(block, dest_ty, operand, src); } @@ -8099,9 +8136,11 @@ fn zirSwitchCond( const union_ty = try sema.resolveTypeFields(block, operand_src, operand_ty); const enum_ty = union_ty.unionTagType() orelse { const msg = msg: { - const msg = try sema.errMsg(block, src, "switch on untagged union", .{}); + const msg = try sema.errMsg(block, src, "switch on union with no attached enum", .{}); errdefer msg.destroy(sema.gpa); - try sema.addDeclaredHereNote(msg, union_ty); + if (union_ty.declSrcLocOrNull(sema.mod)) |union_src| { + try sema.mod.errNoteNonLazy(union_src, msg, "consider 'union(enum)' here", .{}); + } break :msg msg; }; return sema.failWithOwnedErrorMsg(block, msg); @@ -8357,7 +8396,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError return sema.fail( block, src, - "switch must handle all possibilities", + "else prong required when switching on type 'anyerror'", .{}, ); } @@ -8592,7 +8631,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError if (true_count + false_count == 2) { return sema.fail( block, - src, + special_prong_src, "unreachable else prong; all cases already handled", .{}, ); @@ -9720,7 +9759,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - const operand_src = src; // TODO put this on the operand, not the '~' + const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; const operand = try sema.resolveInst(inst_data.operand); const operand_type = sema.typeOf(operand); @@ -10219,7 +10258,7 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const lhs_src = src; - const rhs_src = src; // TODO better source location + const rhs_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; const rhs = try sema.resolveInst(inst_data.operand); const rhs_ty = sema.typeOf(rhs); @@ -10255,7 +10294,7 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const lhs_src = src; - const rhs_src = src; // TODO better source location + const rhs_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; const rhs = try sema.resolveInst(inst_data.operand); const rhs_ty = sema.typeOf(rhs); @@ -10532,18 +10571,17 @@ fn analyzeArithmetic( if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize()) { .One, .Slice => {}, .Many, .C => { - const op_src = src; // TODO better source location const air_tag: Air.Inst.Tag = switch (zir_tag) { .add => .ptr_add, .sub => .ptr_sub, else => return sema.fail( block, - op_src, + src, "invalid pointer arithmetic operand: '{s}''", .{@tagName(zir_tag)}, ), }; - return analyzePtrArithmetic(sema, block, op_src, lhs, rhs, air_tag, lhs_src, rhs_src); + return analyzePtrArithmetic(sema, block, src, lhs, rhs, air_tag, lhs_src, rhs_src); }, }; @@ -11941,7 +11979,6 @@ fn runtimeBoolCmp( fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src = inst_data.src(); const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const ty = try sema.resolveType(block, operand_src, inst_data.operand); switch (ty.zigTypeTag()) { @@ -11951,7 +11988,7 @@ fn zirSizeOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. .Null, .BoundFn, .Opaque, - => return sema.fail(block, src, "no size available for type '{}'", .{ty.fmt(sema.mod)}), + => return sema.fail(block, operand_src, "no size available for type '{}'", .{ty.fmt(sema.mod)}), .Type, .EnumLiteral, @@ -12077,7 +12114,7 @@ fn zirBuiltinSrc( const tracy = trace(@src()); defer tracy.end(); - const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand)); + const src = sema.src; // TODO better source location const extra = sema.code.extraData(Zir.Inst.LineColumn, extended.operand).data; const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{}); const fn_owner_decl = sema.mod.declPtr(func.owner_decl); @@ -12116,9 +12153,8 @@ fn zirBuiltinSrc( field_values[0] = file_name_val; // fn_name: [:0]const u8, field_values[1] = func_name_val; - // TODO these should be runtime only! // line: u32 - field_values[2] = try Value.Tag.int_u64.create(sema.arena, extra.line + 1); + field_values[2] = try Value.Tag.runtime_int.create(sema.arena, extra.line + 1); // column: u32, field_values[3] = try Value.Tag.int_u64.create(sema.arena, extra.column + 1); @@ -13123,7 +13159,7 @@ fn zirBoolNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); - const operand_src = src; // TODO put this on the operand, not the `!` + const operand_src: LazySrcLoc = .{ .node_offset_un_op = inst_data.src_node }; const uncasted_operand = try sema.resolveInst(inst_data.operand); const operand = try sema.coerce(block, Type.bool, uncasted_operand, operand_src); @@ -13667,7 +13703,8 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr defer tracy.end(); const inst_data = sema.code.instructions.items(.data)[inst].ptr_type_simple; - const elem_type = try sema.resolveType(block, .unneeded, inst_data.elem_type); + const elem_ty_src = sema.src; // TODO better source location + const elem_type = try sema.resolveType(block, elem_ty_src, inst_data.elem_type); const ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = elem_type, .@"addrspace" = .generic, @@ -13676,6 +13713,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr .@"volatile" = inst_data.is_volatile, .size = inst_data.size, }); + try sema.validatePtrTy(block, elem_ty_src, ty); return sema.addType(ty); } @@ -13683,9 +13721,12 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const tracy = trace(@src()); defer tracy.end(); - // TODO better source location - const src: LazySrcLoc = sema.src; - const elem_ty_src: LazySrcLoc = .unneeded; + const src: LazySrcLoc = sema.src; // TODO better source location + const elem_ty_src: LazySrcLoc = sema.src; // TODO better source location + const sentinel_src: LazySrcLoc = sema.src; // TODO better source location + const addrspace_src: LazySrcLoc = sema.src; // TODO better source location + const bitoffset_src: LazySrcLoc = sema.src; // TODO better source location + const hostsize_src: LazySrcLoc = sema.src; // TODO better source location const inst_data = sema.code.instructions.items(.data)[inst].ptr_type; const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index); const unresolved_elem_ty = try sema.resolveType(block, elem_ty_src, extra.data.elem_type); @@ -13696,7 +13737,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const sentinel = if (inst_data.flags.has_sentinel) blk: { const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); extra_i += 1; - break :blk (try sema.resolveInstConst(block, .unneeded, ref)).val; + break :blk (try sema.resolveInstConst(block, sentinel_src, ref)).val; } else null; const abi_align: u32 = if (inst_data.flags.has_align) blk: { @@ -13718,20 +13759,20 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const address_space = if (inst_data.flags.has_addrspace) blk: { const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); extra_i += 1; - break :blk try sema.analyzeAddrspace(block, .unneeded, ref, .pointer); + break :blk try sema.analyzeAddrspace(block, addrspace_src, ref, .pointer); } else .generic; const bit_offset = if (inst_data.flags.has_bit_range) blk: { const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); extra_i += 1; - const bit_offset = try sema.resolveInt(block, .unneeded, ref, Type.u16); + const bit_offset = try sema.resolveInt(block, bitoffset_src, ref, Type.u16); break :blk @intCast(u16, bit_offset); } else 0; const host_size: u16 = if (inst_data.flags.has_bit_range) blk: { const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]); extra_i += 1; - const host_size = try sema.resolveInt(block, .unneeded, ref, Type.u16); + const host_size = try sema.resolveInt(block, hostsize_src, ref, Type.u16); break :blk @intCast(u16, host_size); } else 0; @@ -13758,9 +13799,25 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air .@"volatile" = inst_data.flags.is_volatile, .size = inst_data.size, }); + try sema.validatePtrTy(block, elem_ty_src, ty); return sema.addType(ty); } +fn validatePtrTy(sema: *Sema, block: *Block, elem_src: LazySrcLoc, ty: Type) CompileError!void { + const ptr_info = ty.ptrInfo().data; + const pointee_tag = ptr_info.pointee_type.zigTypeTag(); + if (pointee_tag == .NoReturn) { + return sema.fail(block, elem_src, "pointer to noreturn not allowed", .{}); + } else if (ptr_info.size == .Many and pointee_tag == .Opaque) { + return sema.fail(block, elem_src, "unknown-length pointer to opaque not allowed", .{}); + } else if (ptr_info.size == .C) { + // TODO check extern type + if (pointee_tag == .Opaque) { + return sema.fail(block, elem_src, "C pointers cannot point to opaque types", .{}); + } + } +} + fn zirStructInitEmpty(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const tracy = trace(@src()); defer tracy.end(); @@ -14559,14 +14616,12 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air }, .Enum => operand_ty, .Union => operand_ty.unionTagType() orelse { - const decl_index = operand_ty.getOwnerDecl(); - const decl = mod.declPtr(decl_index); const msg = msg: { - const msg = try sema.errMsg(block, src, "union '{s}' is untagged", .{ - decl.name, + const msg = try sema.errMsg(block, src, "union '{}' is untagged", .{ + operand_ty.fmt(sema.mod), }); errdefer msg.destroy(sema.gpa); - try mod.errNoteNonLazy(decl.srcLoc(), msg, "declared here", .{}); + try sema.addDeclaredHereNote(msg, operand_ty); break :msg msg; }; return sema.failWithOwnedErrorMsg(block, msg); @@ -16703,14 +16758,13 @@ fn analyzeShuffle( }); } -fn zirSelect(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { - const inst_data = sema.code.instructions.items(.data)[inst].pl_node; - const extra = sema.code.extraData(Zir.Inst.Select, inst_data.payload_index).data; +fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { + const extra = sema.code.extraData(Zir.Inst.Select, extended.operand).data; - const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; - const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; - const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = inst_data.src_node }; - const b_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = inst_data.src_node }; + const elem_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; + const pred_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node }; + const a_src: LazySrcLoc = .{ .node_offset_builtin_call_arg2 = extra.node }; + const b_src: LazySrcLoc = .{ .node_offset_builtin_call_arg3 = extra.node }; const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_type); try sema.checkVectorElemType(block, elem_ty_src, elem_ty); @@ -17417,7 +17471,7 @@ fn zirVarExtended( const extra = sema.code.extraData(Zir.Inst.ExtendedVar, extended.operand); const src = sema.src; const ty_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at type - const mut_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at mut token + const name_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at the name token const init_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at init expr const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small); @@ -17461,7 +17515,7 @@ fn zirVarExtended( return sema.failWithNeededComptime(block, init_src); } else Value.initTag(.unreachable_value); - try sema.validateVarType(block, mut_src, var_ty, small.is_extern); + try sema.validateVarType(block, name_src, var_ty, small.is_extern); const new_var = try sema.gpa.create(Module.Var); errdefer sema.gpa.destroy(new_var); @@ -17958,6 +18012,9 @@ fn validateVarType( const src_decl = mod.declPtr(block.src_decl); try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(src_decl), var_ty); + if (var_ty.zigTypeTag() == .ComptimeInt or var_ty.zigTypeTag() == .ComptimeFloat) { + try sema.errNote(block, src, msg, "to modify this variable at runtime, it must be given an explicit fixed-size number type", .{}); + } break :msg msg; }; @@ -19445,6 +19502,34 @@ fn elemVal( } } +fn validateRuntimeElemAccess( + sema: *Sema, + block: *Block, + elem_index_src: LazySrcLoc, + elem_ty: Type, + parent_ty: Type, + parent_src: LazySrcLoc, +) CompileError!void { + const valid_rt = try sema.validateRunTimeType(block, elem_index_src, elem_ty, false); + if (!valid_rt) { + const msg = msg: { + const msg = try sema.errMsg( + block, + elem_index_src, + "values of type '{}' must be comptime known, but index value is runtime known", + .{parent_ty.fmt(sema.mod)}, + ); + errdefer msg.destroy(sema.gpa); + + const src_decl = sema.mod.declPtr(block.src_decl); + try sema.explainWhyTypeIsComptime(block, elem_index_src, msg, parent_src.toSrcLoc(src_decl), parent_ty); + + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); + } +} + fn tupleFieldPtr( sema: *Sema, block: *Block, @@ -19485,6 +19570,8 @@ fn tupleFieldPtr( ); } + try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_ptr_src); + try sema.requireRuntimeBlock(block, tuple_ptr_src); return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty); } @@ -19523,6 +19610,8 @@ fn tupleField( return sema.addConstant(field_ty, field_values[field_index]); } + try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src); + try sema.requireRuntimeBlock(block, tuple_src); return block.addStructFieldVal(tuple, field_index, field_ty); } @@ -19573,24 +19662,7 @@ fn elemValArray( } } - const valid_rt = try sema.validateRunTimeType(block, elem_index_src, elem_ty, false); - if (!valid_rt) { - const msg = msg: { - const msg = try sema.errMsg( - block, - elem_index_src, - "values of type '{}' must be comptime known, but index value is runtime known", - .{array_ty.fmt(sema.mod)}, - ); - errdefer msg.destroy(sema.gpa); - - const src_decl = sema.mod.declPtr(block.src_decl); - try sema.explainWhyTypeIsComptime(block, elem_index_src, msg, array_src.toSrcLoc(src_decl), array_ty); - - break :msg msg; - }; - return sema.failWithOwnedErrorMsg(block, msg); - } + try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, array_ty, array_src); const runtime_src = if (maybe_undef_array_val != null) elem_index_src else array_src; try sema.requireRuntimeBlock(block, runtime_src); @@ -19648,23 +19720,8 @@ fn elemPtrArray( } } - const valid_rt = try sema.validateRunTimeType(block, elem_index_src, array_ty.elemType2(), false); - if (!valid_rt and !init) { - const msg = msg: { - const msg = try sema.errMsg( - block, - elem_index_src, - "values of type '{}' must be comptime known, but index value is runtime known", - .{array_ty.fmt(sema.mod)}, - ); - errdefer msg.destroy(sema.gpa); - - const src_decl = sema.mod.declPtr(block.src_decl); - try sema.explainWhyTypeIsComptime(block, elem_index_src, msg, array_ptr_src.toSrcLoc(src_decl), array_ty); - - break :msg msg; - }; - return sema.failWithOwnedErrorMsg(block, msg); + if (!init) { + try sema.validateRuntimeElemAccess(block, elem_index_src, array_ty.elemType2(), array_ty, array_ptr_src); } const runtime_src = if (maybe_undef_array_ptr_val != null) elem_index_src else array_ptr_src; @@ -19720,6 +19777,8 @@ fn elemValSlice( } } + try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ty, slice_ty, slice_src); + try sema.requireRuntimeBlock(block, runtime_src); if (block.wantSafety()) { const len_inst = if (maybe_slice_val) |slice_val| @@ -19773,6 +19832,8 @@ fn elemPtrSlice( } } + try sema.validateRuntimeElemAccess(block, elem_index_src, elem_ptr_ty, slice_ty, slice_src); + const runtime_src = if (maybe_undef_slice_val != null) elem_index_src else slice_src; try sema.requireRuntimeBlock(block, runtime_src); if (block.wantSafety()) { @@ -20042,6 +20103,15 @@ fn coerce( }); return sema.addConstant(dest_ty, slice_val); } + + if (inst_ty.zigTypeTag() == .Array) { + return sema.fail( + block, + inst_src, + "array literal requires address-of operator (&) to coerce to slice type '{}'", + .{dest_ty.fmt(sema.mod)}, + ); + } }, .Many => p: { if (!inst_ty.isSlice()) break :p; @@ -22368,7 +22438,7 @@ fn analyzeLoad( } if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |ptr_val| { - if (try sema.pointerDeref(block, ptr_src, ptr_val, ptr_ty)) |elem_val| { + if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |elem_val| { return sema.addConstant(elem_ty, elem_val); } if (block.is_typeof) { @@ -22543,9 +22613,9 @@ fn analyzeSlice( sentinel_opt: Air.Inst.Ref, sentinel_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { - const ptr_src = src; // TODO better source location - const start_src = src; // TODO better source location - const end_src = src; // TODO better source location + const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = src.node_offset.x }; + const start_src: LazySrcLoc = .{ .node_offset_slice_start = src.node_offset.x }; + const end_src: LazySrcLoc = .{ .node_offset_slice_end = src.node_offset.x }; // Slice expressions can operate on a variable whose type is an array. This requires // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer. const ptr_ptr_ty = sema.typeOf(ptr_ptr); @@ -22575,7 +22645,7 @@ fn analyzeSlice( array_ty = double_child_ty; elem_ty = double_child_ty.childType(); } else { - return sema.fail(block, ptr_src, "slice of single-item pointer", .{}); + return sema.fail(block, src, "slice of single-item pointer", .{}); } }, .Many, .C => { @@ -22588,7 +22658,7 @@ fn analyzeSlice( if (ptr_ptr_child_ty.ptrSize() == .C) { if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| { if (ptr_val.isNull()) { - return sema.fail(block, ptr_src, "slice of null pointer", .{}); + return sema.fail(block, src, "slice of null pointer", .{}); } } } @@ -22601,7 +22671,7 @@ fn analyzeSlice( elem_ty = ptr_ptr_child_ty.childType(); }, }, - else => return sema.fail(block, ptr_src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}), + else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}), } const ptr = if (slice_ty.isSlice()) @@ -22774,7 +22844,7 @@ fn analyzeSlice( return sema.addConstUndef(return_ty); } - return sema.fail(block, ptr_src, "non-zero length slice of undefined pointer", .{}); + return sema.fail(block, src, "non-zero length slice of undefined pointer", .{}); } const return_ty = try Type.ptr(sema.arena, mod, .{ @@ -24434,6 +24504,10 @@ fn semaUnionFields(block: *Block, mod: *Module, union_obj: *Module.Union) Compil } else { // The provided type is the enum tag type. union_obj.tag_ty = try provided_ty.copy(decl_arena_allocator); + if (union_obj.tag_ty.zigTypeTag() != .Enum) { + const tag_ty_src = src; // TODO better source location + return sema.fail(block, tag_ty_src, "expected enum tag type, found '{}'", .{union_obj.tag_ty.fmt(sema.mod)}); + } // The fields of the union must match the enum exactly. // Store a copy of the enum field names so we can check for // missing or extraneous fields later. diff --git a/src/TypedValue.zig b/src/TypedValue.zig index a41c86582714..560ebd9e5c6d 100644 --- a/src/TypedValue.zig +++ b/src/TypedValue.zig @@ -495,5 +495,6 @@ pub fn print( }, .generic_poison_type => return writer.writeAll("(generic poison type)"), .generic_poison => return writer.writeAll("(generic poison)"), + .runtime_int => return writer.writeAll("[runtime value]"), }; } diff --git a/src/Zir.zig b/src/Zir.zig index 98cdd490b86f..b2dde0df573e 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -212,7 +212,7 @@ pub const Inst = struct { /// Uses the `pl_node` union field. Payload is `Bin`. array_mul, /// `[N]T` syntax. No source location provided. - /// Uses the `bin` union field. lhs is length, rhs is element type. + /// Uses the `pl_node` union field. Payload is `Bin`. lhs is length, rhs is element type. array_type, /// `[N:S]T` syntax. Source location is the array type expression node. /// Uses the `pl_node` union field. Payload is `ArrayTypeSentinel`. @@ -244,7 +244,7 @@ pub const Inst = struct { /// Uses the pl_node field with payload `Bin`. bitcast, /// Bitwise NOT. `~` - /// Uses `un_node`. + /// Uses `un_tok`. bit_not, /// Bitwise OR. `|` bit_or, @@ -260,7 +260,7 @@ pub const Inst = struct { /// Uses the `pl_node` union field. Payload is `Block`. suspend_block, /// Boolean NOT. See also `bit_not`. - /// Uses the `un_node` field. + /// Uses the `un_tok` field. bool_not, /// Short-circuiting boolean `and`. `lhs` is a boolean `Ref` and the other operand /// is a block, which is evaluated if `lhs` is `true`. @@ -729,7 +729,7 @@ pub const Inst = struct { /// resulting array initialization value is within a comptime scope. validate_array_init_comptime, /// Check that operand type supports the dereference operand (.*). - /// Uses the `un_tok` field. + /// Uses the `un_node` field. validate_deref, /// A struct literal with a specified type, with no fields. /// Uses the `un_node` field. @@ -778,10 +778,6 @@ pub const Inst = struct { /// Implement builtin `@ptrToInt`. Uses `un_node`. /// Convert a pointer to a `usize` integer. ptr_to_int, - /// Implement builtin `@errToInt`. Uses `un_node`. - error_to_int, - /// Implement builtin `@intToError`. Uses `un_node`. - int_to_error, /// Emit an error message and fail compilation. /// Uses the `un_node` field. compile_error, @@ -802,6 +798,8 @@ pub const Inst = struct { error_name, /// Implement builtin `@panic`. Uses `un_node`. panic, + /// Same as `panic` but forces comptime. + panic_comptime, /// Implement builtin `@setCold`. Uses `un_node`. set_cold, /// Implement builtin `@setRuntimeSafety`. Uses `un_node`. @@ -916,9 +914,6 @@ pub const Inst = struct { /// Implements the `@shuffle` builtin. /// Uses the `pl_node` union field with payload `Shuffle`. shuffle, - /// Implements the `@select` builtin. - /// Uses the `pl_node` union field with payload `Select`. - select, /// Implements the `@atomicLoad` builtin. /// Uses the `pl_node` union field with payload `AtomicLoad`. atomic_load, @@ -1125,8 +1120,6 @@ pub const Inst = struct { .err_union_payload_unsafe_ptr, .err_union_code, .err_union_code_ptr, - .error_to_int, - .int_to_error, .ptr_type, .ptr_type_simple, .ensure_err_payload_void, @@ -1230,7 +1223,6 @@ pub const Inst = struct { .splat, .reduce, .shuffle, - .select, .atomic_load, .atomic_rmw, .atomic_store, @@ -1270,6 +1262,7 @@ pub const Inst = struct { .repeat, .repeat_inline, .panic, + .panic_comptime, => true, }; } @@ -1423,8 +1416,6 @@ pub const Inst = struct { .err_union_payload_unsafe_ptr, .err_union_code, .err_union_code_ptr, - .error_to_int, - .int_to_error, .ptr_type, .ptr_type_simple, .enum_literal, @@ -1516,7 +1507,6 @@ pub const Inst = struct { .splat, .reduce, .shuffle, - .select, .atomic_load, .atomic_rmw, .mul_add, @@ -1546,6 +1536,7 @@ pub const Inst = struct { .repeat, .repeat_inline, .panic, + .panic_comptime, .@"try", .try_ptr, //.try_inline, @@ -1580,7 +1571,7 @@ pub const Inst = struct { .param_anytype_comptime = .str_tok, .array_cat = .pl_node, .array_mul = .pl_node, - .array_type = .bin, + .array_type = .pl_node, .array_type_sentinel = .pl_node, .vector_type = .pl_node, .elem_type_index = .bin, @@ -1713,7 +1704,7 @@ pub const Inst = struct { .validate_struct_init_comptime = .pl_node, .validate_array_init = .pl_node, .validate_array_init_comptime = .pl_node, - .validate_deref = .un_tok, + .validate_deref = .un_node, .struct_init_empty = .un_node, .field_type = .pl_node, .field_type_ref = .pl_node, @@ -1731,8 +1722,6 @@ pub const Inst = struct { .bit_size_of = .un_node, .ptr_to_int = .un_node, - .error_to_int = .un_node, - .int_to_error = .un_node, .compile_error = .un_node, .set_eval_branch_quota = .un_node, .enum_to_int = .un_node, @@ -1741,6 +1730,7 @@ pub const Inst = struct { .embed_file = .un_node, .error_name = .un_node, .panic = .un_node, + .panic_comptime = .un_node, .set_cold = .un_node, .set_runtime_safety = .un_node, .sqrt = .un_node, @@ -1802,7 +1792,6 @@ pub const Inst = struct { .splat = .pl_node, .reduce = .pl_node, .shuffle = .pl_node, - .select = .pl_node, .atomic_load = .pl_node, .atomic_rmw = .pl_node, .atomic_store = .pl_node, @@ -1971,6 +1960,15 @@ pub const Inst = struct { await_nosuspend, /// `operand` is `src_node: i32`. breakpoint, + /// Implements the `@select` builtin. + /// operand` is payload index to `Select`. + select, + /// Implement builtin `@errToInt`. + /// `operand` is payload index to `UnNode`. + error_to_int, + /// Implement builtin `@intToError`. + /// `operand` is payload index to `UnNode`. + int_to_error, pub const InstData = struct { opcode: Extended, @@ -3448,6 +3446,7 @@ pub const Inst = struct { }; pub const Select = struct { + node: i32, elem_type: Ref, pred: Ref, a: Ref, diff --git a/src/print_zir.zig b/src/print_zir.zig index b19076a7f089..f2a11e20bd6c 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -142,7 +142,6 @@ const Writer = struct { const tag = tags[inst]; try stream.print("= {s}(", .{@tagName(tags[inst])}); switch (tag) { - .array_type, .as, .store, .store_to_block_ptr, @@ -189,8 +188,6 @@ const Writer = struct { .typeof_log2_int_type, .log2_int_type, .ptr_to_int, - .error_to_int, - .int_to_error, .compile_error, .set_eval_branch_quota, .enum_to_int, @@ -199,6 +196,7 @@ const Writer = struct { .embed_file, .error_name, .panic, + .panic_comptime, .set_cold, .set_runtime_safety, .sqrt, @@ -284,7 +282,6 @@ const Writer = struct { .memcpy => try self.writeMemcpy(stream, inst), .memset => try self.writeMemset(stream, inst), .shuffle => try self.writeShuffle(stream, inst), - .select => try self.writeSelect(stream, inst), .mul_add => try self.writeMulAdd(stream, inst), .field_parent_ptr => try self.writeFieldParentPtr(stream, inst), .builtin_call => try self.writeBuiltinCall(stream, inst), @@ -356,6 +353,7 @@ const Writer = struct { .elem_ptr, .elem_val, .coerce_result_ptr, + .array_type, => try self.writePlNodeBin(stream, inst), .elem_ptr_imm => try self.writeElemPtrImm(stream, inst), @@ -478,6 +476,8 @@ const Writer = struct { .compile_log => try self.writeNodeMultiOp(stream, extended), .typeof_peer => try self.writeTypeofPeer(stream, extended), + .select => try self.writeSelect(stream, extended), + .add_with_overflow, .sub_with_overflow, .mul_with_overflow, @@ -496,6 +496,8 @@ const Writer = struct { .set_float_mode, .set_align_stack, .wasm_memory_size, + .error_to_int, + .int_to_error, => { const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(inst_data.node); @@ -772,9 +774,8 @@ const Writer = struct { try self.writeSrc(stream, inst_data.src()); } - fn writeSelect(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { - const inst_data = self.code.instructions.items(.data)[inst].pl_node; - const extra = self.code.extraData(Zir.Inst.Select, inst_data.payload_index).data; + fn writeSelect(self: *Writer, stream: anytype, extended: Zir.Inst.Extended.InstData) !void { + const extra = self.code.extraData(Zir.Inst.Select, extended.operand).data; try self.writeInstRef(stream, extra.elem_type); try stream.writeAll(", "); try self.writeInstRef(stream, extra.pred); @@ -783,7 +784,7 @@ const Writer = struct { try stream.writeAll(", "); try self.writeInstRef(stream, extra.b); try stream.writeAll(") "); - try self.writeSrc(stream, inst_data.src()); + try self.writeSrc(stream, LazySrcLoc.nodeOffset(extra.node)); } fn writeMulAdd(self: *Writer, stream: anytype, inst: Zir.Inst.Index) !void { diff --git a/src/value.zig b/src/value.zig index 90cdf8283487..04999c778a83 100644 --- a/src/value.zig +++ b/src/value.zig @@ -111,6 +111,7 @@ pub const Value = extern union { int_i64, int_big_positive, int_big_negative, + runtime_int, function, extern_fn, variable, @@ -304,6 +305,7 @@ pub const Value = extern union { .int_type => Payload.IntType, .int_u64 => Payload.U64, .int_i64 => Payload.I64, + .runtime_int => Payload.U64, .function => Payload.Function, .variable => Payload.Variable, .decl_ref_mut => Payload.DeclRefMut, @@ -483,6 +485,7 @@ pub const Value = extern union { }, .int_type => return self.copyPayloadShallow(arena, Payload.IntType), .int_u64 => return self.copyPayloadShallow(arena, Payload.U64), + .runtime_int => return self.copyPayloadShallow(arena, Payload.U64), .int_i64 => return self.copyPayloadShallow(arena, Payload.I64), .int_big_positive, .int_big_negative => { const old_payload = self.cast(Payload.BigInt).?; @@ -762,6 +765,7 @@ pub const Value = extern union { .int_i64 => return std.fmt.formatIntValue(val.castTag(.int_i64).?.data, "", options, out_stream), .int_big_positive => return out_stream.print("{}", .{val.castTag(.int_big_positive).?.asBigInt()}), .int_big_negative => return out_stream.print("{}", .{val.castTag(.int_big_negative).?.asBigInt()}), + .runtime_int => return out_stream.writeAll("[runtime value]"), .function => return out_stream.print("(function decl={d})", .{val.castTag(.function).?.data.owner_decl}), .extern_fn => return out_stream.writeAll("(extern function)"), .variable => return out_stream.writeAll("(variable)"), @@ -1077,6 +1081,8 @@ pub const Value = extern union { .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt(), .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt(), + .runtime_int => return BigIntMutable.init(&space.limbs, val.castTag(.runtime_int).?.data).toConst(), + .undef => unreachable, .lazy_align => { @@ -1132,6 +1138,8 @@ pub const Value = extern union { .int_big_positive => return val.castTag(.int_big_positive).?.asBigInt().to(u64) catch null, .int_big_negative => return val.castTag(.int_big_negative).?.asBigInt().to(u64) catch null, + .runtime_int => return val.castTag(.runtime_int).?.data, + .undef => unreachable, .lazy_align => { diff --git a/test/cases/compile_errors/stage1/obj/array_access_of_type.zig b/test/cases/compile_errors/array_access_of_type.zig similarity index 54% rename from test/cases/compile_errors/stage1/obj/array_access_of_type.zig rename to test/cases/compile_errors/array_access_of_type.zig index c0029f24924e..d38a13b2fa42 100644 --- a/test/cases/compile_errors/stage1/obj/array_access_of_type.zig +++ b/test/cases/compile_errors/array_access_of_type.zig @@ -4,7 +4,7 @@ export fn foo() void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:2:14: error: array access of non-array type 'type' +// :2:14: error: element access of non-indexable type 'type' diff --git a/test/cases/compile_errors/invalid_array_elem_ty.zig b/test/cases/compile_errors/invalid_array_elem_ty.zig index d1d7e4a070f2..f4b001e00a1e 100644 --- a/test/cases/compile_errors/invalid_array_elem_ty.zig +++ b/test/cases/compile_errors/invalid_array_elem_ty.zig @@ -9,4 +9,4 @@ pub export fn entry() void { // target=native // backend=stage2 // -// :4:1: error: expected type 'type', found 'fn() type' +// :5:12: error: expected type 'type', found 'fn() type' diff --git a/test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_primitive.zig b/test/cases/compile_errors/method_call_with_first_arg_type_primitive.zig similarity index 70% rename from test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_primitive.zig rename to test/cases/compile_errors/method_call_with_first_arg_type_primitive.zig index 316be2d899f0..e93d1e717d7d 100644 --- a/test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_primitive.zig +++ b/test/cases/compile_errors/method_call_with_first_arg_type_primitive.zig @@ -15,7 +15,7 @@ export fn f() void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:14:5: error: expected type 'i32', found 'Foo' +// :14:9: error: type 'tmp.Foo' has no field or member function named 'init' diff --git a/test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_wrong_container.zig b/test/cases/compile_errors/method_call_with_first_arg_type_wrong_container.zig similarity index 82% rename from test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_wrong_container.zig rename to test/cases/compile_errors/method_call_with_first_arg_type_wrong_container.zig index 04ab89fb6ca7..0820151ff10a 100644 --- a/test/cases/compile_errors/stage1/obj/method_call_with_first_arg_type_wrong_container.zig +++ b/test/cases/compile_errors/method_call_with_first_arg_type_wrong_container.zig @@ -24,7 +24,7 @@ export fn foo() void { } // error -// backend=stage1 +// backend=llvm // target=native // -// tmp.zig:23:5: error: expected type '*Allocator', found '*List' +// :23:6: error: type 'tmp.List' has no field or member function named 'init' diff --git a/test/cases/compile_errors/stage1/obj/missing_const_in_slice_with_nested_array_type.zig b/test/cases/compile_errors/missing_const_in_slice_with_nested_array_type.zig similarity index 71% rename from test/cases/compile_errors/stage1/obj/missing_const_in_slice_with_nested_array_type.zig rename to test/cases/compile_errors/missing_const_in_slice_with_nested_array_type.zig index af9d690d4383..1ef986935b73 100644 --- a/test/cases/compile_errors/stage1/obj/missing_const_in_slice_with_nested_array_type.zig +++ b/test/cases/compile_errors/missing_const_in_slice_with_nested_array_type.zig @@ -12,7 +12,7 @@ export fn entry() void { } // error -// backend=stage1 +// backend=llvm // target=native // -// tmp.zig:4:30: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32' +// :4:30: error: array literal requires address-of operator (&) to coerce to slice type '[][2]f32' diff --git a/test/cases/compile_errors/mul_overflow_in_function_evaluation.zig b/test/cases/compile_errors/mul_overflow_in_function_evaluation.zig new file mode 100644 index 000000000000..6be57f770eb8 --- /dev/null +++ b/test/cases/compile_errors/mul_overflow_in_function_evaluation.zig @@ -0,0 +1,14 @@ +const y = mul(300, 6000); +fn mul(a: u16, b: u16) u16 { + return a * b; +} + +export fn entry() usize { return @sizeOf(@TypeOf(&y)); } + +// error +// backend=stage2 +// target=native +// +// :3:14: error: overflow of integer type 'u16' with value '1800000' +// :1:14: note: called from here + diff --git a/test/cases/compile_errors/negation_overflow_in_function_evaluation.zig b/test/cases/compile_errors/negation_overflow_in_function_evaluation.zig new file mode 100644 index 000000000000..abd8549fd20d --- /dev/null +++ b/test/cases/compile_errors/negation_overflow_in_function_evaluation.zig @@ -0,0 +1,13 @@ +const y = neg(-128); +fn neg(x: i8) i8 { + return -x; +} + +export fn entry() usize { return @sizeOf(@TypeOf(&y)); } + +// error +// backend=stage2 +// target=native +// +// :3:12: error: overflow of integer type 'i8' with value '128' +// :1:14: note: called from here diff --git a/test/cases/compile_errors/stage1/obj/no_else_prong_on_switch_on_global_error_set.zig b/test/cases/compile_errors/no_else_prong_on_switch_on_global_error_set.zig similarity index 61% rename from test/cases/compile_errors/stage1/obj/no_else_prong_on_switch_on_global_error_set.zig rename to test/cases/compile_errors/no_else_prong_on_switch_on_global_error_set.zig index 39f4399cafcb..6c13611d64c8 100644 --- a/test/cases/compile_errors/stage1/obj/no_else_prong_on_switch_on_global_error_set.zig +++ b/test/cases/compile_errors/no_else_prong_on_switch_on_global_error_set.zig @@ -8,7 +8,7 @@ fn foo(a: anyerror) void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:5:5: error: else prong required when switching on type 'anyerror' +// :5:5: error: else prong required when switching on type 'anyerror' diff --git a/test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig b/test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig new file mode 100644 index 000000000000..c6713b755a9c --- /dev/null +++ b/test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig @@ -0,0 +1,44 @@ +export fn entry1() void { + var m2 = &2; + _ = m2; +} +export fn entry2() void { + var a = undefined; + _ = a; +} +export fn entry3() void { + var b = 1; + _ = b; +} +export fn entry4() void { + var c = 1.0; + _ = c; +} +export fn entry5() void { + var d = null; + _ = d; +} +export fn entry6(opaque_: *Opaque) void { + var e = opaque_.*; + _ = e; +} +export fn entry7() void { + var f = i32; + _ = f; +} +const Opaque = opaque {}; + +// error +// backend=stage2 +// target=native +// +// :2:8: error: variable of type '*const comptime_int' must be const or comptime +// :6:8: error: variable of type '@TypeOf(undefined)' must be const or comptime +// :10:8: error: variable of type 'comptime_int' must be const or comptime +// :10:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type +// :14:8: error: variable of type 'comptime_float' must be const or comptime +// :14:8: note: to modify this variable at runtime, it must be given an explicit fixed-size number type +// :18:8: error: variable of type '@TypeOf(null)' must be const or comptime +// :22:19: error: values of type 'tmp.Opaque' must be comptime known, but operand value is runtime known +// :26:8: error: variable of type 'type' must be const or comptime +// :26:8: note: types are not available at runtime diff --git a/test/cases/compile_errors/non-inline_for_loop_on_a_type_that_requires_comptime.zig b/test/cases/compile_errors/non-inline_for_loop_on_a_type_that_requires_comptime.zig new file mode 100644 index 000000000000..ec598e8f05a5 --- /dev/null +++ b/test/cases/compile_errors/non-inline_for_loop_on_a_type_that_requires_comptime.zig @@ -0,0 +1,16 @@ +const Foo = struct { + name: []const u8, + T: type, +}; +export fn entry() void { + const xx: [2]Foo = .{ .{ .name = "", .T = u8 }, .{ .name = "", .T = u8 } }; + for (xx) |f| { _ = f;} +} + +// error +// backend=stage2 +// target=native +// +// :7:10: error: values of type '[2]tmp.Foo' must be comptime known, but index value is runtime known +// :3:8: note: struct requires comptime because of this field +// :3:8: note: types are not available at runtime diff --git a/test/cases/compile_errors/non_constant_expression_in_array_size.zig b/test/cases/compile_errors/non_constant_expression_in_array_size.zig new file mode 100644 index 000000000000..8c0854feb041 --- /dev/null +++ b/test/cases/compile_errors/non_constant_expression_in_array_size.zig @@ -0,0 +1,14 @@ +const Foo = struct { + y: [get()]u8, +}; +var global_var: usize = 1; +fn get() usize { return global_var; } + +export fn entry() usize { return @offsetOf(Foo, "y"); } + +// error +// backend=stage2 +// target=native +// +// :5:25: error: unable to resolve comptime value +// :2:15: note: called from here diff --git a/test/cases/compile_errors/non_error_sets_used_in_merge_error_sets_operator.zig b/test/cases/compile_errors/non_error_sets_used_in_merge_error_sets_operator.zig new file mode 100644 index 000000000000..eca7ba698c5b --- /dev/null +++ b/test/cases/compile_errors/non_error_sets_used_in_merge_error_sets_operator.zig @@ -0,0 +1,15 @@ +export fn foo() void { + const Errors = u8 || u16; + _ = Errors; +} +export fn bar() void { + const Errors = error{} || u16; + _ = Errors; +} + +// error +// backend=stage2 +// target=native +// +// :2:20: error: expected error set type, found 'u8' +// :6:31: error: expected error set type, found 'u16' diff --git a/test/cases/compile_errors/stage1/obj/panic_called_at_compile_time.zig b/test/cases/compile_errors/panic_called_at_compile_time.zig similarity index 57% rename from test/cases/compile_errors/stage1/obj/panic_called_at_compile_time.zig rename to test/cases/compile_errors/panic_called_at_compile_time.zig index 7c1693291305..220161930bc4 100644 --- a/test/cases/compile_errors/stage1/obj/panic_called_at_compile_time.zig +++ b/test/cases/compile_errors/panic_called_at_compile_time.zig @@ -5,7 +5,7 @@ export fn entry() void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:3:9: error: encountered @panic at compile-time +// :3:9: error: encountered @panic at comptime diff --git a/test/cases/compile_errors/range_operator_in_switch_used_on_error_set.zig b/test/cases/compile_errors/range_operator_in_switch_used_on_error_set.zig new file mode 100644 index 000000000000..859197929c6f --- /dev/null +++ b/test/cases/compile_errors/range_operator_in_switch_used_on_error_set.zig @@ -0,0 +1,20 @@ +export fn entry() void { + foo(452) catch |err| switch (err) { + error.Foo ... error.Bar => {}, + else => {}, + }; +} +fn foo(x: i32) !void { + switch (x) { + 0 ... 10 => return error.Foo, + 11 ... 20 => return error.Bar, + else => {}, + } +} + +// error +// backend=llvm +// target=native +// +// :2:34: error: ranges not allowed when switching on type '@typeInfo(@typeInfo(@TypeOf(tmp.foo)).Fn.return_type.?).ErrorUnion.error_set' +// :3:19: note: range here diff --git a/test/cases/compile_errors/stage1/obj/reading_past_end_of_pointer_casted_array.zig b/test/cases/compile_errors/reading_past_end_of_pointer_casted_array.zig similarity index 64% rename from test/cases/compile_errors/stage1/obj/reading_past_end_of_pointer_casted_array.zig rename to test/cases/compile_errors/reading_past_end_of_pointer_casted_array.zig index cece3345c3f1..906b2927536d 100644 --- a/test/cases/compile_errors/stage1/obj/reading_past_end_of_pointer_casted_array.zig +++ b/test/cases/compile_errors/reading_past_end_of_pointer_casted_array.zig @@ -7,7 +7,7 @@ comptime { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes +// :5:26: error: dereference of '*const u24' exceeds bounds of containing decl of type '[4]u8' diff --git a/test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig b/test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig new file mode 100644 index 000000000000..a327de8f7161 --- /dev/null +++ b/test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig @@ -0,0 +1,19 @@ +const Struct = struct { + a: u32, +}; +fn getIndex() usize { + return 2; +} +export fn entry() void { + const index = getIndex(); + const field = @typeInfo(Struct).Struct.fields[index]; + _ = field; +} + +// error +// backend=stage2 +// target=native +// +// :9:51: error: values of type '[]const builtin.Type.StructField' must be comptime known, but index value is runtime known +// :?:21: note: struct requires comptime because of this field +// :?:21: note: types are not available at runtime diff --git a/test/cases/compile_errors/setAlignStack_in_inline_function.zig b/test/cases/compile_errors/setAlignStack_in_inline_function.zig new file mode 100644 index 000000000000..62bbb3865c9c --- /dev/null +++ b/test/cases/compile_errors/setAlignStack_in_inline_function.zig @@ -0,0 +1,23 @@ +export fn entry() void { + foo(); +} +fn foo() callconv(.Inline) void { + @setAlignStack(16); +} + +export fn entry1() void { + comptime bar(); +} +fn bar() void { + @setAlignStack(16); +} + + +// error +// backend=stage2 +// target=native +// +// :5:5: error: @setAlignStack in inline function +// :2:8: note: called from here +// :12:5: error: @setAlignStack in inline call +// :9:17: note: called from here diff --git a/test/cases/compile_errors/signed_integer_remainder_division.zig b/test/cases/compile_errors/signed_integer_remainder_division.zig new file mode 100644 index 000000000000..5bc5d34d7eee --- /dev/null +++ b/test/cases/compile_errors/signed_integer_remainder_division.zig @@ -0,0 +1,9 @@ +export fn foo(a: i32, b: i32) i32 { + return a % b; +} + +// error +// backend=stage2 +// target=native +// +// :2:12: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod diff --git a/test/cases/compile_errors/stage1/obj/sizeOf_bad_type.zig b/test/cases/compile_errors/sizeOf_bad_type.zig similarity index 52% rename from test/cases/compile_errors/stage1/obj/sizeOf_bad_type.zig rename to test/cases/compile_errors/sizeOf_bad_type.zig index f8c397f76862..4286aecaaddb 100644 --- a/test/cases/compile_errors/stage1/obj/sizeOf_bad_type.zig +++ b/test/cases/compile_errors/sizeOf_bad_type.zig @@ -3,7 +3,7 @@ export fn entry() usize { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:2:20: error: no size available for type '@Type(.Null)' +// :2:20: error: no size available for type '@TypeOf(null)' diff --git a/test/cases/compile_errors/stage1/obj/slice_cannot_have_its_bytes_reinterpreted.zig b/test/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig similarity index 56% rename from test/cases/compile_errors/stage1/obj/slice_cannot_have_its_bytes_reinterpreted.zig rename to test/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig index 8fcf4f505c94..2280345e15ae 100644 --- a/test/cases/compile_errors/stage1/obj/slice_cannot_have_its_bytes_reinterpreted.zig +++ b/test/cases/compile_errors/slice_cannot_have_its_bytes_reinterpreted.zig @@ -5,7 +5,7 @@ export fn foo() void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// :3:52: error: slice '[]const u8' cannot have its bytes reinterpreted +// :3:52: error: comptime dereference requires '[]const u8' to have a well-defined layout, but it does not. diff --git a/test/cases/compile_errors/slice_passed_as_array_init_type.zig b/test/cases/compile_errors/slice_passed_as_array_init_type.zig new file mode 100644 index 000000000000..b4d96f2604f6 --- /dev/null +++ b/test/cases/compile_errors/slice_passed_as_array_init_type.zig @@ -0,0 +1,11 @@ +export fn entry() void { + const x = []u8{}; + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :2:19: error: type '[]u8' does not support array initialization syntax +// :2:19: note: inferred array length is specified with an underscore: '[_]u8' diff --git a/test/cases/compile_errors/slice_passed_as_array_init_type_with_elems.zig b/test/cases/compile_errors/slice_passed_as_array_init_type_with_elems.zig new file mode 100644 index 000000000000..e336d2d05ee8 --- /dev/null +++ b/test/cases/compile_errors/slice_passed_as_array_init_type_with_elems.zig @@ -0,0 +1,11 @@ +export fn entry() void { + const x = []u8{1, 2}; + _ = x; +} + +// error +// backend=stage2 +// target=native +// +// :2:19: error: type '[]u8' does not support array initialization syntax +// :2:19: note: inferred array length is specified with an underscore: '[_]u8' diff --git a/test/cases/compile_errors/src_fields_runtime.zig b/test/cases/compile_errors/src_fields_runtime.zig new file mode 100644 index 000000000000..0bdb5af81cbe --- /dev/null +++ b/test/cases/compile_errors/src_fields_runtime.zig @@ -0,0 +1,14 @@ +pub export fn entry1() void { + const s = @src(); + comptime var a: []const u8 = s.file; + comptime var b: []const u8 = s.fn_name; + comptime var c: u32 = s.column; + comptime var d: u32 = s.line; + _ = a; _ = b; _ = c; _ = d; +} + +// error +// backend=stage2 +// target=native +// +// :6:28: error: cannot store runtime value in compile time variable diff --git a/test/cases/compile_errors/stage1/obj/non_compile_time_array_concatenation.zig b/test/cases/compile_errors/stage1/non_compile_time_array_concatenation.zig similarity index 100% rename from test/cases/compile_errors/stage1/obj/non_compile_time_array_concatenation.zig rename to test/cases/compile_errors/stage1/non_compile_time_array_concatenation.zig diff --git a/test/cases/compile_errors/stage1/obj/mul_overflow_in_function_evaluation.zig b/test/cases/compile_errors/stage1/obj/mul_overflow_in_function_evaluation.zig deleted file mode 100644 index 8209b33f9414..000000000000 --- a/test/cases/compile_errors/stage1/obj/mul_overflow_in_function_evaluation.zig +++ /dev/null @@ -1,12 +0,0 @@ -const y = mul(300, 6000); -fn mul(a: u16, b: u16) u16 { - return a * b; -} - -export fn entry() usize { return @sizeOf(@TypeOf(y)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:14: error: operation caused overflow diff --git a/test/cases/compile_errors/stage1/obj/negation_overflow_in_function_evaluation.zig b/test/cases/compile_errors/stage1/obj/negation_overflow_in_function_evaluation.zig deleted file mode 100644 index f83e0de6ae33..000000000000 --- a/test/cases/compile_errors/stage1/obj/negation_overflow_in_function_evaluation.zig +++ /dev/null @@ -1,12 +0,0 @@ -const y = neg(-128); -fn neg(x: i8) i8 { - return -x; -} - -export fn entry() usize { return @sizeOf(@TypeOf(y)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:12: error: negation caused overflow diff --git a/test/cases/compile_errors/stage1/obj/non-const_variables_of_things_that_require_const_variables.zig b/test/cases/compile_errors/stage1/obj/non-const_variables_of_things_that_require_const_variables.zig deleted file mode 100644 index 73ef29aa5472..000000000000 --- a/test/cases/compile_errors/stage1/obj/non-const_variables_of_things_that_require_const_variables.zig +++ /dev/null @@ -1,51 +0,0 @@ -export fn entry1() void { - var m2 = &2; - _ = m2; -} -export fn entry2() void { - var a = undefined; - _ = a; -} -export fn entry3() void { - var b = 1; - _ = b; -} -export fn entry4() void { - var c = 1.0; - _ = c; -} -export fn entry5() void { - var d = null; - _ = d; -} -export fn entry6(opaque_: *Opaque) void { - var e = opaque_.*; - _ = e; -} -export fn entry7() void { - var f = i32; - _ = f; -} -export fn entry8() void { - var h = (Foo {}).bar; - _ = h; -} -const Opaque = opaque {}; -const Foo = struct { - fn bar(self: *const Foo) void {_ = self;} -}; - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:4: error: variable of type '*const comptime_int' must be const or comptime -// tmp.zig:6:4: error: variable of type '@Type(.Undefined)' must be const or comptime -// tmp.zig:10:4: error: variable of type 'comptime_int' must be const or comptime -// tmp.zig:10:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type -// tmp.zig:14:4: error: variable of type 'comptime_float' must be const or comptime -// tmp.zig:14:4: note: to modify this variable at runtime, it must be given an explicit fixed-size number type -// tmp.zig:18:4: error: variable of type '@Type(.Null)' must be const or comptime -// tmp.zig:22:4: error: variable of type 'Opaque' not allowed -// tmp.zig:26:4: error: variable of type 'type' must be const or comptime -// tmp.zig:30:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime diff --git a/test/cases/compile_errors/stage1/obj/non-inline_for_loop_on_a_type_that_requires_comptime.zig b/test/cases/compile_errors/stage1/obj/non-inline_for_loop_on_a_type_that_requires_comptime.zig deleted file mode 100644 index d2b4e28ea6d2..000000000000 --- a/test/cases/compile_errors/stage1/obj/non-inline_for_loop_on_a_type_that_requires_comptime.zig +++ /dev/null @@ -1,14 +0,0 @@ -const Foo = struct { - name: []const u8, - T: type, -}; -export fn entry() void { - const xx: [2]Foo = undefined; - for (xx) |f| { _ = f;} -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:7:5: error: values of type 'Foo' must be comptime known, but index value is runtime known diff --git a/test/cases/compile_errors/stage1/obj/non_constant_expression_in_array_size.zig b/test/cases/compile_errors/stage1/obj/non_constant_expression_in_array_size.zig deleted file mode 100644 index a0cb8e8ce15c..000000000000 --- a/test/cases/compile_errors/stage1/obj/non_constant_expression_in_array_size.zig +++ /dev/null @@ -1,14 +0,0 @@ -const Foo = struct { - y: [get()]u8, -}; -var global_var: usize = 1; -fn get() usize { return global_var; } - -export fn entry() usize { return @sizeOf(@TypeOf(Foo)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:5:25: error: cannot store runtime value in compile time variable -// tmp.zig:2:12: note: called from here diff --git a/test/cases/compile_errors/stage1/obj/non_error_sets_used_in_merge_error_sets_operator.zig b/test/cases/compile_errors/stage1/obj/non_error_sets_used_in_merge_error_sets_operator.zig deleted file mode 100644 index fc3431820c52..000000000000 --- a/test/cases/compile_errors/stage1/obj/non_error_sets_used_in_merge_error_sets_operator.zig +++ /dev/null @@ -1,17 +0,0 @@ -export fn foo() void { - const Errors = u8 || u16; - _ = Errors; -} -export fn bar() void { - const Errors = error{} || u16; - _ = Errors; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:20: error: expected error set type, found type 'u8' -// tmp.zig:2:23: note: `||` merges error sets; `or` performs boolean OR -// tmp.zig:6:31: error: expected error set type, found type 'u16' -// tmp.zig:6:28: note: `||` merges error sets; `or` performs boolean OR diff --git a/test/cases/compile_errors/stage1/obj/range_operator_in_switch_used_on_error_set.zig b/test/cases/compile_errors/stage1/obj/range_operator_in_switch_used_on_error_set.zig deleted file mode 100644 index 8108f4297926..000000000000 --- a/test/cases/compile_errors/stage1/obj/range_operator_in_switch_used_on_error_set.zig +++ /dev/null @@ -1,19 +0,0 @@ -export fn entry() void { - try foo(452) catch |err| switch (err) { - error.A ... error.B => {}, - else => {}, - }; -} -fn foo(x: i32) !void { - switch (x) { - 0 ... 10 => return error.Foo, - 11 ... 20 => return error.Bar, - else => {}, - } -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:17: error: operator not allowed for errors diff --git a/test/cases/compile_errors/stage1/obj/runtime_index_into_comptime_type_slice.zig b/test/cases/compile_errors/stage1/obj/runtime_index_into_comptime_type_slice.zig deleted file mode 100644 index 379767c7f368..000000000000 --- a/test/cases/compile_errors/stage1/obj/runtime_index_into_comptime_type_slice.zig +++ /dev/null @@ -1,17 +0,0 @@ -const Struct = struct { - a: u32, -}; -fn getIndex() usize { - return 2; -} -export fn entry() void { - const index = getIndex(); - const field = @typeInfo(Struct).Struct.fields[index]; - _ = field; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:9:51: error: values of type 'std.builtin.Type.StructField' must be comptime known, but index value is runtime known diff --git a/test/cases/compile_errors/stage1/obj/setAlignStack_in_inline_function.zig b/test/cases/compile_errors/stage1/obj/setAlignStack_in_inline_function.zig deleted file mode 100644 index 8490298aa37c..000000000000 --- a/test/cases/compile_errors/stage1/obj/setAlignStack_in_inline_function.zig +++ /dev/null @@ -1,12 +0,0 @@ -export fn entry() void { - foo(); -} -fn foo() callconv(.Inline) void { - @setAlignStack(16); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:5:5: error: @setAlignStack in inline function diff --git a/test/cases/compile_errors/stage1/obj/signed_integer_remainder_division.zig b/test/cases/compile_errors/stage1/obj/signed_integer_remainder_division.zig deleted file mode 100644 index 587767295438..000000000000 --- a/test/cases/compile_errors/stage1/obj/signed_integer_remainder_division.zig +++ /dev/null @@ -1,9 +0,0 @@ -export fn foo(a: i32, b: i32) i32 { - return a % b; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod diff --git a/test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type.zig b/test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type.zig deleted file mode 100644 index 7ad29b1900b9..000000000000 --- a/test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type.zig +++ /dev/null @@ -1,10 +0,0 @@ -export fn entry() void { - const x = []u8{}; - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8' diff --git a/test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type_with_elems.zig b/test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type_with_elems.zig deleted file mode 100644 index 0da4b3fc9de8..000000000000 --- a/test/cases/compile_errors/stage1/obj/slice_passed_as_array_init_type_with_elems.zig +++ /dev/null @@ -1,10 +0,0 @@ -export fn entry() void { - const x = []u8{1, 2}; - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:15: error: array literal requires address-of operator (&) to coerce to slice type '[]u8' diff --git a/test/cases/compile_errors/stage1/obj/sub_overflow_in_function_evaluation.zig b/test/cases/compile_errors/stage1/obj/sub_overflow_in_function_evaluation.zig deleted file mode 100644 index dc259e6dcfca..000000000000 --- a/test/cases/compile_errors/stage1/obj/sub_overflow_in_function_evaluation.zig +++ /dev/null @@ -1,12 +0,0 @@ -const y = sub(10, 20); -fn sub(a: u16, b: u16) u16 { - return a - b; -} - -export fn entry() usize { return @sizeOf(@TypeOf(y)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:14: error: operation caused overflow diff --git a/test/cases/compile_errors/stage1/obj/switch_expression-switch_on_pointer_type_with_no_else.zig b/test/cases/compile_errors/stage1/obj/switch_expression-switch_on_pointer_type_with_no_else.zig deleted file mode 100644 index 6a357beabed5..000000000000 --- a/test/cases/compile_errors/stage1/obj/switch_expression-switch_on_pointer_type_with_no_else.zig +++ /dev/null @@ -1,13 +0,0 @@ -fn foo(x: *u8) void { - switch (x) { - &y => {}, - } -} -const y: u8 = 100; -export fn entry() usize { return @sizeOf(@TypeOf(foo)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:5: error: else prong required when switching on type '*u8' diff --git a/test/cases/compile_errors/stage1/obj/switch_expression-unreachable_else_prong_bool.zig b/test/cases/compile_errors/stage1/obj/switch_expression-unreachable_else_prong_bool.zig deleted file mode 100644 index 2ee39f153187..000000000000 --- a/test/cases/compile_errors/stage1/obj/switch_expression-unreachable_else_prong_bool.zig +++ /dev/null @@ -1,14 +0,0 @@ -fn foo(x: bool) void { - switch (x) { - true => {}, - false => {}, - else => {}, - } -} -export fn entry() usize { return @sizeOf(@TypeOf(foo)); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:5:9: error: unreachable else prong, all cases already handled diff --git a/test/cases/compile_errors/stage1/obj/type_variables_must_be_constant.zig b/test/cases/compile_errors/stage1/obj/type_variables_must_be_constant.zig deleted file mode 100644 index 8273e24b99e7..000000000000 --- a/test/cases/compile_errors/stage1/obj/type_variables_must_be_constant.zig +++ /dev/null @@ -1,10 +0,0 @@ -var foo = u8; -export fn entry() foo { - return 1; -} - -// error -// backend=stage1 -// target=native -// -// :1:1: error: variable of type 'type' must be constant diff --git a/test/cases/compile_errors/stage1/obj/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig b/test/cases/compile_errors/stage1/obj/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig deleted file mode 100644 index 6eda076f1228..000000000000 --- a/test/cases/compile_errors/stage1/obj/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig +++ /dev/null @@ -1,10 +0,0 @@ -export fn foo() void { - _ = @wasmMemoryGrow(0, 1); - return; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:9: error: @wasmMemoryGrow is a wasm32 feature only diff --git a/test/cases/compile_errors/stage1/obj/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig b/test/cases/compile_errors/stage1/obj/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig deleted file mode 100644 index 9bdf81073f75..000000000000 --- a/test/cases/compile_errors/stage1/obj/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig +++ /dev/null @@ -1,10 +0,0 @@ -export fn foo() void { - _ = @wasmMemorySize(0); - return; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:9: error: @wasmMemorySize is a wasm32 feature only diff --git a/test/cases/compile_errors/stage1/obj/wrong_type_for_reify_type.zig b/test/cases/compile_errors/stage1/obj/wrong_type_for_reify_type.zig deleted file mode 100644 index b0c1d92659d8..000000000000 --- a/test/cases/compile_errors/stage1/obj/wrong_type_for_reify_type.zig +++ /dev/null @@ -1,9 +0,0 @@ -export fn entry() void { - _ = @Type(0); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:15: error: expected type 'std.builtin.Type', found 'comptime_int' diff --git a/test/cases/compile_errors/stage1/obj/ptrCast_a_0_bit_type_to_a_non-_0_bit_type.zig b/test/cases/compile_errors/stage1/ptrCast_a_0_bit_type_to_a_non-_0_bit_type.zig similarity index 100% rename from test/cases/compile_errors/stage1/obj/ptrCast_a_0_bit_type_to_a_non-_0_bit_type.zig rename to test/cases/compile_errors/stage1/ptrCast_a_0_bit_type_to_a_non-_0_bit_type.zig diff --git a/test/cases/compile_errors/stage1/obj/ptrToInt_on_void.zig b/test/cases/compile_errors/stage1/ptrToInt_on_void.zig similarity index 100% rename from test/cases/compile_errors/stage1/obj/ptrToInt_on_void.zig rename to test/cases/compile_errors/stage1/ptrToInt_on_void.zig diff --git a/test/cases/compile_errors/stage1/obj/recursive_inferred_error_set.zig b/test/cases/compile_errors/stage1/recursive_inferred_error_set.zig similarity index 100% rename from test/cases/compile_errors/stage1/obj/recursive_inferred_error_set.zig rename to test/cases/compile_errors/stage1/recursive_inferred_error_set.zig diff --git a/test/cases/compile_errors/stage1/obj/slicing_of_global_undefined_pointer.zig b/test/cases/compile_errors/stage1/slicing_of_global_undefined_pointer.zig similarity index 100% rename from test/cases/compile_errors/stage1/obj/slicing_of_global_undefined_pointer.zig rename to test/cases/compile_errors/stage1/slicing_of_global_undefined_pointer.zig diff --git a/test/cases/compile_errors/stage1/obj/switch_with_invalid_expression_parameter.zig b/test/cases/compile_errors/stage1/switch_with_invalid_expression_parameter.zig similarity index 100% rename from test/cases/compile_errors/stage1/obj/switch_with_invalid_expression_parameter.zig rename to test/cases/compile_errors/stage1/switch_with_invalid_expression_parameter.zig diff --git a/test/cases/compile_errors/stage1/obj/use_of_comptime-known_undefined_function_value.zig b/test/cases/compile_errors/stage1/use_of_comptime-known_undefined_function_value.zig similarity index 100% rename from test/cases/compile_errors/stage1/obj/use_of_comptime-known_undefined_function_value.zig rename to test/cases/compile_errors/stage1/use_of_comptime-known_undefined_function_value.zig diff --git a/test/cases/compile_errors/stage2/out_of_bounds_index.zig b/test/cases/compile_errors/stage2/out_of_bounds_index.zig index ea9bc6521d13..3f5b71d530fd 100644 --- a/test/cases/compile_errors/stage2/out_of_bounds_index.zig +++ b/test/cases/compile_errors/stage2/out_of_bounds_index.zig @@ -23,7 +23,7 @@ comptime { // error // target=native // -// :4:26: error: end index 6 out of bounds for slice of length 4 +1 (sentinel) -// :9:22: error: end index 6 out of bounds for array of length 4 +1 (sentinel) -// :14:22: error: end index 5 out of bounds for array of length 4 -// :19:22: error: start index 3 is larger than end index 2 +// :4:30: error: end index 6 out of bounds for slice of length 4 +1 (sentinel) +// :9:26: error: end index 6 out of bounds for array of length 4 +1 (sentinel) +// :14:26: error: end index 5 out of bounds for array of length 4 +// :19:23: error: start index 3 is larger than end index 2 diff --git a/test/cases/compile_errors/sub_overflow_in_function_evaluation.zig b/test/cases/compile_errors/sub_overflow_in_function_evaluation.zig new file mode 100644 index 000000000000..c87f99837309 --- /dev/null +++ b/test/cases/compile_errors/sub_overflow_in_function_evaluation.zig @@ -0,0 +1,13 @@ +const y = sub(10, 20); +fn sub(a: u16, b: u16) u16 { + return a - b; +} + +export fn entry() usize { return @sizeOf(@TypeOf(&y)); } + +// error +// backend=stage2 +// target=native +// +// :3:14: error: overflow of integer type 'u16' with value '-10' +// :1:14: note: called from here diff --git a/test/cases/compile_errors/stage1/obj/switch_expression-duplicate_or_overlapping_integer_value.zig b/test/cases/compile_errors/switch_expression-duplicate_or_overlapping_integer_value.zig similarity index 54% rename from test/cases/compile_errors/stage1/obj/switch_expression-duplicate_or_overlapping_integer_value.zig rename to test/cases/compile_errors/switch_expression-duplicate_or_overlapping_integer_value.zig index 2810bc13e1ee..60e361a47afe 100644 --- a/test/cases/compile_errors/stage1/obj/switch_expression-duplicate_or_overlapping_integer_value.zig +++ b/test/cases/compile_errors/switch_expression-duplicate_or_overlapping_integer_value.zig @@ -6,11 +6,11 @@ fn foo(x: u8) u8 { 206 ... 255 => 3, }; } -export fn entry() usize { return @sizeOf(@TypeOf(foo)); } +export fn entry() usize { return @sizeOf(@TypeOf(&foo)); } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:6:9: error: duplicate switch value -// tmp.zig:5:14: note: previous value here +// :6:13: error: duplicate switch value +// :5:18: note: previous value here diff --git a/test/cases/compile_errors/switch_expression-switch_on_pointer_type_with_no_else.zig b/test/cases/compile_errors/switch_expression-switch_on_pointer_type_with_no_else.zig new file mode 100644 index 000000000000..bbad58c74c84 --- /dev/null +++ b/test/cases/compile_errors/switch_expression-switch_on_pointer_type_with_no_else.zig @@ -0,0 +1,13 @@ +fn foo(x: *u8) void { + switch (x) { + &y => {}, + } +} +var y: u8 = 100; +export fn entry() usize { return @sizeOf(@TypeOf(&foo)); } + +// error +// backend=stage2 +// target=native +// +// :2:5: error: else prong required when switching on type '*u8' diff --git a/test/cases/compile_errors/switch_expression-unreachable_else_prong_bool.zig b/test/cases/compile_errors/switch_expression-unreachable_else_prong_bool.zig new file mode 100644 index 000000000000..5dfc839c13f6 --- /dev/null +++ b/test/cases/compile_errors/switch_expression-unreachable_else_prong_bool.zig @@ -0,0 +1,14 @@ +fn foo(x: bool) void { + switch (x) { + true => {}, + false => {}, + else => {}, + } +} +export fn entry() usize { return @sizeOf(@TypeOf(&foo)); } + +// error +// backend=stage2 +// target=native +// +// :5:14: error: unreachable else prong; all cases already handled diff --git a/test/cases/compile_errors/stage1/obj/switch_on_union_with_no_attached_enum.zig b/test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig similarity index 64% rename from test/cases/compile_errors/stage1/obj/switch_on_union_with_no_attached_enum.zig rename to test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig index 684861a898d7..4d8742d32e1a 100644 --- a/test/cases/compile_errors/stage1/obj/switch_on_union_with_no_attached_enum.zig +++ b/test/cases/compile_errors/switch_on_union_with_no_attached_enum.zig @@ -5,7 +5,7 @@ const Payload = union { }; export fn entry() void { const a = Payload { .A = 1234 }; - foo(a); + foo(&a); } fn foo(a: *const Payload) void { switch (a.*) { @@ -15,8 +15,8 @@ fn foo(a: *const Payload) void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:11:14: error: switch on union which has no attached enum -// tmp.zig:1:17: note: consider 'union(enum)' here +// :11:14: error: switch on union with no attached enum +// :1:17: note: consider 'union(enum)' here diff --git a/test/cases/compile_errors/stage1/obj/switch_with_overlapping_case_ranges.zig b/test/cases/compile_errors/switch_with_overlapping_case_ranges.zig similarity index 60% rename from test/cases/compile_errors/stage1/obj/switch_with_overlapping_case_ranges.zig rename to test/cases/compile_errors/switch_with_overlapping_case_ranges.zig index 1b03d3fe5407..46dc08be62da 100644 --- a/test/cases/compile_errors/stage1/obj/switch_with_overlapping_case_ranges.zig +++ b/test/cases/compile_errors/switch_with_overlapping_case_ranges.zig @@ -7,7 +7,8 @@ export fn entry() void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:5:9: error: duplicate switch value +// :5:10: error: duplicate switch value +// :4:10: note: previous value here diff --git a/test/cases/compile_errors/stage1/obj/tagName_used_on_union_with_no_associated_enum_tag.zig b/test/cases/compile_errors/tagName_used_on_union_with_no_associated_enum_tag.zig similarity index 66% rename from test/cases/compile_errors/stage1/obj/tagName_used_on_union_with_no_associated_enum_tag.zig rename to test/cases/compile_errors/tagName_used_on_union_with_no_associated_enum_tag.zig index efd9b8ceefc9..cbe0f642a5fb 100644 --- a/test/cases/compile_errors/stage1/obj/tagName_used_on_union_with_no_associated_enum_tag.zig +++ b/test/cases/compile_errors/tagName_used_on_union_with_no_associated_enum_tag.zig @@ -9,8 +9,8 @@ export fn entry() void { } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:7:19: error: union has no associated enum -// tmp.zig:1:18: note: declared here +// :7:19: error: union 'tmp.FloatInt' is untagged +// :1:25: note: union declared here diff --git a/test/cases/compile_errors/type_variables_must_be_constant.zig b/test/cases/compile_errors/type_variables_must_be_constant.zig new file mode 100644 index 000000000000..35e94f36412c --- /dev/null +++ b/test/cases/compile_errors/type_variables_must_be_constant.zig @@ -0,0 +1,11 @@ +var foo = u8; +export fn entry() foo { + return 1; +} + +// error +// backend=stage2 +// target=native +// +// :1:1: error: variable of type 'type' must be const or comptime +// :1:1: note: types are not available at runtime diff --git a/test/cases/compile_errors/stage1/obj/unreachable_executed_at_comptime.zig b/test/cases/compile_errors/unreachable_executed_at_comptime.zig similarity index 56% rename from test/cases/compile_errors/stage1/obj/unreachable_executed_at_comptime.zig rename to test/cases/compile_errors/unreachable_executed_at_comptime.zig index 34cb354e9416..5131a3362dbb 100644 --- a/test/cases/compile_errors/stage1/obj/unreachable_executed_at_comptime.zig +++ b/test/cases/compile_errors/unreachable_executed_at_comptime.zig @@ -5,12 +5,12 @@ fn foo(comptime x: i32) i32 { } } export fn entry() void { - _ = foo(-42); + _ = comptime foo(-42); } // error -// backend=stage1 +// backend=stage2 // target=native // -// tmp.zig:4:9: error: reached unreachable code -// tmp.zig:8:12: note: called from here +// :4:9: error: reached unreachable code +// :8:21: note: called from here diff --git a/test/cases/compile_errors/unreachable_variable.zig b/test/cases/compile_errors/unreachable_variable.zig index fac4b72196f6..6a7927ee4ee6 100644 --- a/test/cases/compile_errors/unreachable_variable.zig +++ b/test/cases/compile_errors/unreachable_variable.zig @@ -7,4 +7,4 @@ export fn f() void { // backend=stage2 // target=native // -// :2:25: error: expected type 'noreturn', found 'void' +// :2:25: error: cannot cast to noreturn diff --git a/test/cases/compile_errors/use_invalid_number_literal_as_array_index.zig b/test/cases/compile_errors/use_invalid_number_literal_as_array_index.zig index 6fab70abf8cc..120ba5c5886d 100644 --- a/test/cases/compile_errors/use_invalid_number_literal_as_array_index.zig +++ b/test/cases/compile_errors/use_invalid_number_literal_as_array_index.zig @@ -9,3 +9,4 @@ export fn entry() void { // target=native // // :1:1: error: variable of type 'comptime_int' must be const or comptime +// :1:1: note: to modify this variable at runtime, it must be given an explicit fixed-size number type diff --git a/test/cases/compile_errors/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig b/test/cases/compile_errors/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig new file mode 100644 index 000000000000..fb25e71542ee --- /dev/null +++ b/test/cases/compile_errors/wasmMemoryGrow_is_a_compile_error_in_non-Wasm_targets.zig @@ -0,0 +1,10 @@ +export fn foo() void { + _ = @wasmMemoryGrow(0, 1); + return; +} + +// error +// backend=stage2 +// target=x86_64-native +// +// :2:9: error: builtin @wasmMemoryGrow is available when targeting WebAssembly; targeted CPU architecture is x86_64 diff --git a/test/cases/compile_errors/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig b/test/cases/compile_errors/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig new file mode 100644 index 000000000000..df72e6f41b4c --- /dev/null +++ b/test/cases/compile_errors/wasmMemorySize_is_a_compile_error_in_non-Wasm_targets.zig @@ -0,0 +1,10 @@ +export fn foo() void { + _ = @wasmMemorySize(0); + return; +} + +// error +// backend=stage2 +// target=x86_64-native +// +// :2:9: error: builtin @wasmMemorySize is available when targeting WebAssembly; targeted CPU architecture is x86_64 diff --git a/test/cases/compile_errors/wrong_type_for_reify_type.zig b/test/cases/compile_errors/wrong_type_for_reify_type.zig new file mode 100644 index 000000000000..7f712b441f7b --- /dev/null +++ b/test/cases/compile_errors/wrong_type_for_reify_type.zig @@ -0,0 +1,9 @@ +export fn entry() void { + _ = @Type(0); +} + +// error +// backend=stage2 +// target=native +// +// :2:15: error: expected type 'builtin.Type', found 'comptime_int'