diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-02-26 22:57:05 +0200 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-02-26 18:44:23 -0500 |
| commit | bf3c88b68d9f8042b79b7d69d401429811d9de7c (patch) | |
| tree | 7efd2e71a3b105adf417c831b75aa23b7637af35 /src | |
| parent | 058e482247c73ecb6404c7c1e3d2194f4aa9e059 (diff) | |
| download | zig-bf3c88b68d9f8042b79b7d69d401429811d9de7c.tar.gz zig-bf3c88b68d9f8042b79b7d69d401429811d9de7c.zip | |
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
Diffstat (limited to 'src')
| -rw-r--r-- | src/Module.zig | 2 | ||||
| -rw-r--r-- | src/Sema.zig | 88 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 3 | ||||
| -rw-r--r-- | src/type.zig | 6 |
4 files changed, 87 insertions, 12 deletions
diff --git a/src/Module.zig b/src/Module.zig index e596ab0aba..7f52dc23e9 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1435,7 +1435,7 @@ pub const Fn = struct { /// All currently known errors that this error set contains. This includes direct additions /// via `return error.Foo;`, and possibly also errors that are returned from any dependent functions. /// When the inferred error set is fully resolved, this map contains all the errors that the function might return. - errors: std.StringHashMapUnmanaged(void) = .{}, + errors: ErrorSet.NameMap = .{}, /// Other inferred error sets which this inferred error set should include. inferred_error_sets: std.AutoHashMapUnmanaged(*InferredErrorSet, void) = .{}, diff --git a/src/Sema.zig b/src/Sema.zig index 4588f487e2..e5c38c8450 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1613,10 +1613,15 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE //} // The last one is always `store`. - const trash_inst = trash_block.instructions.pop(); - assert(air_tags[trash_inst] == .store); - assert(trash_inst == sema.air_instructions.len - 1); - sema.air_instructions.len -= 1; + const trash_inst = trash_block.instructions.items[trash_block.instructions.items.len - 1]; + if (air_tags[trash_inst] != .store) { + // no store instruction is generated for zero sized types + assert((try sema.typeHasOnePossibleValue(block, src, pointee_ty)) != null); + } else { + trash_block.instructions.items.len -= 1; + assert(trash_inst == sema.air_instructions.len - 1); + sema.air_instructions.len -= 1; + } } const ptr_ty = try Type.ptr(sema.arena, .{ @@ -5236,6 +5241,22 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) { return Air.Inst.Ref.anyerror_type; } + + if (lhs_ty.castTag(.error_set_inferred)) |payload| { + try sema.resolveInferredErrorSet(payload.data); + // isAnyError might have changed from a false negative to a true positive after resolution. + if (lhs_ty.isAnyError()) { + return Air.Inst.Ref.anyerror_type; + } + } + if (rhs_ty.castTag(.error_set_inferred)) |payload| { + try sema.resolveInferredErrorSet(payload.data); + // isAnyError might have changed from a false negative to a true positive after resolution. + if (rhs_ty.isAnyError()) { + return Air.Inst.Ref.anyerror_type; + } + } + // Resolve both error sets now. const lhs_names = lhs_ty.errorSetNames(); const rhs_names = rhs_ty.errorSetNames(); @@ -6809,6 +6830,10 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError } } + if (operand_ty.castTag(.error_set_inferred)) |inferred| { + try sema.resolveInferredErrorSet(inferred.data); + } + if (operand_ty.isAnyError()) { if (special_prong != .@"else") { return sema.fail( @@ -14597,6 +14622,12 @@ fn elemPtr( }, .Array => return sema.elemPtrArray(block, array_ptr_src, array_ptr, elem_index, elem_index_src), .Vector => return sema.fail(block, src, "TODO implement Sema for elemPtr for vector", .{}), + .Struct => { + // Tuple field access. + const index_val = try sema.resolveConstValue(block, elem_index_src, elem_index); + const index = @intCast(u32, index_val.toUnsignedInt()); + return sema.tupleFieldPtr(block, array_ptr, index, src, elem_index_src); + }, else => unreachable, } } @@ -14673,6 +14704,45 @@ fn elemVal( } } +fn tupleFieldPtr( + sema: *Sema, + block: *Block, + tuple_ptr: Air.Inst.Ref, + field_index: u32, + tuple_src: LazySrcLoc, + field_index_src: LazySrcLoc, +) CompileError!Air.Inst.Ref { + const tuple_ptr_ty = sema.typeOf(tuple_ptr); + const tuple_ty = tuple_ptr_ty.childType(); + const tuple_info = tuple_ty.castTag(.tuple).?.data; + + if (field_index > tuple_info.types.len) { + return sema.fail(block, field_index_src, "index {d} outside tuple of length {d}", .{ + field_index, tuple_info.types.len, + }); + } + + const field_ty = tuple_info.types[field_index]; + const ptr_field_ty = try Type.ptr(sema.arena, .{ + .pointee_type = field_ty, + .mutable = tuple_ptr_ty.ptrIsMutable(), + .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(), + }); + + if (try sema.resolveMaybeUndefVal(block, tuple_src, tuple_ptr)) |tuple_ptr_val| { + return sema.addConstant( + ptr_field_ty, + try Value.Tag.field_ptr.create(sema.arena, .{ + .container_ptr = tuple_ptr_val, + .field_index = field_index, + }), + ); + } + + try sema.requireRuntimeBlock(block, tuple_src); + return block.addStructFieldPtr(tuple_ptr, field_index, ptr_field_ty); +} + fn tupleField( sema: *Sema, block: *Block, @@ -15273,9 +15343,8 @@ fn coerceInMemoryAllowedErrorSets( return .no_match; } - var it = src_data.errors.keyIterator(); - while (it.next()) |name_ptr| { - if (!dest_ty.errorSetHasField(name_ptr.*)) { + for (src_data.errors.keys()) |key| { + if (!dest_ty.errorSetHasField(key)) { return .no_match; } } @@ -17525,9 +17594,8 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE try sema.ensureDeclAnalyzed(decl); // To ensure that all dependencies are properly added to the set. try sema.resolveInferredErrorSet(other_error_set_ptr.*); - var error_it = other_error_set_ptr.*.errors.keyIterator(); - while (error_it.next()) |entry| { - try inferred_error_set.errors.put(sema.gpa, entry.*, {}); + for (other_error_set_ptr.*.errors.keys()) |key| { + try inferred_error_set.errors.put(sema.gpa, key, {}); } if (other_error_set_ptr.*.is_anyerror) inferred_error_set.is_anyerror = true; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 51bb713ed5..bc5f5ca7c7 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -4025,7 +4025,7 @@ pub const FuncGen = struct { if (self.liveness.isUnused(inst)) return null; const ptr_ty = self.air.typeOfIndex(inst); const ret_ty = ptr_ty.childType(); - if (!ret_ty.isFnOrHasRuntimeBits()) return null; + if (!ret_ty.isFnOrHasRuntimeBits()) return self.dg.lowerPtrToVoid(ptr_ty); if (self.ret_ptr) |ret_ptr| return ret_ptr; const ret_llvm_ty = try self.dg.llvmType(ret_ty); const target = self.dg.module.getTarget(); @@ -4845,6 +4845,7 @@ pub const FuncGen = struct { struct_ptr_ty: Type, field_index: u32, ) !?*const llvm.Value { + if (self.liveness.isUnused(inst)) return null; const struct_ty = struct_ptr_ty.childType(); switch (struct_ty.zigTypeTag()) { .Struct => switch (struct_ty.containerLayout()) { diff --git a/src/type.zig b/src/type.zig index 581465c51a..ccf1b37471 100644 --- a/src/type.zig +++ b/src/type.zig @@ -3878,6 +3878,12 @@ pub const Type = extern union { }, .error_set_merged => ty.castTag(.error_set_merged).?.data.keys(), .error_set => ty.castTag(.error_set).?.data.names.keys(), + .error_set_inferred => { + const inferred_error_set = ty.castTag(.error_set_inferred).?.data; + assert(inferred_error_set.is_resolved); + assert(!inferred_error_set.is_anyerror); + return inferred_error_set.errors.keys(); + }, else => unreachable, }; } |
