Commit bd8b5c25ec
Changed files (3)
test
cases
compile_errors
src/Sema.zig
@@ -6565,7 +6565,10 @@ fn analyzeCall(
};
if (modifier == .never_inline and func_ty_info.cc == .Inline) {
- return sema.fail(block, call_src, "no-inline call of inline function", .{});
+ return sema.fail(block, call_src, "'never_inline' call of inline function", .{});
+ }
+ if (modifier == .always_inline and func_ty_info.is_noinline) {
+ return sema.fail(block, call_src, "'always_inline' call of noinline function", .{});
}
const gpa = sema.gpa;
@@ -8784,7 +8787,8 @@ fn funcCommon(
if (!is_generic and block.params.items.len == 0 and !var_args and !inferred_error_set and
alignment.? == 0 and
address_space.? == target_util.defaultAddressSpace(target, .function) and
- section == .default)
+ section == .default and
+ !is_noinline)
{
if (bare_return_type.zigTypeTag() == .NoReturn and cc.? == .Unspecified) {
break :fn_ty Type.initTag(.fn_noreturn_no_args);
@@ -9002,6 +9006,7 @@ fn funcCommon(
.addrspace_is_generic = address_space == null,
.is_var_args = var_args,
.is_generic = is_generic,
+ .is_noinline = is_noinline,
.noalias_bits = noalias_bits,
});
};
@@ -19217,6 +19222,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
.cc = cc,
.is_var_args = is_var_args,
.is_generic = false,
+ .is_noinline = false,
.align_is_generic = false,
.cc_is_generic = false,
.section_is_generic = false,
src/type.zig
@@ -666,6 +666,9 @@ pub const Type = extern union {
if (a_info.is_generic != b_info.is_generic)
return false;
+ if (a_info.is_noinline != b_info.is_noinline)
+ return false;
+
if (a_info.noalias_bits != b_info.noalias_bits)
return false;
@@ -1074,6 +1077,7 @@ pub const Type = extern union {
}
std.hash.autoHash(hasher, fn_info.is_var_args);
std.hash.autoHash(hasher, fn_info.is_generic);
+ std.hash.autoHash(hasher, fn_info.is_noinline);
std.hash.autoHash(hasher, fn_info.noalias_bits);
std.hash.autoHash(hasher, fn_info.param_types.len);
@@ -1454,6 +1458,7 @@ pub const Type = extern union {
.alignment = payload.alignment,
.is_var_args = payload.is_var_args,
.is_generic = payload.is_generic,
+ .is_noinline = payload.is_noinline,
.comptime_params = comptime_params.ptr,
.align_is_generic = payload.align_is_generic,
.cc_is_generic = payload.cc_is_generic,
@@ -2069,6 +2074,9 @@ pub const Type = extern union {
.function => {
const fn_info = ty.fnInfo();
+ if (fn_info.is_noinline) {
+ try writer.writeAll("noinline ");
+ }
try writer.writeAll("fn(");
for (fn_info.param_types, 0..) |param_ty, i| {
if (i != 0) try writer.writeAll(", ");
@@ -4863,6 +4871,7 @@ pub const Type = extern union {
.alignment = 0,
.is_var_args = false,
.is_generic = false,
+ .is_noinline = false,
.align_is_generic = false,
.cc_is_generic = false,
.section_is_generic = false,
@@ -4877,6 +4886,7 @@ pub const Type = extern union {
.alignment = 0,
.is_var_args = false,
.is_generic = false,
+ .is_noinline = false,
.align_is_generic = false,
.cc_is_generic = false,
.section_is_generic = false,
@@ -4891,6 +4901,7 @@ pub const Type = extern union {
.alignment = 0,
.is_var_args = false,
.is_generic = false,
+ .is_noinline = false,
.align_is_generic = false,
.cc_is_generic = false,
.section_is_generic = false,
@@ -4905,6 +4916,7 @@ pub const Type = extern union {
.alignment = 0,
.is_var_args = false,
.is_generic = false,
+ .is_noinline = false,
.align_is_generic = false,
.cc_is_generic = false,
.section_is_generic = false,
@@ -6367,6 +6379,7 @@ pub const Type = extern union {
cc: std.builtin.CallingConvention,
is_var_args: bool,
is_generic: bool,
+ is_noinline: bool,
align_is_generic: bool,
cc_is_generic: bool,
section_is_generic: bool,
test/cases/compile_errors/bad_usage_of_call.zig
@@ -14,14 +14,25 @@ export fn entry5(c: bool) void {
var baz = if (c) &baz1 else &baz2;
@call(.compile_time, baz, .{});
}
+export fn entry6() void {
+ _ = @call(.always_inline, dummy, .{});
+}
+export fn entry7() void {
+ _ = @call(.always_inline, dummy2, .{});
+}
pub export fn entry() void {
var call_me: *const fn () void = undefined;
@call(.always_inline, call_me, .{});
}
+
fn foo() void {}
-fn bar() callconv(.Inline) void {}
+inline fn bar() void {}
fn baz1() void {}
fn baz2() void {}
+noinline fn dummy() u32 {
+ return 0;
+}
+noinline fn dummy2() void {}
// error
// backend=stage2
@@ -30,7 +41,8 @@ fn baz2() void {}
// :2:23: error: expected a tuple, found 'void'
// :5:21: error: unable to perform 'never_inline' call at compile-time
// :8:21: error: unable to perform 'never_tail' call at compile-time
-// :11:5: error: no-inline call of inline function
+// :11:5: error: 'never_inline' call of inline function
// :15:26: error: modifier 'compile_time' requires a comptime-known function
-// :19:27: error: modifier 'always_inline' requires a comptime-known function
-
+// :18:9: error: 'always_inline' call of noinline function
+// :21:9: error: 'always_inline' call of noinline function
+// :25:27: error: modifier 'always_inline' requires a comptime-known function