| ... | @@ -16858,6 +16858,8 @@ fn resolvePeerTypes( | ... | @@ -16858,6 +16858,8 @@ fn resolvePeerTypes( |
| 16858 | | 16858 | |
| 16859 | var chosen = instructions[0]; | 16859 | var chosen = instructions[0]; |
| 16860 | var any_are_null = false; | 16860 | var any_are_null = false; |
| | 16861 | var make_the_slice_const = false; |
| | 16862 | var convert_to_slice = false; |
| 16861 | var chosen_i: usize = 0; | 16863 | var chosen_i: usize = 0; |
| 16862 | for (instructions[1..]) |candidate, candidate_i| { | 16864 | for (instructions[1..]) |candidate, candidate_i| { |
| 16863 | const candidate_ty = sema.typeOf(candidate); | 16865 | const candidate_ty = sema.typeOf(candidate); |
| ... | @@ -16955,6 +16957,46 @@ fn resolvePeerTypes( | ... | @@ -16955,6 +16957,46 @@ fn resolvePeerTypes( |
| 16955 | continue; | 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 | .Optional => { | 17001 | .Optional => { |
| 16960 | var opt_child_buf: Type.Payload.ElemType = undefined; | 17002 | var opt_child_buf: Type.Payload.ElemType = undefined; |
| ... | @@ -17037,6 +17079,22 @@ fn resolvePeerTypes( | ... | @@ -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 | return chosen_ty; | 17098 | return chosen_ty; |
| 17041 | } | 17099 | } |
| 17042 | | 17100 | |