mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 21:38:33 +00:00
Merge remote-tracking branch 'origin/master' into llvm14
This commit is contained in:
commit
8e07b0c4b9
@ -156,11 +156,11 @@ pub fn defaultLog(
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
if (builtin.os.tag == .freestanding) {
|
||||
// On freestanding one must provide a log function; we do not have
|
||||
// any I/O configured.
|
||||
return;
|
||||
}
|
||||
if (builtin.os.tag == .freestanding)
|
||||
@compileError(
|
||||
\\freestanding targets do not have I/O configured;
|
||||
\\please provide at least an empty `log` function declaration
|
||||
);
|
||||
|
||||
const level_txt = comptime message_level.asText();
|
||||
const prefix2 = if (scope == .default) ": " else "(" ++ @tagName(scope) ++ "): ";
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -4997,10 +5008,14 @@ fn orelseCatchExpr(
|
||||
var err_val_scope: Scope.LocalVal = undefined;
|
||||
const else_sub_scope = blk: {
|
||||
const payload = payload_token orelse break :blk &else_scope.base;
|
||||
if (mem.eql(u8, tree.tokenSlice(payload), "_")) {
|
||||
const err_str = tree.tokenSlice(payload);
|
||||
if (mem.eql(u8, err_str, "_")) {
|
||||
return astgen.failTok(payload, "discard of error capture; omit it instead", .{});
|
||||
}
|
||||
const err_name = try astgen.identAsString(payload);
|
||||
|
||||
try astgen.detectLocalShadowing(scope, err_name, payload, err_str);
|
||||
|
||||
err_val_scope = .{
|
||||
.parent = &else_scope.base,
|
||||
.gen_zir = &else_scope,
|
||||
@ -7355,15 +7370,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 +7409,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 +7664,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]),
|
||||
|
||||
@ -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,
|
||||
|
||||
304
src/Sema.zig
304
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.
|
||||
|
||||
@ -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]"),
|
||||
};
|
||||
}
|
||||
|
||||
43
src/Zir.zig
43
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,
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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 => {
|
||||
|
||||
@ -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'
|
||||
@ -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'
|
||||
|
||||
@ -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'
|
||||
@ -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'
|
||||
@ -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'
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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'
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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'
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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'
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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)'
|
||||
@ -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.
|
||||
@ -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'
|
||||
@ -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'
|
||||
14
test/cases/compile_errors/src_fields_runtime.zig
Normal file
14
test/cases/compile_errors/src_fields_runtime.zig
Normal file
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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'
|
||||
@ -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'
|
||||
@ -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
|
||||
@ -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'
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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'
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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'
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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
|
||||
9
test/cases/compile_errors/wrong_type_for_reify_type.zig
Normal file
9
test/cases/compile_errors/wrong_type_for_reify_type.zig
Normal file
@ -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'
|
||||
9
test/cases/variable_shadowing.10.zig
Normal file
9
test/cases/variable_shadowing.10.zig
Normal file
@ -0,0 +1,9 @@
|
||||
fn foo() !void {
|
||||
var i: anyerror!usize = 1;
|
||||
_ = i catch |i| return i;
|
||||
}
|
||||
|
||||
// error
|
||||
//
|
||||
// :3:18: error: redeclaration of local variable 'i'
|
||||
// :2:9: note: previous declaration here
|
||||
@ -1,5 +1,17 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn log(
|
||||
comptime message_level: std.log.Level,
|
||||
comptime scope: @Type(.EnumLiteral),
|
||||
comptime format: []const u8,
|
||||
args: anytype,
|
||||
) void {
|
||||
_ = message_level;
|
||||
_ = scope;
|
||||
_ = format;
|
||||
_ = args;
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
std.log.info("All your codebase are belong to us.", .{});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user