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(
42654265 // are in scope, so that field types, alignments, and default value expressions
42664266 // can refer to decls within the struct itself.
42674267 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;
42684271 var block_scope: GenZir = .{
42694272 .parent = &namespace.base,
42704273 .decl_node_index = node,
4271 .decl_line = astgen.source_line,
4274 .decl_line = decl_line,
42724275 .astgen = astgen,
42734276 .force_comptime = true,
42744277 .in_defer = false,
......@@ -11756,7 +11759,6 @@ fn scanDecls(astgen: *AstGen, namespace: *Scope.Namespace, members: []const Ast.
1175611759 }
1175711760 }
1175811761
11759 // const index_name = try astgen.identAsString(index_token);
1176011762 var s = namespace.parent;
1176111763 while (true) switch (s.tag) {
1176211764 .local_val => {
src/Sema.zig+23-25
......@@ -78,6 +78,9 @@ post_hoc_blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, *LabeledBlock) = .{},
7878err: ?*Module.ErrorMsg = null,
7979/// True when analyzing a generic instantiation. Used to suppress some errors.
8080is_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
8285const std = @import("std");
8386const math = std.math;
......@@ -4068,6 +4071,19 @@ fn zirValidateArrayInit(
40684071
40694072 // 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
40714087 const elem_ptr_air_ref = sema.inst_map.get(elem_ptr).?;
40724088 const elem_ptr_air_inst = Air.refToIndex(elem_ptr_air_ref).?;
40734089 // Find the block index of the elem_ptr so that we can look at the next
......@@ -4084,19 +4100,6 @@ fn zirValidateArrayInit(
40844100 }
40854101 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
41004103 // If the next instructon is a store with a comptime operand, this element
41014104 // is comptime.
41024105 const next_air_inst = block.instructions.items[block_index + 1];
......@@ -5938,10 +5941,9 @@ fn analyzeCall(
59385941 undefined,
59395942 ) catch |err| switch (err) {
59405943 error.NeededSourceLocation => {
5941 sema.inst_map.clearRetainingCapacity();
5944 _ = sema.inst_map.remove(inst);
59425945 const decl = sema.mod.declPtr(block.src_decl);
59435946 child_block.src_decl = block.src_decl;
5944 arg_i = 0;
59455947 try sema.analyzeInlineCallArg(
59465948 block,
59475949 &child_block,
......@@ -7917,6 +7919,7 @@ fn funcCommon(
79177919 if (cc_workaround == .Inline and is_noinline) {
79187920 return sema.fail(block, cc_src, "'noinline' function cannot have callconv 'Inline'", .{});
79197921 }
7922 if (is_generic and sema.no_partial_func_ty) return error.GenericPoison;
79207923
79217924 break :fn_ty try Type.Tag.function.create(sema.arena, .{
79227925 .param_types = param_types,
......@@ -8097,25 +8100,19 @@ fn zirParam(
80978100 // Make sure any nested param instructions don't clobber our work.
80988101 const prev_params = block.params;
80998102 const prev_preallocated_new_func = sema.preallocated_new_func;
8103 const prev_no_partial_func_type = sema.no_partial_func_ty;
81008104 block.params = .{};
81018105 sema.preallocated_new_func = null;
8106 sema.no_partial_func_ty = true;
81028107 defer {
81038108 block.params.deinit(sema.gpa);
81048109 block.params = prev_params;
81058110 sema.preallocated_new_func = prev_preallocated_new_func;
8111 sema.no_partial_func_ty = prev_no_partial_func_type;
81068112 }
81078113
81088114 if (sema.resolveBody(block, body, inst)) |param_ty_inst| {
81098115 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 }
81198116 break :param_ty param_ty;
81208117 } else |err| break :err err;
81218118 } else |err| break :err err;
......@@ -26140,11 +26137,12 @@ fn analyzeSlice(
2614026137 var array_ty = ptr_ptr_child_ty;
2614126138 var slice_ty = ptr_ptr_ty;
2614226139 var ptr_or_slice = ptr_ptr;
26143 var elem_ty = ptr_ptr_child_ty.childType();
26140 var elem_ty: Type = undefined;
2614426141 var ptr_sentinel: ?Value = null;
2614526142 switch (ptr_ptr_child_ty.zigTypeTag()) {
2614626143 .Array => {
2614726144 ptr_sentinel = ptr_ptr_child_ty.sentinel();
26145 elem_ty = ptr_ptr_child_ty.childType();
2614826146 },
2614926147 .Pointer => switch (ptr_ptr_child_ty.ptrSize()) {
2615026148 .One => {
src/value.zig+6
......@@ -2689,6 +2689,12 @@ pub const Value = extern union {
26892689 // to have only one possible value itself.
26902690 .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
26922698 else => unreachable,
26932699 }
26942700 }
test/behavior/generics.zig+15
......@@ -342,3 +342,18 @@ test "generic instantiation of tagged union with only one field" {
342342 try expect(S.foo(.{ .s = "a" }) == 1);
343343 try expect(S.foo(.{ .s = "ab" }) == 2);
344344}
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" {
290290 };
291291 try S.foo(.{123});
292292}
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 @@
11fn f(_: anytype) void {}
2fn g(h: *const fn (anytype) void) void {
2const T = *const fn (anytype) void;
3fn g(h: T) void {
34 h({});
45}
56pub export fn entry() void {
......@@ -19,5 +20,5 @@ pub export fn entry1() void {
1920// backend=stage2
2021// target=native
2122//
22// :2: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 comptime
23// :3:6: error: parameter of type '*const fn(anytype) void' must be declared comptime
24// :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'