From 373b3586a1b1d6a3989220a8aac0d1c30f9fdb3a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 12 Apr 2018 16:26:23 -0400 Subject: [PATCH 1/4] inline functions must be stored in const or comptime var closes #913 --- src/ir.cpp | 14 +++++++++++++- test/cases/fn.zig | 7 +++++++ test/compile_errors.zig | 9 +++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ir.cpp b/src/ir.cpp index 7d8088d5e..3ba58a09b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11395,7 +11395,19 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc } break; case VarClassRequiredAny: - // OK + if (casted_init_value->value.special == ConstValSpecialStatic && + casted_init_value->value.type->id == TypeTableEntryIdFn && + casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) + { + var_class_requires_const = true; + if (!var->src_is_const && !is_comptime_var) { + ErrorMsg *msg = ir_add_error_node(ira, source_node, + buf_sprintf("functions marked inline must be stored in const or comptime var")); + AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; + add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); + result_type = ira->codegen->builtin_types.entry_invalid; + } + } break; } } diff --git a/test/cases/fn.zig b/test/cases/fn.zig index c125d98d8..5388deac1 100644 --- a/test/cases/fn.zig +++ b/test/cases/fn.zig @@ -104,3 +104,10 @@ test "number literal as an argument" { fn numberLiteralArg(a: var) void { assert(a == 3); } + +test "assign inline fn to const variable" { + const a = inlineFn; + a(); +} + +inline fn inlineFn() void { } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 21e384e38..b22816a9a 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1,6 +1,15 @@ const tests = @import("tests.zig"); pub fn addCases(cases: &tests.CompileErrorContext) void { + cases.add("assign inline fn to non-comptime var", + \\export fn entry() void { + \\ var a = b; + \\} + \\inline fn b() void { } + , + ".tmp_source.zig:2:5: error: functions marked inline must be stored in const or comptime var", + ".tmp_source.zig:4:8: note: declared here"); + cases.add("wrong type passed to @panic", \\export fn entry() void { \\ var e = error.Foo; From d4572d1140bb22aaeb587a66d3eee7bbdf162b1c Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 12 Apr 2018 21:23:18 -0400 Subject: [PATCH 2/4] zig fmt: container init fields each on own line See #911 --- std/zig/parser.zig | 91 +++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 25 deletions(-) diff --git a/std/zig/parser.zig b/std/zig/parser.zig index 8948990f4..3ad408afc 100644 --- a/std/zig/parser.zig +++ b/std/zig/parser.zig @@ -3579,33 +3579,45 @@ pub const Parser = struct { try stack.append(RenderState { .Expression = suffix_op.lhs }); }, ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| { - try stack.append(RenderState { .Text = " }"}); + if (field_inits.len == 0) { + try stack.append(RenderState { .Text = "{}" }); + try stack.append(RenderState { .Expression = suffix_op.lhs }); + continue; + } + try stack.append(RenderState { .Text = "}"}); + try stack.append(RenderState.PrintIndent); + try stack.append(RenderState { .Indent = indent }); var i = field_inits.len; while (i != 0) { i -= 1; const field_init = field_inits.at(i); + try stack.append(RenderState { .Text = ",\n" }); try stack.append(RenderState { .FieldInitializer = field_init }); - try stack.append(RenderState { .Text = " " }); - if (i != 0) { - try stack.append(RenderState { .Text = "," }); - } + try stack.append(RenderState.PrintIndent); } - try stack.append(RenderState { .Text = "{"}); + try stack.append(RenderState { .Indent = indent + indent_delta }); + try stack.append(RenderState { .Text = " {\n"}); try stack.append(RenderState { .Expression = suffix_op.lhs }); }, ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| { - try stack.append(RenderState { .Text = " }"}); + if (exprs.len == 0) { + try stack.append(RenderState { .Text = "{}" }); + try stack.append(RenderState { .Expression = suffix_op.lhs }); + continue; + } + try stack.append(RenderState { .Text = "}"}); + try stack.append(RenderState.PrintIndent); + try stack.append(RenderState { .Indent = indent }); var i = exprs.len; while (i != 0) { i -= 1; const expr = exprs.at(i); + try stack.append(RenderState { .Text = ",\n" }); try stack.append(RenderState { .Expression = expr }); - try stack.append(RenderState { .Text = " " }); - if (i != 0) { - try stack.append(RenderState { .Text = "," }); - } + try stack.append(RenderState.PrintIndent); } - try stack.append(RenderState { .Text = "{"}); + try stack.append(RenderState { .Indent = indent + indent_delta }); + try stack.append(RenderState { .Text = " {\n"}); try stack.append(RenderState { .Expression = suffix_op.lhs }); }, } @@ -4562,10 +4574,10 @@ test "zig fmt: precedence" { \\ (a!b)(); \\ !a!b; \\ !(a!b); - \\ !a{ }; - \\ !(a{ }); - \\ a + b{ }; - \\ (a + b){ }; + \\ !a{}; + \\ !(a{}); + \\ a + b{}; + \\ (a + b){}; \\ a << b + c; \\ (a << b) + c; \\ a & b << c; @@ -4805,9 +4817,15 @@ test "zig fmt: error set declaration" { test "zig fmt: arrays" { try testCanonical( \\test "test array" { - \\ const a: [2]u8 = [2]u8{ 1, 2 }; - \\ const a: [2]u8 = []u8{ 1, 2 }; - \\ const a: [0]u8 = []u8{ }; + \\ const a: [2]u8 = [2]u8 { + \\ 1, + \\ 2, + \\ }; + \\ const a: [2]u8 = []u8 { + \\ 1, + \\ 2, + \\ }; + \\ const a: [0]u8 = []u8{}; \\} \\ ); @@ -4815,10 +4833,18 @@ test "zig fmt: arrays" { test "zig fmt: container initializers" { try testCanonical( - \\const a1 = []u8{ }; - \\const a2 = []u8{ 1, 2, 3, 4 }; - \\const s1 = S{ }; - \\const s2 = S{ .a = 1, .b = 2 }; + \\const a1 = []u8{}; + \\const a2 = []u8 { + \\ 1, + \\ 2, + \\ 3, + \\ 4, + \\}; + \\const s1 = S{}; + \\const s2 = S { + \\ .a = 1, + \\ .b = 2, + \\}; \\ ); } @@ -4883,7 +4909,9 @@ test "zig fmt: switch" { \\ Float: f64 \\ }; \\ - \\ const u = Union{ .Int = 0 }; + \\ const u = Union { + \\ .Int = 0, + \\ }; \\ switch (u) { \\ Union.Int => |int| {}, \\ Union.Float => |*float| unreachable @@ -4962,7 +4990,11 @@ test "zig fmt: while" { test "zig fmt: for" { try testCanonical( \\test "for" { - \\ const a = []u8{ 1, 2, 3 }; + \\ const a = []u8 { + \\ 1, + \\ 2, + \\ 3, + \\ }; \\ for (a) |v| { \\ continue; \\ } @@ -5192,3 +5224,12 @@ test "zig fmt: error return" { \\ ); } + +test "zig fmt: struct literals with fields on each line" { + try testCanonical( + \\var self = BufSet { + \\ .hash_map = BufSetHashMap.init(a), + \\}; + \\ + ); +} From 9e701e951b637b5627a25d9530c074d2900d9362 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 12 Apr 2018 21:39:45 -0400 Subject: [PATCH 3/4] zig fmt includes trailing commas See #911 --- std/zig/parser.zig | 64 +++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 37 deletions(-) diff --git a/std/zig/parser.zig b/std/zig/parser.zig index 3ad408afc..91623ba59 100644 --- a/std/zig/parser.zig +++ b/std/zig/parser.zig @@ -3758,6 +3758,14 @@ pub const Parser = struct { while (i != 0) { i -= 1; const node = fields_and_decls[i]; + switch (node.id) { + ast.Node.Id.StructField, + ast.Node.Id.UnionTag, + ast.Node.Id.EnumTag => { + try stack.append(RenderState { .Text = "," }); + }, + else => { } + } try stack.append(RenderState { .TopLevelDecl = node}); try stack.append(RenderState.PrintIndent); try stack.append(RenderState { @@ -3772,18 +3780,6 @@ pub const Parser = struct { break :blk "\n"; }, }); - - if (i != 0) { - const prev_node = fields_and_decls[i - 1]; - switch (prev_node.id) { - ast.Node.Id.StructField, - ast.Node.Id.UnionTag, - ast.Node.Id.EnumTag => { - try stack.append(RenderState { .Text = "," }); - }, - else => { } - } - } } try stack.append(RenderState { .Indent = indent + indent_delta}); try stack.append(RenderState { .Text = "{"}); @@ -3812,6 +3808,7 @@ pub const Parser = struct { while (i != 0) { i -= 1; const node = decls[i]; + try stack.append(RenderState { .Text = "," }); try stack.append(RenderState { .Expression = &node.base}); try stack.append(RenderState.PrintIndent); try stack.append(RenderState { @@ -3826,10 +3823,6 @@ pub const Parser = struct { break :blk "\n"; }, }); - - if (i != 0) { - try stack.append(RenderState { .Text = "," }); - } } try stack.append(RenderState { .Indent = indent + indent_delta}); try stack.append(RenderState { .Text = "{"}); @@ -3942,6 +3935,7 @@ pub const Parser = struct { while (i != 0) { i -= 1; const node = cases[i]; + try stack.append(RenderState { .Text = ","}); try stack.append(RenderState { .Expression = &node.base}); try stack.append(RenderState.PrintIndent); try stack.append(RenderState { @@ -3956,10 +3950,6 @@ pub const Parser = struct { break :blk "\n"; }, }); - - if (i != 0) { - try stack.append(RenderState { .Text = "," }); - } } try stack.append(RenderState { .Indent = indent + indent_delta}); try stack.append(RenderState { .Text = ") {"}); @@ -4714,21 +4704,21 @@ test "zig fmt: struct declaration" { \\ return *self; \\ } \\ - \\ f2: u8 + \\ f2: u8, \\}; \\ \\const Ps = packed struct { \\ a: u8, \\ pub b: u8, \\ - \\ c: u8 + \\ c: u8, \\}; \\ \\const Es = extern struct { \\ a: u8, \\ pub b: u8, \\ - \\ c: u8 + \\ c: u8, \\}; \\ ); @@ -4738,25 +4728,25 @@ test "zig fmt: enum declaration" { try testCanonical( \\const E = enum { \\ Ok, - \\ SomethingElse = 0 + \\ SomethingElse = 0, \\}; \\ \\const E2 = enum(u8) { \\ Ok, \\ SomethingElse = 255, - \\ SomethingThird + \\ SomethingThird, \\}; \\ \\const Ee = extern enum { \\ Ok, \\ SomethingElse, - \\ SomethingThird + \\ SomethingThird, \\}; \\ \\const Ep = packed enum { \\ Ok, \\ SomethingElse, - \\ SomethingThird + \\ SomethingThird, \\}; \\ ); @@ -4768,35 +4758,35 @@ test "zig fmt: union declaration" { \\ Int: u8, \\ Float: f32, \\ None, - \\ Bool: bool + \\ Bool: bool, \\}; \\ \\const Ue = union(enum) { \\ Int: u8, \\ Float: f32, \\ None, - \\ Bool: bool + \\ Bool: bool, \\}; \\ \\const E = enum { \\ Int, \\ Float, \\ None, - \\ Bool + \\ Bool, \\}; \\ \\const Ue2 = union(E) { \\ Int: u8, \\ Float: f32, \\ None, - \\ Bool: bool + \\ Bool: bool, \\}; \\ \\const Eu = extern union { \\ Int: u8, \\ Float: f32, \\ None, - \\ Bool: bool + \\ Bool: bool, \\}; \\ ); @@ -4808,7 +4798,7 @@ test "zig fmt: error set declaration" { \\ A, \\ B, \\ - \\ C + \\ C, \\}; \\ ); @@ -4894,19 +4884,19 @@ test "zig fmt: switch" { \\ else => { \\ const a = 1; \\ const b = a; - \\ } + \\ }, \\ } \\ \\ const res = switch (0) { \\ 0 => 0, \\ 1 => 2, \\ 1 => a = 4, - \\ else => 4 + \\ else => 4, \\ }; \\ \\ const Union = union(enum) { \\ Int: i64, - \\ Float: f64 + \\ Float: f64, \\ }; \\ \\ const u = Union { @@ -4914,7 +4904,7 @@ test "zig fmt: switch" { \\ }; \\ switch (u) { \\ Union.Int => |int| {}, - \\ Union.Float => |*float| unreachable + \\ Union.Float => |*float| unreachable, \\ } \\} \\ From 0f652b4d80a57f5b5a1054d06cd5767ce52402a1 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 12 Apr 2018 21:56:12 -0400 Subject: [PATCH 4/4] zig fmt: switch cases on new lines See #911 --- std/zig/parser.zig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/std/zig/parser.zig b/std/zig/parser.zig index 91623ba59..1aa299b49 100644 --- a/std/zig/parser.zig +++ b/std/zig/parser.zig @@ -3972,7 +3972,8 @@ pub const Parser = struct { try stack.append(RenderState { .Expression = items[i] }); if (i != 0) { - try stack.append(RenderState { .Text = ", " }); + try stack.append(RenderState.PrintIndent); + try stack.append(RenderState { .Text = ",\n" }); } } }, @@ -4878,7 +4879,8 @@ test "zig fmt: switch" { \\ switch (0) { \\ 0 => {}, \\ 1 => unreachable, - \\ 2, 3 => {}, + \\ 2, + \\ 3 => {}, \\ 4 ... 7 => {}, \\ 1 + 4 * 3 + 22 => {}, \\ else => {