| ... | ... | @@ -16052,13 +16052,38 @@ fn coerce( |
| 16052 | 16052 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); |
| 16053 | 16053 | } |
| 16054 | 16054 | |
| 16055 | | // cast from pointer to anonymous struct to pointer to union |
| 16056 | | if (dest_info.pointee_type.zigTypeTag() == .Union and |
| 16057 | | inst_ty.zigTypeTag() == .Pointer and |
| 16058 | | inst_ty.childType().tag() == .anon_struct and |
| 16059 | | !dest_info.mutable) |
| 16060 | | { |
| 16061 | | return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 16055 | switch (dest_info.size) { |
| 16056 | .C, .Many => {}, |
| 16057 | .One => switch (dest_info.pointee_type.zigTypeTag()) { |
| 16058 | .Union => { |
| 16059 | // cast from pointer to anonymous struct to pointer to union |
| 16060 | if (inst_ty.isSinglePointer() and |
| 16061 | inst_ty.childType().isAnonStruct() and |
| 16062 | !dest_info.mutable) |
| 16063 | { |
| 16064 | return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 16065 | } |
| 16066 | }, |
| 16067 | .Struct => { |
| 16068 | // cast from pointer to anonymous struct to pointer to struct |
| 16069 | if (inst_ty.isSinglePointer() and |
| 16070 | inst_ty.childType().isAnonStruct() and |
| 16071 | !dest_info.mutable) |
| 16072 | { |
| 16073 | return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 16074 | } |
| 16075 | }, |
| 16076 | else => {}, |
| 16077 | }, |
| 16078 | .Slice => { |
| 16079 | // pointer to tuple to slice |
| 16080 | if (inst_ty.isSinglePointer() and |
| 16081 | inst_ty.childType().isTuple() and |
| 16082 | !dest_info.mutable and dest_info.size == .Slice) |
| 16083 | { |
| 16084 | return sema.coerceTupleToSlicePtrs(block, dest_ty, dest_ty_src, inst, inst_src); |
| 16085 | } |
| 16086 | }, |
| 16062 | 16087 | } |
| 16063 | 16088 | |
| 16064 | 16089 | // This will give an extra hint on top of what the bottom of this func would provide. |
| ... | ... | @@ -17365,6 +17390,20 @@ fn coerceAnonStructToUnionPtrs( |
| 17365 | 17390 | return sema.analyzeRef(block, union_ty_src, union_inst); |
| 17366 | 17391 | } |
| 17367 | 17392 | |
| 17393 | fn coerceAnonStructToStructPtrs( |
| 17394 | sema: *Sema, |
| 17395 | block: *Block, |
| 17396 | ptr_struct_ty: Type, |
| 17397 | struct_ty_src: LazySrcLoc, |
| 17398 | ptr_anon_struct: Air.Inst.Ref, |
| 17399 | anon_struct_src: LazySrcLoc, |
| 17400 | ) !Air.Inst.Ref { |
| 17401 | const struct_ty = ptr_struct_ty.childType(); |
| 17402 | const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); |
| 17403 | const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, struct_ty_src, anon_struct, anon_struct_src); |
| 17404 | return sema.analyzeRef(block, struct_ty_src, struct_inst); |
| 17405 | } |
| 17406 | |
| 17368 | 17407 | /// If the lengths match, coerces element-wise. |
| 17369 | 17408 | fn coerceArrayLike( |
| 17370 | 17409 | sema: *Sema, |
| ... | ... | @@ -17494,6 +17533,27 @@ fn coerceTupleToArray( |
| 17494 | 17533 | ); |
| 17495 | 17534 | } |
| 17496 | 17535 | |
| 17536 | /// If the lengths match, coerces element-wise. |
| 17537 | fn coerceTupleToSlicePtrs( |
| 17538 | sema: *Sema, |
| 17539 | block: *Block, |
| 17540 | slice_ty: Type, |
| 17541 | slice_ty_src: LazySrcLoc, |
| 17542 | ptr_tuple: Air.Inst.Ref, |
| 17543 | tuple_src: LazySrcLoc, |
| 17544 | ) !Air.Inst.Ref { |
| 17545 | const tuple_ty = sema.typeOf(ptr_tuple).childType(); |
| 17546 | const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); |
| 17547 | const slice_info = slice_ty.ptrInfo().data; |
| 17548 | const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type); |
| 17549 | const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src); |
| 17550 | if (slice_info.@"align" != 0) { |
| 17551 | return sema.fail(block, slice_ty_src, "TODO: override the alignment of the array decl we create here", .{}); |
| 17552 | } |
| 17553 | const ptr_array = try sema.analyzeRef(block, slice_ty_src, array_inst); |
| 17554 | return sema.coerceArrayPtrToSlice(block, slice_ty, ptr_array, slice_ty_src); |
| 17555 | } |
| 17556 | |
| 17497 | 17557 | /// Handles both tuples and anon struct literals. Coerces field-wise. Reports |
| 17498 | 17558 | /// errors for both extra fields and missing fields. |
| 17499 | 17559 | fn coerceTupleToStruct( |
| ... | ... | @@ -17504,11 +17564,13 @@ fn coerceTupleToStruct( |
| 17504 | 17564 | inst: Air.Inst.Ref, |
| 17505 | 17565 | inst_src: LazySrcLoc, |
| 17506 | 17566 | ) !Air.Inst.Ref { |
| 17507 | | if (dest_ty.isTupleOrAnonStruct()) { |
| 17567 | const struct_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty); |
| 17568 | |
| 17569 | if (struct_ty.isTupleOrAnonStruct()) { |
| 17508 | 17570 | return sema.fail(block, dest_ty_src, "TODO: implement coercion from tuples to tuples", .{}); |
| 17509 | 17571 | } |
| 17510 | 17572 | |
| 17511 | | const fields = dest_ty.structFields(); |
| 17573 | const fields = struct_ty.structFields(); |
| 17512 | 17574 | const field_vals = try sema.arena.alloc(Value, fields.count()); |
| 17513 | 17575 | const field_refs = try sema.arena.alloc(Air.Inst.Ref, field_vals.len); |
| 17514 | 17576 | mem.set(Air.Inst.Ref, field_refs, .none); |
| ... | ... | @@ -17523,7 +17585,7 @@ fn coerceTupleToStruct( |
| 17523 | 17585 | payload.data.names[i] |
| 17524 | 17586 | else |
| 17525 | 17587 | try std.fmt.allocPrint(sema.arena, "{d}", .{i}); |
| 17526 | | const field_index = try sema.structFieldIndex(block, dest_ty, field_name, field_src); |
| 17588 | const field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src); |
| 17527 | 17589 | const field = fields.values()[field_index]; |
| 17528 | 17590 | if (field.is_comptime) { |
| 17529 | 17591 | return sema.fail(block, dest_ty_src, "TODO: implement coercion from tuples to structs when one of the destination struct fields is comptime", .{}); |
| ... | ... | @@ -17567,17 +17629,17 @@ fn coerceTupleToStruct( |
| 17567 | 17629 | } |
| 17568 | 17630 | |
| 17569 | 17631 | if (root_msg) |msg| { |
| 17570 | | try sema.addDeclaredHereNote(msg, dest_ty); |
| 17632 | try sema.addDeclaredHereNote(msg, struct_ty); |
| 17571 | 17633 | return sema.failWithOwnedErrorMsg(block, msg); |
| 17572 | 17634 | } |
| 17573 | 17635 | |
| 17574 | 17636 | if (runtime_src) |rs| { |
| 17575 | 17637 | try sema.requireRuntimeBlock(block, rs); |
| 17576 | | return block.addAggregateInit(dest_ty, field_refs); |
| 17638 | return block.addAggregateInit(struct_ty, field_refs); |
| 17577 | 17639 | } |
| 17578 | 17640 | |
| 17579 | 17641 | return sema.addConstant( |
| 17580 | | dest_ty, |
| 17642 | struct_ty, |
| 17581 | 17643 | try Value.Tag.@"struct".create(sema.arena, field_vals), |
| 17582 | 17644 | ); |
| 17583 | 17645 | } |