diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-09 18:47:42 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-09 18:49:37 -0700 |
| commit | f736cde397a6abb1399827ed5988c43001706580 (patch) | |
| tree | c1ce080f82846a4322eac7be653a78044338e740 /src/Sema.zig | |
| parent | 017d3864de1f337d01726e87534a4e2093c7265f (diff) | |
| download | zig-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.zig | 62 |
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( |
