aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-03-09 18:47:42 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-03-09 18:49:37 -0700
commitf736cde397a6abb1399827ed5988c43001706580 (patch)
treec1ce080f82846a4322eac7be653a78044338e740 /src/Sema.zig
parent017d3864de1f337d01726e87534a4e2093c7265f (diff)
downloadzig-f736cde397a6abb1399827ed5988c43001706580.tar.gz
zig-f736cde397a6abb1399827ed5988c43001706580.zip
Sema: implement pointer to tuple to pointer to array coercion
This involved an LLVM backend fix for the aggregate_init instruction.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig62
1 files changed, 44 insertions, 18 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 64d6e1b373..11f250e44c 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -16005,9 +16005,17 @@ fn coerce(
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
}
- // coercion to C pointer
- if (dest_info.size == .C) {
- switch (inst_ty.zigTypeTag()) {
+ // cast from *T and [*]T to *anyopaque
+ // but don't do it if the source type is a double pointer
+ if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and
+ inst_ty.childType().zigTypeTag() != .Pointer)
+ {
+ return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
+ }
+
+ switch (dest_info.size) {
+ // coercion to C pointer
+ .C => switch (inst_ty.zigTypeTag()) {
.Null => {
return sema.addConstant(dest_ty, Value.@"null");
},
@@ -16041,22 +16049,10 @@ fn coerce(
return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
},
else => {},
- }
- }
-
- // cast from *T and [*]T to *anyopaque
- // but don't do it if the source type is a double pointer
- if (dest_info.pointee_type.tag() == .anyopaque and inst_ty.zigTypeTag() == .Pointer and
- inst_ty.childType().zigTypeTag() != .Pointer)
- {
- return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src);
- }
-
- switch (dest_info.size) {
- .C, .Many => {},
+ },
.One => switch (dest_info.pointee_type.zigTypeTag()) {
.Union => {
- // cast from pointer to anonymous struct to pointer to union
+ // pointer to anonymous struct to pointer to union
if (inst_ty.isSinglePointer() and
inst_ty.childType().isAnonStruct() and
!dest_info.mutable)
@@ -16065,7 +16061,7 @@ fn coerce(
}
},
.Struct => {
- // cast from pointer to anonymous struct to pointer to struct
+ // pointer to anonymous struct to pointer to struct
if (inst_ty.isSinglePointer() and
inst_ty.childType().isAnonStruct() and
!dest_info.mutable)
@@ -16073,6 +16069,15 @@ fn coerce(
return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src);
}
},
+ .Array => {
+ // pointer to tuple to pointer to array
+ if (inst_ty.isSinglePointer() and
+ inst_ty.childType().isTuple() and
+ !dest_info.mutable)
+ {
+ return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src);
+ }
+ },
else => {},
},
.Slice => {
@@ -16084,6 +16089,7 @@ fn coerce(
return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src);
}
},
+ .Many => {},
}
// This will give an extra hint on top of what the bottom of this func would provide.
@@ -17554,6 +17560,26 @@ fn coerceTupleToSlicePtrs(
return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src);
}
+/// If the lengths match, coerces element-wise.
+fn coerceTupleToArrayPtrs(
+ sema: *Sema,
+ block: *Block,
+ ptr_array_ty: Type,
+ array_ty_src: LazySrcLoc,
+ ptr_tuple: Air.Inst.Ref,
+ tuple_src: LazySrcLoc,
+) !Air.Inst.Ref {
+ const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src);
+ const ptr_info = ptr_array_ty.ptrInfo().data;
+ const array_ty = ptr_info.pointee_type;
+ const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src);
+ if (ptr_info.@"align" != 0) {
+ return sema.fail(block, array_ty_src, "TODO: override the alignment of the array decl we create here", .{});
+ }
+ const ptr_array = try sema.analyzeRef(block, array_ty_src, array_inst);
+ return ptr_array;
+}
+
/// Handles both tuples and anon struct literals. Coerces field-wise. Reports
/// errors for both extra fields and missing fields.
fn coerceTupleToStruct(