| author | |
| committer | |
| log | 8feb3987608945040c955bd7b24be3841ebf74ac |
| tree | 192a1ec257081c7f4771e59ee1fc3e499ae7cf6f |
| parent | d851b24180fdf2b622b06e9a35e315541fb10aa1 |
13 files changed, 204 insertions(+), 95 deletions(-)
src/Module.zig+11| ... | @@ -2439,6 +2439,7 @@ pub const SrcLoc = struct { | ... | @@ -2439,6 +2439,7 @@ pub const SrcLoc = struct { |
| 2439 | 2439 | ||
| 2440 | .node_offset_fn_type_ret_ty => |node_off| { | 2440 | .node_offset_fn_type_ret_ty => |node_off| { |
| 2441 | const tree = try src_loc.file_scope.getTree(gpa); | 2441 | const tree = try src_loc.file_scope.getTree(gpa); |
| 2442 | const node_datas = tree.nodes.items(.data); | ||
| 2442 | const node_tags = tree.nodes.items(.tag); | 2443 | const node_tags = tree.nodes.items(.tag); |
| 2443 | const node = src_loc.declRelativeToNodeIndex(node_off); | 2444 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| 2444 | var params: [1]Ast.Node.Index = undefined; | 2445 | var params: [1]Ast.Node.Index = undefined; |
| ... | @@ -2447,6 +2448,16 @@ pub const SrcLoc = struct { | ... | @@ -2447,6 +2448,16 @@ pub const SrcLoc = struct { |
| 2447 | .fn_proto_multi => tree.fnProtoMulti(node), | 2448 | .fn_proto_multi => tree.fnProtoMulti(node), |
| 2448 | .fn_proto_one => tree.fnProtoOne(&params, node), | 2449 | .fn_proto_one => tree.fnProtoOne(&params, node), |
| 2449 | .fn_proto => tree.fnProto(node), | 2450 | .fn_proto => tree.fnProto(node), |
| 2451 | .fn_decl => blk: { | ||
| 2452 | const fn_proto = node_datas[node].lhs; | ||
| 2453 | break :blk switch (node_tags[fn_proto]) { | ||
| 2454 | .fn_proto_simple => tree.fnProtoSimple(&params, fn_proto), | ||
| 2455 | .fn_proto_multi => tree.fnProtoMulti(fn_proto), | ||
| 2456 | .fn_proto_one => tree.fnProtoOne(&params, fn_proto), | ||
| 2457 | .fn_proto => tree.fnProto(fn_proto), | ||
| 2458 | else => unreachable, | ||
| 2459 | }; | ||
| 2460 | }, | ||
| 2450 | else => unreachable, | 2461 | else => unreachable, |
| 2451 | }; | 2462 | }; |
| 2452 | return nodeToSpan(tree, full.ast.return_type); | 2463 | return nodeToSpan(tree, full.ast.return_type); |
src/Sema.zig+85-13| ... | @@ -7243,7 +7243,10 @@ fn funcCommon( | ... | @@ -7243,7 +7243,10 @@ fn funcCommon( |
| 7243 | break :new_func new_func; | 7243 | break :new_func new_func; |
| 7244 | } | 7244 | } |
| 7245 | destroy_fn_on_error = true; | 7245 | destroy_fn_on_error = true; |
| 7246 | break :new_func try sema.gpa.create(Module.Fn); | 7246 | const new_func = try sema.gpa.create(Module.Fn); |
| 7247 | // Set this here so that the inferred return type can be printed correctly if it appears in an error. | ||
| 7248 | new_func.owner_decl = sema.owner_decl_index; | ||
| 7249 | break :new_func new_func; | ||
| 7247 | }; | 7250 | }; |
| 7248 | errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func); | 7251 | errdefer if (destroy_fn_on_error) sema.gpa.destroy(new_func); |
| 7249 | 7252 | ||
| ... | @@ -7277,18 +7280,67 @@ fn funcCommon( | ... | @@ -7277,18 +7280,67 @@ fn funcCommon( |
| 7277 | } | 7280 | } |
| 7278 | } | 7281 | } |
| 7279 | 7282 | ||
| 7283 | // These locals are pulled out from the init expression below to work around | ||
| 7284 | // a stage1 compiler bug. | ||
| 7285 | // In the case of generic calling convention, or generic alignment, we use | ||
| 7286 | // default values which are only meaningful for the generic function, *not* | ||
| 7287 | // the instantiation, which can depend on comptime parameters. | ||
| 7288 | // Related proposal: https://github.com/ziglang/zig/issues/11834 | ||
| 7289 | const cc_workaround = cc orelse .Unspecified; | ||
| 7290 | const align_workaround = alignment orelse 0; | ||
| 7291 | |||
| 7280 | const param_types = try sema.arena.alloc(Type, block.params.items.len); | 7292 | const param_types = try sema.arena.alloc(Type, block.params.items.len); |
| 7281 | const comptime_params = try sema.arena.alloc(bool, block.params.items.len); | 7293 | const comptime_params = try sema.arena.alloc(bool, block.params.items.len); |
| 7282 | for (block.params.items) |param, i| { | 7294 | for (block.params.items) |param, i| { |
| 7283 | const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location | 7295 | const param_src = LazySrcLoc.nodeOffset(src_node_offset); // TODO better soruce location |
| 7284 | param_types[i] = param.ty; | 7296 | param_types[i] = param.ty; |
| 7285 | comptime_params[i] = param.is_comptime or | 7297 | const requires_comptime = try sema.typeRequiresComptime(block, param_src, param.ty); |
| 7286 | try sema.typeRequiresComptime(block, param_src, param.ty); | 7298 | comptime_params[i] = param.is_comptime or requires_comptime; |
| 7287 | is_generic = is_generic or comptime_params[i] or param.ty.tag() == .generic_poison; | 7299 | is_generic = is_generic or comptime_params[i] or param.ty.tag() == .generic_poison; |
| 7288 | if (is_extern and is_generic) { | 7300 | if (is_extern and is_generic) { |
| 7289 | // TODO add note: function is generic because of this parameter | 7301 | // TODO add note: function is generic because of this parameter |
| 7290 | return sema.fail(block, param_src, "extern function cannot be generic", .{}); | 7302 | return sema.fail(block, param_src, "extern function cannot be generic", .{}); |
| 7291 | } | 7303 | } |
| 7304 | if (!param.ty.isValidParamType()) { | ||
| 7305 | const opaque_str = if (param.ty.zigTypeTag() == .Opaque) "opaque " else ""; | ||
| 7306 | const msg = msg: { | ||
| 7307 | const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{ | ||
| 7308 | opaque_str, param.ty.fmt(sema.mod), | ||
| 7309 | }); | ||
| 7310 | errdefer msg.destroy(sema.gpa); | ||
| 7311 | |||
| 7312 | try sema.addDeclaredHereNote(msg, param.ty); | ||
| 7313 | break :msg msg; | ||
| 7314 | }; | ||
| 7315 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 7316 | } | ||
| 7317 | if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !(try sema.validateExternType(param.ty, .param_ty))) { | ||
| 7318 | const msg = msg: { | ||
| 7319 | const msg = try sema.errMsg(block, param_src, "parameter of type '{}' not allowed in function with calling convention '{s}'", .{ | ||
| 7320 | param.ty.fmt(sema.mod), @tagName(cc_workaround), | ||
| 7321 | }); | ||
| 7322 | errdefer msg.destroy(sema.gpa); | ||
| 7323 | |||
| 7324 | const src_decl = sema.mod.declPtr(block.src_decl); | ||
| 7325 | try sema.explainWhyTypeIsNotExtern(block, param_src, msg, param_src.toSrcLoc(src_decl), param.ty, .param_ty); | ||
| 7326 | |||
| 7327 | try sema.addDeclaredHereNote(msg, param.ty); | ||
| 7328 | break :msg msg; | ||
| 7329 | }; | ||
| 7330 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 7331 | } | ||
| 7332 | if (requires_comptime and !param.is_comptime) { | ||
| 7333 | const msg = msg: { | ||
| 7334 | const msg = try sema.errMsg(block, param_src, "parametter of type '{}' must be declared comptime", .{ | ||
| 7335 | param.ty.fmt(sema.mod), | ||
| 7336 | }); | ||
| 7337 | errdefer msg.destroy(sema.gpa); | ||
| 7338 | |||
| 7339 | try sema.addDeclaredHereNote(msg, param.ty); | ||
| 7340 | break :msg msg; | ||
| 7341 | }; | ||
| 7342 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 7343 | } | ||
| 7292 | } | 7344 | } |
| 7293 | 7345 | ||
| 7294 | const ret_poison = if (!is_generic) rp: { | 7346 | const ret_poison = if (!is_generic) rp: { |
| ... | @@ -7318,14 +7370,34 @@ fn funcCommon( | ... | @@ -7318,14 +7370,34 @@ fn funcCommon( |
| 7318 | }); | 7370 | }); |
| 7319 | }; | 7371 | }; |
| 7320 | 7372 | ||
| 7321 | // These locals are pulled out from the init expression below to work around | 7373 | if (!bare_return_type.isValidReturnType()) { |
| 7322 | // a stage1 compiler bug. | 7374 | const opaque_str = if (bare_return_type.zigTypeTag() == .Opaque) "opaque " else ""; |
| 7323 | // In the case of generic calling convention, or generic alignment, we use | 7375 | const msg = msg: { |
| 7324 | // default values which are only meaningful for the generic function, *not* | 7376 | const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{ |
| 7325 | // the instantiation, which can depend on comptime parameters. | 7377 | opaque_str, bare_return_type.fmt(sema.mod), |
| 7326 | // Related proposal: https://github.com/ziglang/zig/issues/11834 | 7378 | }); |
| 7327 | const cc_workaround = cc orelse .Unspecified; | 7379 | errdefer msg.destroy(sema.gpa); |
| 7328 | const align_workaround = alignment orelse 0; | 7380 | |
| 7381 | try sema.addDeclaredHereNote(msg, bare_return_type); | ||
| 7382 | break :msg msg; | ||
| 7383 | }; | ||
| 7384 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 7385 | } | ||
| 7386 | if (!Type.fnCallingConventionAllowsZigTypes(cc_workaround) and !(try sema.validateExternType(return_type, .ret_ty))) { | ||
| 7387 | const msg = msg: { | ||
| 7388 | const msg = try sema.errMsg(block, ret_ty_src, "return type '{}' not allowed in function with calling convention '{s}'", .{ | ||
| 7389 | return_type.fmt(sema.mod), @tagName(cc_workaround), | ||
| 7390 | }); | ||
| 7391 | errdefer msg.destroy(sema.gpa); | ||
| 7392 | |||
| 7393 | const src_decl = sema.mod.declPtr(block.src_decl); | ||
| 7394 | try sema.explainWhyTypeIsNotExtern(block, ret_ty_src, msg, ret_ty_src.toSrcLoc(src_decl), return_type, .ret_ty); | ||
| 7395 | |||
| 7396 | try sema.addDeclaredHereNote(msg, return_type); | ||
| 7397 | break :msg msg; | ||
| 7398 | }; | ||
| 7399 | return sema.failWithOwnedErrorMsg(block, msg); | ||
| 7400 | } | ||
| 7329 | 7401 | ||
| 7330 | const arch = sema.mod.getTarget().cpu.arch; | 7402 | const arch = sema.mod.getTarget().cpu.arch; |
| 7331 | if (switch (cc_workaround) { | 7403 | if (switch (cc_workaround) { |
| ... | @@ -18399,7 +18471,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr | ... | @@ -18399,7 +18471,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr |
| 18399 | .BoundFn, | 18471 | .BoundFn, |
| 18400 | .Frame, | 18472 | .Frame, |
| 18401 | => return false, | 18473 | => return false, |
| 18402 | .Void => return position == .union_field, | 18474 | .Void => return position == .union_field or position == .ret_ty, |
| 18403 | .NoReturn => return position == .ret_ty, | 18475 | .NoReturn => return position == .ret_ty, |
| 18404 | .Opaque, | 18476 | .Opaque, |
| 18405 | .Bool, | 18477 | .Bool, |
| ... | @@ -18411,7 +18483,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr | ... | @@ -18411,7 +18483,7 @@ fn validateExternType(sema: *Sema, ty: Type, position: ExternPosition) CompileEr |
| 18411 | 8, 16, 32, 64, 128 => return true, | 18483 | 8, 16, 32, 64, 128 => return true, |
| 18412 | else => return false, | 18484 | else => return false, |
| 18413 | }, | 18485 | }, |
| 18414 | .Fn => return !ty.fnCallingConventionAllowsZigTypes(), | 18486 | .Fn => return !Type.fnCallingConventionAllowsZigTypes(ty.fnCallingConvention()), |
| 18415 | .Enum => { | 18487 | .Enum => { |
| 18416 | var buf: Type.Payload.Bits = undefined; | 18488 | var buf: Type.Payload.Bits = undefined; |
| 18417 | return sema.validateExternType(ty.intTagType(&buf), position); | 18489 | return sema.validateExternType(ty.intTagType(&buf), position); |
src/type.zig+20-2| ... | @@ -4643,13 +4643,27 @@ pub const Type = extern union { | ... | @@ -4643,13 +4643,27 @@ pub const Type = extern union { |
| 4643 | } | 4643 | } |
| 4644 | 4644 | ||
| 4645 | /// Asserts the type is a function. | 4645 | /// Asserts the type is a function. |
| 4646 | pub fn fnCallingConventionAllowsZigTypes(self: Type) bool { | 4646 | pub fn fnCallingConventionAllowsZigTypes(cc: std.builtin.CallingConvention) bool { |
| 4647 | return switch (self.fnCallingConvention()) { | 4647 | return switch (cc) { |
| 4648 | .Unspecified, .Async, .Inline, .PtxKernel => true, | 4648 | .Unspecified, .Async, .Inline, .PtxKernel => true, |
| 4649 | else => false, | 4649 | else => false, |
| 4650 | }; | 4650 | }; |
| 4651 | } | 4651 | } |
| 4652 | 4652 | ||
| 4653 | pub fn isValidParamType(self: Type) bool { | ||
| 4654 | return switch (self.zigTypeTagOrPoison() catch return true) { | ||
| 4655 | .Undefined, .Null, .Opaque, .NoReturn => false, | ||
| 4656 | else => true, | ||
| 4657 | }; | ||
| 4658 | } | ||
| 4659 | |||
| 4660 | pub fn isValidReturnType(self: Type) bool { | ||
| 4661 | return switch (self.zigTypeTagOrPoison() catch return true) { | ||
| 4662 | .Undefined, .Null, .Opaque => false, | ||
| 4663 | else => true, | ||
| 4664 | }; | ||
| 4665 | } | ||
| 4666 | |||
| 4653 | /// Asserts the type is a function. | 4667 | /// Asserts the type is a function. |
| 4654 | pub fn fnIsVarArgs(self: Type) bool { | 4668 | pub fn fnIsVarArgs(self: Type) bool { |
| 4655 | return switch (self.tag()) { | 4669 | return switch (self.tag()) { |
| ... | @@ -5650,6 +5664,10 @@ pub const Type = extern union { | ... | @@ -5650,6 +5664,10 @@ pub const Type = extern union { |
| 5650 | const union_obj = ty.cast(Payload.Union).?.data; | 5664 | const union_obj = ty.cast(Payload.Union).?.data; |
| 5651 | return union_obj.srcLoc(mod); | 5665 | return union_obj.srcLoc(mod); |
| 5652 | }, | 5666 | }, |
| 5667 | .@"opaque" => { | ||
| 5668 | const opaque_obj = ty.cast(Payload.Opaque).?.data; | ||
| 5669 | return opaque_obj.srcLoc(mod); | ||
| 5670 | }, | ||
| 5653 | .atomic_order, | 5671 | .atomic_order, |
| 5654 | .atomic_rmw_op, | 5672 | .atomic_rmw_op, |
| 5655 | .calling_convention, | 5673 | .calling_convention, |
test/cases/compile_errors/function_parameter_is_opaque.zig created+30| ... | @@ -0,0 +1,30 @@ | ||
| 1 | const FooType = opaque {}; | ||
| 2 | export fn entry1() void { | ||
| 3 | const someFuncPtr: fn (FooType) void = undefined; | ||
| 4 | _ = someFuncPtr; | ||
| 5 | } | ||
| 6 | |||
| 7 | export fn entry2() void { | ||
| 8 | const someFuncPtr: fn (@TypeOf(null)) void = undefined; | ||
| 9 | _ = someFuncPtr; | ||
| 10 | } | ||
| 11 | |||
| 12 | fn foo(p: FooType) void {_ = p;} | ||
| 13 | export fn entry3() void { | ||
| 14 | _ = foo; | ||
| 15 | } | ||
| 16 | |||
| 17 | fn bar(p: @TypeOf(null)) void {_ = p;} | ||
| 18 | export fn entry4() void { | ||
| 19 | _ = bar; | ||
| 20 | } | ||
| 21 | |||
| 22 | // error | ||
| 23 | // backend=stage2 | ||
| 24 | // target=native | ||
| 25 | // | ||
| 26 | // :3:24: error: parameter of opaque type 'tmp.FooType' not allowed | ||
| 27 | // :1:17: note: opaque declared here | ||
| 28 | // :8:24: error: parameter of type '@TypeOf(null)' not allowed | ||
| 29 | // :12:1: error: parameter of opaque type 'tmp.FooType' not allowed | ||
| 30 | // :17:1: error: parameter of type '@TypeOf(null)' not allowed | ||
test/cases/compile_errors/function_returning_opaque_type.zig created+19| ... | @@ -0,0 +1,19 @@ | ||
| 1 | const FooType = opaque {}; | ||
| 2 | export fn bar() !FooType { | ||
| 3 | return error.InvalidValue; | ||
| 4 | } | ||
| 5 | export fn bav() !@TypeOf(null) { | ||
| 6 | return error.InvalidValue; | ||
| 7 | } | ||
| 8 | export fn baz() !@TypeOf(undefined) { | ||
| 9 | return error.InvalidValue; | ||
| 10 | } | ||
| 11 | |||
| 12 | // error | ||
| 13 | // backend=stage2 | ||
| 14 | // target=native | ||
| 15 | // | ||
| 16 | // :2:18: error: opaque return type 'tmp.FooType' not allowed | ||
| 17 | // :1:17: note: opaque declared here | ||
| 18 | // :5:18: error: return type '@TypeOf(null)' not allowed | ||
| 19 | // :8:18: error: return type '@TypeOf(undefined)' not allowed | ||
test/cases/compile_errors/function_with_non-extern_non-packed_enum_parameter.zig created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | const Foo = enum { A, B, C }; | ||
| 2 | export fn entry(foo: Foo) void { _ = foo; } | ||
| 3 | |||
| 4 | // error | ||
| 5 | // backend=stage2 | ||
| 6 | // target=native | ||
| 7 | // | ||
| 8 | // :2:8: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C' | ||
| 9 | // :2:8: note: enum tag type 'u2' is not extern compatible | ||
| 10 | // :2:8: note: only integers with power of two bits are extern compatible | ||
| 11 | // :1:13: note: enum declared here | ||
test/cases/compile_errors/function_with_non-extern_non-packed_struct_parameter.zig created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | const Foo = struct { | ||
| 2 | A: i32, | ||
| 3 | B: f32, | ||
| 4 | C: bool, | ||
| 5 | }; | ||
| 6 | export fn entry(foo: Foo) void { _ = foo; } | ||
| 7 | |||
| 8 | // error | ||
| 9 | // backend=stage2 | ||
| 10 | // target=native | ||
| 11 | // | ||
| 12 | // :6:8: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C' | ||
| 13 | // :6:8: note: only structs with packed or extern layout are extern compatible | ||
| 14 | // :1:13: note: struct declared here | ||
test/cases/compile_errors/function_with_non-extern_non-packed_union_parameter.zig created+14| ... | @@ -0,0 +1,14 @@ | ||
| 1 | const Foo = union { | ||
| 2 | A: i32, | ||
| 3 | B: f32, | ||
| 4 | C: bool, | ||
| 5 | }; | ||
| 6 | export fn entry(foo: Foo) void { _ = foo; } | ||
| 7 | |||
| 8 | // error | ||
| 9 | // backend=stage2 | ||
| 10 | // target=native | ||
| 11 | // | ||
| 12 | // :6:8: error: parameter of type 'tmp.Foo' not allowed in function with calling convention 'C' | ||
| 13 | // :6:8: note: only unions with packed or extern layout are extern compatible | ||
| 14 | // :1:13: note: union declared here | ||
test/cases/compile_errors/stage1/obj/function_parameter_is_opaque.zig deleted-29| ... | @@ -1,29 +0,0 @@ | ||
| 1 | const FooType = opaque {}; | ||
| 2 | export fn entry1() void { | ||
| 3 | const someFuncPtr: fn (FooType) void = undefined; | ||
| 4 | _ = someFuncPtr; | ||
| 5 | } | ||
| 6 | |||
| 7 | export fn entry2() void { | ||
| 8 | const someFuncPtr: fn (@TypeOf(null)) void = undefined; | ||
| 9 | _ = someFuncPtr; | ||
| 10 | } | ||
| 11 | |||
| 12 | fn foo(p: FooType) void {_ = p;} | ||
| 13 | export fn entry3() void { | ||
| 14 | _ = foo; | ||
| 15 | } | ||
| 16 | |||
| 17 | fn bar(p: @TypeOf(null)) void {_ = p;} | ||
| 18 | export fn entry4() void { | ||
| 19 | _ = bar; | ||
| 20 | } | ||
| 21 | |||
| 22 | // error | ||
| 23 | // backend=stage1 | ||
| 24 | // target=native | ||
| 25 | // | ||
| 26 | // tmp.zig:3:28: error: parameter of opaque type 'FooType' not allowed | ||
| 27 | // tmp.zig:8:28: error: parameter of type '@Type(.Null)' not allowed | ||
| 28 | // tmp.zig:12:11: error: parameter of opaque type 'FooType' not allowed | ||
| 29 | // tmp.zig:17:11: error: parameter of type '@Type(.Null)' not allowed | ||
test/cases/compile_errors/stage1/obj/function_returning_opaque_type.zig deleted-19| ... | @@ -1,19 +0,0 @@ | ||
| 1 | const FooType = opaque {}; | ||
| 2 | export fn bar() !FooType { | ||
| 3 | return error.InvalidValue; | ||
| 4 | } | ||
| 5 | export fn bav() !@TypeOf(null) { | ||
| 6 | return error.InvalidValue; | ||
| 7 | } | ||
| 8 | export fn baz() !@TypeOf(undefined) { | ||
| 9 | return error.InvalidValue; | ||
| 10 | } | ||
| 11 | |||
| 12 | // error | ||
| 13 | // backend=stage1 | ||
| 14 | // target=native | ||
| 15 | // | ||
| 16 | // tmp.zig:2:18: error: Opaque return type 'FooType' not allowed | ||
| 17 | // tmp.zig:1:1: note: type declared here | ||
| 18 | // tmp.zig:5:18: error: Null return type '@Type(.Null)' not allowed | ||
| 19 | // tmp.zig:8:18: error: Undefined return type '@Type(.Undefined)' not allowed | ||
test/cases/compile_errors/stage1/obj/function_with_non-extern_non-packed_enum_parameter.zig deleted-8| ... | @@ -1,8 +0,0 @@ | ||
| 1 | const Foo = enum { A, B, C }; | ||
| 2 | export fn entry(foo: Foo) void { _ = foo; } | ||
| 3 | |||
| 4 | // error | ||
| 5 | // backend=stage1 | ||
| 6 | // target=native | ||
| 7 | // | ||
| 8 | // tmp.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C' | ||
test/cases/compile_errors/stage1/obj/function_with_non-extern_non-packed_struct_parameter.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const Foo = struct { | ||
| 2 | A: i32, | ||
| 3 | B: f32, | ||
| 4 | C: bool, | ||
| 5 | }; | ||
| 6 | export fn entry(foo: Foo) void { _ = foo; } | ||
| 7 | |||
| 8 | // error | ||
| 9 | // backend=stage1 | ||
| 10 | // target=native | ||
| 11 | // | ||
| 12 | // tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C' | ||
test/cases/compile_errors/stage1/obj/function_with_non-extern_non-packed_union_parameter.zig deleted-12| ... | @@ -1,12 +0,0 @@ | ||
| 1 | const Foo = union { | ||
| 2 | A: i32, | ||
| 3 | B: f32, | ||
| 4 | C: bool, | ||
| 5 | }; | ||
| 6 | export fn entry(foo: Foo) void { _ = foo; } | ||
| 7 | |||
| 8 | // error | ||
| 9 | // backend=stage1 | ||
| 10 | // target=native | ||
| 11 | // | ||
| 12 | // tmp.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'C' | ||