| ... | @@ -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) = .{}, |
| 78 | err: ?*Module.ErrorMsg = null, | 78 | err: ?*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. |
| 80 | is_generic_instantiation: bool = false, | 80 | is_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. |
| | 83 | no_partial_func_ty: bool = false, |
| 81 | | 84 | |
| 82 | const std = @import("std"); | 85 | const std = @import("std"); |
| 83 | const math = std.math; | 86 | const math = std.math; |
| ... | @@ -4068,6 +4071,19 @@ fn zirValidateArrayInit( | ... | @@ -4068,6 +4071,19 @@ fn zirValidateArrayInit( |
| 4068 | | 4071 | |
| 4069 | // Determine whether the value stored to this pointer is comptime-known. | 4072 | // Determine whether the value stored to this pointer is comptime-known. |
| 4070 | | 4073 | |
| | 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 next | 4089 | // 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); |
| 4086 | | 4102 | |
| 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 element | 4103 | // 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; |
| 7920 | | 7923 | |
| 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 | } |
| 8107 | | 8113 | |
| 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 => { |