| author | |
| committer | |
| log | 9e49a65e1bd474f0f678465fb4b965ddc5899226 |
| tree | 06a5c5982192f100dc6c0ecad8afba507e1ed579 |
| parent | 55e86b724a2ce60b777bd94d1203f243435727b7 |
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 | 483 | .asm_output => unreachable, // Handled in `asmExpr`. |
| 484 | 484 | .asm_input => unreachable, // Handled in `asmExpr`. |
| 485 | 485 | |
| 486 | .@"anytype" => unreachable, // Handled in `containerDecl`. | |
| 487 | ||
| 486 | 488 | .assign => { |
| 487 | 489 | try assign(gz, scope, node); |
| 488 | 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 | 871 | .struct_init_comma, |
| 870 | 872 | => return structInitExpr(gz, scope, rl, node, tree.structInit(node)), |
| 871 | 873 | |
| 872 | .@"anytype" => return astgen.failNode(node, "TODO implement astgen.expr for .anytype", .{}), | |
| 873 | ||
| 874 | 874 | .fn_proto_simple => { |
| 875 | 875 | var params: [1]ast.Node.Index = undefined; |
| 876 | 876 | return fnProtoExpr(gz, scope, rl, tree.fnProtoSimple(&params, node)); |
| ... | ... | @@ -3318,7 +3318,10 @@ fn structDeclInner( |
| 3318 | 3318 | const field_name = try gz.identAsString(member.ast.name_token); |
| 3319 | 3319 | fields_data.appendAssumeCapacity(field_name); |
| 3320 | 3320 | |
| 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 | 3325 | fields_data.appendAssumeCapacity(@enumToInt(field_type)); |
| 3323 | 3326 | |
| 3324 | 3327 | const have_align = member.ast.align_expr != 0; |
| ... | ... | @@ -3336,7 +3339,9 @@ fn structDeclInner( |
| 3336 | 3339 | fields_data.appendAssumeCapacity(@enumToInt(align_inst)); |
| 3337 | 3340 | } |
| 3338 | 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 | 3345 | fields_data.appendAssumeCapacity(@enumToInt(default_inst)); |
| 3341 | 3346 | } else if (member.comptime_token) |comptime_token| { |
| 3342 | 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 | 467 | node_offset: i32, |
| 468 | 468 | |
| 469 | 469 | pub const Field = struct { |
| 470 | /// Uses `noreturn` to indicate `anytype`. | |
| 470 | 471 | ty: Type, |
| 471 | 472 | abi_align: Value, |
| 472 | 473 | /// Uses `unreachable_value` to indicate no default. |
src/Sema.zig+10-4| ... | ... | @@ -750,10 +750,16 @@ pub fn zirStructDecl( |
| 750 | 750 | |
| 751 | 751 | // This string needs to outlive the ZIR code. |
| 752 | 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 location | |
| 754 | // that points to this type expression rather than the struct. | |
| 755 | // But only resolve the source location if we need to emit a compile error. | |
| 756 | const field_ty = try sema.resolveType(block, src, field_type_ref); | |
| 753 | if (field_type_ref == .none) { | |
| 754 | return sema.mod.fail(&block.base, src, "TODO: implement anytype struct field", .{}); | |
| 755 | } | |
| 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); | |
| 757 | 763 | |
| 758 | 764 | const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name); |
| 759 | 765 | assert(!gop.found_existing); |
src/Zir.zig+5-5| ... | ... | @@ -3367,15 +3367,15 @@ const Writer = struct { |
| 3367 | 3367 | var extra_index: usize = undefined; |
| 3368 | 3368 | |
| 3369 | 3369 | if (decls_len == 0) { |
| 3370 | try stream.writeAll("}) "); | |
| 3370 | try stream.writeAll("{}, "); | |
| 3371 | 3371 | extra_index = extra.end; |
| 3372 | 3372 | } else { |
| 3373 | try stream.writeAll("\n"); | |
| 3373 | try stream.writeAll("{\n"); | |
| 3374 | 3374 | self.indent += 2; |
| 3375 | 3375 | extra_index = try self.writeDecls(stream, decls_len, extra.end); |
| 3376 | 3376 | self.indent -= 2; |
| 3377 | 3377 | try stream.writeByteNTimes(' ', self.indent); |
| 3378 | try stream.writeAll("}) "); | |
| 3378 | try stream.writeAll("}, "); | |
| 3379 | 3379 | } |
| 3380 | 3380 | |
| 3381 | 3381 | const body = self.code.extra[extra_index..][0..extra.data.body_len]; |
| ... | ... | @@ -3383,7 +3383,7 @@ const Writer = struct { |
| 3383 | 3383 | |
| 3384 | 3384 | if (fields_len == 0) { |
| 3385 | 3385 | assert(body.len == 0); |
| 3386 | try stream.writeAll("{}, {}, {"); | |
| 3386 | try stream.writeAll("{}, {}) "); | |
| 3387 | 3387 | extra_index = extra.end; |
| 3388 | 3388 | } else { |
| 3389 | 3389 | self.indent += 2; |
| ... | ... | @@ -3451,7 +3451,7 @@ const Writer = struct { |
| 3451 | 3451 | |
| 3452 | 3452 | self.indent -= 2; |
| 3453 | 3453 | try stream.writeByteNTimes(' ', self.indent); |
| 3454 | try stream.writeAll("}, {"); | |
| 3454 | try stream.writeAll("}) "); | |
| 3455 | 3455 | } |
| 3456 | 3456 | try self.writeSrc(stream, inst_data.src()); |
| 3457 | 3457 | } |