authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-24 15:59:46-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-08-24 15:59:46-04:00
log7a881435ed54b0cf59f48679c3912600b3bd0d58
tree551acc0660ddd455edcc6ee4ab4644b7a9bc8363
parent2a96209c4060bbf8a41fbe34e687a7a4741d2fe1
parent69a3c4e279238874cc74cf6acd5eb0426d5b65ee
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12623 from Vexu/stage2-fixes

Stage2 fixes

8 files changed, 86 insertions(+), 30 deletions(-)

src/AstGen.zig+4-2
...@@ -4265,10 +4265,13 @@ fn structDeclInner(...@@ -4265,10 +4265,13 @@ fn structDeclInner(
4265 // are in scope, so that field types, alignments, and default value expressions4265 // are in scope, so that field types, alignments, and default value expressions
4266 // can refer to decls within the struct itself.4266 // can refer to decls within the struct itself.
4267 astgen.advanceSourceCursorToNode(node);4267 astgen.advanceSourceCursorToNode(node);
4268 // If `node == 0` then this is the root struct and all the declarations should
4269 // be relative to the beginning of the file.
4270 const decl_line = if (node == 0) 0 else astgen.source_line;
4268 var block_scope: GenZir = .{4271 var block_scope: GenZir = .{
4269 .parent = &namespace.base,4272 .parent = &namespace.base,
4270 .decl_node_index = node,4273 .decl_node_index = node,
4271 .decl_line = astgen.source_line,4274 .decl_line = decl_line,
4272 .astgen = astgen,4275 .astgen = astgen,
4273 .force_comptime = true,4276 .force_comptime = true,
4274 .in_defer = false,4277 .in_defer = false,
...@@ -11756,7 +11759,6 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast....@@ -11756,7 +11759,6 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
11756 }11759 }
11757 }11760 }
1175811761
11759 // const index_name = try astgen.identAsString(index_token);
11760 var s = namespace.parent;11762 var s = namespace.parent;
11761 while (true) switch (s.tag) {11763 while (true) switch (s.tag) {
11762 .local_val => {11764 .local_val => {
src/Sema.zig+23-25
...@@ -78,6 +78,9 @@ post_hoc_blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, *LabeledBlock) = .{},...@@ -78,6 +78,9 @@ post_hoc_blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, *LabeledBlock) = .{},
78err: ?*Module.ErrorMsg = null,78err: ?*Module.ErrorMsg = null,
79/// True when analyzing a generic instantiation. Used to suppress some errors.79/// True when analyzing a generic instantiation. Used to suppress some errors.
80is_generic_instantiation: bool = false,80is_generic_instantiation: bool = false,
81/// Set to true when analyzing a func type instruction so that nested generic
82/// function types will emit generic poison instead of a partial type.
83no_partial_func_ty: bool = false,
8184
82const std = @import("std");85const std = @import("std");
83const math = std.math;86const math = std.math;
...@@ -4068,6 +4071,19 @@ fn zirValidateArrayInit(...@@ -4068,6 +4071,19 @@ fn zirValidateArrayInit(
40684071
4069 // Determine whether the value stored to this pointer is comptime-known.4072 // Determine whether the value stored to this pointer is comptime-known.
40704073
4074 if (array_ty.isTuple()) {
4075 if (array_ty.structFieldValueComptime(i)) |opv| {
4076 element_vals[i] = opv;
4077 continue;
4078 }
4079 } else {
4080 // Array has one possible value, so value is always comptime-known
4081 if (opt_opv) |opv| {
4082 element_vals[i] = opv;
4083 continue;
4084 }
4085 }
4086
4071 const elem_ptr_air_ref = sema.inst_map.get(elem_ptr).?;4087 const elem_ptr_air_ref = sema.inst_map.get(elem_ptr).?;
4072 const elem_ptr_air_inst = Air.refToIndex(elem_ptr_air_ref).?;4088 const elem_ptr_air_inst = Air.refToIndex(elem_ptr_air_ref).?;
4073 // Find the block index of the elem_ptr so that we can look at the next4089 // Find the block index of the elem_ptr so that we can look at the next
...@@ -4084,19 +4100,6 @@ fn zirValidateArrayInit(...@@ -4084,19 +4100,6 @@ fn zirValidateArrayInit(
4084 }4100 }
4085 first_block_index = @minimum(first_block_index, block_index);4101 first_block_index = @minimum(first_block_index, block_index);
40864102
4087 if (array_ty.isTuple()) {
4088 if (array_ty.structFieldValueComptime(i)) |opv| {
4089 element_vals[i] = opv;
4090 continue;
4091 }
4092 } else {
4093 // Array has one possible value, so value is always comptime-known
4094 if (opt_opv) |opv| {
4095 element_vals[i] = opv;
4096 continue;
4097 }
4098 }
4099
4100 // If the next instructon is a store with a comptime operand, this element4103 // If the next instructon is a store with a comptime operand, this element
4101 // is comptime.4104 // is comptime.
4102 const next_air_inst = block.instructions.items[block_index + 1];4105 const next_air_inst = block.instructions.items[block_index + 1];
...@@ -5938,10 +5941,9 @@ fn analyzeCall(...@@ -5938,10 +5941,9 @@ fn analyzeCall(
5938 undefined,5941 undefined,
5939 ) catch |err| switch (err) {5942 ) catch |err| switch (err) {
5940 error.NeededSourceLocation => {5943 error.NeededSourceLocation => {
5941 sema.inst_map.clearRetainingCapacity();5944 _ = sema.inst_map.remove(inst);
5942 const decl = sema.mod.declPtr(block.src_decl);5945 const decl = sema.mod.declPtr(block.src_decl);
5943 child_block.src_decl = block.src_decl;5946 child_block.src_decl = block.src_decl;
5944 arg_i = 0;
5945 try sema.analyzeInlineCallArg(5947 try sema.analyzeInlineCallArg(
5946 block,5948 block,
5947 &child_block,5949 &child_block,
...@@ -7917,6 +7919,7 @@ fn funcCommon(...@@ -7917,6 +7919,7 @@ fn funcCommon(
7917 if (cc_workaround == .Inline and is_noinline) {7919 if (cc_workaround == .Inline and is_noinline) {
7918 return sema.fail(block, cc_src, "'noinline' function cannot have callconv 'Inline'", .{});7920 return sema.fail(block, cc_src, "'noinline' function cannot have callconv 'Inline'", .{});
7919 }7921 }
7922 if (is_generic and sema.no_partial_func_ty) return error.GenericPoison;
79207923
7921 break :fn_ty try Type.Tag.function.create(sema.arena, .{7924 break :fn_ty try Type.Tag.function.create(sema.arena, .{
7922 .param_types = param_types,7925 .param_types = param_types,
...@@ -8097,25 +8100,19 @@ fn zirParam(...@@ -8097,25 +8100,19 @@ fn zirParam(
8097 // Make sure any nested param instructions don't clobber our work.8100 // Make sure any nested param instructions don't clobber our work.
8098 const prev_params = block.params;8101 const prev_params = block.params;
8099 const prev_preallocated_new_func = sema.preallocated_new_func;8102 const prev_preallocated_new_func = sema.preallocated_new_func;
8103 const prev_no_partial_func_type = sema.no_partial_func_ty;
8100 block.params = .{};8104 block.params = .{};
8101 sema.preallocated_new_func = null;8105 sema.preallocated_new_func = null;
8106 sema.no_partial_func_ty = true;
8102 defer {8107 defer {
8103 block.params.deinit(sema.gpa);8108 block.params.deinit(sema.gpa);
8104 block.params = prev_params;8109 block.params = prev_params;
8105 sema.preallocated_new_func = prev_preallocated_new_func;8110 sema.preallocated_new_func = prev_preallocated_new_func;
8111 sema.no_partial_func_ty = prev_no_partial_func_type;
8106 }8112 }
81078113
8108 if (sema.resolveBody(block, body, inst)) |param_ty_inst| {8114 if (sema.resolveBody(block, body, inst)) |param_ty_inst| {
8109 if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| {8115 if (sema.analyzeAsType(block, src, param_ty_inst)) |param_ty| {
8110 if (param_ty.zigTypeTag() == .Fn and param_ty.fnInfo().is_generic) {
8111 // zirFunc will not emit error.GenericPoison to build a
8112 // partial type for generic functions but we still need to
8113 // detect if a function parameter is a generic function
8114 // to force the parent function to also be generic.
8115 if (!sema.inst_map.contains(inst)) {
8116 break :err error.GenericPoison;
8117 }
8118 }
8119 break :param_ty param_ty;8116 break :param_ty param_ty;
8120 } else |err| break :err err;8117 } else |err| break :err err;
8121 } else |err| break :err err;8118 } else |err| break :err err;
...@@ -26140,11 +26137,12 @@ fn analyzeSlice(...@@ -26140,11 +26137,12 @@ fn analyzeSlice(
26140 var array_ty = ptr_ptr_child_ty;26137 var array_ty = ptr_ptr_child_ty;
26141 var slice_ty = ptr_ptr_ty;26138 var slice_ty = ptr_ptr_ty;
26142 var ptr_or_slice = ptr_ptr;26139 var ptr_or_slice = ptr_ptr;
26143 var elem_ty = ptr_ptr_child_ty.childType();26140 var elem_ty: Type = undefined;
26144 var ptr_sentinel: ?Value = null;26141 var ptr_sentinel: ?Value = null;
26145 switch (ptr_ptr_child_ty.zigTypeTag()) {26142 switch (ptr_ptr_child_ty.zigTypeTag()) {
26146 .Array => {26143 .Array => {
26147 ptr_sentinel = ptr_ptr_child_ty.sentinel();26144 ptr_sentinel = ptr_ptr_child_ty.sentinel();
26145 elem_ty = ptr_ptr_child_ty.childType();
26148 },26146 },
26149 .Pointer => switch (ptr_ptr_child_ty.ptrSize()) {26147 .Pointer => switch (ptr_ptr_child_ty.ptrSize()) {
26150 .One => {26148 .One => {
src/value.zig+6
...@@ -2689,6 +2689,12 @@ pub const Value = extern union {...@@ -2689,6 +2689,12 @@ pub const Value = extern union {
2689 // to have only one possible value itself.2689 // to have only one possible value itself.
2690 .the_only_possible_value => return val,2690 .the_only_possible_value => return val,
26912691
2692 // pointer to integer casted to pointer of array
2693 .int_u64, .int_i64 => {
2694 assert(index == 0);
2695 return val;
2696 },
2697
2692 else => unreachable,2698 else => unreachable,
2693 }2699 }
2694 }2700 }
test/behavior/generics.zig+15
...@@ -342,3 +342,18 @@ test "generic instantiation of tagged union with only one field" {...@@ -342,3 +342,18 @@ test "generic instantiation of tagged union with only one field" {
342 try expect(S.foo(.{ .s = "a" }) == 1);342 try expect(S.foo(.{ .s = "a" }) == 1);
343 try expect(S.foo(.{ .s = "ab" }) == 2);343 try expect(S.foo(.{ .s = "ab" }) == 2);
344}344}
345
346test "nested generic function" {
347 const S = struct {
348 fn foo(comptime T: type, callback: *const fn (user_data: T) anyerror!void, data: T) anyerror!void {
349 try callback(data);
350 }
351 fn bar(a: u32) anyerror!void {
352 try expect(a == 123);
353 }
354
355 fn g(_: *const fn (anytype) void) void {}
356 };
357 try expect(@typeInfo(@TypeOf(S.g)).Fn.is_generic);
358 try S.foo(u32, S.bar, 123);
359}
test/behavior/tuple.zig+11
...@@ -290,3 +290,14 @@ test "coerce tuple to tuple" {...@@ -290,3 +290,14 @@ test "coerce tuple to tuple" {
290 };290 };
291 try S.foo(.{123});291 try S.foo(.{123});
292}292}
293
294test "tuple type with void field" {
295 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
296 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
297 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
298 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
299
300 const T = std.meta.Tuple(&[_]type{void});
301 const x = T{{}};
302 try expect(@TypeOf(x[0]) == void);
303}
test/cases/compile_errors/comptime_parameter_not_declared_as_such.zig+4-3
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1fn f(_: anytype) void {}1fn f(_: anytype) void {}
2fn g(h: *const fn (anytype) void) void {2const T = *const fn (anytype) void;
3fn g(h: T) void {
3 h({});4 h({});
4}5}
5pub export fn entry() void {6pub export fn entry() void {
...@@ -19,5 +20,5 @@ pub export fn entry1() void {...@@ -19,5 +20,5 @@ pub export fn entry1() void {
19// backend=stage220// backend=stage2
20// target=native21// target=native
21//22//
22// :2:6: error: parameter of type '*const fn(anytype) void' must be declared comptime23// :3:6: error: parameter of type '*const fn(anytype) void' must be declared comptime
23// :9:34: error: parameter of type 'comptime_int' must be declared comptime24// :10:34: error: parameter of type 'comptime_int' must be declared comptime
test/cases/compile_errors/error_in_typeof_param.zig created+14
...@@ -0,0 +1,14 @@
1fn getSize() usize {
2 return 2;
3}
4pub fn expectEqual(expected: anytype, _: @TypeOf(expected)) !void {}
5pub export fn entry() void {
6 try expectEqual(2, getSize());
7}
8
9// error
10// backend=stage2
11// target=native
12//
13// :6:31: error: unable to resolve comptime value
14// :6:31: note: argument to parameter with comptime only type must be comptime known
test/cases/compile_errors/slice_of_non_array_type.zig created+9
...@@ -0,0 +1,9 @@
1comptime {
2 _ = 1[0..];
3}
4
5// error
6// backend=stage2
7// target=native
8//
9// :2:10: error: slice of non-array type 'comptime_int'