Merged with master

master
Jimmi Holst Christensen 2018-04-13 10:40:37 +02:00
commit a498993fd1
4 changed files with 126 additions and 65 deletions

View File

@ -11395,7 +11395,19 @@ static TypeTableEntry *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstruc
} }
break; break;
case VarClassRequiredAny: 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; break;
} }
} }

View File

@ -3614,33 +3614,45 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = suffix_op.lhs }); try stack.append(RenderState { .Expression = suffix_op.lhs });
}, },
ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| { 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; var i = field_inits.len;
while (i != 0) { while (i != 0) {
i -= 1; i -= 1;
const field_init = field_inits.at(i); const field_init = field_inits.at(i);
try stack.append(RenderState { .Text = ",\n" });
try stack.append(RenderState { .FieldInitializer = field_init }); try stack.append(RenderState { .FieldInitializer = field_init });
try stack.append(RenderState { .Text = " " }); try stack.append(RenderState.PrintIndent);
if (i != 0) {
try stack.append(RenderState { .Text = "," });
}
} }
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 }); try stack.append(RenderState { .Expression = suffix_op.lhs });
}, },
ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| { 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; var i = exprs.len;
while (i != 0) { while (i != 0) {
i -= 1; i -= 1;
const expr = exprs.at(i); const expr = exprs.at(i);
try stack.append(RenderState { .Text = ",\n" });
try stack.append(RenderState { .Expression = expr }); try stack.append(RenderState { .Expression = expr });
try stack.append(RenderState { .Text = " " }); try stack.append(RenderState.PrintIndent);
if (i != 0) {
try stack.append(RenderState { .Text = "," });
}
} }
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 }); try stack.append(RenderState { .Expression = suffix_op.lhs });
}, },
} }
@ -3784,6 +3796,14 @@ pub const Parser = struct {
while (i != 0) { while (i != 0) {
i -= 1; i -= 1;
const node = fields_and_decls[i]; 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 { .TopLevelDecl = node});
try stack.append(RenderState.PrintIndent); try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { try stack.append(RenderState {
@ -3798,18 +3818,6 @@ pub const Parser = struct {
break :blk "\n"; 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 { .Indent = indent + indent_delta});
try stack.append(RenderState { .Text = "{"}); try stack.append(RenderState { .Text = "{"});
@ -3838,6 +3846,7 @@ pub const Parser = struct {
while (i != 0) { while (i != 0) {
i -= 1; i -= 1;
const node = decls[i]; const node = decls[i];
try stack.append(RenderState { .Text = "," });
try stack.append(RenderState { .Expression = node }); try stack.append(RenderState { .Expression = node });
try stack.append(RenderState.PrintIndent); try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { try stack.append(RenderState {
@ -3852,10 +3861,6 @@ pub const Parser = struct {
break :blk "\n"; break :blk "\n";
}, },
}); });
if (i != 0) {
try stack.append(RenderState { .Text = "," });
}
} }
try stack.append(RenderState { .Indent = indent + indent_delta}); try stack.append(RenderState { .Indent = indent + indent_delta});
try stack.append(RenderState { .Text = "{"}); try stack.append(RenderState { .Text = "{"});
@ -3968,6 +3973,7 @@ pub const Parser = struct {
while (i != 0) { while (i != 0) {
i -= 1; i -= 1;
const node = cases[i]; const node = cases[i];
try stack.append(RenderState { .Text = ","});
try stack.append(RenderState { .Expression = &node.base}); try stack.append(RenderState { .Expression = &node.base});
try stack.append(RenderState.PrintIndent); try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { try stack.append(RenderState {
@ -3982,10 +3988,6 @@ pub const Parser = struct {
break :blk "\n"; break :blk "\n";
}, },
}); });
if (i != 0) {
try stack.append(RenderState { .Text = "," });
}
} }
try stack.append(RenderState { .Indent = indent + indent_delta}); try stack.append(RenderState { .Indent = indent + indent_delta});
try stack.append(RenderState { .Text = ") {"}); try stack.append(RenderState { .Text = ") {"});
@ -4008,7 +4010,8 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = items[i] }); try stack.append(RenderState { .Expression = items[i] });
if (i != 0) { if (i != 0) {
try stack.append(RenderState { .Text = ", " }); try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { .Text = ",\n" });
} }
} }
}, },
@ -4600,10 +4603,10 @@ test "zig fmt: precedence" {
\\ (a!b)(); \\ (a!b)();
\\ !a!b; \\ !a!b;
\\ !(a!b); \\ !(a!b);
\\ !a{ }; \\ !a{};
\\ !(a{ }); \\ !(a{});
\\ a + b{ }; \\ a + b{};
\\ (a + b){ }; \\ (a + b){};
\\ a << b + c; \\ a << b + c;
\\ (a << b) + c; \\ (a << b) + c;
\\ a & b << c; \\ a & b << c;
@ -4740,21 +4743,21 @@ test "zig fmt: struct declaration" {
\\ return *self; \\ return *self;
\\ } \\ }
\\ \\
\\ f2: u8 \\ f2: u8,
\\}; \\};
\\ \\
\\const Ps = packed struct { \\const Ps = packed struct {
\\ a: u8, \\ a: u8,
\\ pub b: u8, \\ pub b: u8,
\\ \\
\\ c: u8 \\ c: u8,
\\}; \\};
\\ \\
\\const Es = extern struct { \\const Es = extern struct {
\\ a: u8, \\ a: u8,
\\ pub b: u8, \\ pub b: u8,
\\ \\
\\ c: u8 \\ c: u8,
\\}; \\};
\\ \\
); );
@ -4764,25 +4767,25 @@ test "zig fmt: enum declaration" {
try testCanonical( try testCanonical(
\\const E = enum { \\const E = enum {
\\ Ok, \\ Ok,
\\ SomethingElse = 0 \\ SomethingElse = 0,
\\}; \\};
\\ \\
\\const E2 = enum(u8) { \\const E2 = enum(u8) {
\\ Ok, \\ Ok,
\\ SomethingElse = 255, \\ SomethingElse = 255,
\\ SomethingThird \\ SomethingThird,
\\}; \\};
\\ \\
\\const Ee = extern enum { \\const Ee = extern enum {
\\ Ok, \\ Ok,
\\ SomethingElse, \\ SomethingElse,
\\ SomethingThird \\ SomethingThird,
\\}; \\};
\\ \\
\\const Ep = packed enum { \\const Ep = packed enum {
\\ Ok, \\ Ok,
\\ SomethingElse, \\ SomethingElse,
\\ SomethingThird \\ SomethingThird,
\\}; \\};
\\ \\
); );
@ -4794,35 +4797,35 @@ test "zig fmt: union declaration" {
\\ Int: u8, \\ Int: u8,
\\ Float: f32, \\ Float: f32,
\\ None, \\ None,
\\ Bool: bool \\ Bool: bool,
\\}; \\};
\\ \\
\\const Ue = union(enum) { \\const Ue = union(enum) {
\\ Int: u8, \\ Int: u8,
\\ Float: f32, \\ Float: f32,
\\ None, \\ None,
\\ Bool: bool \\ Bool: bool,
\\}; \\};
\\ \\
\\const E = enum { \\const E = enum {
\\ Int, \\ Int,
\\ Float, \\ Float,
\\ None, \\ None,
\\ Bool \\ Bool,
\\}; \\};
\\ \\
\\const Ue2 = union(E) { \\const Ue2 = union(E) {
\\ Int: u8, \\ Int: u8,
\\ Float: f32, \\ Float: f32,
\\ None, \\ None,
\\ Bool: bool \\ Bool: bool,
\\}; \\};
\\ \\
\\const Eu = extern union { \\const Eu = extern union {
\\ Int: u8, \\ Int: u8,
\\ Float: f32, \\ Float: f32,
\\ None, \\ None,
\\ Bool: bool \\ Bool: bool,
\\}; \\};
\\ \\
); );
@ -4834,7 +4837,7 @@ test "zig fmt: error set declaration" {
\\ A, \\ A,
\\ B, \\ B,
\\ \\
\\ C \\ C,
\\}; \\};
\\ \\
); );
@ -4843,9 +4846,15 @@ test "zig fmt: error set declaration" {
test "zig fmt: arrays" { test "zig fmt: arrays" {
try testCanonical( try testCanonical(
\\test "test array" { \\test "test array" {
\\ const a: [2]u8 = [2]u8{ 1, 2 }; \\ const a: [2]u8 = [2]u8 {
\\ const a: [2]u8 = []u8{ 1, 2 }; \\ 1,
\\ const a: [0]u8 = []u8{ }; \\ 2,
\\ };
\\ const a: [2]u8 = []u8 {
\\ 1,
\\ 2,
\\ };
\\ const a: [0]u8 = []u8{};
\\} \\}
\\ \\
); );
@ -4853,10 +4862,18 @@ test "zig fmt: arrays" {
test "zig fmt: container initializers" { test "zig fmt: container initializers" {
try testCanonical( try testCanonical(
\\const a1 = []u8{ }; \\const a1 = []u8{};
\\const a2 = []u8{ 1, 2, 3, 4 }; \\const a2 = []u8 {
\\const s1 = S{ }; \\ 1,
\\const s2 = S{ .a = 1, .b = 2 }; \\ 2,
\\ 3,
\\ 4,
\\};
\\const s1 = S{};
\\const s2 = S {
\\ .a = 1,
\\ .b = 2,
\\};
\\ \\
); );
} }
@ -4900,31 +4917,34 @@ test "zig fmt: switch" {
\\ switch (0) { \\ switch (0) {
\\ 0 => {}, \\ 0 => {},
\\ 1 => unreachable, \\ 1 => unreachable,
\\ 2, 3 => {}, \\ 2,
\\ 3 => {},
\\ 4 ... 7 => {}, \\ 4 ... 7 => {},
\\ 1 + 4 * 3 + 22 => {}, \\ 1 + 4 * 3 + 22 => {},
\\ else => { \\ else => {
\\ const a = 1; \\ const a = 1;
\\ const b = a; \\ const b = a;
\\ } \\ },
\\ } \\ }
\\ \\
\\ const res = switch (0) { \\ const res = switch (0) {
\\ 0 => 0, \\ 0 => 0,
\\ 1 => 2, \\ 1 => 2,
\\ 1 => a = 4, \\ 1 => a = 4,
\\ else => 4 \\ else => 4,
\\ }; \\ };
\\ \\
\\ const Union = union(enum) { \\ const Union = union(enum) {
\\ Int: i64, \\ Int: i64,
\\ Float: f64 \\ Float: f64,
\\ }; \\ };
\\ \\
\\ const u = Union{ .Int = 0 }; \\ const u = Union {
\\ .Int = 0,
\\ };
\\ switch (u) { \\ switch (u) {
\\ Union.Int => |int| {}, \\ Union.Int => |int| {},
\\ Union.Float => |*float| unreachable \\ Union.Float => |*float| unreachable,
\\ } \\ }
\\} \\}
\\ \\
@ -5000,7 +5020,11 @@ test "zig fmt: while" {
test "zig fmt: for" { test "zig fmt: for" {
try testCanonical( try testCanonical(
\\test "for" { \\test "for" {
\\ const a = []u8{ 1, 2, 3 }; \\ const a = []u8 {
\\ 1,
\\ 2,
\\ 3,
\\ };
\\ for (a) |v| { \\ for (a) |v| {
\\ continue; \\ continue;
\\ } \\ }
@ -5230,3 +5254,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),
\\};
\\
);
}

View File

@ -104,3 +104,10 @@ test "number literal as an argument" {
fn numberLiteralArg(a: var) void { fn numberLiteralArg(a: var) void {
assert(a == 3); assert(a == 3);
} }
test "assign inline fn to const variable" {
const a = inlineFn;
a();
}
inline fn inlineFn() void { }

View File

@ -1,6 +1,15 @@
const tests = @import("tests.zig"); const tests = @import("tests.zig");
pub fn addCases(cases: &tests.CompileErrorContext) void { 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", cases.add("wrong type passed to @panic",
\\export fn entry() void { \\export fn entry() void {
\\ var e = error.Foo; \\ var e = error.Foo;