| ... | ... | @@ -16858,6 +16858,8 @@ fn resolvePeerTypes( |
| 16858 | 16858 | |
| 16859 | 16859 | var chosen = instructions[0]; |
| 16860 | 16860 | var any_are_null = false; |
| 16861 | var make_the_slice_const = false; |
| 16862 | var convert_to_slice = false; |
| 16861 | 16863 | var chosen_i: usize = 0; |
| 16862 | 16864 | for (instructions[1..]) |candidate, candidate_i| { |
| 16863 | 16865 | const candidate_ty = sema.typeOf(candidate); |
| ... | ... | @@ -16955,6 +16957,46 @@ fn resolvePeerTypes( |
| 16955 | 16957 | continue; |
| 16956 | 16958 | } |
| 16957 | 16959 | } |
| 16960 | |
| 16961 | // *[N]T and *[M]T |
| 16962 | // verify both are pointers to known lengths |
| 16963 | if (chosen_ty_tag == .Pointer and |
| 16964 | chosen_ty.ptrSize() == .One and |
| 16965 | candidate_ty.ptrSize() == .One) |
| 16966 | { |
| 16967 | // verify both pointers are two arrays |
| 16968 | const chosen_child_ty = chosen_ty.childType(); |
| 16969 | const candidate_child_ty = candidate_ty.childType(); |
| 16970 | if (chosen_child_ty.zigTypeTag() == .Array and candidate_child_ty.zigTypeTag() == .Array) { |
| 16971 | // If there is a sentinel, it must match |
| 16972 | if (chosen_child_ty.sentinel()) |chosen_sentinel| { |
| 16973 | if (candidate_child_ty.sentinel()) |candidate_sentinel| { |
| 16974 | if (!chosen_sentinel.eql(candidate_sentinel, chosen_child_ty)) { |
| 16975 | continue; |
| 16976 | } |
| 16977 | } else { |
| 16978 | continue; |
| 16979 | } |
| 16980 | } |
| 16981 | |
| 16982 | // If we can cerce the element types, then we can do this. |
| 16983 | const chosen_elem_ty = chosen_child_ty.elemType2(); |
| 16984 | const candidate_elem_ty = candidate_child_ty.elemType2(); |
| 16985 | if ((try sema.coerceInMemoryAllowed(block, candidate_elem_ty, chosen_elem_ty, false, target, src, src)) == .ok) { |
| 16986 | chosen = candidate; |
| 16987 | chosen_i = candidate_i + 1; |
| 16988 | |
| 16989 | convert_to_slice = true; |
| 16990 | |
| 16991 | // If one of the pointers is to const data, the slice |
| 16992 | // must also be const. |
| 16993 | if (candidate_child_ty.isConstPtr() or chosen_child_ty.isConstPtr()) |
| 16994 | make_the_slice_const = true; |
| 16995 | |
| 16996 | continue; |
| 16997 | } |
| 16998 | } |
| 16999 | } |
| 16958 | 17000 | }, |
| 16959 | 17001 | .Optional => { |
| 16960 | 17002 | var opt_child_buf: Type.Payload.ElemType = undefined; |
| ... | ... | @@ -17037,6 +17079,22 @@ fn resolvePeerTypes( |
| 17037 | 17079 | } |
| 17038 | 17080 | } |
| 17039 | 17081 | |
| 17082 | if (convert_to_slice) { |
| 17083 | // turn *[N]T => []T |
| 17084 | const chosen_child_ty = chosen_ty.childType(); |
| 17085 | var info = chosen_ty.ptrInfo(); |
| 17086 | info.data.sentinel = chosen_child_ty.sentinel(); |
| 17087 | info.data.size = .Slice; |
| 17088 | info.data.mutable = chosen_child_ty.isConstPtr() or make_the_slice_const; |
| 17089 | info.data.pointee_type = switch (chosen_child_ty.tag()) { |
| 17090 | .array => chosen_child_ty.elemType2(), |
| 17091 | .array_u8, .array_u8_sentinel_0 => Type.initTag(.u8), |
| 17092 | else => unreachable, |
| 17093 | }; |
| 17094 | |
| 17095 | return Type.ptr(sema.arena, info.data); |
| 17096 | } |
| 17097 | |
| 17040 | 17098 | return chosen_ty; |
| 17041 | 17099 | } |
| 17042 | 17100 | |