mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
commit
8667d6d61e
@ -5024,8 +5024,8 @@ fn shiftLeftOne(a: u32) callconv(.Inline) u32 {
|
||||
// Another file can use @import and call sub2
|
||||
pub fn sub2(a: i8, b: i8) i8 { return a - b; }
|
||||
|
||||
// Functions can be used as values and are equivalent to pointers.
|
||||
const call2_op = fn (a: i8, b: i8) i8;
|
||||
// Function pointers are prefixed with `*const `.
|
||||
const call2_op = *const fn (a: i8, b: i8) i8;
|
||||
fn do_op(fn_call: call2_op, op1: i8, op2: i8) i8 {
|
||||
return fn_call(op1, op2);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ pub fn isSep(byte: u8) bool {
|
||||
|
||||
/// This is different from mem.join in that the separator will not be repeated if
|
||||
/// it is found at the end or beginning of a pair of consecutive paths.
|
||||
fn joinSepMaybeZ(allocator: Allocator, separator: u8, sepPredicate: fn (u8) bool, paths: []const []const u8, zero: bool) ![]u8 {
|
||||
fn joinSepMaybeZ(allocator: Allocator, separator: u8, comptime sepPredicate: fn (u8) bool, paths: []const []const u8, zero: bool) ![]u8 {
|
||||
if (paths.len == 0) return if (zero) try allocator.dupe(u8, &[1]u8{0}) else &[0]u8{};
|
||||
|
||||
// Find first non-empty path index.
|
||||
|
||||
@ -1548,7 +1548,7 @@ test "boolMask" {
|
||||
}
|
||||
|
||||
/// Return the mod of `num` with the smallest integer type
|
||||
pub fn comptimeMod(num: anytype, denom: comptime_int) IntFittingRange(0, denom - 1) {
|
||||
pub fn comptimeMod(num: anytype, comptime denom: comptime_int) IntFittingRange(0, denom - 1) {
|
||||
return @intCast(IntFittingRange(0, denom - 1), @mod(num, denom));
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ inline fn mantissaOne(comptime T: type) comptime_int {
|
||||
}
|
||||
|
||||
/// Creates floating point type T from an unbiased exponent and raw mantissa.
|
||||
inline fn reconstructFloat(comptime T: type, exponent: comptime_int, mantissa: comptime_int) T {
|
||||
inline fn reconstructFloat(comptime T: type, comptime exponent: comptime_int, comptime mantissa: comptime_int) T {
|
||||
const TBits = @Type(.{ .Int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } });
|
||||
const biased_exponent = @as(TBits, exponent + floatExponentMax(T));
|
||||
return @bitCast(T, (biased_exponent << floatMantissaBits(T)) | @as(TBits, mantissa));
|
||||
|
||||
@ -349,7 +349,7 @@ test "shuffleVectorIndex" {
|
||||
|
||||
/// Constructs a [*c] pointer with the const and volatile annotations
|
||||
/// from SelfType for pointing to a C flexible array of ElementType.
|
||||
pub fn FlexibleArrayType(comptime SelfType: type, ElementType: type) type {
|
||||
pub fn FlexibleArrayType(comptime SelfType: type, comptime ElementType: type) type {
|
||||
switch (@typeInfo(SelfType)) {
|
||||
.Pointer => |ptr| {
|
||||
return @Type(.{ .Pointer = .{
|
||||
|
||||
@ -3670,7 +3670,7 @@ const Parser = struct {
|
||||
}
|
||||
|
||||
/// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)?
|
||||
fn parseIf(p: *Parser, bodyParseFn: fn (p: *Parser) Error!Node.Index) !Node.Index {
|
||||
fn parseIf(p: *Parser, comptime bodyParseFn: fn (p: *Parser) Error!Node.Index) !Node.Index {
|
||||
const if_token = p.eatToken(.keyword_if) orelse return null_node;
|
||||
_ = try p.expectToken(.l_paren);
|
||||
const condition = try p.expectExpr();
|
||||
|
||||
@ -6072,17 +6072,17 @@ pub fn paramSrc(
|
||||
else => unreachable,
|
||||
};
|
||||
var it = full.iterate(tree);
|
||||
while (true) {
|
||||
if (it.param_i == param_i) {
|
||||
const param = it.next().?;
|
||||
var i: usize = 0;
|
||||
while (it.next()) |param| : (i += 1) {
|
||||
if (i == param_i) {
|
||||
if (param.anytype_ellipsis3) |some| {
|
||||
const main_token = tree.nodes.items(.main_token)[decl.src_node];
|
||||
return .{ .token_offset_param = @bitCast(i32, some) - @bitCast(i32, main_token) };
|
||||
}
|
||||
return .{ .node_offset_param = decl.nodeIndexToRelative(param.type_expr) };
|
||||
}
|
||||
_ = it.next();
|
||||
}
|
||||
unreachable;
|
||||
}
|
||||
|
||||
pub fn argSrc(
|
||||
|
||||
63
src/Sema.zig
63
src/Sema.zig
@ -76,6 +76,8 @@ types_to_resolve: std.ArrayListUnmanaged(Air.Inst.Ref) = .{},
|
||||
post_hoc_blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, *LabeledBlock) = .{},
|
||||
/// Populated with the last compile error created.
|
||||
err: ?*Module.ErrorMsg = null,
|
||||
/// True when analyzing a generic instantiation. Used to suppress some errors.
|
||||
is_generic_instantiation: bool = false,
|
||||
|
||||
const std = @import("std");
|
||||
const math = std.math;
|
||||
@ -1696,7 +1698,10 @@ fn resolveMaybeUndefValIntable(
|
||||
.elem_ptr => check = check.castTag(.elem_ptr).?.data.array_ptr,
|
||||
.eu_payload_ptr, .opt_payload_ptr => check = check.cast(Value.Payload.PayloadPtr).?.data.container_ptr,
|
||||
.generic_poison => return error.GenericPoison,
|
||||
else => return val,
|
||||
else => {
|
||||
try sema.resolveLazyValue(block, src, val);
|
||||
return val;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -6495,6 +6500,7 @@ fn instantiateGenericCall(
|
||||
.comptime_args = try new_decl_arena_allocator.alloc(TypedValue, uncasted_args.len),
|
||||
.comptime_args_fn_inst = module_fn.zir_body_inst,
|
||||
.preallocated_new_func = new_module_func,
|
||||
.is_generic_instantiation = true,
|
||||
};
|
||||
defer child_sema.deinit();
|
||||
|
||||
@ -7255,6 +7261,8 @@ fn zirOptionalPayload(
|
||||
if (operand_ty.ptrSize() != .C) {
|
||||
return sema.failWithExpectedOptionalType(block, src, operand_ty);
|
||||
}
|
||||
// TODO https://github.com/ziglang/zig/issues/6597
|
||||
if (true) break :t operand_ty;
|
||||
const ptr_info = operand_ty.ptrInfo().data;
|
||||
break :t try Type.ptr(sema.arena, sema.mod, .{
|
||||
.pointee_type = try ptr_info.pointee_type.copy(sema.arena),
|
||||
@ -7789,6 +7797,7 @@ fn funcCommon(
|
||||
&is_generic,
|
||||
is_extern,
|
||||
cc_workaround,
|
||||
has_body,
|
||||
) catch |err| switch (err) {
|
||||
error.NeededSourceLocation => {
|
||||
const decl = sema.mod.declPtr(block.src_decl);
|
||||
@ -7802,6 +7811,7 @@ fn funcCommon(
|
||||
&is_generic,
|
||||
is_extern,
|
||||
cc_workaround,
|
||||
has_body,
|
||||
);
|
||||
return error.AnalysisFail;
|
||||
},
|
||||
@ -8005,6 +8015,7 @@ fn analyzeParameter(
|
||||
is_generic: *bool,
|
||||
is_extern: bool,
|
||||
cc: std.builtin.CallingConvention,
|
||||
has_body: bool,
|
||||
) !void {
|
||||
const requires_comptime = try sema.typeRequiresComptime(block, param_src, param.ty);
|
||||
comptime_params[i] = param.is_comptime or requires_comptime;
|
||||
@ -8053,9 +8064,9 @@ fn analyzeParameter(
|
||||
};
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
}
|
||||
if (requires_comptime and !param.is_comptime) {
|
||||
if (!sema.is_generic_instantiation and requires_comptime and !param.is_comptime and has_body) {
|
||||
const msg = msg: {
|
||||
const msg = try sema.errMsg(block, param_src, "parametter of type '{}' must be declared comptime", .{
|
||||
const msg = try sema.errMsg(block, param_src, "parameter of type '{}' must be declared comptime", .{
|
||||
param.ty.fmt(sema.mod),
|
||||
});
|
||||
errdefer msg.destroy(sema.gpa);
|
||||
@ -8153,7 +8164,7 @@ fn zirParam(
|
||||
|
||||
try block.params.append(sema.gpa, .{
|
||||
.ty = param_ty,
|
||||
.is_comptime = is_comptime,
|
||||
.is_comptime = comptime_syntax,
|
||||
.name = param_name,
|
||||
});
|
||||
const result = try sema.addConstant(param_ty, Value.initTag(.generic_poison));
|
||||
@ -16318,7 +16329,7 @@ fn zirUnaryMath(
|
||||
block: *Block,
|
||||
inst: Zir.Inst.Index,
|
||||
air_tag: Air.Inst.Tag,
|
||||
eval: fn (Value, Type, Allocator, std.Target) Allocator.Error!Value,
|
||||
comptime eval: fn (Value, Type, Allocator, std.Target) Allocator.Error!Value,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@ -17777,7 +17788,7 @@ fn zirBitCount(
|
||||
block: *Block,
|
||||
inst: Zir.Inst.Index,
|
||||
air_tag: Air.Inst.Tag,
|
||||
comptimeOp: fn (val: Value, ty: Type, target: std.Target) u64,
|
||||
comptime comptimeOp: fn (val: Value, ty: Type, target: std.Target) u64,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const src = inst_data.src();
|
||||
@ -20554,8 +20565,8 @@ fn validatePackedType(ty: Type) bool {
|
||||
.AnyFrame,
|
||||
.Fn,
|
||||
.Array,
|
||||
.Optional,
|
||||
=> return false,
|
||||
.Optional => return ty.isPtrLikeOptional(),
|
||||
.Void,
|
||||
.Bool,
|
||||
.Float,
|
||||
@ -21383,14 +21394,30 @@ fn fieldCallBind(
|
||||
switch (concrete_ty.zigTypeTag()) {
|
||||
.Struct => {
|
||||
const struct_ty = try sema.resolveTypeFields(block, src, concrete_ty);
|
||||
const struct_obj = struct_ty.castTag(.@"struct").?.data;
|
||||
if (struct_ty.castTag(.@"struct")) |struct_obj| {
|
||||
const field_index_usize = struct_obj.data.fields.getIndex(field_name) orelse
|
||||
break :find_field;
|
||||
const field_index = @intCast(u32, field_index_usize);
|
||||
const field = struct_obj.data.fields.values()[field_index];
|
||||
|
||||
const field_index_usize = struct_obj.fields.getIndex(field_name) orelse
|
||||
break :find_field;
|
||||
const field_index = @intCast(u32, field_index_usize);
|
||||
const field = struct_obj.fields.values()[field_index];
|
||||
|
||||
return finishFieldCallBind(sema, block, src, ptr_ty, field.ty, field_index, object_ptr);
|
||||
return finishFieldCallBind(sema, block, src, ptr_ty, field.ty, field_index, object_ptr);
|
||||
} else if (struct_ty.isTuple()) {
|
||||
if (mem.eql(u8, field_name, "len")) {
|
||||
return sema.addIntUnsigned(Type.usize, struct_ty.structFieldCount());
|
||||
}
|
||||
if (std.fmt.parseUnsigned(u32, field_name, 10)) |field_index| {
|
||||
if (field_index >= struct_ty.structFieldCount()) break :find_field;
|
||||
return finishFieldCallBind(sema, block, src, ptr_ty, struct_ty.structFieldType(field_index), field_index, object_ptr);
|
||||
} else |_| {}
|
||||
} else {
|
||||
const max = struct_ty.structFieldCount();
|
||||
var i: u32 = 0;
|
||||
while (i < max) : (i += 1) {
|
||||
if (mem.eql(u8, struct_ty.structFieldName(i), field_name)) {
|
||||
return finishFieldCallBind(sema, block, src, ptr_ty, struct_ty.structFieldType(i), i, object_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
.Union => {
|
||||
const union_ty = try sema.resolveTypeFields(block, src, concrete_ty);
|
||||
@ -22553,7 +22580,7 @@ fn coerceExtra(
|
||||
// Function body to function pointer.
|
||||
if (inst_ty.zigTypeTag() == .Fn) {
|
||||
const fn_val = try sema.resolveConstValue(block, .unneeded, inst, undefined);
|
||||
const fn_decl = fn_val.castTag(.function).?.data.owner_decl;
|
||||
const fn_decl = fn_val.pointerDecl().?;
|
||||
const inst_as_ptr = try sema.analyzeDeclRef(fn_decl);
|
||||
return sema.coerce(block, dest_ty, inst_as_ptr, inst_src);
|
||||
}
|
||||
@ -27909,7 +27936,9 @@ fn resolveInferredErrorSetTy(
|
||||
fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void {
|
||||
const gpa = mod.gpa;
|
||||
const decl_index = struct_obj.owner_decl;
|
||||
const zir = struct_obj.namespace.file_scope.zir;
|
||||
const file_scope = struct_obj.namespace.file_scope;
|
||||
if (file_scope.status != .success_zir) return error.AnalysisFail;
|
||||
const zir = file_scope.zir;
|
||||
const extended = zir.instructions.items(.data)[struct_obj.zir_index].extended;
|
||||
assert(extended.opcode == .struct_decl);
|
||||
const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);
|
||||
@ -29489,7 +29518,7 @@ pub fn typeRequiresComptime(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Typ
|
||||
=> {
|
||||
const child_ty = ty.childType();
|
||||
if (child_ty.zigTypeTag() == .Fn) {
|
||||
return false;
|
||||
return child_ty.fnInfo().is_generic;
|
||||
} else {
|
||||
return sema.typeRequiresComptime(block, src, child_ty);
|
||||
}
|
||||
|
||||
@ -3417,7 +3417,10 @@ pub const DeclGen = struct {
|
||||
});
|
||||
const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
|
||||
const small_int_ty = dg.context.intType(ty_bit_size);
|
||||
const small_int_val = non_int_val.constBitCast(small_int_ty);
|
||||
const small_int_val = if (field.ty.isPtrAtRuntime())
|
||||
non_int_val.constPtrToInt(small_int_ty)
|
||||
else
|
||||
non_int_val.constBitCast(small_int_ty);
|
||||
const shift_rhs = int_llvm_ty.constInt(running_bits, .False);
|
||||
// If the field is as large as the entire packed struct, this
|
||||
// zext would go from, e.g. i16 to i16. This is legal with
|
||||
@ -5343,7 +5346,7 @@ pub const FuncGen = struct {
|
||||
const same_size_int = self.context.intType(elem_bits);
|
||||
const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
|
||||
return self.builder.buildBitCast(truncated_int, elem_llvm_ty, "");
|
||||
} else if (field_ty.zigTypeTag() == .Pointer) {
|
||||
} else if (field_ty.isPtrAtRuntime()) {
|
||||
const elem_bits = @intCast(c_uint, field_ty.bitSize(target));
|
||||
const same_size_int = self.context.intType(elem_bits);
|
||||
const truncated_int = self.builder.buildTrunc(shifted_value, same_size_int, "");
|
||||
@ -8408,7 +8411,7 @@ pub const FuncGen = struct {
|
||||
const non_int_val = try self.resolveInst(elem);
|
||||
const ty_bit_size = @intCast(u16, field.ty.bitSize(target));
|
||||
const small_int_ty = self.dg.context.intType(ty_bit_size);
|
||||
const small_int_val = if (field.ty.zigTypeTag() == .Pointer)
|
||||
const small_int_val = if (field.ty.isPtrAtRuntime())
|
||||
self.builder.buildPtrToInt(non_int_val, small_int_ty, "")
|
||||
else
|
||||
self.builder.buildBitCast(non_int_val, small_int_ty, "");
|
||||
|
||||
@ -2394,7 +2394,7 @@ pub const Type = extern union {
|
||||
if (ignore_comptime_only) {
|
||||
return true;
|
||||
} else if (ty.childType().zigTypeTag() == .Fn) {
|
||||
return true;
|
||||
return !ty.childType().fnInfo().is_generic;
|
||||
} else if (sema_kit) |sk| {
|
||||
return !(try sk.sema.typeRequiresComptime(sk.block, sk.src, ty));
|
||||
} else {
|
||||
|
||||
@ -1281,7 +1281,7 @@ test "*const [N]null u8 to ?[]const u8" {
|
||||
test "cast between [*c]T and ?[*:0]T on fn parameter" {
|
||||
const S = struct {
|
||||
const Handler = ?fn ([*c]const u8) callconv(.C) void;
|
||||
fn addCallback(handler: Handler) void {
|
||||
fn addCallback(comptime handler: Handler) void {
|
||||
_ = handler;
|
||||
}
|
||||
|
||||
|
||||
@ -168,7 +168,7 @@ fn entryPtr() void {
|
||||
fooPtr(ptr);
|
||||
}
|
||||
|
||||
fn foo2(f: fn () anyerror!void) void {
|
||||
fn foo2(comptime f: fn () anyerror!void) void {
|
||||
const x = f();
|
||||
x catch {
|
||||
@panic("fail");
|
||||
|
||||
@ -1325,3 +1325,25 @@ test "value in if block is comptime known" {
|
||||
};
|
||||
comptime try expect(std.mem.eql(u8, first, second));
|
||||
}
|
||||
|
||||
test "lazy sizeof is resolved in division" {
|
||||
const A = struct {
|
||||
a: u32,
|
||||
};
|
||||
const a = 2;
|
||||
try expect(@sizeOf(A) / a == 2);
|
||||
try expect(@sizeOf(A) - a == 2);
|
||||
}
|
||||
|
||||
test "lazy value is resolved as slice operand" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const A = struct { a: u32 };
|
||||
var a: [512]u64 = undefined;
|
||||
|
||||
const ptr1 = a[0..@sizeOf(A)];
|
||||
const ptr2 = @ptrCast([*]u8, &a)[0..@sizeOf(A)];
|
||||
try expect(@ptrToInt(ptr1) == @ptrToInt(ptr2));
|
||||
try expect(ptr1.len == ptr2.len);
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ test "implicit cast function unreachable return" {
|
||||
wantsFnWithVoid(fnWithUnreachable);
|
||||
}
|
||||
|
||||
fn wantsFnWithVoid(f: fn () void) void {
|
||||
fn wantsFnWithVoid(comptime f: fn () void) void {
|
||||
_ = f;
|
||||
}
|
||||
|
||||
@ -422,3 +422,24 @@ test "import passed byref to function in return type" {
|
||||
var list = S.get();
|
||||
try expect(list.items.len == 0);
|
||||
}
|
||||
|
||||
test "implicit cast function to function ptr" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S1 = struct {
|
||||
export fn someFunctionThatReturnsAValue() c_int {
|
||||
return 123;
|
||||
}
|
||||
};
|
||||
var fnPtr1: *const fn () callconv(.C) c_int = S1.someFunctionThatReturnsAValue;
|
||||
try expect(fnPtr1() == 123);
|
||||
const S2 = struct {
|
||||
extern fn someFunctionThatReturnsAValue() c_int;
|
||||
};
|
||||
var fnPtr2: *const fn () callconv(.C) c_int = S2.someFunctionThatReturnsAValue;
|
||||
try expect(fnPtr2() == 123);
|
||||
}
|
||||
|
||||
@ -405,3 +405,10 @@ test "optional of noreturn used with orelse" {
|
||||
const val = NoReturn.testOrelse();
|
||||
try expect(val == 123);
|
||||
}
|
||||
|
||||
test "orelse on C pointer" {
|
||||
// TODO https://github.com/ziglang/zig/issues/6597
|
||||
const foo: [*c]const u8 = "hey";
|
||||
const d = foo orelse @compileError("bad");
|
||||
try expectEqual([*c]const u8, @TypeOf(d));
|
||||
}
|
||||
|
||||
@ -434,3 +434,15 @@ test "@ptrToInt on a packed struct field" {
|
||||
};
|
||||
try expect(@ptrToInt(&S.p0.z) - @ptrToInt(&S.p0.x) == 2);
|
||||
}
|
||||
|
||||
test "optional pointer in packed struct" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
|
||||
const T = packed struct { ptr: ?*const u8 };
|
||||
var n: u8 = 0;
|
||||
const x = T{ .ptr = &n };
|
||||
try expect(x.ptr.? == &n);
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ test "fn call of struct field" {
|
||||
return 13;
|
||||
}
|
||||
|
||||
fn callStructField(foo: Foo) i32 {
|
||||
fn callStructField(comptime foo: Foo) i32 {
|
||||
return foo.ptr();
|
||||
}
|
||||
};
|
||||
|
||||
@ -3,9 +3,17 @@ fn f(m: []const u8) void {
|
||||
m.copy(u8, self[0..], m);
|
||||
}
|
||||
export fn entry() usize { return @sizeOf(@TypeOf(&f)); }
|
||||
pub export fn entry1() void {
|
||||
.{}.bar();
|
||||
}
|
||||
pub export fn entry2() void {
|
||||
.{ .foo = 1 }.bar();
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :7:8: error: no field or member function named 'bar' in '@TypeOf(.{})'
|
||||
// :10:18: error: no field or member function named 'bar' in 'struct{comptime foo: comptime_int = 1}'
|
||||
// :3:6: error: no field or member function named 'copy' in '[]const u8'
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
fn f(_: anytype) void {}
|
||||
fn g(h: *const fn (anytype) void) void {
|
||||
h({});
|
||||
}
|
||||
pub export fn entry() void {
|
||||
g(f);
|
||||
}
|
||||
|
||||
pub fn comptimeMod(num: anytype, denom: comptime_int) void {
|
||||
_ = num;
|
||||
_ = denom;
|
||||
}
|
||||
|
||||
pub export fn entry1() void {
|
||||
_ = comptimeMod(1, 2);
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :2:6: error: parameter of type '*const fn(anytype) void' must be declared comptime
|
||||
// :9:34: error: parameter of type 'comptime_int' must be declared comptime
|
||||
@ -184,7 +184,7 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
}
|
||||
|
||||
{
|
||||
const case = ctx.obj("argument causes error ", .{});
|
||||
const case = ctx.obj("argument causes error", .{});
|
||||
case.backend = .stage2;
|
||||
|
||||
case.addSourceFile("b.zig",
|
||||
@ -208,6 +208,23 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const case = ctx.obj("astgen failure in file struct", .{});
|
||||
case.backend = .stage2;
|
||||
|
||||
case.addSourceFile("b.zig",
|
||||
\\bad
|
||||
);
|
||||
|
||||
case.addError(
|
||||
\\pub export fn entry() void {
|
||||
\\ _ = (@sizeOf(@import("b.zig")));
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
":1:1: error: struct field missing type",
|
||||
});
|
||||
}
|
||||
|
||||
// TODO test this in stage2, but we won't even try in stage1
|
||||
//ctx.objErrStage1("inline fn calls itself indirectly",
|
||||
// \\export fn foo() void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user