authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-29 17:13:18-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-29 17:13:18-07:00
log9e49a65e1bd474f0f678465fb4b965ddc5899226
tree06a5c5982192f100dc6c0ecad8afba507e1ed579
parent55e86b724a2ce60b777bd94d1203f243435727b7

AstGen: implement anytype struct fields


4 files changed, 25 insertions(+), 13 deletions(-)

src/AstGen.zig+9-4
...@@ -483,6 +483,8 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn...@@ -483,6 +483,8 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
483 .asm_output => unreachable, // Handled in `asmExpr`.483 .asm_output => unreachable, // Handled in `asmExpr`.
484 .asm_input => unreachable, // Handled in `asmExpr`.484 .asm_input => unreachable, // Handled in `asmExpr`.
485485
486 .@"anytype" => unreachable, // Handled in `containerDecl`.
487
486 .assign => {488 .assign => {
487 try assign(gz, scope, node);489 try assign(gz, scope, node);
488 return rvalue(gz, scope, rl, .void_value, node);490 return rvalue(gz, scope, rl, .void_value, node);
...@@ -869,8 +871,6 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn...@@ -869,8 +871,6 @@ pub fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) Inn
869 .struct_init_comma,871 .struct_init_comma,
870 => return structInitExpr(gz, scope, rl, node, tree.structInit(node)),872 => return structInitExpr(gz, scope, rl, node, tree.structInit(node)),
871873
872 .@"anytype" => return astgen.failNode(node, "TODO implement astgen.expr for .anytype", .{}),
873
874 .fn_proto_simple => {874 .fn_proto_simple => {
875 var params: [1]ast.Node.Index = undefined;875 var params: [1]ast.Node.Index = undefined;
876 return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node));876 return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node));
...@@ -3318,7 +3318,10 @@ fn structDeclInner(...@@ -3318,7 +3318,10 @@ fn structDeclInner(
3318 const field_name = try gz.identAsString(member.ast.name_token);3318 const field_name = try gz.identAsString(member.ast.name_token);
3319 fields_data.appendAssumeCapacity(field_name);3319 fields_data.appendAssumeCapacity(field_name);
33203320
3321 const field_type = try typeExpr(&block_scope, &block_scope.base, member.ast.type_expr);3321 const field_type: Zir.Inst.Ref = if (node_tags[member.ast.type_expr] == .@"anytype")
3322 .none
3323 else
3324 try typeExpr(&block_scope, &block_scope.base, member.ast.type_expr);
3322 fields_data.appendAssumeCapacity(@enumToInt(field_type));3325 fields_data.appendAssumeCapacity(@enumToInt(field_type));
33233326
3324 const have_align = member.ast.align_expr != 0;3327 const have_align = member.ast.align_expr != 0;
...@@ -3336,7 +3339,9 @@ fn structDeclInner(...@@ -3336,7 +3339,9 @@ fn structDeclInner(
3336 fields_data.appendAssumeCapacity(@enumToInt(align_inst));3339 fields_data.appendAssumeCapacity(@enumToInt(align_inst));
3337 }3340 }
3338 if (have_value) {3341 if (have_value) {
3339 const default_inst = try expr(&block_scope, &block_scope.base, .{ .ty = field_type }, member.ast.value_expr);3342 const rl: ResultLoc = if (field_type == .none) .none else .{ .ty = field_type };
3343
3344 const default_inst = try expr(&block_scope, &block_scope.base, rl, member.ast.value_expr);
3340 fields_data.appendAssumeCapacity(@enumToInt(default_inst));3345 fields_data.appendAssumeCapacity(@enumToInt(default_inst));
3341 } else if (member.comptime_token) |comptime_token| {3346 } else if (member.comptime_token) |comptime_token| {
3342 return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});3347 return astgen.failTok(comptime_token, "comptime field without default initialization value", .{});
src/Module.zig+1
...@@ -467,6 +467,7 @@ pub const Struct = struct {...@@ -467,6 +467,7 @@ pub const Struct = struct {
467 node_offset: i32,467 node_offset: i32,
468468
469 pub const Field = struct {469 pub const Field = struct {
470 /// Uses `noreturn` to indicate `anytype`.
470 ty: Type,471 ty: Type,
471 abi_align: Value,472 abi_align: Value,
472 /// Uses `unreachable_value` to indicate no default.473 /// Uses `unreachable_value` to indicate no default.
src/Sema.zig+10-4
...@@ -750,10 +750,16 @@ pub fn zirStructDecl(...@@ -750,10 +750,16 @@ pub fn zirStructDecl(
750750
751 // This string needs to outlive the ZIR code.751 // This string needs to outlive the ZIR code.
752 const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir);752 const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir);
753 // TODO: if we need to report an error here, use a source location753 if (field_type_ref == .none) {
754 // that points to this type expression rather than the struct.754 return sema.mod.fail(&block.base, src, "TODO: implement anytype struct field", .{});
755 // But only resolve the source location if we need to emit a compile error.755 }
756 const field_ty = try sema.resolveType(block, src, field_type_ref);756 const field_ty: Type = if (field_type_ref == .none)
757 Type.initTag(.noreturn)
758 else
759 // TODO: if we need to report an error here, use a source location
760 // that points to this type expression rather than the struct.
761 // But only resolve the source location if we need to emit a compile error.
762 try sema.resolveType(block, src, field_type_ref);
757763
758 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);764 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
759 assert(!gop.found_existing);765 assert(!gop.found_existing);
src/Zir.zig+5-5
...@@ -3367,15 +3367,15 @@ const Writer = struct {...@@ -3367,15 +3367,15 @@ const Writer = struct {
3367 var extra_index: usize = undefined;3367 var extra_index: usize = undefined;
33683368
3369 if (decls_len == 0) {3369 if (decls_len == 0) {
3370 try stream.writeAll("}) ");3370 try stream.writeAll("{}, ");
3371 extra_index = extra.end;3371 extra_index = extra.end;
3372 } else {3372 } else {
3373 try stream.writeAll("\n");3373 try stream.writeAll("{\n");
3374 self.indent += 2;3374 self.indent += 2;
3375 extra_index = try self.writeDecls(stream, decls_len, extra.end);3375 extra_index = try self.writeDecls(stream, decls_len, extra.end);
3376 self.indent -= 2;3376 self.indent -= 2;
3377 try stream.writeByteNTimes(' ', self.indent);3377 try stream.writeByteNTimes(' ', self.indent);
3378 try stream.writeAll("}) ");3378 try stream.writeAll("}, ");
3379 }3379 }
33803380
3381 const body = self.code.extra[extra_index..][0..extra.data.body_len];3381 const body = self.code.extra[extra_index..][0..extra.data.body_len];
...@@ -3383,7 +3383,7 @@ const Writer = struct {...@@ -3383,7 +3383,7 @@ const Writer = struct {
33833383
3384 if (fields_len == 0) {3384 if (fields_len == 0) {
3385 assert(body.len == 0);3385 assert(body.len == 0);
3386 try stream.writeAll("{}, {}, {");3386 try stream.writeAll("{}, {}) ");
3387 extra_index = extra.end;3387 extra_index = extra.end;
3388 } else {3388 } else {
3389 self.indent += 2;3389 self.indent += 2;
...@@ -3451,7 +3451,7 @@ const Writer = struct {...@@ -3451,7 +3451,7 @@ const Writer = struct {
34513451
3452 self.indent -= 2;3452 self.indent -= 2;
3453 try stream.writeByteNTimes(' ', self.indent);3453 try stream.writeByteNTimes(' ', self.indent);
3454 try stream.writeAll("}, {");3454 try stream.writeAll("}) ");
3455 }3455 }
3456 try self.writeSrc(stream, inst_data.src());3456 try self.writeSrc(stream, inst_data.src());
3457 }3457 }