From d769fd0102dee7ea24f957c3c96e2336d1c18839 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 8 Aug 2022 22:51:08 +0300 Subject: [PATCH] stage2: pass anon name strategy to reify --- src/AstGen.zig | 26 ++++++++++++-- src/Autodoc.zig | 2 +- src/Sema.zig | 24 +++++++------ src/Zir.zig | 9 +++-- src/print_zir.zig | 2 +- ...or_tagged_union_with_extra_union_field.zig | 35 +++++++++++++++++++ 6 files changed, 78 insertions(+), 20 deletions(-) create mode 100644 test/cases/compile_errors/reify_type_for_tagged_union_with_extra_union_field.zig diff --git a/src/AstGen.zig b/src/AstGen.zig index 9c8252da55..ffe489a216 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2454,7 +2454,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .trunc, .round, .tag_name, - .reify, .type_name, .frame_type, .frame_size, @@ -7553,7 +7552,6 @@ fn builtinCall( .trunc => return simpleUnOp(gz, scope, rl, node, .none, params[0], .trunc), .round => return simpleUnOp(gz, scope, rl, node, .none, params[0], .round), .tag_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .tag_name), - .Type => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .type_info_type }, params[0], .reify), .type_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .type_name), .Frame => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_type), .frame_size => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_size), @@ -7568,6 +7566,30 @@ fn builtinCall( .truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate), // zig fmt: on + .Type => { + const operand = try expr(gz, scope, .{ .coerced_ty = .type_info_type }, params[0]); + + const gpa = gz.astgen.gpa; + + try gz.instructions.ensureUnusedCapacity(gpa, 1); + try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); + + const payload_index = try gz.astgen.addExtra(Zir.Inst.UnNode{ + .node = gz.nodeIndexToRelative(node), + .operand = operand, + }); + const new_index = @intCast(Zir.Inst.Index, gz.astgen.instructions.len); + gz.astgen.instructions.appendAssumeCapacity(.{ + .tag = .extended, + .data = .{ .extended = .{ + .opcode = .reify, + .small = @enumToInt(gz.anon_name_strategy), + .operand = payload_index, + } }, + }); + gz.instructions.appendAssumeCapacity(new_index); + return indexToRef(new_index); + }, .panic => { try emitDbgNode(gz, node); return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], if (gz.force_comptime) .panic_comptime else .panic); diff --git a/src/Autodoc.zig b/src/Autodoc.zig index c2b0359c64..9e3874979d 100644 --- a/src/Autodoc.zig +++ b/src/Autodoc.zig @@ -1220,7 +1220,6 @@ fn walkInstruction( .trunc, .round, .tag_name, - .reify, .type_name, .frame_type, .frame_size, @@ -2605,6 +2604,7 @@ fn walkInstruction( }, .error_to_int, .int_to_error, + .reify, => { const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data; const bin_index = self.exprs.items.len; diff --git a/src/Sema.zig b/src/Sema.zig index 2f3c931e16..c91f4cddb1 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -816,7 +816,6 @@ fn analyzeBodyInner( .embed_file => try sema.zirEmbedFile(block, inst), .error_name => try sema.zirErrorName(block, inst), .tag_name => try sema.zirTagName(block, inst), - .reify => try sema.zirReify(block, inst), .type_name => try sema.zirTypeName(block, inst), .frame_type => try sema.zirFrameType(block, inst), .frame_size => try sema.zirFrameSize(block, inst), @@ -951,6 +950,7 @@ fn analyzeBodyInner( .select => try sema.zirSelect( block, extended), .error_to_int => try sema.zirErrorToInt( block, extended), .int_to_error => try sema.zirIntToError( block, extended), + .reify => try sema.zirReify( block, extended, inst), // zig fmt: on .fence => { try sema.zirFence(block, extended); @@ -16023,13 +16023,14 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air return block.addUnOp(.tag_name, casted_operand); } -fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { +fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { const mod = sema.mod; - const inst_data = sema.code.instructions.items(.data)[inst].un_node; - const src = inst_data.src(); + const name_strategy = @intToEnum(Zir.Inst.NameStrategy, extended.small); + const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; + const src = LazySrcLoc.nodeOffset(extra.node); const type_info_ty = try sema.resolveBuiltinTypeFields(block, src, "Type"); - const uncasted_operand = try sema.resolveInst(inst_data.operand); - const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const uncasted_operand = try sema.resolveInst(extra.operand); + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src); const val = try sema.resolveConstValue(block, operand_src, type_info, "operand to @Type must be comptime known"); const union_val = val.cast(Value.Payload.Union).?.data; @@ -16289,7 +16290,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I return if (is_tuple_val.toBool()) try sema.reifyTuple(block, src, fields_val) else - try sema.reifyStruct(block, inst, src, layout_val, fields_val); + try sema.reifyStruct(block, inst, src, layout_val, fields_val, name_strategy); }, .Enum => { const struct_val = union_val.val.castTag(.aggregate).?.data; @@ -16338,7 +16339,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{ .ty = Type.type, .val = enum_val, - }, .anon, "enum", null); + }, name_strategy, "enum", inst); const new_decl = mod.declPtr(new_decl_index); new_decl.owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -16435,7 +16436,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{ .ty = Type.type, .val = opaque_val, - }, .anon, "opaque", null); + }, name_strategy, "opaque", inst); const new_decl = mod.declPtr(new_decl_index); new_decl.owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -16494,7 +16495,7 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{ .ty = Type.type, .val = new_union_val, - }, .anon, "union", null); + }, name_strategy, "union", inst); const new_decl = mod.declPtr(new_decl_index); new_decl.owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); @@ -16787,6 +16788,7 @@ fn reifyStruct( src: LazySrcLoc, layout_val: Value, fields_val: Value, + name_strategy: Zir.Inst.NameStrategy, ) CompileError!Air.Inst.Ref { var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa); errdefer new_decl_arena.deinit(); @@ -16799,7 +16801,7 @@ fn reifyStruct( const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{ .ty = Type.type, .val = new_struct_val, - }, .anon, "struct", null); + }, name_strategy, "struct", inst); const new_decl = mod.declPtr(new_decl_index); new_decl.owns_tv = true; errdefer mod.abortAnonDecl(new_decl_index); diff --git a/src/Zir.zig b/src/Zir.zig index 6427420840..c5618a58c0 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -839,8 +839,6 @@ pub const Inst = struct { round, /// Implement builtin `@tagName`. Uses `un_node`. tag_name, - /// Implement builtin `@Type`. Uses `un_node`. - reify, /// Implement builtin `@typeName`. Uses `un_node`. type_name, /// Implement builtin `@Frame`. Uses `un_node`. @@ -1197,7 +1195,6 @@ pub const Inst = struct { .trunc, .round, .tag_name, - .reify, .type_name, .frame_type, .frame_size, @@ -1484,7 +1481,6 @@ pub const Inst = struct { .trunc, .round, .tag_name, - .reify, .type_name, .frame_type, .frame_size, @@ -1759,7 +1755,6 @@ pub const Inst = struct { .trunc = .un_node, .round = .un_node, .tag_name = .un_node, - .reify = .un_node, .type_name = .un_node, .frame_type = .un_node, .frame_size = .un_node, @@ -1980,6 +1975,10 @@ pub const Inst = struct { /// Implement builtin `@intToError`. /// `operand` is payload index to `UnNode`. int_to_error, + /// Implement builtin `@Type`. + /// `operand` is payload index to `UnNode`. + /// `small` contains `NameStrategy + reify, pub const InstData = struct { opcode: Extended, diff --git a/src/print_zir.zig b/src/print_zir.zig index 6e33154bbd..ca2368fe10 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -214,7 +214,6 @@ const Writer = struct { .trunc, .round, .tag_name, - .reify, .type_name, .frame_type, .frame_size, @@ -500,6 +499,7 @@ const Writer = struct { .wasm_memory_size, .error_to_int, .int_to_error, + .reify, => { const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(inst_data.node); diff --git a/test/cases/compile_errors/reify_type_for_tagged_union_with_extra_union_field.zig b/test/cases/compile_errors/reify_type_for_tagged_union_with_extra_union_field.zig new file mode 100644 index 0000000000..9d6170b9d0 --- /dev/null +++ b/test/cases/compile_errors/reify_type_for_tagged_union_with_extra_union_field.zig @@ -0,0 +1,35 @@ +const Tag = @Type(.{ + .Enum = .{ + .layout = .Auto, + .tag_type = u1, + .fields = &.{ + .{ .name = "signed", .value = 0 }, + .{ .name = "unsigned", .value = 1 }, + }, + .decls = &.{}, + .is_exhaustive = true, + }, +}); +const Tagged = @Type(.{ + .Union = .{ + .layout = .Auto, + .tag_type = Tag, + .fields = &.{ + .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) }, + .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) }, + .{ .name = "arst", .field_type = f32, .alignment = @alignOf(f32) }, + }, + .decls = &.{}, + }, +}); +export fn entry() void { + var tagged = Tagged{ .signed = -1 }; + tagged = .{ .unsigned = 1 }; +} + +// error +// backend=stage2 +// target=native +// +// :13:16: error: no field named 'arst' in enum 'tmp.Tag' +// :1:13: note: enum declared here