mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Merge pull request #11973 from Vexu/stage2-compile-errors
more stage2 compile error fixes
This commit is contained in:
commit
7e2eb1326b
@ -82,7 +82,7 @@ fn memset(dest: ?[*]u8, c: u8, len: usize) callconv(.C) ?[*]u8 {
|
||||
var d = dest.?;
|
||||
var n = len;
|
||||
while (true) {
|
||||
d.* = c;
|
||||
d[0] = c;
|
||||
n -= 1;
|
||||
if (n == 0) break;
|
||||
d += 1;
|
||||
|
||||
@ -1868,7 +1868,7 @@ pub fn getenv(key: []const u8) ?[]const u8 {
|
||||
}
|
||||
// Search the entire `environ` because we don't have a null terminated pointer.
|
||||
var ptr = std.c.environ;
|
||||
while (ptr.*) |line| : (ptr += 1) {
|
||||
while (ptr[0]) |line| : (ptr += 1) {
|
||||
var line_i: usize = 0;
|
||||
while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
|
||||
const this_key = line[0..line_i];
|
||||
|
||||
@ -313,7 +313,7 @@ pub fn getEnvMap(allocator: Allocator) !EnvMap {
|
||||
return result;
|
||||
} else if (builtin.link_libc) {
|
||||
var ptr = std.c.environ;
|
||||
while (ptr.*) |line| : (ptr += 1) {
|
||||
while (ptr[0]) |line| : (ptr += 1) {
|
||||
var line_i: usize = 0;
|
||||
while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
|
||||
const key = line[0..line_i];
|
||||
|
||||
@ -812,6 +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]);
|
||||
switch (rl) {
|
||||
.ref => return lhs,
|
||||
else => {
|
||||
@ -2500,6 +2501,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
|
||||
.memset,
|
||||
.validate_array_init_ty,
|
||||
.validate_struct_init_ty,
|
||||
.validate_deref,
|
||||
=> break :b true,
|
||||
}
|
||||
} else switch (maybe_unused_result) {
|
||||
@ -5152,16 +5154,14 @@ fn arrayAccess(
|
||||
const tree = astgen.tree;
|
||||
const node_datas = tree.nodes.items(.data);
|
||||
switch (rl) {
|
||||
.ref => return gz.addBin(
|
||||
.elem_ptr,
|
||||
try expr(gz, scope, .ref, node_datas[node].lhs),
|
||||
try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs),
|
||||
),
|
||||
else => return rvalue(gz, rl, try gz.addBin(
|
||||
.elem_val,
|
||||
try expr(gz, scope, .none, node_datas[node].lhs),
|
||||
try expr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs),
|
||||
), node),
|
||||
.ref => return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{
|
||||
.lhs = try expr(gz, scope, .ref, node_datas[node].lhs),
|
||||
.rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs),
|
||||
}),
|
||||
else => return rvalue(gz, rl, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{
|
||||
.lhs = try expr(gz, scope, .none, node_datas[node].lhs),
|
||||
.rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs),
|
||||
}), node),
|
||||
}
|
||||
}
|
||||
|
||||
@ -5683,7 +5683,7 @@ fn whileExpr(
|
||||
try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst);
|
||||
}
|
||||
if (while_full.ast.cont_expr != 0) {
|
||||
_ = try expr(&loop_scope, then_sub_scope, .{ .ty = .void_type }, while_full.ast.cont_expr);
|
||||
_ = try unusedResultExpr(&loop_scope, then_sub_scope, while_full.ast.cont_expr);
|
||||
}
|
||||
try then_scope.addDbgBlockEnd();
|
||||
const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat;
|
||||
@ -5888,7 +5888,10 @@ fn forExpr(
|
||||
if (!mem.eql(u8, value_name, "_")) {
|
||||
const name_str_index = try astgen.identAsString(ident);
|
||||
const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val;
|
||||
const payload_inst = try then_scope.addBin(tag, array_ptr, index);
|
||||
const payload_inst = try then_scope.addPlNode(tag, for_full.ast.cond_expr, Zir.Inst.Bin{
|
||||
.lhs = array_ptr,
|
||||
.rhs = index,
|
||||
});
|
||||
try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name);
|
||||
payload_val_scope = .{
|
||||
.parent = &then_scope.base,
|
||||
|
||||
186
src/Sema.zig
186
src/Sema.zig
@ -1080,6 +1080,11 @@ fn analyzeBodyInner(
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.validate_deref => {
|
||||
try sema.zirValidateDeref(block, inst);
|
||||
i += 1;
|
||||
continue;
|
||||
},
|
||||
.@"export" => {
|
||||
try sema.zirExport(block, inst);
|
||||
i += 1;
|
||||
@ -2434,9 +2439,9 @@ fn zirEnumDecl(
|
||||
const field_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, field_i);
|
||||
const other_tag_src = enumFieldSrcLoc(sema.mod.declPtr(block.src_decl), tree.*, src.node_offset.x, gop.index);
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, field_src, "duplicate enum tag", .{});
|
||||
const msg = try sema.errMsg(block, field_src, "duplicate enum field '{s}'", .{field_name});
|
||||
errdefer msg.destroy(gpa);
|
||||
try sema.errNote(block, other_tag_src, msg, "other tag here", .{});
|
||||
try sema.errNote(block, other_tag_src, msg, "other field here", .{});
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
@ -2733,6 +2738,7 @@ fn ensureResultUsed(
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
switch (operand_ty.zigTypeTag()) {
|
||||
.Void, .NoReturn => return,
|
||||
.ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is ignored. consider using `try`, `catch`, or `if`", .{}),
|
||||
else => return sema.fail(block, src, "expression value is ignored", .{}),
|
||||
}
|
||||
}
|
||||
@ -2746,7 +2752,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
|
||||
const src = inst_data.src();
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
switch (operand_ty.zigTypeTag()) {
|
||||
.ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded", .{}),
|
||||
.ErrorSet, .ErrorUnion => return sema.fail(block, src, "error is discarded. consider using `try`, `catch`, or `if`", .{}),
|
||||
else => return,
|
||||
}
|
||||
}
|
||||
@ -3849,6 +3855,28 @@ 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 src = inst_data.src();
|
||||
const operand_src: LazySrcLoc = .{ .token_offset = inst_data.src_tok + 1 };
|
||||
const operand = try sema.resolveInst(inst_data.operand);
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
|
||||
if (operand_ty.zigTypeTag() != .Pointer) {
|
||||
return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(sema.mod)});
|
||||
} else switch (operand_ty.ptrSize()) {
|
||||
.One, .C => {},
|
||||
.Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(sema.mod)}),
|
||||
.Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}),
|
||||
}
|
||||
|
||||
if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |val| {
|
||||
if (val.isUndef()) {
|
||||
return sema.fail(block, src, "cannot dereference undefined value", .{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn failWithBadMemberAccess(
|
||||
sema: *Sema,
|
||||
block: *Block,
|
||||
@ -4272,7 +4300,8 @@ fn zirCompileLog(
|
||||
}
|
||||
try writer.print("\n", .{});
|
||||
|
||||
const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, sema.owner_decl_index);
|
||||
const decl_index = if (sema.func) |some| some.owner_decl else sema.owner_decl_index;
|
||||
const gop = try sema.mod.compile_log_decls.getOrPut(sema.gpa, decl_index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = src_node;
|
||||
}
|
||||
@ -6416,6 +6445,7 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
if (dest_ty.zigTypeTag() != .Enum) {
|
||||
return sema.fail(block, dest_ty_src, "expected enum, found '{}'", .{dest_ty.fmt(sema.mod)});
|
||||
}
|
||||
_ = try sema.checkIntType(block, operand_src, sema.typeOf(operand));
|
||||
|
||||
if (try sema.resolveMaybeUndefVal(block, operand_src, operand)) |int_val| {
|
||||
if (dest_ty.isNonexhaustiveEnum()) {
|
||||
@ -7007,6 +7037,7 @@ fn funcCommon(
|
||||
noalias_bits: u32,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = src_node_offset };
|
||||
const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = src_node_offset };
|
||||
|
||||
var is_generic = bare_return_type.tag() == .generic_poison or
|
||||
alignment == null or
|
||||
@ -7062,7 +7093,7 @@ fn funcCommon(
|
||||
const param_types = try sema.arena.alloc(Type, block.params.items.len);
|
||||
const comptime_params = try sema.arena.alloc(bool, block.params.items.len);
|
||||
for (block.params.items) |param, i| {
|
||||
const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better src
|
||||
const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location
|
||||
param_types[i] = param.ty;
|
||||
comptime_params[i] = param.is_comptime or
|
||||
try sema.typeRequiresComptime(block, param_src, param.ty);
|
||||
@ -7109,6 +7140,45 @@ fn funcCommon(
|
||||
const cc_workaround = cc orelse .Unspecified;
|
||||
const align_workaround = alignment orelse 0;
|
||||
|
||||
const arch = sema.mod.getTarget().cpu.arch;
|
||||
if (switch (cc_workaround) {
|
||||
.Unspecified, .C, .Naked, .Async, .Inline => null,
|
||||
.Interrupt => switch (arch) {
|
||||
.i386, .x86_64, .avr, .msp430 => null,
|
||||
else => @as([]const u8, "i386, x86_64, AVR, and MSP430"),
|
||||
},
|
||||
.Signal => switch (arch) {
|
||||
.avr => null,
|
||||
else => @as([]const u8, "AVR"),
|
||||
},
|
||||
.Stdcall, .Fastcall, .Thiscall => switch (arch) {
|
||||
.i386 => null,
|
||||
else => @as([]const u8, "i386"),
|
||||
},
|
||||
.Vectorcall => switch (arch) {
|
||||
.i386, .aarch64, .aarch64_be, .aarch64_32 => null,
|
||||
else => @as([]const u8, "i386 and AArch64"),
|
||||
},
|
||||
.APCS, .AAPCS, .AAPCSVFP => switch (arch) {
|
||||
.arm, .armeb, .aarch64, .aarch64_be, .aarch64_32 => null,
|
||||
else => @as([]const u8, "ARM"),
|
||||
},
|
||||
.SysV, .Win64 => switch (arch) {
|
||||
.x86_64 => null,
|
||||
else => @as([]const u8, "x86_64"),
|
||||
},
|
||||
.PtxKernel => switch (arch) {
|
||||
.nvptx, .nvptx64 => null,
|
||||
else => @as([]const u8, "nvptx and nvptx64"),
|
||||
},
|
||||
}) |allowed_platform| {
|
||||
return sema.fail(block, cc_src, "callconv '{s}' is only available on {s}, not {s}", .{
|
||||
@tagName(cc_workaround),
|
||||
allowed_platform,
|
||||
@tagName(arch),
|
||||
});
|
||||
}
|
||||
|
||||
break :fn_ty try Type.Tag.function.create(sema.arena, .{
|
||||
.param_types = param_types,
|
||||
.comptime_params = comptime_params.ptr,
|
||||
@ -7617,11 +7687,11 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
|
||||
const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
|
||||
const operand = try sema.resolveInst(extra.rhs);
|
||||
switch (dest_ty.zigTypeTag()) {
|
||||
.AnyFrame,
|
||||
.ComptimeFloat,
|
||||
.ComptimeInt,
|
||||
.Enum,
|
||||
.EnumLiteral,
|
||||
.ErrorSet,
|
||||
.ErrorUnion,
|
||||
@ -7634,7 +7704,21 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
.Type,
|
||||
.Undefined,
|
||||
.Void,
|
||||
=> return sema.fail(block, dest_ty_src, "invalid type '{}' for @bitCast", .{dest_ty.fmt(sema.mod)}),
|
||||
=> return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)}),
|
||||
|
||||
.Enum => {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, dest_ty_src, "cannot @bitCast to '{}'", .{dest_ty.fmt(sema.mod)});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
switch (sema.typeOf(operand).zigTypeTag()) {
|
||||
.Int, .ComptimeInt => try sema.errNote(block, dest_ty_src, msg, "use @intToEnum for type coercion", .{}),
|
||||
else => {},
|
||||
}
|
||||
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
},
|
||||
|
||||
.Pointer => return sema.fail(block, dest_ty_src, "cannot @bitCast to '{}', use @ptrCast to cast to a pointer", .{
|
||||
dest_ty.fmt(sema.mod),
|
||||
@ -7658,8 +7742,6 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
.Vector,
|
||||
=> {},
|
||||
}
|
||||
|
||||
const operand = try sema.resolveInst(extra.rhs);
|
||||
return sema.bitCast(block, dest_ty, operand, operand_src);
|
||||
}
|
||||
|
||||
@ -7717,12 +7799,12 @@ fn zirElemVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const bin_inst = sema.code.instructions.items(.data)[inst].bin;
|
||||
const src = sema.src; // TODO better source location
|
||||
const elem_index_src = sema.src; // TODO better source location
|
||||
const array = try sema.resolveInst(bin_inst.lhs);
|
||||
const elem_index = try sema.resolveInst(bin_inst.rhs);
|
||||
return sema.elemVal(block, src, array, elem_index, elem_index_src);
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const array = try sema.resolveInst(extra.lhs);
|
||||
const elem_index = try sema.resolveInst(extra.rhs);
|
||||
return sema.elemVal(block, src, array, elem_index, src);
|
||||
}
|
||||
|
||||
fn zirElemValNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
@ -7742,10 +7824,12 @@ fn zirElemPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const bin_inst = sema.code.instructions.items(.data)[inst].bin;
|
||||
const array_ptr = try sema.resolveInst(bin_inst.lhs);
|
||||
const elem_index = try sema.resolveInst(bin_inst.rhs);
|
||||
return sema.elemPtr(block, sema.src, array_ptr, elem_index, sema.src, false);
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const array_ptr = try sema.resolveInst(extra.lhs);
|
||||
const elem_index = try sema.resolveInst(extra.rhs);
|
||||
return sema.elemPtr(block, src, array_ptr, elem_index, src, false);
|
||||
}
|
||||
|
||||
fn zirElemPtrNode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
@ -8297,19 +8381,15 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
|
||||
block,
|
||||
src,
|
||||
msg,
|
||||
"unhandled error value: error.{s}",
|
||||
"unhandled error value: 'error.{s}'",
|
||||
.{error_name},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (maybe_msg) |msg| {
|
||||
try sema.mod.errNoteNonLazy(
|
||||
operand_ty.declSrcLoc(sema.mod),
|
||||
msg,
|
||||
"error set '{}' declared here",
|
||||
.{operand_ty.fmt(sema.mod)},
|
||||
);
|
||||
maybe_msg = null;
|
||||
try sema.addDeclaredHereNote(msg, operand_ty);
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
}
|
||||
|
||||
@ -17062,9 +17142,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
|
||||
const field_index = struct_obj.fields.getIndex(field_name) orelse
|
||||
return sema.failWithBadStructFieldAccess(block, struct_obj, name_src, field_name);
|
||||
|
||||
if (field_ptr_ty.zigTypeTag() != .Pointer) {
|
||||
return sema.fail(block, ty_src, "expected pointer type, found '{}'", .{field_ptr_ty.fmt(sema.mod)});
|
||||
}
|
||||
try sema.checkPtrOperand(block, ptr_src, field_ptr_ty);
|
||||
const field = struct_obj.fields.values()[field_index];
|
||||
const field_ptr_ty_info = field_ptr_ty.ptrInfo().data;
|
||||
|
||||
@ -17087,8 +17165,29 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
|
||||
const result_ptr = try Type.ptr(sema.arena, sema.mod, ptr_ty_data);
|
||||
|
||||
if (try sema.resolveDefinedValue(block, src, casted_field_ptr)) |field_ptr_val| {
|
||||
const payload = field_ptr_val.castTag(.field_ptr).?.data;
|
||||
return sema.addConstant(result_ptr, payload.container_ptr);
|
||||
const payload = field_ptr_val.castTag(.field_ptr) orelse {
|
||||
return sema.fail(block, ptr_src, "pointer value not based on parent struct", .{});
|
||||
};
|
||||
if (payload.data.field_index != field_index) {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(
|
||||
block,
|
||||
src,
|
||||
"field '{s}' has index '{d}' but pointer value is index '{d}' of struct '{}'",
|
||||
.{
|
||||
field_name,
|
||||
field_index,
|
||||
payload.data.field_index,
|
||||
struct_ty.fmt(sema.mod),
|
||||
},
|
||||
);
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
try sema.addDeclaredHereNote(msg, struct_ty);
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
}
|
||||
return sema.addConstant(result_ptr, payload.data.container_ptr);
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
@ -18434,7 +18533,16 @@ fn fieldVal(
|
||||
kw_name, child_type.fmt(sema.mod), field_name,
|
||||
});
|
||||
},
|
||||
else => return sema.fail(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)}),
|
||||
else => {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, src, "type '{}' has no members", .{child_type.fmt(sema.mod)});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
if (child_type.isSlice()) try sema.errNote(block, src, msg, "slice values have 'len' and 'ptr' members", .{});
|
||||
if (child_type.zigTypeTag() == .Array) try sema.errNote(block, src, msg, "array values have 'len' member", .{});
|
||||
break :msg msg;
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(block, msg);
|
||||
},
|
||||
}
|
||||
},
|
||||
.Struct => if (is_pointer_to) {
|
||||
@ -18658,7 +18766,7 @@ fn fieldPtr(
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return sema.fail(block, src, "type '{}' does not support field access (fieldPtr, {}.{s})", .{ object_ty.fmt(sema.mod), object_ptr_ty.fmt(sema.mod), field_name });
|
||||
return sema.fail(block, src, "type '{}' does not support field access", .{object_ty.fmt(sema.mod)});
|
||||
}
|
||||
|
||||
fn fieldCallBind(
|
||||
@ -19349,7 +19457,7 @@ fn tupleFieldPtr(
|
||||
const tuple_fields = tuple_ty.tupleFields();
|
||||
|
||||
if (tuple_fields.types.len == 0) {
|
||||
return sema.fail(block, field_index_src, "indexing into empty tuple", .{});
|
||||
return sema.fail(block, tuple_ptr_src, "indexing into empty tuple is not allowed", .{});
|
||||
}
|
||||
|
||||
if (field_index >= tuple_fields.types.len) {
|
||||
@ -19392,7 +19500,7 @@ fn tupleField(
|
||||
const tuple_fields = tuple_ty.tupleFields();
|
||||
|
||||
if (tuple_fields.types.len == 0) {
|
||||
return sema.fail(block, field_index_src, "indexing into empty tuple", .{});
|
||||
return sema.fail(block, tuple_src, "indexing into empty tuple is not allowed", .{});
|
||||
}
|
||||
|
||||
if (field_index >= tuple_fields.types.len) {
|
||||
@ -19433,7 +19541,7 @@ fn elemValArray(
|
||||
const elem_ty = array_ty.childType();
|
||||
|
||||
if (array_len_s == 0) {
|
||||
return sema.fail(block, elem_index_src, "indexing into empty array", .{});
|
||||
return sema.fail(block, array_src, "indexing into empty array is not allowed", .{});
|
||||
}
|
||||
|
||||
const maybe_undef_array_val = try sema.resolveMaybeUndefVal(block, array_src, array);
|
||||
@ -19513,7 +19621,7 @@ fn elemPtrArray(
|
||||
const array_len_s = array_len + @boolToInt(array_sent);
|
||||
|
||||
if (array_len_s == 0) {
|
||||
return sema.fail(block, elem_index_src, "indexing into empty array", .{});
|
||||
return sema.fail(block, array_ptr_src, "indexing into empty array is not allowed", .{});
|
||||
}
|
||||
|
||||
const maybe_undef_array_ptr_val = try sema.resolveMaybeUndefVal(block, array_ptr_src, array_ptr);
|
||||
@ -19595,7 +19703,7 @@ fn elemValSlice(
|
||||
const slice_len = slice_val.sliceLen(sema.mod);
|
||||
const slice_len_s = slice_len + @boolToInt(slice_sent);
|
||||
if (slice_len_s == 0) {
|
||||
return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
|
||||
return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
|
||||
}
|
||||
if (maybe_index_val) |index_val| {
|
||||
const index = @intCast(usize, index_val.toUnsignedInt(target));
|
||||
@ -19652,7 +19760,7 @@ fn elemPtrSlice(
|
||||
const slice_len = slice_val.sliceLen(sema.mod);
|
||||
const slice_len_s = slice_len + @boolToInt(slice_sent);
|
||||
if (slice_len_s == 0) {
|
||||
return sema.fail(block, elem_index_src, "indexing into empty slice", .{});
|
||||
return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
|
||||
}
|
||||
if (offset) |index| {
|
||||
if (index >= slice_len_s) {
|
||||
|
||||
25
src/Zir.zig
25
src/Zir.zig
@ -370,24 +370,23 @@ pub const Inst = struct {
|
||||
/// Uses the `pl_node` union field. Payload is `Bin`.
|
||||
div,
|
||||
/// Given a pointer to an array, slice, or pointer, returns a pointer to the element at
|
||||
/// the provided index. Uses the `bin` union field. Source location is implied
|
||||
/// to be the same as the previous instruction.
|
||||
elem_ptr,
|
||||
/// Same as `elem_ptr` except also stores a source location node.
|
||||
/// the provided index.
|
||||
/// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`.
|
||||
elem_ptr_node,
|
||||
/// Same as `elem_ptr_node` but used only for for loop.
|
||||
/// Uses the `pl_node` union field. AST node is the condition of a for loop. Payload is `Bin`.
|
||||
elem_ptr,
|
||||
/// Same as `elem_ptr_node` except the index is stored immediately rather than
|
||||
/// as a reference to another ZIR instruction.
|
||||
/// Uses the `pl_node` union field. AST node is an element inside array initialization
|
||||
/// syntax. Payload is `ElemPtrImm`.
|
||||
elem_ptr_imm,
|
||||
/// Given an array, slice, or pointer, returns the element at the provided index.
|
||||
/// Uses the `bin` union field. Source location is implied to be the same
|
||||
/// as the previous instruction.
|
||||
elem_val,
|
||||
/// Same as `elem_val` except also stores a source location node.
|
||||
/// Uses the `pl_node` union field. AST node is a[b] syntax. Payload is `Bin`.
|
||||
elem_val_node,
|
||||
/// Same as `elem_val_node` but used only for for loop.
|
||||
/// Uses the `pl_node` union field. AST node is the condition of a for loop. Payload is `Bin`.
|
||||
elem_val,
|
||||
/// Emits a compile error if the operand is not `void`.
|
||||
/// Uses the `un_node` field.
|
||||
ensure_result_used,
|
||||
@ -729,6 +728,9 @@ pub const Inst = struct {
|
||||
/// Same as `validate_array_init` but additionally communicates that the
|
||||
/// 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.
|
||||
validate_deref,
|
||||
/// A struct literal with a specified type, with no fields.
|
||||
/// Uses the `un_node` field.
|
||||
struct_init_empty,
|
||||
@ -1156,6 +1158,7 @@ pub const Inst = struct {
|
||||
.validate_struct_init_comptime,
|
||||
.validate_array_init,
|
||||
.validate_array_init_comptime,
|
||||
.validate_deref,
|
||||
.struct_init_empty,
|
||||
.struct_init,
|
||||
.struct_init_ref,
|
||||
@ -1309,6 +1312,7 @@ pub const Inst = struct {
|
||||
.validate_struct_init_comptime,
|
||||
.validate_array_init,
|
||||
.validate_array_init_comptime,
|
||||
.validate_deref,
|
||||
.@"export",
|
||||
.export_value,
|
||||
.set_cold,
|
||||
@ -1622,10 +1626,10 @@ pub const Inst = struct {
|
||||
.decl_val = .str_tok,
|
||||
.load = .un_node,
|
||||
.div = .pl_node,
|
||||
.elem_ptr = .bin,
|
||||
.elem_ptr = .pl_node,
|
||||
.elem_ptr_node = .pl_node,
|
||||
.elem_ptr_imm = .pl_node,
|
||||
.elem_val = .bin,
|
||||
.elem_val = .pl_node,
|
||||
.elem_val_node = .pl_node,
|
||||
.ensure_result_used = .un_node,
|
||||
.ensure_result_non_error = .un_node,
|
||||
@ -1709,6 +1713,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,
|
||||
.struct_init_empty = .un_node,
|
||||
.field_type = .pl_node,
|
||||
.field_type_ref = .pl_node,
|
||||
|
||||
@ -144,8 +144,6 @@ const Writer = struct {
|
||||
switch (tag) {
|
||||
.array_type,
|
||||
.as,
|
||||
.elem_ptr,
|
||||
.elem_val,
|
||||
.store,
|
||||
.store_to_block_ptr,
|
||||
.store_to_inferred_ptr,
|
||||
@ -242,6 +240,7 @@ const Writer = struct {
|
||||
.ret_tok,
|
||||
.ensure_err_payload_void,
|
||||
.closure_capture,
|
||||
.validate_deref,
|
||||
=> try self.writeUnTok(stream, inst),
|
||||
|
||||
.bool_br_and,
|
||||
@ -354,6 +353,8 @@ const Writer = struct {
|
||||
.minimum,
|
||||
.elem_ptr_node,
|
||||
.elem_val_node,
|
||||
.elem_ptr,
|
||||
.elem_val,
|
||||
.coerce_result_ptr,
|
||||
=> try self.writePlNodeBin(stream, inst),
|
||||
|
||||
|
||||
@ -189,7 +189,7 @@ pub const Type = extern union {
|
||||
.Frame,
|
||||
=> false,
|
||||
|
||||
.Pointer => is_equality_cmp or ty.isCPtr(),
|
||||
.Pointer => !ty.isSlice() and (is_equality_cmp or ty.isCPtr()),
|
||||
.Optional => {
|
||||
if (!is_equality_cmp) return false;
|
||||
var buf: Payload.ElemType = undefined;
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
export fn entry() void {
|
||||
'a'.* = 1;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:8: error: cannot dereference non-pointer type 'comptime_int'
|
||||
12
test/cases/compile_errors/bitCast_to_enum_type.zig
Normal file
12
test/cases/compile_errors/bitCast_to_enum_type.zig
Normal file
@ -0,0 +1,12 @@
|
||||
export fn entry() void {
|
||||
const E = enum(u32) { a, b };
|
||||
const y = @bitCast(E, @as(u32, 3));
|
||||
_ = y;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:24: error: cannot @bitCast to 'tmp.entry.E'
|
||||
// :3:24: note: use @intToEnum for type coercion
|
||||
@ -2,7 +2,7 @@ const x = @import("builtin").bogus;
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(x)); }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:1:29: error: container 'builtin' has no member called 'bogus'
|
||||
// :1:29: error: struct 'builtin.builtin' has no member named 'bogus'
|
||||
@ -0,0 +1,11 @@
|
||||
export fn entry1() callconv(.APCS) void {}
|
||||
export fn entry2() callconv(.AAPCS) void {}
|
||||
export fn entry3() callconv(.AAPCSVFP) void {}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// :1:30: error: callconv 'APCS' is only available on ARM, not x86_64
|
||||
// :2:30: error: callconv 'AAPCS' is only available on ARM, not x86_64
|
||||
// :3:30: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64
|
||||
@ -0,0 +1,7 @@
|
||||
export fn entry() callconv(.Interrupt) void {}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=aarch64-linux-none
|
||||
//
|
||||
// :1:29: error: callconv 'Interrupt' is only available on i386, x86_64, AVR, and MSP430, not aarch64
|
||||
@ -0,0 +1,7 @@
|
||||
export fn entry() callconv(.Signal) void {}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// :1:29: error: callconv 'Signal' is only available on AVR, not x86_64
|
||||
@ -15,9 +15,9 @@ export fn entry3() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// tmp.zig:1:27: error: callconv 'Stdcall' is only available on x86, not x86_64
|
||||
// tmp.zig:2:27: error: callconv 'Fastcall' is only available on x86, not x86_64
|
||||
// tmp.zig:3:27: error: callconv 'Thiscall' is only available on x86, not x86_64
|
||||
// :1:28: error: callconv 'Stdcall' is only available on i386, not x86_64
|
||||
// :2:28: error: callconv 'Fastcall' is only available on i386, not x86_64
|
||||
// :3:28: error: callconv 'Thiscall' is only available on i386, not x86_64
|
||||
@ -0,0 +1,7 @@
|
||||
export fn entry() callconv(.Vectorcall) void {}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// :1:29: error: callconv 'Vectorcall' is only available on i386 and AArch64, not x86_64
|
||||
@ -6,7 +6,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:4:17: error: division by zero
|
||||
// :4:19: error: division by zero here causes undefined behavior
|
||||
@ -6,7 +6,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:4:17: error: division by zero
|
||||
// :4:19: error: division by zero here causes undefined behavior
|
||||
@ -6,12 +6,12 @@ fn testCompileLog(x: Bar) void {
|
||||
@compileLog(x);
|
||||
}
|
||||
|
||||
pub fn main () void {
|
||||
pub export fn entry() void {
|
||||
comptime testCompileLog(Bar{.X = 123});
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:6:5: error: found compile log statement
|
||||
// :6:5: error: found compile log statement
|
||||
@ -8,9 +8,7 @@ fn bar(a: i32, b: []const u8) void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=llvm
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:5:5: error: found compile log statement
|
||||
// tmp.zig:6:5: error: found compile log statement
|
||||
// tmp.zig:7:5: error: found compile log statement
|
||||
// :5:5: error: found compile log statement
|
||||
@ -8,7 +8,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:5: error: found compile log statement
|
||||
// :2:5: error: found compile log statement
|
||||
@ -6,7 +6,8 @@ fn foo(x: u32) u32 {
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(y)); }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=llvm
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:14: error: division by zero
|
||||
// :3:16: error: division by zero here causes undefined behavior
|
||||
// :1:14: note: called from here
|
||||
@ -4,7 +4,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:9: error: attempt to dereference undefined value
|
||||
// :3:10: error: cannot dereference undefined value
|
||||
@ -4,7 +4,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:10: error: attempt to dereference non-pointer type '[]u8'
|
||||
// :3:10: error: index syntax required for slice type '[]u8'
|
||||
@ -5,10 +5,10 @@ pub fn pass(in: []u8) []u8 {
|
||||
return out.*[0..1];
|
||||
}
|
||||
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(pass)); }
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(&pass)); }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:4:10: error: attempt to dereference non-pointer type '[10]u8'
|
||||
// :4:10: error: cannot dereference non-pointer type '[10]u8'
|
||||
12
test/cases/compile_errors/dereference_slice.zig
Normal file
12
test/cases/compile_errors/dereference_slice.zig
Normal file
@ -0,0 +1,12 @@
|
||||
fn entry(x: []i32) i32 {
|
||||
return x.*;
|
||||
}
|
||||
comptime {
|
||||
_ = entry;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:13: error: index syntax required for slice type '[]i32'
|
||||
@ -0,0 +1,9 @@
|
||||
export fn entry(x: [*]i32) i32 {
|
||||
return x.*;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:13: error: index syntax required for unknown-length pointer type '[*]i32'
|
||||
@ -6,7 +6,7 @@ fn foo() !void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:12: error: error is discarded. consider using `try`, `catch`, or `if`
|
||||
// :2:12: error: error is discarded. consider using `try`, `catch`, or `if`
|
||||
@ -6,13 +6,12 @@ const float_x = @as(f32, 1.0) / @as(f32, 0.0);
|
||||
export fn entry1() usize { return @sizeOf(@TypeOf(lit_int_x)); }
|
||||
export fn entry2() usize { return @sizeOf(@TypeOf(lit_float_x)); }
|
||||
export fn entry3() usize { return @sizeOf(@TypeOf(int_x)); }
|
||||
export fn entry4() usize { return @sizeOf(@TypeOf(float_x)); }
|
||||
export fn entry4() usize { return @sizeOf(@TypeOf(float_x)); } // no error on purpose
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:1:21: error: division by zero
|
||||
// tmp.zig:2:25: error: division by zero
|
||||
// tmp.zig:3:27: error: division by zero
|
||||
// tmp.zig:4:31: error: division by zero
|
||||
// :1:23: error: division by zero here causes undefined behavior
|
||||
// :2:27: error: division by zero here causes undefined behavior
|
||||
// :3:29: error: division by zero here causes undefined behavior
|
||||
@ -9,8 +9,8 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:5: error: duplicate enum field: 'Bar'
|
||||
// tmp.zig:2:5: note: other field here
|
||||
// :3:5: error: duplicate enum field 'Bar'
|
||||
// :2:5: note: other field here
|
||||
@ -15,8 +15,8 @@ fn foo(x: i32) !void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=llvm
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:5:14: error: duplicate switch value: '@typeInfo(@typeInfo(@TypeOf(foo)).Fn.return_type.?).ErrorUnion.error_set.Foo'
|
||||
// tmp.zig:3:14: note: other value here
|
||||
// :5:9: error: duplicate switch value
|
||||
// :3:9: note: other value here
|
||||
@ -13,8 +13,9 @@ fn foo(x: i32) !void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=llvm
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:26: error: error.Baz not handled in switch
|
||||
// tmp.zig:2:26: error: error.Bar not handled in switch
|
||||
// :2:26: error: switch must handle all possibilities
|
||||
// :2:26: note: unhandled error value: 'error.Bar'
|
||||
// :2:26: note: unhandled error value: 'error.Baz'
|
||||
@ -12,7 +12,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:10:31: error: expected integer type, found 'f32'
|
||||
// :10:31: error: expected integer type, found 'f32'
|
||||
@ -11,7 +11,7 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:9:55: error: pointer value not based on parent struct
|
||||
// :9:55: error: pointer value not based on parent struct
|
||||
@ -10,7 +10,8 @@ comptime {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'
|
||||
// :8:29: error: field 'b' has index '1' but pointer value is index '0' of struct 'tmp.Foo'
|
||||
// :1:13: note: struct declared here
|
||||
@ -6,7 +6,7 @@ export fn foo(a: i32) *Foo {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:5:38: error: expected pointer, found 'i32'
|
||||
// :5:38: error: expected pointer type, found 'i32'
|
||||
@ -10,7 +10,7 @@ fn bar(x: *MyType) bool {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:9:13: error: no member named 'blah' in opaque type 'MyType'
|
||||
// :9:13: error: type '*tmp.MyType' does not support field access
|
||||
@ -5,7 +5,8 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:32: error: type 'type' does not support field access
|
||||
// :3:32: error: type '[]i32' has no members
|
||||
// :3:32: note: slice values have 'len' and 'ptr' members
|
||||
@ -7,7 +7,7 @@ export fn entry(foo: [*]Foo) void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:6:8: error: type '[*]Foo' does not support field access
|
||||
// :6:8: error: type '[*]tmp.Foo' does not support field access
|
||||
@ -4,7 +4,7 @@ export fn foo() void {
|
||||
fn bar() anyerror!i32 { return 0; }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:14: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
// :2:14: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
@ -14,9 +14,9 @@ fn bad() anyerror!void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:24: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
// tmp.zig:6:25: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
// tmp.zig:10:25: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
// :2:24: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
// :6:25: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
// :10:25: error: error is ignored. consider using `try`, `catch`, or `if`
|
||||
20
test/cases/compile_errors/illegal_comparison_of_types.zig
Normal file
20
test/cases/compile_errors/illegal_comparison_of_types.zig
Normal file
@ -0,0 +1,20 @@
|
||||
fn bad_eql_1(a: []u8, b: []u8) bool {
|
||||
return a == b;
|
||||
}
|
||||
const EnumWithData = union(enum) {
|
||||
One: void,
|
||||
Two: i32,
|
||||
};
|
||||
fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool {
|
||||
return a.* == b.*;
|
||||
}
|
||||
|
||||
export fn entry1() usize { return @sizeOf(@TypeOf(&bad_eql_1)); }
|
||||
export fn entry2() usize { return @sizeOf(@TypeOf(&bad_eql_2)); }
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:14: error: operator == not allowed for type '[]u8'
|
||||
// :9:16: error: operator == not allowed for type 'tmp.EnumWithData'
|
||||
@ -11,7 +11,7 @@ export fn entry() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:9:22: error: expected type 'u2', found 'Small'
|
||||
// :9:22: error: expected type 'u2', found 'tmp.Small'
|
||||
@ -15,7 +15,7 @@
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:8:16: error: expected type 'A', found 'B'
|
||||
// :8:16: error: expected type 'tmp.A', found 'tmp.B'
|
||||
@ -5,7 +5,7 @@ export fn foo() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:27: error: accessing a zero length array is not allowed
|
||||
// :3:27: error: indexing into empty array is not allowed
|
||||
@ -6,7 +6,7 @@ export fn foo() void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:4:27: error: accessing a zero length array is not allowed
|
||||
// :4:27: error: indexing into empty array is not allowed
|
||||
@ -3,7 +3,7 @@ export fn entry(ptr: *i32) i32 {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:15: error: index of single-item pointer
|
||||
// :2:15: error: element access of non-indexable type '*i32'
|
||||
@ -11,7 +11,7 @@ fn foo(x: usize) void {
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:9:10: error: expected type 'usize', found 'E'
|
||||
// :9:10: error: expected type 'usize', found 'tmp.E'
|
||||
@ -11,7 +11,7 @@ const Tile = enum {
|
||||
};
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:17: error: attempt to dereference non-pointer type 'Tile'
|
||||
// :3:17: error: cannot dereference non-pointer type 'tmp.Tile'
|
||||
@ -12,8 +12,8 @@ pub const Box = struct {
|
||||
};
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:3:8: error: attempt to dereference non-pointer type 'Box'
|
||||
// tmp.zig:8:13: error: attempt to dereference non-pointer type 'Box'
|
||||
// :3:8: error: cannot dereference non-pointer type 'tmp.Box'
|
||||
// :8:13: error: cannot dereference non-pointer type 'tmp.Box'
|
||||
@ -24,9 +24,9 @@ pub export fn entry3() void {
|
||||
// target=native
|
||||
// backend=stage2
|
||||
//
|
||||
// :6:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
|
||||
// :6:5: note: use '*const fn() void' for a function pointer type
|
||||
// :13:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
|
||||
// :13:5: note: use '*const fn() void' for a function pointer type
|
||||
// :19:5: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
|
||||
// :19:5: note: use '*const fn() void' for a function pointer type
|
||||
// :7:10: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
|
||||
// :7:10: note: use '*const fn() void' for a function pointer type
|
||||
// :15:18: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
|
||||
// :15:17: note: use '*const fn() void' for a function pointer type
|
||||
// :21:19: error: values of type '[2]fn() void' must be comptime known, but index value is runtime known
|
||||
// :21:18: note: use '*const fn() void' for a function pointer type
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
export fn entry() void {
|
||||
'a'.* = 1;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:8: error: attempt to dereference non-pointer type 'comptime_int'
|
||||
@ -1,10 +0,0 @@
|
||||
export fn entry() void {
|
||||
const y = @bitCast(enum(u32) { a, b }, @as(u32, 3));
|
||||
_ = y;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:24: error: cannot cast a value of type 'y'
|
||||
@ -1,11 +0,0 @@
|
||||
export fn entry1() callconv(.APCS) void {}
|
||||
export fn entry2() callconv(.AAPCS) void {}
|
||||
export fn entry3() callconv(.AAPCSVFP) void {}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// tmp.zig:1:29: error: callconv 'APCS' is only available on ARM, not x86_64
|
||||
// tmp.zig:2:29: error: callconv 'AAPCS' is only available on ARM, not x86_64
|
||||
// tmp.zig:3:29: error: callconv 'AAPCSVFP' is only available on ARM, not x86_64
|
||||
@ -1,7 +0,0 @@
|
||||
export fn entry() callconv(.Interrupt) void {}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=aarch64-linux-none
|
||||
//
|
||||
// tmp.zig:1:28: error: callconv 'Interrupt' is only available on x86, x86_64, AVR, and MSP430, not aarch64
|
||||
@ -1,7 +0,0 @@
|
||||
export fn entry() callconv(.Signal) void {}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// tmp.zig:1:28: error: callconv 'Signal' is only available on AVR, not x86_64
|
||||
@ -1,11 +0,0 @@
|
||||
export fn entry1() callconv(.Stdcall) void {}
|
||||
export fn entry2() callconv(.Fastcall) void {}
|
||||
export fn entry3() callconv(.Thiscall) void {}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// tmp.zig:1:29: error: callconv 'Stdcall' is only available on x86, not x86_64
|
||||
// tmp.zig:2:29: error: callconv 'Fastcall' is only available on x86, not x86_64
|
||||
// tmp.zig:3:29: error: callconv 'Thiscall' is only available on x86, not x86_64
|
||||
@ -1,7 +0,0 @@
|
||||
export fn entry() callconv(.Vectorcall) void {}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=x86_64-linux-none
|
||||
//
|
||||
// tmp.zig:1:28: error: callconv 'Vectorcall' is only available on x86 and AArch64, not x86_64
|
||||
@ -1,9 +0,0 @@
|
||||
export fn entry(x: [*]i32) i32 {
|
||||
return x.*;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:13: error: index syntax required for unknown-length pointer type '[*]i32'
|
||||
@ -1,20 +0,0 @@
|
||||
fn bad_eql_1(a: []u8, b: []u8) bool {
|
||||
return a == b;
|
||||
}
|
||||
const EnumWithData = union(enum) {
|
||||
One: void,
|
||||
Two: i32,
|
||||
};
|
||||
fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool {
|
||||
return a.* == b.*;
|
||||
}
|
||||
|
||||
export fn entry1() usize { return @sizeOf(@TypeOf(bad_eql_1)); }
|
||||
export fn entry2() usize { return @sizeOf(@TypeOf(bad_eql_2)); }
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:14: error: operator not allowed for type '[]u8'
|
||||
// tmp.zig:9:16: error: operator not allowed for type 'EnumWithData'
|
||||
@ -1,10 +0,0 @@
|
||||
export fn entry() void {
|
||||
const x = 'a'.*[0..];
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage1
|
||||
// target=native
|
||||
//
|
||||
// tmp.zig:2:18: error: attempt to dereference non-pointer type 'comptime_int'
|
||||
@ -0,0 +1,10 @@
|
||||
export fn entry() void {
|
||||
const x = 'a'.*[0..];
|
||||
_ = x;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:18: error: cannot dereference non-pointer type 'comptime_int'
|
||||
@ -729,8 +729,8 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\ _ = E1.a;
|
||||
\\}
|
||||
, &.{
|
||||
":1:28: error: duplicate enum tag",
|
||||
":1:22: note: other tag here",
|
||||
":1:28: error: duplicate enum field 'b'",
|
||||
":1:22: note: other field here",
|
||||
});
|
||||
|
||||
case.addError(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user