| ... | @@ -5141,15 +5141,15 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -5141,15 +5141,15 @@ fn zirErrorUnionType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr |
| 5141 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 5141 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 5142 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; | 5142 | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; |
| 5143 | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = inst_data.src_node }; | 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 | const payload = try sema.resolveType(block, rhs_src, extra.rhs); | 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 | return sema.fail(block, lhs_src, "expected error set type, found {}", .{ | 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 | return sema.addType(err_union_ty); | 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,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. | 5284 | const err_set_ty = try lhs_ty.errorSetMerge(sema.arena, rhs_ty); |
| 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); | | |
| 5309 | return sema.addType(err_set_ty); | 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,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| { | 6837 | try sema.resolveInferredErrorSetTy(operand_ty); |
| 6862 | try sema.resolveInferredErrorSet(inferred.data); | | |
| 6863 | } | | |
| 6864 | | 6838 | |
| 6865 | if (operand_ty.isAnyError()) { | 6839 | if (operand_ty.isAnyError()) { |
| 6866 | if (special_prong != .@"else") { | 6840 | if (special_prong != .@"else") { |
| ... | @@ -10361,9 +10335,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -10361,9 +10335,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 10361 | }; | 10335 | }; |
| 10362 | | 10336 | |
| 10363 | // If the error set is inferred it has to be resolved at this point | 10337 | // If the error set is inferred it has to be resolved at this point |
| 10364 | if (ty.castTag(.error_set_inferred)) |payload| { | 10338 | try sema.resolveInferredErrorSetTy(ty); |
| 10365 | try sema.resolveInferredErrorSet(payload.data); | | |
| 10366 | } | | |
| 10367 | | 10339 | |
| 10368 | // Build our list of Error values | 10340 | // Build our list of Error values |
| 10369 | // Optional value is only null if anyerror | 10341 | // Optional value is only null if anyerror |
| ... | @@ -17610,32 +17582,25 @@ fn resolvePeerTypes( | ... | @@ -17610,32 +17582,25 @@ fn resolvePeerTypes( |
| 17610 | const target = sema.mod.getTarget(); | 17582 | const target = sema.mod.getTarget(); |
| 17611 | | 17583 | |
| 17612 | var chosen = instructions[0]; | 17584 | var chosen = instructions[0]; |
| 17613 | var err_set_ty: ?Type = blk: { | 17585 | // If this is non-null then it does the following thing, depending on the chosen zigTypeTag(). |
| 17614 | const chosen_ty = sema.typeOf(chosen); | 17586 | // * ErrorSet: this is an override |
| 17615 | const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison(); | 17587 | // * ErrorUnion: this is an override of the error set only |
| 17616 | if (chosen_ty_tag != .ErrorSet) | 17588 | // * other: at the end we make an ErrorUnion with the other thing and this |
| 17617 | break :blk null; | 17589 | var err_set_ty: ?Type = 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 | | | |
| 17627 | var any_are_null = false; | 17590 | var any_are_null = false; |
| 17628 | var make_the_slice_const = false; | 17591 | var seen_const = false; |
| 17629 | var convert_to_slice = false; | 17592 | var convert_to_slice = false; |
| 17630 | var chosen_i: usize = 0; | 17593 | var chosen_i: usize = 0; |
| 17631 | for (instructions[1..]) |candidate, candidate_i| { | 17594 | for (instructions[1..]) |candidate, candidate_i| { |
| 17632 | const candidate_ty = sema.typeOf(candidate); | 17595 | const candidate_ty = sema.typeOf(candidate); |
| 17633 | const chosen_ty = sema.typeOf(chosen); | 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 | if (candidate_ty.eql(chosen_ty)) | 17601 | if (candidate_ty.eql(chosen_ty)) |
| 17635 | continue; | 17602 | continue; |
| 17636 | | 17603 | |
| 17637 | const candidate_ty_tag = candidate_ty.zigTypeTag(); | | |
| 17638 | const chosen_ty_tag = chosen_ty.zigTypeTag(); | | |
| 17639 | switch (candidate_ty_tag) { | 17604 | switch (candidate_ty_tag) { |
| 17640 | .NoReturn, .Undefined => continue, | 17605 | .NoReturn, .Undefined => continue, |
| 17641 | | 17606 | |
| ... | @@ -17713,131 +17678,70 @@ fn resolvePeerTypes( | ... | @@ -17713,131 +17678,70 @@ fn resolvePeerTypes( |
| 17713 | }, | 17678 | }, |
| 17714 | else => {}, | 17679 | else => {}, |
| 17715 | }, | 17680 | }, |
| 17716 | .ErrorSet => { | 17681 | .ErrorSet => switch (chosen_ty_tag) { |
| 17717 | if (chosen_ty_tag == .ErrorSet) { | 17682 | .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 | | | |
| 17737 | // If chosen is superset of candidate, keep it. | 17683 | // If chosen is superset of candidate, keep it. |
| 17738 | // If candidate is superset of chosen, switch it. | 17684 | // If candidate is superset of chosen, switch it. |
| 17739 | // If neither is a superset, merge errors. | 17685 | // If neither is a superset, merge errors. |
| 17740 | for (candidate_ty.errorSetNames()) |name| { | 17686 | const chosen_set_ty = err_set_ty orelse chosen_ty; |
| 17741 | if (!err_set_ty.?.errorSetHasField(name)) { | | |
| 17742 | break; | | |
| 17743 | } | | |
| 17744 | } else continue; | | |
| 17745 | | 17687 | |
| 17746 | for (err_set_ty.?.errorSetNames()) |name| { | 17688 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17747 | if (!candidate_ty.errorSetHasField(name)) { | 17689 | continue; |
| 17748 | break; | 17690 | } |
| 17749 | } | 17691 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { |
| 17750 | } else { | 17692 | err_set_ty = null; |
| 17751 | // Swap to candidate | | |
| 17752 | err_set_ty = candidate_ty; | | |
| 17753 | chosen = candidate; | 17693 | chosen = candidate; |
| 17754 | chosen_i = candidate_i + 1; | 17694 | chosen_i = candidate_i + 1; |
| 17755 | continue; | 17695 | continue; |
| 17756 | } | 17696 | } |
| 17757 | | 17697 | |
| 17758 | // Merge errors | 17698 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| 17759 | err_set_ty = try candidate_ty.errorSetMerge(sema.arena, err_set_ty.?); | | |
| 17760 | chosen = candidate; | | |
| 17761 | chosen_i = candidate_i + 1; | | |
| 17762 | continue; | 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 | 17704 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17766 | if (candidate_ty.castTag(.error_set_inferred)) |inferred| { | 17705 | continue; |
| 17767 | try sema.resolveInferredErrorSet(inferred.data); | 17706 | } |
| 17768 | } | 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 | 17712 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| 17771 | if (candidate_ty.isAnyError()) { | | |
| 17772 | err_set_ty = candidate_ty; | | |
| 17773 | continue; | 17713 | continue; |
| 17774 | } | 17714 | }, |
| 17775 | if (err_set_ty) |ty| | 17715 | else => { |
| 17776 | if (ty.isAnyError()) continue; | 17716 | if (err_set_ty) |chosen_set_ty| { |
| 17777 | | 17717 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17778 | if (err_set_ty == null) { | 17718 | continue; |
| 17779 | // Error unions are lazy, we're forced to resolve now. | 17719 | } |
| 17780 | // Otherwise, our candidate type cause we've never seen | 17720 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { |
| 17781 | // error sets up to this point | 17721 | err_set_ty = candidate_ty; |
| 17782 | if (chosen_ty_tag == .ErrorUnion) { | 17722 | continue; |
| 17783 | err_set_ty = chosen_ty.errorUnionSet(); | | |
| 17784 | | | |
| 17785 | if (err_set_ty.?.castTag(.error_set_inferred)) |inferred| { | | |
| 17786 | try sema.resolveInferredErrorSet(inferred.data); | | |
| 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 | } else { | 17727 | } else { |
| 17791 | err_set_ty = candidate_ty; | 17728 | err_set_ty = candidate_ty; |
| 17792 | continue; | 17729 | continue; |
| 17793 | } | 17730 | } |
| 17794 | } | 17731 | }, |
| 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; | | |
| 17806 | }, | 17732 | }, |
| 17807 | .ErrorUnion => switch (chosen_ty_tag) { | 17733 | .ErrorUnion => switch (chosen_ty_tag) { |
| 17808 | .ErrorSet => { | 17734 | .ErrorSet => { |
| 17809 | if (err_set_ty.?.isAnyError()) { | 17735 | const chosen_set_ty = err_set_ty orelse chosen_ty; |
| 17810 | chosen = candidate; | 17736 | const candidate_set_ty = candidate_ty.errorUnionSet(); |
| 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 | } | | |
| 17825 | | 17737 | |
| 17826 | // If candidate is a superset of the error type, then use it. | 17738 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { |
| 17827 | for (err_set_ty.?.errorSetNames()) |name| { | 17739 | err_set_ty = chosen_set_ty; |
| 17828 | if (!eu_set_ty.errorSetHasField(name)) { | 17740 | } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { |
| 17829 | break; | 17741 | err_set_ty = null; |
| 17830 | } | | |
| 17831 | } else { | 17742 | } else { |
| 17832 | // Swap to candidate | 17743 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| 17833 | err_set_ty = eu_set_ty; | | |
| 17834 | chosen = candidate; | | |
| 17835 | chosen_i = candidate_i + 1; | | |
| 17836 | continue; | | |
| 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 | chosen = candidate; | 17745 | chosen = candidate; |
| 17842 | chosen_i = candidate_i + 1; | 17746 | chosen_i = candidate_i + 1; |
| 17843 | continue; | 17747 | continue; |
| ... | @@ -17859,104 +17763,35 @@ fn resolvePeerTypes( | ... | @@ -17859,104 +17763,35 @@ fn resolvePeerTypes( |
| 17859 | chosen_i = candidate_i + 1; | 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 | const candidate_set_ty = chosen_ty.errorUnionSet(); | 17767 | const candidate_set_ty = chosen_ty.errorUnionSet(); |
| 17864 | | 17768 | |
| 17865 | // If our error sets match already, then we are done. | 17769 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { |
| 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()) { | | |
| 17879 | err_set_ty = chosen_set_ty; | 17770 | err_set_ty = chosen_set_ty; |
| 17880 | continue; | 17771 | } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { |
| 17881 | } | | |
| 17882 | | | |
| 17883 | if (candidate_set_ty.isAnyError()) { | | |
| 17884 | err_set_ty = candidate_set_ty; | 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 | } else { | 17773 | } else { |
| 17902 | err_set_ty = candidate_ty; | 17774 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| 17903 | continue; | | |
| 17904 | } | 17775 | } |
| 17905 | | | |
| 17906 | // Merge errors | | |
| 17907 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); | | |
| 17908 | continue; | 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 | else => { | 17780 | else => { |
| 17937 | // Chosen coercing into payload type | 17781 | if (err_set_ty) |chosen_set_ty| { |
| 17938 | // Then merge error sets (if any) | 17782 | const candidate_set_ty = candidate_ty.errorUnionSet(); |
| 17939 | const payload_ty = candidate_ty.errorUnionPayload(); | 17783 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { |
| 17940 | if ((try sema.coerceInMemoryAllowed(block, payload_ty, chosen_ty, false, target, src, src)) == .ok) { | 17784 | err_set_ty = chosen_set_ty; |
| 17941 | chosen = candidate; | 17785 | } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { |
| 17942 | chosen_i = candidate_i + 1; | 17786 | err_set_ty = null; |
| 17943 | | 17787 | } else { |
| 17944 | if (err_set_ty) |ty| { | 17788 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_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); | | |
| 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 | .Pointer => { | 17797 | .Pointer => { |
| ... | @@ -17983,7 +17818,7 @@ fn resolvePeerTypes( | ... | @@ -17983,7 +17818,7 @@ fn resolvePeerTypes( |
| 17983 | convert_to_slice = false; | 17818 | convert_to_slice = false; |
| 17984 | | 17819 | |
| 17985 | if (chosen_ty.childType().isConstPtr() and !candidate_ty.childType().isConstPtr()) | 17820 | if (chosen_ty.childType().isConstPtr() and !candidate_ty.childType().isConstPtr()) |
| 17986 | make_the_slice_const = true; | 17821 | seen_const = true; |
| 17987 | | 17822 | |
| 17988 | continue; | 17823 | continue; |
| 17989 | } | 17824 | } |
| ... | @@ -17995,7 +17830,7 @@ fn resolvePeerTypes( | ... | @@ -17995,7 +17830,7 @@ fn resolvePeerTypes( |
| 17995 | chosen_ty.ptrSize() == .Many) | 17830 | chosen_ty.ptrSize() == .Many) |
| 17996 | { | 17831 | { |
| 17997 | if (candidate_ty.childType().isConstPtr() and !chosen_ty.childType().isConstPtr()) | 17832 | if (candidate_ty.childType().isConstPtr() and !chosen_ty.childType().isConstPtr()) |
| 17998 | make_the_slice_const = true; | 17833 | seen_const = true; |
| 17999 | | 17834 | |
| 18000 | continue; | 17835 | continue; |
| 18001 | } | 17836 | } |
| ... | @@ -18016,7 +17851,7 @@ fn resolvePeerTypes( | ... | @@ -18016,7 +17851,7 @@ fn resolvePeerTypes( |
| 18016 | | 17851 | |
| 18017 | // If the pointer is const then we need to const | 17852 | // If the pointer is const then we need to const |
| 18018 | if (candidate_ty.childType().isConstPtr()) | 17853 | if (candidate_ty.childType().isConstPtr()) |
| 18019 | make_the_slice_const = true; | 17854 | seen_const = true; |
| 18020 | | 17855 | |
| 18021 | continue; | 17856 | continue; |
| 18022 | } | 17857 | } |
| ... | @@ -18039,7 +17874,7 @@ fn resolvePeerTypes( | ... | @@ -18039,7 +17874,7 @@ fn resolvePeerTypes( |
| 18039 | | 17874 | |
| 18040 | // If the prev pointer is const then we need to const | 17875 | // If the prev pointer is const then we need to const |
| 18041 | if (chosen_child_ty.isConstPtr()) | 17876 | if (chosen_child_ty.isConstPtr()) |
| 18042 | make_the_slice_const = true; | 17877 | seen_const = true; |
| 18043 | | 17878 | |
| 18044 | continue; | 17879 | continue; |
| 18045 | } | 17880 | } |
| ... | @@ -18075,7 +17910,7 @@ fn resolvePeerTypes( | ... | @@ -18075,7 +17910,7 @@ fn resolvePeerTypes( |
| 18075 | // If one of the pointers is to const data, the slice | 17910 | // If one of the pointers is to const data, the slice |
| 18076 | // must also be const. | 17911 | // must also be const. |
| 18077 | if (candidate_child_ty.isConstPtr() or chosen_child_ty.isConstPtr()) | 17912 | if (candidate_child_ty.isConstPtr() or chosen_child_ty.isConstPtr()) |
| 18078 | make_the_slice_const = true; | 17913 | seen_const = true; |
| 18079 | | 17914 | |
| 18080 | continue; | 17915 | continue; |
| 18081 | } | 17916 | } |
| ... | @@ -18186,39 +18021,47 @@ fn resolvePeerTypes( | ... | @@ -18186,39 +18021,47 @@ fn resolvePeerTypes( |
| 18186 | var info = chosen_ty.ptrInfo(); | 18021 | var info = chosen_ty.ptrInfo(); |
| 18187 | info.data.sentinel = chosen_child_ty.sentinel(); | 18022 | info.data.sentinel = chosen_child_ty.sentinel(); |
| 18188 | info.data.size = .Slice; | 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 | info.data.pointee_type = switch (chosen_child_ty.tag()) { | 18025 | info.data.pointee_type = switch (chosen_child_ty.tag()) { |
| 18191 | .array => chosen_child_ty.elemType2(), | 18026 | .array => chosen_child_ty.elemType2(), |
| 18192 | .array_u8, .array_u8_sentinel_0 => Type.initTag(.u8), | 18027 | .array_u8, .array_u8_sentinel_0 => Type.initTag(.u8), |
| 18193 | else => unreachable, | 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 | // turn []T => []const T | 18037 | // turn []T => []const T |
| 18201 | var info = chosen_ty.ptrInfo(); | 18038 | switch (chosen_ty.zigTypeTag()) { |
| 18202 | info.data.mutable = false; | 18039 | .ErrorUnion => { |
| 18203 | return Type.ptr(sema.arena, target, info.data); | 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 | if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) { | 18058 | if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) { |
| 18207 | .ErrorSet => return ty, | 18059 | .ErrorSet => return ty, |
| 18208 | | | |
| 18209 | .ErrorUnion => { | 18060 | .ErrorUnion => { |
| 18210 | const payload_ty = chosen_ty.errorUnionPayload(); | 18061 | const payload_ty = chosen_ty.errorUnionPayload(); |
| 18211 | return try Module.errorUnionType(sema.arena, ty, payload_ty); | 18062 | return try Module.errorUnionType(sema.arena, ty, payload_ty); |
| 18212 | }, | 18063 | }, |
| 18213 | | 18064 | else => return try Module.errorUnionType(sema.arena, ty, chosen_ty), |
| 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 | }, | | |
| 18222 | }; | 18065 | }; |
| 18223 | | 18066 | |
| 18224 | return chosen_ty; | 18067 | return chosen_ty; |
| ... | @@ -18507,6 +18350,12 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE | ... | @@ -18507,6 +18350,12 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE |
| 18507 | inferred_error_set.is_resolved = true; | 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 | fn semaStructFields( | 18359 | fn semaStructFields( |
| 18511 | mod: *Module, | 18360 | mod: *Module, |
| 18512 | struct_obj: *Module.Struct, | 18361 | struct_obj: *Module.Struct, |