| author | |
| committer | |
| log | 34835bbbcfe81cc87e823d14dc9b25e698ad5edc |
| tree | 28a56101f900d2b5a098b78ee800f4df909ae577 |
| parent | f6312e4b6933b8c8d163d6e6b20da135c5fa986a |
| parent | 2a4e89e0c9428b1ca59bc23c7c1d667c8ddb2304 |
| signature |
fix stack trace line numbers13 files changed, 93 insertions(+), 24 deletions(-)
src/AstGen.zig+4-7| ... | @@ -4233,13 +4233,10 @@ fn structDeclInner( | ... | @@ -4233,13 +4233,10 @@ fn structDeclInner( |
| 4233 | // are in scope, so that field types, alignments, and default value expressions | 4233 | // are in scope, so that field types, alignments, and default value expressions |
| 4234 | // can refer to decls within the struct itself. | 4234 | // can refer to decls within the struct itself. |
| 4235 | astgen.advanceSourceCursorToNode(node); | 4235 | astgen.advanceSourceCursorToNode(node); |
| 4236 | // If `node == 0` then this is the root struct and all the declarations should | ||
| 4237 | // be relative to the beginning of the file. | ||
| 4238 | const decl_line = if (node == 0) 0 else astgen.source_line; | ||
| 4239 | var block_scope: GenZir = .{ | 4236 | var block_scope: GenZir = .{ |
| 4240 | .parent = &namespace.base, | 4237 | .parent = &namespace.base, |
| 4241 | .decl_node_index = node, | 4238 | .decl_node_index = node, |
| 4242 | .decl_line = decl_line, | 4239 | .decl_line = gz.decl_line, |
| 4243 | .astgen = astgen, | 4240 | .astgen = astgen, |
| 4244 | .force_comptime = true, | 4241 | .force_comptime = true, |
| 4245 | .instructions = gz.instructions, | 4242 | .instructions = gz.instructions, |
| ... | @@ -4439,7 +4436,7 @@ fn unionDeclInner( | ... | @@ -4439,7 +4436,7 @@ fn unionDeclInner( |
| 4439 | var block_scope: GenZir = .{ | 4436 | var block_scope: GenZir = .{ |
| 4440 | .parent = &namespace.base, | 4437 | .parent = &namespace.base, |
| 4441 | .decl_node_index = node, | 4438 | .decl_node_index = node, |
| 4442 | .decl_line = astgen.source_line, | 4439 | .decl_line = gz.decl_line, |
| 4443 | .astgen = astgen, | 4440 | .astgen = astgen, |
| 4444 | .force_comptime = true, | 4441 | .force_comptime = true, |
| 4445 | .instructions = gz.instructions, | 4442 | .instructions = gz.instructions, |
| ... | @@ -4722,7 +4719,7 @@ fn containerDecl( | ... | @@ -4722,7 +4719,7 @@ fn containerDecl( |
| 4722 | var block_scope: GenZir = .{ | 4719 | var block_scope: GenZir = .{ |
| 4723 | .parent = &namespace.base, | 4720 | .parent = &namespace.base, |
| 4724 | .decl_node_index = node, | 4721 | .decl_node_index = node, |
| 4725 | .decl_line = astgen.source_line, | 4722 | .decl_line = gz.decl_line, |
| 4726 | .astgen = astgen, | 4723 | .astgen = astgen, |
| 4727 | .force_comptime = true, | 4724 | .force_comptime = true, |
| 4728 | .instructions = gz.instructions, | 4725 | .instructions = gz.instructions, |
| ... | @@ -4827,7 +4824,7 @@ fn containerDecl( | ... | @@ -4827,7 +4824,7 @@ fn containerDecl( |
| 4827 | var block_scope: GenZir = .{ | 4824 | var block_scope: GenZir = .{ |
| 4828 | .parent = &namespace.base, | 4825 | .parent = &namespace.base, |
| 4829 | .decl_node_index = node, | 4826 | .decl_node_index = node, |
| 4830 | .decl_line = astgen.source_line, | 4827 | .decl_line = gz.decl_line, |
| 4831 | .astgen = astgen, | 4828 | .astgen = astgen, |
| 4832 | .force_comptime = true, | 4829 | .force_comptime = true, |
| 4833 | .instructions = gz.instructions, | 4830 | .instructions = gz.instructions, |
src/Module.zig+1| ... | @@ -4435,6 +4435,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { | ... | @@ -4435,6 +4435,7 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { |
| 4435 | new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive. | 4435 | new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive. |
| 4436 | new_decl.analysis = .in_progress; | 4436 | new_decl.analysis = .in_progress; |
| 4437 | new_decl.generation = mod.generation; | 4437 | new_decl.generation = mod.generation; |
| 4438 | new_decl.name_fully_qualified = true; | ||
| 4438 | 4439 | ||
| 4439 | if (file.status == .success_zir) { | 4440 | if (file.status == .success_zir) { |
| 4440 | assert(file.zir_loaded); | 4441 | assert(file.zir_loaded); |
src/Sema.zig+13-4| ... | @@ -4353,6 +4353,11 @@ fn failWithBadMemberAccess( | ... | @@ -4353,6 +4353,11 @@ fn failWithBadMemberAccess( |
| 4353 | .Enum => "enum", | 4353 | .Enum => "enum", |
| 4354 | else => unreachable, | 4354 | else => unreachable, |
| 4355 | }; | 4355 | }; |
| 4356 | if (sema.mod.declIsRoot(agg_ty.getOwnerDecl())) { | ||
| 4357 | return sema.fail(block, field_src, "root struct of file '{}' has no member named '{s}'", .{ | ||
| 4358 | agg_ty.fmt(sema.mod), field_name, | ||
| 4359 | }); | ||
| 4360 | } | ||
| 4356 | const msg = msg: { | 4361 | const msg = msg: { |
| 4357 | const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{ | 4362 | const msg = try sema.errMsg(block, field_src, "{s} '{}' has no member named '{s}'", .{ |
| 4358 | kw_name, agg_ty.fmt(sema.mod), field_name, | 4363 | kw_name, agg_ty.fmt(sema.mod), field_name, |
| ... | @@ -21664,14 +21669,17 @@ fn fieldPtr( | ... | @@ -21664,14 +21669,17 @@ fn fieldPtr( |
| 21664 | else | 21669 | else |
| 21665 | object_ptr; | 21670 | object_ptr; |
| 21666 | 21671 | ||
| 21672 | const attr_ptr_ty = if (is_pointer_to) object_ty else object_ptr_ty; | ||
| 21673 | |||
| 21667 | if (mem.eql(u8, field_name, "ptr")) { | 21674 | if (mem.eql(u8, field_name, "ptr")) { |
| 21668 | const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); | 21675 | const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer); |
| 21669 | const slice_ptr_ty = inner_ty.slicePtrFieldType(buf); | 21676 | const slice_ptr_ty = inner_ty.slicePtrFieldType(buf); |
| 21670 | 21677 | ||
| 21671 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ | 21678 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 21672 | .pointee_type = slice_ptr_ty, | 21679 | .pointee_type = slice_ptr_ty, |
| 21673 | .mutable = object_ptr_ty.ptrIsMutable(), | 21680 | .mutable = attr_ptr_ty.ptrIsMutable(), |
| 21674 | .@"addrspace" = object_ptr_ty.ptrAddressSpace(), | 21681 | .@"volatile" = attr_ptr_ty.isVolatilePtr(), |
| 21682 | .@"addrspace" = attr_ptr_ty.ptrAddressSpace(), | ||
| 21675 | }); | 21683 | }); |
| 21676 | 21684 | ||
| 21677 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { | 21685 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
| ... | @@ -21690,8 +21698,9 @@ fn fieldPtr( | ... | @@ -21690,8 +21698,9 @@ fn fieldPtr( |
| 21690 | } else if (mem.eql(u8, field_name, "len")) { | 21698 | } else if (mem.eql(u8, field_name, "len")) { |
| 21691 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ | 21699 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 21692 | .pointee_type = Type.usize, | 21700 | .pointee_type = Type.usize, |
| 21693 | .mutable = object_ptr_ty.ptrIsMutable(), | 21701 | .mutable = attr_ptr_ty.ptrIsMutable(), |
| 21694 | .@"addrspace" = object_ptr_ty.ptrAddressSpace(), | 21702 | .@"volatile" = attr_ptr_ty.isVolatilePtr(), |
| 21703 | .@"addrspace" = attr_ptr_ty.ptrAddressSpace(), | ||
| 21695 | }); | 21704 | }); |
| 21696 | 21705 | ||
| 21697 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { | 21706 | if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { |
src/type.zig+18-2| ... | @@ -3458,12 +3458,21 @@ pub const Type = extern union { | ... | @@ -3458,12 +3458,21 @@ pub const Type = extern union { |
| 3458 | else => {}, | 3458 | else => {}, |
| 3459 | } | 3459 | } |
| 3460 | 3460 | ||
| 3461 | const payload_size = switch (try child_type.abiSizeAdvanced(target, strat)) { | ||
| 3462 | .scalar => |elem_size| elem_size, | ||
| 3463 | .val => switch (strat) { | ||
| 3464 | .sema_kit => unreachable, | ||
| 3465 | .eager => unreachable, | ||
| 3466 | .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) }, | ||
| 3467 | }, | ||
| 3468 | }; | ||
| 3469 | |||
| 3461 | // Optional types are represented as a struct with the child type as the first | 3470 | // Optional types are represented as a struct with the child type as the first |
| 3462 | // field and a boolean as the second. Since the child type's abi alignment is | 3471 | // field and a boolean as the second. Since the child type's abi alignment is |
| 3463 | // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal | 3472 | // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal |
| 3464 | // to the child type's ABI alignment. | 3473 | // to the child type's ABI alignment. |
| 3465 | return AbiSizeAdvanced{ | 3474 | return AbiSizeAdvanced{ |
| 3466 | .scalar = child_type.abiAlignment(target) + child_type.abiSize(target), | 3475 | .scalar = child_type.abiAlignment(target) + payload_size, |
| 3467 | }; | 3476 | }; |
| 3468 | }, | 3477 | }, |
| 3469 | 3478 | ||
| ... | @@ -3478,7 +3487,14 @@ pub const Type = extern union { | ... | @@ -3478,7 +3487,14 @@ pub const Type = extern union { |
| 3478 | } | 3487 | } |
| 3479 | const code_align = abiAlignment(Type.anyerror, target); | 3488 | const code_align = abiAlignment(Type.anyerror, target); |
| 3480 | const payload_align = abiAlignment(data.payload, target); | 3489 | const payload_align = abiAlignment(data.payload, target); |
| 3481 | const payload_size = abiSize(data.payload, target); | 3490 | const payload_size = switch (try data.payload.abiSizeAdvanced(target, strat)) { |
| 3491 | .scalar => |elem_size| elem_size, | ||
| 3492 | .val => switch (strat) { | ||
| 3493 | .sema_kit => unreachable, | ||
| 3494 | .eager => unreachable, | ||
| 3495 | .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) }, | ||
| 3496 | }, | ||
| 3497 | }; | ||
| 3482 | 3498 | ||
| 3483 | var size: u64 = 0; | 3499 | var size: u64 = 0; |
| 3484 | if (code_align > payload_align) { | 3500 | if (code_align > payload_align) { |
test/behavior.zig+1| ... | @@ -98,6 +98,7 @@ test { | ... | @@ -98,6 +98,7 @@ test { |
| 98 | _ = @import("behavior/bugs/12911.zig"); | 98 | _ = @import("behavior/bugs/12911.zig"); |
| 99 | _ = @import("behavior/bugs/12928.zig"); | 99 | _ = @import("behavior/bugs/12928.zig"); |
| 100 | _ = @import("behavior/bugs/12945.zig"); | 100 | _ = @import("behavior/bugs/12945.zig"); |
| 101 | _ = @import("behavior/bugs/12984.zig"); | ||
| 101 | _ = @import("behavior/byteswap.zig"); | 102 | _ = @import("behavior/byteswap.zig"); |
| 102 | _ = @import("behavior/byval_arg_var.zig"); | 103 | _ = @import("behavior/byval_arg_var.zig"); |
| 103 | _ = @import("behavior/call.zig"); | 104 | _ = @import("behavior/call.zig"); |
test/behavior/bugs/12984.zig created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | |||
| 4 | pub fn DeleagateWithContext(comptime Function: type) type { | ||
| 5 | const ArgArgs = std.meta.ArgsTuple(Function); | ||
| 6 | return struct { | ||
| 7 | t: ArgArgs, | ||
| 8 | }; | ||
| 9 | } | ||
| 10 | |||
| 11 | pub const OnConfirm = DeleagateWithContext(fn (bool) void); | ||
| 12 | pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void); | ||
| 13 | |||
| 14 | test "simple test" { | ||
| 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 17 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 18 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 19 | |||
| 20 | var c: CustomDraw = undefined; | ||
| 21 | _ = c; | ||
| 22 | } | ||
test/behavior/slice.zig+28| ... | @@ -684,3 +684,31 @@ test "slice len modification at comptime" { | ... | @@ -684,3 +684,31 @@ test "slice len modification at comptime" { |
| 684 | try expect(items[1] == 1); | 684 | try expect(items[1] == 1); |
| 685 | } | 685 | } |
| 686 | } | 686 | } |
| 687 | |||
| 688 | test "slice field ptr const" { | ||
| 689 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 690 | |||
| 691 | const const_slice: []const u8 = "string"; | ||
| 692 | |||
| 693 | const const_ptr_const_slice = &const_slice; | ||
| 694 | try expectEqual(*const []const u8, @TypeOf(&const_ptr_const_slice.*)); | ||
| 695 | try expectEqual(*const [*]const u8, @TypeOf(&const_ptr_const_slice.ptr)); | ||
| 696 | |||
| 697 | var var_ptr_const_slice = &const_slice; | ||
| 698 | try expectEqual(*const []const u8, @TypeOf(&var_ptr_const_slice.*)); | ||
| 699 | try expectEqual(*const [*]const u8, @TypeOf(&var_ptr_const_slice.ptr)); | ||
| 700 | } | ||
| 701 | |||
| 702 | test "slice field ptr var" { | ||
| 703 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 704 | |||
| 705 | var var_slice: []const u8 = "string"; | ||
| 706 | |||
| 707 | var var_ptr_var_slice = &var_slice; | ||
| 708 | try expectEqual(*[]const u8, @TypeOf(&var_ptr_var_slice.*)); | ||
| 709 | try expectEqual(*[*]const u8, @TypeOf(&var_ptr_var_slice.ptr)); | ||
| 710 | |||
| 711 | const const_ptr_var_slice = &var_slice; | ||
| 712 | try expectEqual(*[]const u8, @TypeOf(&const_ptr_var_slice.*)); | ||
| 713 | try expectEqual(*[*]const u8, @TypeOf(&const_ptr_var_slice.ptr)); | ||
| 714 | } |
test/cases/aarch64-macos/hello_world_with_updates.0.zig+1-2| ... | @@ -2,5 +2,4 @@ | ... | @@ -2,5 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=aarch64-macos | 3 | // target=aarch64-macos |
| 4 | // | 4 | // |
| 5 | // :109:9: error: struct 'tmp.tmp' has no member named 'main' | 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' |
| 6 | // :7:1: note: struct declared here |
test/cases/compile_errors/bogus_compile_var.zig+1-2| ... | @@ -5,5 +5,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(x)); } | ... | @@ -5,5 +5,4 @@ export fn entry() usize { return @sizeOf(@TypeOf(x)); } |
| 5 | // backend=stage2 | 5 | // backend=stage2 |
| 6 | // target=native | 6 | // target=native |
| 7 | // | 7 | // |
| 8 | // :1:29: error: struct 'builtin.builtin' has no member named 'bogus' | 8 | // :1:29: error: root struct of file 'builtin' has no member named 'bogus' |
| 9 | // :1:1: note: struct declared here |
test/cases/compile_errors/issue_2032_compile_diagnostic_string_for_top_level_decl_type.zig+1-1| ... | @@ -7,5 +7,5 @@ export fn entry() void { | ... | @@ -7,5 +7,5 @@ export fn entry() void { |
| 7 | // backend=stage2 | 7 | // backend=stage2 |
| 8 | // target=native | 8 | // target=native |
| 9 | // | 9 | // |
| 10 | // :2:27: error: expected type 'u32', found 'tmp.tmp' | 10 | // :2:27: error: expected type 'u32', found 'tmp' |
| 11 | // :1:1: note: struct declared here | 11 | // :1:1: note: struct declared here |
test/cases/x86_64-linux/hello_world_with_updates.0.zig+1-2| ... | @@ -2,5 +2,4 @@ | ... | @@ -2,5 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-linux | 3 | // target=x86_64-linux |
| 4 | // | 4 | // |
| 5 | // :109:9: error: struct 'tmp.tmp' has no member named 'main' | 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' |
| 6 | // :7:1: note: struct declared here |
test/cases/x86_64-macos/hello_world_with_updates.0.zig+1-2| ... | @@ -2,5 +2,4 @@ | ... | @@ -2,5 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-macos | 3 | // target=x86_64-macos |
| 4 | // | 4 | // |
| 5 | // :109:9: error: struct 'tmp.tmp' has no member named 'main' | 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' |
| 6 | // :7:1: note: struct declared here |
test/cases/x86_64-windows/hello_world_with_updates.0.zig+1-2| ... | @@ -2,5 +2,4 @@ | ... | @@ -2,5 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-windows | 3 | // target=x86_64-windows |
| 4 | // | 4 | // |
| 5 | // :130:9: error: struct 'tmp.tmp' has no member named 'main' | 5 | // :130:9: error: root struct of file 'tmp' has no member named 'main' |
| 6 | // :7:1: note: struct declared here |