aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-03-01 21:57:06 +0200
committerVeikka Tuominen <git@vexu.eu>2022-03-02 12:26:04 +0200
commit403a1fe5d767e801b58fc706eaa54f1171ae27de (patch)
treecba681d1d2a81d83a323b444bf1135860e4f9354 /src
parent58530c17364d2525655c90e97fd2cdd2937e5c19 (diff)
downloadzig-403a1fe5d767e801b58fc706eaa54f1171ae27de.tar.gz
zig-403a1fe5d767e801b58fc706eaa54f1171ae27de.zip
stage2: add cast from ?*T to ?*anyopaque
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig14
-rw-r--r--src/type.zig17
2 files changed, 25 insertions, 6 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 6496adf96d..d96acfea24 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -12371,7 +12371,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
const type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
const type_res = try sema.resolveType(block, src, extra.lhs);
try sema.checkPtrType(block, type_src, type_res);
- _ = try sema.resolveTypeLayout(block, src, type_res.childType());
+ try sema.resolveTypeLayout(block, src, type_res.elemType2());
const ptr_align = type_res.ptrAlignment(sema.mod.getTarget());
if (try sema.resolveDefinedValue(block, operand_src, operand_coerced)) |val| {
@@ -15512,6 +15512,14 @@ fn coerce(
return sema.addConstant(dest_ty, Value.@"null");
}
+ // cast from ?*T and ?[*]T to ?*anyopaque
+ // but don't do it if the source type is a double pointer
+ if (dest_ty.isPtrLikeOptional() and dest_ty.elemType2().tag() == .anyopaque and
+ inst_ty.isPtrLikeOptional() and inst_ty.elemType2().zigTypeTag() != .Pointer)
+ {
+ return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
+ }
+
// T to ?T
const child_type = try dest_ty.optionalChildAlloc(sema.arena);
const intermediate = try sema.coerce(block, child_type, inst, inst_src);
@@ -16791,6 +16799,7 @@ fn coerceCompatiblePtrs(
inst: Air.Inst.Ref,
inst_src: LazySrcLoc,
) !Air.Inst.Ref {
+ // TODO check const/volatile/alignment
if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| {
// The comptime Value representation is compatible with both types.
return sema.addConstant(dest_ty, val);
@@ -18506,6 +18515,7 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE
if (inferred_error_set.is_resolved) {
return;
}
+ inferred_error_set.is_resolved = true;
var it = inferred_error_set.inferred_error_sets.keyIterator();
while (it.next()) |other_error_set_ptr| {
@@ -18526,8 +18536,6 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE
if (other_error_set_ptr.*.is_anyerror)
inferred_error_set.is_anyerror = true;
}
-
- inferred_error_set.is_resolved = true;
}
fn resolveInferredErrorSetTy(sema: *Sema, ty: Type) CompileError!void {
diff --git a/src/type.zig b/src/type.zig
index 6e58f7a42f..3c08ed5b63 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -2168,7 +2168,14 @@ pub const Type = extern union {
.mut_slice,
.optional_single_const_pointer,
.optional_single_mut_pointer,
- => return self.cast(Payload.ElemType).?.data.abiAlignment(target),
+ => {
+ const child_type = self.cast(Payload.ElemType).?.data;
+ if (child_type.zigTypeTag() == .Opaque) {
+ return 1;
+ } else {
+ return child_type.abiAlignment(target);
+ }
+ },
.manyptr_u8,
.manyptr_const_u8,
@@ -2181,10 +2188,13 @@ pub const Type = extern union {
const ptr_info = self.castTag(.pointer).?.data;
if (ptr_info.@"align" != 0) {
return ptr_info.@"align";
+ } else if (ptr_info.pointee_type.zigTypeTag() == .Opaque) {
+ return 1;
} else {
return ptr_info.pointee_type.abiAlignment(target);
}
},
+ .optional => return self.castTag(.optional).?.data.ptrAlignment(target),
else => unreachable,
}
@@ -3235,8 +3245,9 @@ pub const Type = extern union {
return child_ty;
}
},
-
- // TODO handle optionals
+ .optional => ty.castTag(.optional).?.data.childType(),
+ .optional_single_mut_pointer => ty.castPointer().?.data,
+ .optional_single_const_pointer => ty.castPointer().?.data,
else => unreachable,
};