| ... | ... | @@ -5141,15 +5141,15 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5141 | 5141 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 5142 | 5142 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 5143 | 5143 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; |
| 5144 | | const error_union = try sema.resolveType(block, lhs_src, extra.lhs); |
| 5144 | const error_set = try sema.resolveType(block, lhs_src, extra.lhs); |
| 5145 | 5145 | const payload = try sema.resolveType(block, rhs_src, extra.rhs); |
| 5146 | 5146 | |
| 5147 | | if (error_union.zigTypeTag() != .ErrorSet) { |
| 5147 | if (error_set.zigTypeTag() != .ErrorSet) { |
| 5148 | 5148 | return sema.fail(block, lhs_src, "expected error set type, found {}", .{ |
| 5149 | | error_union.elemType(), |
| 5149 | error_set, |
| 5150 | 5150 | }); |
| 5151 | 5151 | } |
| 5152 | | const err_union_ty = try Module.errorUnionType(sema.arena, error_union, payload); |
| 5152 | const err_union_ty = try Module.errorUnionType(sema.arena, error_set, payload); |
| 5153 | 5153 | return sema.addType(err_union_ty); |
| 5154 | 5154 | } |
| 5155 | 5155 | |
| ... | ... | @@ -5281,31 +5281,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5281 | 5281 | } |
| 5282 | 5282 | } |
| 5283 | 5283 | |
| 5284 | | // Resolve both error sets now. |
| 5285 | | const lhs_names = lhs_ty.errorSetNames(); |
| 5286 | | const rhs_names = rhs_ty.errorSetNames(); |
| 5287 | | |
| 5288 | | // TODO do we really want to create a Decl for this? |
| 5289 | | // The reason we do it right now is for memory management. |
| 5290 | | var anon_decl = try block.startAnonDecl(src); |
| 5291 | | defer anon_decl.deinit(); |
| 5292 | | |
| 5293 | | var names = Module.ErrorSet.NameMap{}; |
| 5294 | | // TODO: Guess is an upper bound, but maybe this needs to be reduced by computing the exact size first. |
| 5295 | | try names.ensureUnusedCapacity(anon_decl.arena(), @intCast(u32, lhs_names.len + rhs_names.len)); |
| 5296 | | for (lhs_names) |name| { |
| 5297 | | names.putAssumeCapacityNoClobber(name, {}); |
| 5298 | | } |
| 5299 | | for (rhs_names) |name| { |
| 5300 | | names.putAssumeCapacity(name, {}); |
| 5301 | | } |
| 5302 | | |
| 5303 | | const err_set_ty = try Type.Tag.error_set_merged.create(anon_decl.arena(), names); |
| 5304 | | const err_set_decl = try anon_decl.finish( |
| 5305 | | Type.type, |
| 5306 | | try Value.Tag.ty.create(anon_decl.arena(), err_set_ty), |
| 5307 | | ); |
| 5308 | | try sema.mod.declareDeclDependency(sema.owner_decl, err_set_decl); |
| 5284 | const err_set_ty = try lhs_ty.errorSetMerge(sema.arena, rhs_ty); |
| 5309 | 5285 | return sema.addType(err_set_ty); |
| 5310 | 5286 | } |
| 5311 | 5287 | |
| ... | ... | @@ -6858,9 +6834,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6858 | 6834 | } |
| 6859 | 6835 | } |
| 6860 | 6836 | |
| 6861 | | if (operand_ty.castTag(.error_set_inferred)) |inferred| { |
| 6862 | | try sema.resolveInferredErrorSet(inferred.data); |
| 6863 | | } |
| 6837 | try sema.resolveInferredErrorSetTy(operand_ty); |
| 6864 | 6838 | |
| 6865 | 6839 | if (operand_ty.isAnyError()) { |
| 6866 | 6840 | if (special_prong != .@"else") { |
| ... | ... | @@ -10361,9 +10335,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10361 | 10335 | }; |
| 10362 | 10336 | |
| 10363 | 10337 | // If the error set is inferred it has to be resolved at this point |
| 10364 | | if (ty.castTag(.error_set_inferred)) |payload| { |
| 10365 | | try sema.resolveInferredErrorSet(payload.data); |
| 10366 | | } |
| 10338 | try sema.resolveInferredErrorSetTy(ty); |
| 10367 | 10339 | |
| 10368 | 10340 | // Build our list of Error values |
| 10369 | 10341 | // Optional value is only null if anyerror |
| ... | ... | @@ -17610,32 +17582,25 @@ fn resolvePeerTypes( |
| 17610 | 17582 | const target = sema.mod.getTarget(); |
| 17611 | 17583 | |
| 17612 | 17584 | var chosen = instructions[0]; |
| 17613 | | var err_set_ty: ?Type = blk: { |
| 17614 | | const chosen_ty = sema.typeOf(chosen); |
| 17615 | | const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison(); |
| 17616 | | if (chosen_ty_tag != .ErrorSet) |
| 17617 | | break :blk null; |
| 17618 | | |
| 17619 | | // If our chosen type is inferred, we have to resolve it now. |
| 17620 | | if (chosen_ty.castTag(.error_set_inferred)) |inferred| { |
| 17621 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17622 | | } |
| 17623 | | |
| 17624 | | break :blk chosen_ty; |
| 17625 | | }; |
| 17626 | | |
| 17585 | // If this is non-null then it does the following thing, depending on the chosen zigTypeTag(). |
| 17586 | // * ErrorSet: this is an override |
| 17587 | // * ErrorUnion: this is an override of the error set only |
| 17588 | // * other: at the end we make an ErrorUnion with the other thing and this |
| 17589 | var err_set_ty: ?Type = null; |
| 17627 | 17590 | var any_are_null = false; |
| 17628 | | var make_the_slice_const = false; |
| 17591 | var seen_const = false; |
| 17629 | 17592 | var convert_to_slice = false; |
| 17630 | 17593 | var chosen_i: usize = 0; |
| 17631 | 17594 | for (instructions[1..]) |candidate, candidate_i| { |
| 17632 | 17595 | const candidate_ty = sema.typeOf(candidate); |
| 17633 | 17596 | const chosen_ty = sema.typeOf(chosen); |
| 17597 | |
| 17598 | const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison(); |
| 17599 | const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison(); |
| 17600 | |
| 17634 | 17601 | if (candidate_ty.eql(chosen_ty)) |
| 17635 | 17602 | continue; |
| 17636 | 17603 | |
| 17637 | | const candidate_ty_tag = candidate_ty.zigTypeTag(); |
| 17638 | | const chosen_ty_tag = chosen_ty.zigTypeTag(); |
| 17639 | 17604 | switch (candidate_ty_tag) { |
| 17640 | 17605 | .NoReturn, .Undefined => continue, |
| 17641 | 17606 | |
| ... | ... | @@ -17713,131 +17678,70 @@ fn resolvePeerTypes( |
| 17713 | 17678 | }, |
| 17714 | 17679 | else => {}, |
| 17715 | 17680 | }, |
| 17716 | | .ErrorSet => { |
| 17717 | | if (chosen_ty_tag == .ErrorSet) { |
| 17718 | | assert(err_set_ty != null); |
| 17719 | | |
| 17720 | | // If chosen type is anyerror, then we can use the prev type |
| 17721 | | if (err_set_ty.?.isAnyError()) continue; |
| 17722 | | |
| 17723 | | // At this point, we must resolve any inferred error sets |
| 17724 | | if (candidate_ty.castTag(.error_set_inferred)) |inferred| { |
| 17725 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17726 | | } |
| 17727 | | |
| 17728 | | // If candidate is anyerror then we use it because it |
| 17729 | | // is trivially a supserset of previous error set |
| 17730 | | if (candidate_ty.isAnyError()) { |
| 17731 | | err_set_ty = candidate_ty; |
| 17732 | | chosen = candidate; |
| 17733 | | chosen_i = candidate_i + 1; |
| 17734 | | continue; |
| 17735 | | } |
| 17736 | | |
| 17681 | .ErrorSet => switch (chosen_ty_tag) { |
| 17682 | .ErrorSet => { |
| 17737 | 17683 | // If chosen is superset of candidate, keep it. |
| 17738 | 17684 | // If candidate is superset of chosen, switch it. |
| 17739 | 17685 | // If neither is a superset, merge errors. |
| 17740 | | for (candidate_ty.errorSetNames()) |name| { |
| 17741 | | if (!err_set_ty.?.errorSetHasField(name)) { |
| 17742 | | break; |
| 17743 | | } |
| 17744 | | } else continue; |
| 17686 | const chosen_set_ty = err_set_ty orelse chosen_ty; |
| 17745 | 17687 | |
| 17746 | | for (err_set_ty.?.errorSetNames()) |name| { |
| 17747 | | if (!candidate_ty.errorSetHasField(name)) { |
| 17748 | | break; |
| 17749 | | } |
| 17750 | | } else { |
| 17751 | | // Swap to candidate |
| 17752 | | err_set_ty = candidate_ty; |
| 17688 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17689 | continue; |
| 17690 | } |
| 17691 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { |
| 17692 | err_set_ty = null; |
| 17753 | 17693 | chosen = candidate; |
| 17754 | 17694 | chosen_i = candidate_i + 1; |
| 17755 | 17695 | continue; |
| 17756 | 17696 | } |
| 17757 | 17697 | |
| 17758 | | // Merge errors |
| 17759 | | err_set_ty = try candidate_ty.errorSetMerge(sema.arena, err_set_ty.?); |
| 17760 | | chosen = candidate; |
| 17761 | | chosen_i = candidate_i + 1; |
| 17698 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| 17762 | 17699 | continue; |
| 17763 | | } |
| 17700 | }, |
| 17701 | .ErrorUnion => { |
| 17702 | const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); |
| 17764 | 17703 | |
| 17765 | | // At this point, we must resolve any inferred error sets |
| 17766 | | if (candidate_ty.castTag(.error_set_inferred)) |inferred| { |
| 17767 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17768 | | } |
| 17704 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17705 | continue; |
| 17706 | } |
| 17707 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { |
| 17708 | err_set_ty = candidate_ty; |
| 17709 | continue; |
| 17710 | } |
| 17769 | 17711 | |
| 17770 | | // If anything is anyerror, we use anyerror always |
| 17771 | | if (candidate_ty.isAnyError()) { |
| 17772 | | err_set_ty = candidate_ty; |
| 17712 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| 17773 | 17713 | continue; |
| 17774 | | } |
| 17775 | | if (err_set_ty) |ty| |
| 17776 | | if (ty.isAnyError()) continue; |
| 17777 | | |
| 17778 | | if (err_set_ty == null) { |
| 17779 | | // Error unions are lazy, we're forced to resolve now. |
| 17780 | | // Otherwise, our candidate type cause we've never seen |
| 17781 | | // error sets up to this point |
| 17782 | | if (chosen_ty_tag == .ErrorUnion) { |
| 17783 | | err_set_ty = chosen_ty.errorUnionSet(); |
| 17784 | | |
| 17785 | | if (err_set_ty.?.castTag(.error_set_inferred)) |inferred| { |
| 17786 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17714 | }, |
| 17715 | else => { |
| 17716 | if (err_set_ty) |chosen_set_ty| { |
| 17717 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17718 | continue; |
| 17719 | } |
| 17720 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { |
| 17721 | err_set_ty = candidate_ty; |
| 17722 | continue; |
| 17787 | 17723 | } |
| 17788 | 17724 | |
| 17789 | | if (err_set_ty.?.isAnyError()) continue; |
| 17725 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| 17726 | continue; |
| 17790 | 17727 | } else { |
| 17791 | 17728 | err_set_ty = candidate_ty; |
| 17792 | 17729 | continue; |
| 17793 | 17730 | } |
| 17794 | | } |
| 17795 | | |
| 17796 | | // If previous is superset, keep the previous |
| 17797 | | for (candidate_ty.errorSetNames()) |name| { |
| 17798 | | if (!err_set_ty.?.errorSetHasField(name)) { |
| 17799 | | break; |
| 17800 | | } |
| 17801 | | } else continue; |
| 17802 | | |
| 17803 | | // Merge |
| 17804 | | err_set_ty = try err_set_ty.?.errorSetMerge(sema.arena, candidate_ty); |
| 17805 | | continue; |
| 17731 | }, |
| 17806 | 17732 | }, |
| 17807 | 17733 | .ErrorUnion => switch (chosen_ty_tag) { |
| 17808 | 17734 | .ErrorSet => { |
| 17809 | | if (err_set_ty.?.isAnyError()) { |
| 17810 | | chosen = candidate; |
| 17811 | | chosen_i = candidate_i + 1; |
| 17812 | | continue; |
| 17813 | | } |
| 17814 | | |
| 17815 | | const eu_set_ty = candidate_ty.errorUnionSet(); |
| 17816 | | if (eu_set_ty.castTag(.error_set_inferred)) |inferred| { |
| 17817 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17818 | | } |
| 17819 | | if (eu_set_ty.isAnyError()) { |
| 17820 | | err_set_ty = eu_set_ty; |
| 17821 | | chosen = candidate; |
| 17822 | | chosen_i = candidate_i + 1; |
| 17823 | | continue; |
| 17824 | | } |
| 17735 | const chosen_set_ty = err_set_ty orelse chosen_ty; |
| 17736 | const candidate_set_ty = candidate_ty.errorUnionSet(); |
| 17825 | 17737 | |
| 17826 | | // If candidate is a superset of the error type, then use it. |
| 17827 | | for (err_set_ty.?.errorSetNames()) |name| { |
| 17828 | | if (!eu_set_ty.errorSetHasField(name)) { |
| 17829 | | break; |
| 17830 | | } |
| 17738 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { |
| 17739 | err_set_ty = chosen_set_ty; |
| 17740 | } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { |
| 17741 | err_set_ty = null; |
| 17831 | 17742 | } else { |
| 17832 | | // Swap to candidate |
| 17833 | | err_set_ty = eu_set_ty; |
| 17834 | | chosen = candidate; |
| 17835 | | chosen_i = candidate_i + 1; |
| 17836 | | continue; |
| 17743 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| 17837 | 17744 | } |
| 17838 | | |
| 17839 | | // Not a superset, create merged error set |
| 17840 | | err_set_ty = try eu_set_ty.errorSetMerge(sema.arena, err_set_ty.?); |
| 17841 | 17745 | chosen = candidate; |
| 17842 | 17746 | chosen_i = candidate_i + 1; |
| 17843 | 17747 | continue; |
| ... | ... | @@ -17859,104 +17763,35 @@ fn resolvePeerTypes( |
| 17859 | 17763 | chosen_i = candidate_i + 1; |
| 17860 | 17764 | } |
| 17861 | 17765 | |
| 17862 | | const chosen_set_ty = chosen_ty.errorUnionSet(); |
| 17766 | const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); |
| 17863 | 17767 | const candidate_set_ty = chosen_ty.errorUnionSet(); |
| 17864 | 17768 | |
| 17865 | | // If our error sets match already, then we are done. |
| 17866 | | if (chosen_set_ty.eql(candidate_set_ty)) continue; |
| 17867 | | |
| 17868 | | // They don't match, so we need to figure out if we |
| 17869 | | // need to merge them, use the superset, etc. This |
| 17870 | | // requires resolution. |
| 17871 | | if (chosen_set_ty.castTag(.error_set_inferred)) |inferred| { |
| 17872 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17873 | | } |
| 17874 | | if (candidate_set_ty.castTag(.error_set_inferred)) |inferred| { |
| 17875 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17876 | | } |
| 17877 | | |
| 17878 | | if (chosen_set_ty.isAnyError()) { |
| 17769 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { |
| 17879 | 17770 | err_set_ty = chosen_set_ty; |
| 17880 | | continue; |
| 17881 | | } |
| 17882 | | |
| 17883 | | if (candidate_set_ty.isAnyError()) { |
| 17771 | } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { |
| 17884 | 17772 | err_set_ty = candidate_set_ty; |
| 17885 | | continue; |
| 17886 | | } |
| 17887 | | |
| 17888 | | if (err_set_ty == null) err_set_ty = chosen_set_ty; |
| 17889 | | |
| 17890 | | // If the previous error set type is a superset, we're done. |
| 17891 | | for (candidate_set_ty.errorSetNames()) |name| { |
| 17892 | | if (!chosen_set_ty.errorSetHasField(name)) { |
| 17893 | | break; |
| 17894 | | } |
| 17895 | | } else continue; |
| 17896 | | |
| 17897 | | for (chosen_set_ty.errorSetNames()) |name| { |
| 17898 | | if (!candidate_set_ty.errorSetHasField(name)) { |
| 17899 | | break; |
| 17900 | | } |
| 17901 | 17773 | } else { |
| 17902 | | err_set_ty = candidate_ty; |
| 17903 | | continue; |
| 17774 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| 17904 | 17775 | } |
| 17905 | | |
| 17906 | | // Merge errors |
| 17907 | | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| 17908 | 17776 | continue; |
| 17909 | 17777 | } |
| 17910 | 17778 | }, |
| 17911 | 17779 | |
| 17912 | | .Pointer => { |
| 17913 | | const payload_ty = candidate_ty.errorUnionPayload(); |
| 17914 | | if (chosen_ty.ptrSize() == .One and |
| 17915 | | chosen_ty.childType().zigTypeTag() == .Array and |
| 17916 | | payload_ty.isSlice()) |
| 17917 | | { |
| 17918 | | const chosen_child_ty = chosen_ty.childType(); |
| 17919 | | const chosen_elem_ty = chosen_child_ty.elemType2(); |
| 17920 | | const candidate_elem_ty = payload_ty.elemType2(); |
| 17921 | | if ((try sema.coerceInMemoryAllowed(block, candidate_elem_ty, chosen_elem_ty, false, target, src, src)) == .ok) { |
| 17922 | | chosen = candidate; |
| 17923 | | chosen_i = candidate_i + 1; |
| 17924 | | |
| 17925 | | convert_to_slice = false; // it already is a slice |
| 17926 | | |
| 17927 | | // If the prev pointer is const then we need to const |
| 17928 | | if (chosen_child_ty.isConstPtr()) |
| 17929 | | make_the_slice_const = true; |
| 17930 | | |
| 17931 | | continue; |
| 17932 | | } |
| 17933 | | } |
| 17934 | | }, |
| 17935 | | |
| 17936 | 17780 | else => { |
| 17937 | | // Chosen coercing into payload type |
| 17938 | | // Then merge error sets (if any) |
| 17939 | | const payload_ty = candidate_ty.errorUnionPayload(); |
| 17940 | | if ((try sema.coerceInMemoryAllowed(block, payload_ty, chosen_ty, false, target, src, src)) == .ok) { |
| 17941 | | chosen = candidate; |
| 17942 | | chosen_i = candidate_i + 1; |
| 17943 | | |
| 17944 | | if (err_set_ty) |ty| { |
| 17945 | | const cand_set_ty = candidate_ty.errorUnionSet(); |
| 17946 | | if (cand_set_ty.castTag(.error_set_inferred)) |inferred| { |
| 17947 | | try sema.resolveInferredErrorSet(inferred.data); |
| 17948 | | } |
| 17949 | | if (cand_set_ty.isAnyError()) { |
| 17950 | | err_set_ty = cand_set_ty; |
| 17951 | | continue; |
| 17952 | | } |
| 17953 | | if (ty.isAnyError()) continue; |
| 17954 | | |
| 17955 | | err_set_ty = try err_set_ty.?.errorSetMerge(sema.arena, cand_set_ty); |
| 17781 | if (err_set_ty) |chosen_set_ty| { |
| 17782 | const candidate_set_ty = candidate_ty.errorUnionSet(); |
| 17783 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { |
| 17784 | err_set_ty = chosen_set_ty; |
| 17785 | } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { |
| 17786 | err_set_ty = null; |
| 17787 | } else { |
| 17788 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| 17956 | 17789 | } |
| 17957 | | |
| 17958 | | continue; |
| 17959 | 17790 | } |
| 17791 | seen_const = seen_const or chosen_ty.isConstPtr(); |
| 17792 | chosen = candidate; |
| 17793 | chosen_i = candidate_i + 1; |
| 17794 | continue; |
| 17960 | 17795 | }, |
| 17961 | 17796 | }, |
| 17962 | 17797 | .Pointer => { |
| ... | ... | @@ -17983,7 +17818,7 @@ fn resolvePeerTypes( |
| 17983 | 17818 | convert_to_slice = false; |
| 17984 | 17819 | |
| 17985 | 17820 | if (chosen_ty.childType().isConstPtr() and !candidate_ty.childType().isConstPtr()) |
| 17986 | | make_the_slice_const = true; |
| 17821 | seen_const = true; |
| 17987 | 17822 | |
| 17988 | 17823 | continue; |
| 17989 | 17824 | } |
| ... | ... | @@ -17995,7 +17830,7 @@ fn resolvePeerTypes( |
| 17995 | 17830 | chosen_ty.ptrSize() == .Many) |
| 17996 | 17831 | { |
| 17997 | 17832 | if (candidate_ty.childType().isConstPtr() and !chosen_ty.childType().isConstPtr()) |
| 17998 | | make_the_slice_const = true; |
| 17833 | seen_const = true; |
| 17999 | 17834 | |
| 18000 | 17835 | continue; |
| 18001 | 17836 | } |
| ... | ... | @@ -18016,7 +17851,7 @@ fn resolvePeerTypes( |
| 18016 | 17851 | |
| 18017 | 17852 | // If the pointer is const then we need to const |
| 18018 | 17853 | if (candidate_ty.childType().isConstPtr()) |
| 18019 | | make_the_slice_const = true; |
| 17854 | seen_const = true; |
| 18020 | 17855 | |
| 18021 | 17856 | continue; |
| 18022 | 17857 | } |
| ... | ... | @@ -18039,7 +17874,7 @@ fn resolvePeerTypes( |
| 18039 | 17874 | |
| 18040 | 17875 | // If the prev pointer is const then we need to const |
| 18041 | 17876 | if (chosen_child_ty.isConstPtr()) |
| 18042 | | make_the_slice_const = true; |
| 17877 | seen_const = true; |
| 18043 | 17878 | |
| 18044 | 17879 | continue; |
| 18045 | 17880 | } |
| ... | ... | @@ -18075,7 +17910,7 @@ fn resolvePeerTypes( |
| 18075 | 17910 | // If one of the pointers is to const data, the slice |
| 18076 | 17911 | // must also be const. |
| 18077 | 17912 | if (candidate_child_ty.isConstPtr() or chosen_child_ty.isConstPtr()) |
| 18078 | | make_the_slice_const = true; |
| 17913 | seen_const = true; |
| 18079 | 17914 | |
| 18080 | 17915 | continue; |
| 18081 | 17916 | } |
| ... | ... | @@ -18186,39 +18021,47 @@ fn resolvePeerTypes( |
| 18186 | 18021 | var info = chosen_ty.ptrInfo(); |
| 18187 | 18022 | info.data.sentinel = chosen_child_ty.sentinel(); |
| 18188 | 18023 | info.data.size = .Slice; |
| 18189 | | info.data.mutable = chosen_child_ty.isConstPtr() or make_the_slice_const; |
| 18024 | info.data.mutable = seen_const or chosen_child_ty.isConstPtr(); |
| 18190 | 18025 | info.data.pointee_type = switch (chosen_child_ty.tag()) { |
| 18191 | 18026 | .array => chosen_child_ty.elemType2(), |
| 18192 | 18027 | .array_u8, .array_u8_sentinel_0 => Type.initTag(.u8), |
| 18193 | 18028 | else => unreachable, |
| 18194 | 18029 | }; |
| 18195 | 18030 | |
| 18196 | | return Type.ptr(sema.arena, target, info.data); |
| 18031 | const new_ptr_ty = try Type.ptr(sema.arena, target, info.data); |
| 18032 | const set_ty = err_set_ty orelse return new_ptr_ty; |
| 18033 | return try Module.errorUnionType(sema.arena, set_ty, new_ptr_ty); |
| 18197 | 18034 | } |
| 18198 | 18035 | |
| 18199 | | if (make_the_slice_const) { |
| 18036 | if (seen_const) { |
| 18200 | 18037 | // turn []T => []const T |
| 18201 | | var info = chosen_ty.ptrInfo(); |
| 18202 | | info.data.mutable = false; |
| 18203 | | return Type.ptr(sema.arena, target, info.data); |
| 18038 | switch (chosen_ty.zigTypeTag()) { |
| 18039 | .ErrorUnion => { |
| 18040 | const ptr_ty = chosen_ty.errorUnionPayload(); |
| 18041 | var info = ptr_ty.ptrInfo(); |
| 18042 | info.data.mutable = false; |
| 18043 | const new_ptr_ty = try Type.ptr(sema.arena, target, info.data); |
| 18044 | const set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); |
| 18045 | return try Module.errorUnionType(sema.arena, set_ty, new_ptr_ty); |
| 18046 | }, |
| 18047 | .Pointer => { |
| 18048 | var info = chosen_ty.ptrInfo(); |
| 18049 | info.data.mutable = false; |
| 18050 | const new_ptr_ty = try Type.ptr(sema.arena, target, info.data); |
| 18051 | const set_ty = err_set_ty orelse return new_ptr_ty; |
| 18052 | return try Module.errorUnionType(sema.arena, set_ty, new_ptr_ty); |
| 18053 | }, |
| 18054 | else => return chosen_ty, |
| 18055 | } |
| 18204 | 18056 | } |
| 18205 | 18057 | |
| 18206 | 18058 | if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) { |
| 18207 | 18059 | .ErrorSet => return ty, |
| 18208 | | |
| 18209 | 18060 | .ErrorUnion => { |
| 18210 | 18061 | const payload_ty = chosen_ty.errorUnionPayload(); |
| 18211 | 18062 | return try Module.errorUnionType(sema.arena, ty, payload_ty); |
| 18212 | 18063 | }, |
| 18213 | | |
| 18214 | | .ComptimeInt, .ComptimeFloat => return sema.fail(block, src, "unable to make error union out of number literal", .{}), |
| 18215 | | |
| 18216 | | .Null => return sema.fail(block, src, "unable to make error union out of null literal", .{}), |
| 18217 | | |
| 18218 | | else => { |
| 18219 | | // Create error union of our error set and the chosen type |
| 18220 | | return try Module.errorUnionType(sema.arena, ty, chosen_ty); |
| 18221 | | }, |
| 18064 | else => return try Module.errorUnionType(sema.arena, ty, chosen_ty), |
| 18222 | 18065 | }; |
| 18223 | 18066 | |
| 18224 | 18067 | return chosen_ty; |
| ... | ... | @@ -18507,6 +18350,12 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE |
| 18507 | 18350 | inferred_error_set.is_resolved = true; |
| 18508 | 18351 | } |
| 18509 | 18352 | |
| 18353 | fn resolveInferredErrorSetTy(sema: *Sema, ty: Type) CompileError!void { |
| 18354 | if (ty.castTag(.error_set_inferred)) |inferred| { |
| 18355 | try sema.resolveInferredErrorSet(inferred.data); |
| 18356 | } |
| 18357 | } |
| 18358 | |
| 18510 | 18359 | fn semaStructFields( |
| 18511 | 18360 | mod: *Module, |
| 18512 | 18361 | struct_obj: *Module.Struct, |