| ... | @@ -16052,13 +16052,38 @@ fn coerce( | ... | @@ -16052,13 +16052,38 @@ fn coerce( |
| 16052 | return sema.coerceCompatiblePtrs(block, dest_ty, inst, inst_src); | 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 | 16055 | switch (dest_info.size) { |
| 16056 | if (dest_info.pointee_type.zigTypeTag() == .Union and | 16056 | .C, .Many => {}, |
| 16057 | inst_ty.zigTypeTag() == .Pointer and | 16057 | .One => switch (dest_info.pointee_type.zigTypeTag()) { |
| 16058 | inst_ty.childType().tag() == .anon_struct and | 16058 | .Union => { |
| 16059 | !dest_info.mutable) | 16059 | // cast from pointer to anonymous struct to pointer to union |
| 16060 | { | 16060 | if (inst_ty.isSinglePointer() and |
| 16061 | return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src); | 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 | // This will give an extra hint on top of what the bottom of this func would provide. | 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,6 +17390,20 @@ fn coerceAnonStructToUnionPtrs( |
| 17365 | return sema.analyzeRef(block, union_ty_src, union_inst); | 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 | /// If the lengths match, coerces element-wise. | 17407 | /// If the lengths match, coerces element-wise. |
| 17369 | fn coerceArrayLike( | 17408 | fn coerceArrayLike( |
| 17370 | sema: *Sema, | 17409 | sema: *Sema, |
| ... | @@ -17494,6 +17533,27 @@ fn coerceTupleToArray( | ... | @@ -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 | /// Handles both tuples and anon struct literals. Coerces field-wise. Reports | 17557 | /// Handles both tuples and anon struct literals. Coerces field-wise. Reports |
| 17498 | /// errors for both extra fields and missing fields. | 17558 | /// errors for both extra fields and missing fields. |
| 17499 | fn coerceTupleToStruct( | 17559 | fn coerceTupleToStruct( |
| ... | @@ -17504,11 +17564,13 @@ fn coerceTupleToStruct( | ... | @@ -17504,11 +17564,13 @@ fn coerceTupleToStruct( |
| 17504 | inst: Air.Inst.Ref, | 17564 | inst: Air.Inst.Ref, |
| 17505 | inst_src: LazySrcLoc, | 17565 | inst_src: LazySrcLoc, |
| 17506 | ) !Air.Inst.Ref { | 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 | return sema.fail(block, dest_ty_src, "TODO: implement coercion from tuples to tuples", .{}); | 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 | const field_vals = try sema.arena.alloc(Value, fields.count()); | 17574 | const field_vals = try sema.arena.alloc(Value, fields.count()); |
| 17513 | const field_refs = try sema.arena.alloc(Air.Inst.Ref, field_vals.len); | 17575 | const field_refs = try sema.arena.alloc(Air.Inst.Ref, field_vals.len); |
| 17514 | mem.set(Air.Inst.Ref, field_refs, .none); | 17576 | mem.set(Air.Inst.Ref, field_refs, .none); |
| ... | @@ -17523,7 +17585,7 @@ fn coerceTupleToStruct( | ... | @@ -17523,7 +17585,7 @@ fn coerceTupleToStruct( |
| 17523 | payload.data.names[i] | 17585 | payload.data.names[i] |
| 17524 | else | 17586 | else |
| 17525 | try std.fmt.allocPrint(sema.arena, "{d}", .{i}); | 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 | const field = fields.values()[field_index]; | 17589 | const field = fields.values()[field_index]; |
| 17528 | if (field.is_comptime) { | 17590 | if (field.is_comptime) { |
| 17529 | return sema.fail(block, dest_ty_src, "TODO: implement coercion from tuples to structs when one of the destination struct fields is comptime", .{}); | 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,17 +17629,17 @@ fn coerceTupleToStruct( |
| 17567 | } | 17629 | } |
| 17568 | | 17630 | |
| 17569 | if (root_msg) |msg| { | 17631 | if (root_msg) |msg| { |
| 17570 | try sema.addDeclaredHereNote(msg, dest_ty); | 17632 | try sema.addDeclaredHereNote(msg, struct_ty); |
| 17571 | return sema.failWithOwnedErrorMsg(block, msg); | 17633 | return sema.failWithOwnedErrorMsg(block, msg); |
| 17572 | } | 17634 | } |
| 17573 | | 17635 | |
| 17574 | if (runtime_src) |rs| { | 17636 | if (runtime_src) |rs| { |
| 17575 | try sema.requireRuntimeBlock(block, rs); | 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 | return sema.addConstant( | 17641 | return sema.addConstant( |
| 17580 | dest_ty, | 17642 | struct_ty, |
| 17581 | try Value.Tag.@"struct".create(sema.arena, field_vals), | 17643 | try Value.Tag.@"struct".create(sema.arena, field_vals), |
| 17582 | ); | 17644 | ); |
| 17583 | } | 17645 | } |