authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-26 22:57:05+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-02-26 18:44:23-05:00
logbf3c88b68d9f8042b79b7d69d401429811d9de7c
tree7efd2e71a3b105adf417c831b75aa23b7637af35
parent058e482247c73ecb6404c7c1e3d2194f4aa9e059

stage2: various fixes to get one test passing

* resolve error sets before merging them * implement tupleFieldPtr * make ret_ptr behave like alloc with zero sized types in llvm backend

5 files changed, 88 insertions(+), 13 deletions(-)

src/Module.zig+1-1
...@@ -1435,7 +1435,7 @@ pub const Fn = struct {...@@ -1435,7 +1435,7 @@ pub const Fn = struct {
1435 /// All currently known errors that this error set contains. This includes direct additions1435 /// All currently known errors that this error set contains. This includes direct additions
1436 /// via `return error.Foo;`, and possibly also errors that are returned from any dependent functions.1436 /// via `return error.Foo;`, and possibly also errors that are returned from any dependent functions.
1437 /// When the inferred error set is fully resolved, this map contains all the errors that the function might return.1437 /// When the inferred error set is fully resolved, this map contains all the errors that the function might return.
1438 errors: std.StringHashMapUnmanaged(void) = .{},1438 errors: ErrorSet.NameMap = .{},
14391439
1440 /// Other inferred error sets which this inferred error set should include.1440 /// Other inferred error sets which this inferred error set should include.
1441 inferred_error_sets: std.AutoHashMapUnmanaged(*InferredErrorSet, void) = .{},1441 inferred_error_sets: std.AutoHashMapUnmanaged(*InferredErrorSet, void) = .{},
src/Sema.zig+78-10
...@@ -1613,10 +1613,15 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE...@@ -1613,10 +1613,15 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE
1613 //}1613 //}
16141614
1615 // The last one is always `store`.1615 // The last one is always `store`.
1616 const trash_inst = trash_block.instructions.pop();1616 const trash_inst = trash_block.instructions.items[trash_block.instructions.items.len - 1];
1617 assert(air_tags[trash_inst] == .store);1617 if (air_tags[trash_inst] != .store) {
1618 assert(trash_inst == sema.air_instructions.len - 1);1618 // no store instruction is generated for zero sized types
1619 sema.air_instructions.len -= 1;1619 assert((try sema.typeHasOnePossibleValue(block, src, pointee_ty)) != null);
1620 } else {
1621 trash_block.instructions.items.len -= 1;
1622 assert(trash_inst == sema.air_instructions.len - 1);
1623 sema.air_instructions.len -= 1;
1624 }
1620 }1625 }
16211626
1622 const ptr_ty = try Type.ptr(sema.arena, .{1627 const ptr_ty = try Type.ptr(sema.arena, .{
...@@ -5236,6 +5241,22 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -5236,6 +5241,22 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
5236 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {5241 if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) {
5237 return Air.Inst.Ref.anyerror_type;5242 return Air.Inst.Ref.anyerror_type;
5238 }5243 }
5244
5245 if (lhs_ty.castTag(.error_set_inferred)) |payload| {
5246 try sema.resolveInferredErrorSet(payload.data);
5247 // isAnyError might have changed from a false negative to a true positive after resolution.
5248 if (lhs_ty.isAnyError()) {
5249 return Air.Inst.Ref.anyerror_type;
5250 }
5251 }
5252 if (rhs_ty.castTag(.error_set_inferred)) |payload| {
5253 try sema.resolveInferredErrorSet(payload.data);
5254 // isAnyError might have changed from a false negative to a true positive after resolution.
5255 if (rhs_ty.isAnyError()) {
5256 return Air.Inst.Ref.anyerror_type;
5257 }
5258 }
5259
5239 // Resolve both error sets now.5260 // Resolve both error sets now.
5240 const lhs_names = lhs_ty.errorSetNames();5261 const lhs_names = lhs_ty.errorSetNames();
5241 const rhs_names = rhs_ty.errorSetNames();5262 const rhs_names = rhs_ty.errorSetNames();
...@@ -6809,6 +6830,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -6809,6 +6830,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
6809 }6830 }
6810 }6831 }
68116832
6833 if (operand_ty.castTag(.error_set_inferred)) |inferred| {
6834 try sema.resolveInferredErrorSet(inferred.data);
6835 }
6836
6812 if (operand_ty.isAnyError()) {6837 if (operand_ty.isAnyError()) {
6813 if (special_prong != .@"else") {6838 if (special_prong != .@"else") {
6814 return sema.fail(6839 return sema.fail(
...@@ -14597,6 +14622,12 @@ fn elemPtr(...@@ -14597,6 +14622,12 @@ fn elemPtr(
14597 },14622 },
14598 .Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),14623 .Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src),
14599 .Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),14624 .Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}),
14625 .Struct => {
14626 // Tuple field access.
14627 const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index);
14628 const index = @intCast(u32, index_val.toUnsignedInt());
14629 return sema.tupleFieldPtr(block, array_ptr, index, src, elem_index_src);
14630 },
14600 else => unreachable,14631 else => unreachable,
14601 }14632 }
14602}14633}
...@@ -14673,6 +14704,45 @@ fn elemVal(...@@ -14673,6 +14704,45 @@ fn elemVal(
14673 }14704 }
14674}14705}
1467514706
14707fn tupleFieldPtr(
14708 sema: *Sema,
14709 block: *Block,
14710 tuple_ptr: Air.Inst.Ref,
14711 field_index: u32,
14712 tuple_src: LazySrcLoc,
14713 field_index_src: LazySrcLoc,
14714) CompileError!Air.Inst.Ref {
14715 const tuple_ptr_ty = sema.typeOf(tuple_ptr);
14716 const tuple_ty = tuple_ptr_ty.childType();
14717 const tuple_info = tuple_ty.castTag(.tuple).?.data;
14718
14719 if (field_index > tuple_info.types.len) {
14720 return sema.fail(block, field_index_src, "index {d} outside tuple of length {d}", .{
14721 field_index, tuple_info.types.len,
14722 });
14723 }
14724
14725 const field_ty = tuple_info.types[field_index];
14726 const ptr_field_ty = try Type.ptr(sema.arena, .{
14727 .pointee_type = field_ty,
14728 .mutable = tuple_ptr_ty.ptrIsMutable(),
14729 .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(),
14730 });
14731
14732 if (try sema.resolveMaybeUndefVal(block, tuple_src, tuple_ptr)) |tuple_ptr_val| {
14733 return sema.addConstant(
14734 ptr_field_ty,
14735 try Value.Tag.field_ptr.create(sema.arena, .{
14736 .container_ptr = tuple_ptr_val,
14737 .field_index = field_index,
14738 }),
14739 );
14740 }
14741
14742 try sema.requireRuntimeBlock(block, tuple_src);
14743 return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty);
14744}
14745
14676fn tupleField(14746fn tupleField(
14677 sema: *Sema,14747 sema: *Sema,
14678 block: *Block,14748 block: *Block,
...@@ -15273,9 +15343,8 @@ fn coerceInMemoryAllowedErrorSets(...@@ -15273,9 +15343,8 @@ fn coerceInMemoryAllowedErrorSets(
15273 return .no_match;15343 return .no_match;
15274 }15344 }
1527515345
15276 var it = src_data.errors.keyIterator();15346 for (src_data.errors.keys()) |key| {
15277 while (it.next()) |name_ptr| {15347 if (!dest_ty.errorSetHasField(key)) {
15278 if (!dest_ty.errorSetHasField(name_ptr.*)) {
15279 return .no_match;15348 return .no_match;
15280 }15349 }
15281 }15350 }
...@@ -17525,9 +17594,8 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE...@@ -17525,9 +17594,8 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE
17525 try sema.ensureDeclAnalyzed(decl); // To ensure that all dependencies are properly added to the set.17594 try sema.ensureDeclAnalyzed(decl); // To ensure that all dependencies are properly added to the set.
17526 try sema.resolveInferredErrorSet(other_error_set_ptr.*);17595 try sema.resolveInferredErrorSet(other_error_set_ptr.*);
1752717596
17528 var error_it = other_error_set_ptr.*.errors.keyIterator();17597 for (other_error_set_ptr.*.errors.keys()) |key| {
17529 while (error_it.next()) |entry| {17598 try inferred_error_set.errors.put(sema.gpa, key, {});
17530 try inferred_error_set.errors.put(sema.gpa, entry.*, {});
17531 }17599 }
17532 if (other_error_set_ptr.*.is_anyerror)17600 if (other_error_set_ptr.*.is_anyerror)
17533 inferred_error_set.is_anyerror = true;17601 inferred_error_set.is_anyerror = true;
src/codegen/llvm.zig+2-1
...@@ -4025,7 +4025,7 @@ pub const FuncGen = struct {...@@ -4025,7 +4025,7 @@ pub const FuncGen = struct {
4025 if (self.liveness.isUnused(inst)) return null;4025 if (self.liveness.isUnused(inst)) return null;
4026 const ptr_ty = self.air.typeOfIndex(inst);4026 const ptr_ty = self.air.typeOfIndex(inst);
4027 const ret_ty = ptr_ty.childType();4027 const ret_ty = ptr_ty.childType();
4028 if (!ret_ty.isFnOrHasRuntimeBits()) return null;4028 if (!ret_ty.isFnOrHasRuntimeBits()) return self.dg.lowerPtrToVoid(ptr_ty);
4029 if (self.ret_ptr) |ret_ptr| return ret_ptr;4029 if (self.ret_ptr) |ret_ptr| return ret_ptr;
4030 const ret_llvm_ty = try self.dg.llvmType(ret_ty);4030 const ret_llvm_ty = try self.dg.llvmType(ret_ty);
4031 const target = self.dg.module.getTarget();4031 const target = self.dg.module.getTarget();
...@@ -4845,6 +4845,7 @@ pub const FuncGen = struct {...@@ -4845,6 +4845,7 @@ pub const FuncGen = struct {
4845 struct_ptr_ty: Type,4845 struct_ptr_ty: Type,
4846 field_index: u32,4846 field_index: u32,
4847 ) !?*const llvm.Value {4847 ) !?*const llvm.Value {
4848 if (self.liveness.isUnused(inst)) return null;
4848 const struct_ty = struct_ptr_ty.childType();4849 const struct_ty = struct_ptr_ty.childType();
4849 switch (struct_ty.zigTypeTag()) {4850 switch (struct_ty.zigTypeTag()) {
4850 .Struct => switch (struct_ty.containerLayout()) {4851 .Struct => switch (struct_ty.containerLayout()) {
src/type.zig+6
...@@ -3878,6 +3878,12 @@ pub const Type = extern union {...@@ -3878,6 +3878,12 @@ pub const Type = extern union {
3878 },3878 },
3879 .error_set_merged => ty.castTag(.error_set_merged).?.data.keys(),3879 .error_set_merged => ty.castTag(.error_set_merged).?.data.keys(),
3880 .error_set => ty.castTag(.error_set).?.data.names.keys(),3880 .error_set => ty.castTag(.error_set).?.data.names.keys(),
3881 .error_set_inferred => {
3882 const inferred_error_set = ty.castTag(.error_set_inferred).?.data;
3883 assert(inferred_error_set.is_resolved);
3884 assert(!inferred_error_set.is_anyerror);
3885 return inferred_error_set.errors.keys();
3886 },
3881 else => unreachable,3887 else => unreachable,
3882 };3888 };
3883 }3889 }
test/behavior.zig+1-1
...@@ -132,6 +132,7 @@ test {...@@ -132,6 +132,7 @@ test {
132 _ = @import("behavior/bugs/3384.zig");132 _ = @import("behavior/bugs/3384.zig");
133 _ = @import("behavior/bugs/3742.zig");133 _ = @import("behavior/bugs/3742.zig");
134 _ = @import("behavior/bugs/5398.zig");134 _ = @import("behavior/bugs/5398.zig");
135 _ = @import("behavior/bugs/5487.zig");
135 _ = @import("behavior/struct_contains_null_ptr_itself.zig");136 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
136 _ = @import("behavior/switch_prong_err_enum.zig");137 _ = @import("behavior/switch_prong_err_enum.zig");
137 _ = @import("behavior/switch_prong_implicit_cast.zig");138 _ = @import("behavior/switch_prong_implicit_cast.zig");
...@@ -153,7 +154,6 @@ test {...@@ -153,7 +154,6 @@ test {
153 _ = @import("behavior/bugs/1851.zig");154 _ = @import("behavior/bugs/1851.zig");
154 _ = @import("behavior/bugs/3779.zig");155 _ = @import("behavior/bugs/3779.zig");
155 _ = @import("behavior/bugs/5413.zig");156 _ = @import("behavior/bugs/5413.zig");
156 _ = @import("behavior/bugs/5487.zig");
157 _ = @import("behavior/bugs/6456.zig");157 _ = @import("behavior/bugs/6456.zig");
158 _ = @import("behavior/bugs/6781.zig");158 _ = @import("behavior/bugs/6781.zig");
159 _ = @import("behavior/bugs/7003.zig");159 _ = @import("behavior/bugs/7003.zig");