| ... | @@ -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,29 +17582,24 @@ fn resolvePeerTypes( | ... | @@ -17610,29 +17582,24 @@ 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]; |
| | 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; |
| 17613 | var any_are_null = false; | 17590 | var any_are_null = false; |
| 17614 | var make_the_slice_const = false; | 17591 | var seen_const = false; |
| 17615 | var convert_to_slice = false; | 17592 | var convert_to_slice = false; |
| 17616 | var chosen_i: usize = 0; | 17593 | var chosen_i: usize = 0; |
| 17617 | for (instructions[1..]) |candidate, candidate_i| { | 17594 | for (instructions[1..]) |candidate, candidate_i| { |
| 17618 | const candidate_ty = sema.typeOf(candidate); | 17595 | const candidate_ty = sema.typeOf(candidate); |
| 17619 | const chosen_ty = sema.typeOf(chosen); | 17596 | const chosen_ty = sema.typeOf(chosen); |
| 17620 | if (candidate_ty.eql(chosen_ty)) | | |
| 17621 | continue; | | |
| 17622 | | 17597 | |
| 17623 | // If the candidate can coerce into our chosen type, we're done. | 17598 | const candidate_ty_tag = try candidate_ty.zigTypeTagOrPoison(); |
| 17624 | // If the chosen type can coerce into the candidate, use that. | 17599 | const chosen_ty_tag = try chosen_ty.zigTypeTagOrPoison(); |
| 17625 | if ((try sema.coerceInMemoryAllowed(block, chosen_ty, candidate_ty, false, target, src, src)) == .ok) { | | |
| 17626 | continue; | | |
| 17627 | } | | |
| 17628 | if ((try sema.coerceInMemoryAllowed(block, candidate_ty, chosen_ty, false, target, src, src)) == .ok) { | | |
| 17629 | chosen = candidate; | | |
| 17630 | chosen_i = candidate_i + 1; | | |
| 17631 | continue; | | |
| 17632 | } | | |
| 17633 | | 17600 | |
| 17634 | const candidate_ty_tag = candidate_ty.zigTypeTag(); | 17601 | if (candidate_ty.eql(chosen_ty)) |
| 17635 | const chosen_ty_tag = chosen_ty.zigTypeTag(); | 17602 | continue; |
| 17636 | | 17603 | |
| 17637 | switch (candidate_ty_tag) { | 17604 | switch (candidate_ty_tag) { |
| 17638 | .NoReturn, .Undefined => continue, | 17605 | .NoReturn, .Undefined => continue, |
| ... | @@ -17711,29 +17678,121 @@ fn resolvePeerTypes( | ... | @@ -17711,29 +17678,121 @@ fn resolvePeerTypes( |
| 17711 | }, | 17678 | }, |
| 17712 | else => {}, | 17679 | else => {}, |
| 17713 | }, | 17680 | }, |
| 17714 | .ErrorUnion => { | 17681 | .ErrorSet => switch (chosen_ty_tag) { |
| 17715 | const payload_ty = candidate_ty.errorUnionPayload(); | 17682 | .ErrorSet => { |
| 17716 | if (chosen_ty_tag == .Pointer and | 17683 | // If chosen is superset of candidate, keep it. |
| 17717 | chosen_ty.ptrSize() == .One and | 17684 | // If candidate is superset of chosen, switch it. |
| 17718 | chosen_ty.childType().zigTypeTag() == .Array and | 17685 | // If neither is a superset, merge errors. |
| 17719 | payload_ty.isSlice()) | 17686 | const chosen_set_ty = err_set_ty orelse chosen_ty; |
| 17720 | { | 17687 | |
| 17721 | const chosen_child_ty = chosen_ty.childType(); | 17688 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17722 | const chosen_elem_ty = chosen_child_ty.elemType2(); | 17689 | continue; |
| 17723 | const candidate_elem_ty = payload_ty.elemType2(); | 17690 | } |
| 17724 | if ((try sema.coerceInMemoryAllowed(block, candidate_elem_ty, chosen_elem_ty, false, target, src, src)) == .ok) { | 17691 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { |
| | 17692 | err_set_ty = null; |
| 17725 | chosen = candidate; | 17693 | chosen = candidate; |
| 17726 | chosen_i = candidate_i + 1; | 17694 | chosen_i = candidate_i + 1; |
| | 17695 | continue; |
| | 17696 | } |
| 17727 | | 17697 | |
| 17728 | convert_to_slice = false; // it already is a slice | 17698 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| | 17699 | continue; |
| | 17700 | }, |
| | 17701 | .ErrorUnion => { |
| | 17702 | const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); |
| 17729 | | 17703 | |
| 17730 | // If the prev pointer is const then we need to const | 17704 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_ty)) { |
| 17731 | if (chosen_child_ty.isConstPtr()) | 17705 | continue; |
| 17732 | make_the_slice_const = true; | 17706 | } |
| | 17707 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_ty, chosen_set_ty)) { |
| | 17708 | err_set_ty = candidate_ty; |
| | 17709 | continue; |
| | 17710 | } |
| 17733 | | 17711 | |
| | 17712 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| | 17713 | continue; |
| | 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; |
| | 17723 | } |
| | 17724 | |
| | 17725 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_ty); |
| | 17726 | continue; |
| | 17727 | } else { |
| | 17728 | err_set_ty = candidate_ty; |
| 17734 | continue; | 17729 | continue; |
| 17735 | } | 17730 | } |
| 17736 | } | 17731 | }, |
| | 17732 | }, |
| | 17733 | .ErrorUnion => switch (chosen_ty_tag) { |
| | 17734 | .ErrorSet => { |
| | 17735 | const chosen_set_ty = err_set_ty orelse chosen_ty; |
| | 17736 | const candidate_set_ty = candidate_ty.errorUnionSet(); |
| | 17737 | |
| | 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; |
| | 17742 | } else { |
| | 17743 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| | 17744 | } |
| | 17745 | chosen = candidate; |
| | 17746 | chosen_i = candidate_i + 1; |
| | 17747 | continue; |
| | 17748 | }, |
| | 17749 | |
| | 17750 | .ErrorUnion => { |
| | 17751 | const chosen_payload_ty = chosen_ty.errorUnionPayload(); |
| | 17752 | const candidate_payload_ty = candidate_ty.errorUnionPayload(); |
| | 17753 | |
| | 17754 | const coerce_chosen = (try sema.coerceInMemoryAllowed(block, chosen_payload_ty, candidate_payload_ty, false, target, src, src)) == .ok; |
| | 17755 | const coerce_candidate = (try sema.coerceInMemoryAllowed(block, candidate_payload_ty, chosen_payload_ty, false, target, src, src)) == .ok; |
| | 17756 | |
| | 17757 | if (coerce_chosen or coerce_candidate) { |
| | 17758 | // If we can coerce to the candidate, we switch to that |
| | 17759 | // type. This is the same logic as the bare (non-union) |
| | 17760 | // coercion check we do at the top of this func. |
| | 17761 | if (coerce_candidate) { |
| | 17762 | chosen = candidate; |
| | 17763 | chosen_i = candidate_i + 1; |
| | 17764 | } |
| | 17765 | |
| | 17766 | const chosen_set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); |
| | 17767 | const candidate_set_ty = chosen_ty.errorUnionSet(); |
| | 17768 | |
| | 17769 | if (.ok == try sema.coerceInMemoryAllowedErrorSets(chosen_set_ty, candidate_set_ty)) { |
| | 17770 | err_set_ty = chosen_set_ty; |
| | 17771 | } else if (.ok == try sema.coerceInMemoryAllowedErrorSets(candidate_set_ty, chosen_set_ty)) { |
| | 17772 | err_set_ty = candidate_set_ty; |
| | 17773 | } else { |
| | 17774 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| | 17775 | } |
| | 17776 | continue; |
| | 17777 | } |
| | 17778 | }, |
| | 17779 | |
| | 17780 | else => { |
| | 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); |
| | 17789 | } |
| | 17790 | } |
| | 17791 | seen_const = seen_const or chosen_ty.isConstPtr(); |
| | 17792 | chosen = candidate; |
| | 17793 | chosen_i = candidate_i + 1; |
| | 17794 | continue; |
| | 17795 | }, |
| 17737 | }, | 17796 | }, |
| 17738 | .Pointer => { | 17797 | .Pointer => { |
| 17739 | if (candidate_ty.ptrSize() == .C) { | 17798 | if (candidate_ty.ptrSize() == .C) { |
| ... | @@ -17759,7 +17818,7 @@ fn resolvePeerTypes( | ... | @@ -17759,7 +17818,7 @@ fn resolvePeerTypes( |
| 17759 | convert_to_slice = false; | 17818 | convert_to_slice = false; |
| 17760 | | 17819 | |
| 17761 | if (chosen_ty.childType().isConstPtr() and !candidate_ty.childType().isConstPtr()) | 17820 | if (chosen_ty.childType().isConstPtr() and !candidate_ty.childType().isConstPtr()) |
| 17762 | make_the_slice_const = true; | 17821 | seen_const = true; |
| 17763 | | 17822 | |
| 17764 | continue; | 17823 | continue; |
| 17765 | } | 17824 | } |
| ... | @@ -17771,7 +17830,7 @@ fn resolvePeerTypes( | ... | @@ -17771,7 +17830,7 @@ fn resolvePeerTypes( |
| 17771 | chosen_ty.ptrSize() == .Many) | 17830 | chosen_ty.ptrSize() == .Many) |
| 17772 | { | 17831 | { |
| 17773 | if (candidate_ty.childType().isConstPtr() and !chosen_ty.childType().isConstPtr()) | 17832 | if (candidate_ty.childType().isConstPtr() and !chosen_ty.childType().isConstPtr()) |
| 17774 | make_the_slice_const = true; | 17833 | seen_const = true; |
| 17775 | | 17834 | |
| 17776 | continue; | 17835 | continue; |
| 17777 | } | 17836 | } |
| ... | @@ -17792,7 +17851,7 @@ fn resolvePeerTypes( | ... | @@ -17792,7 +17851,7 @@ fn resolvePeerTypes( |
| 17792 | | 17851 | |
| 17793 | // If the pointer is const then we need to const | 17852 | // If the pointer is const then we need to const |
| 17794 | if (candidate_ty.childType().isConstPtr()) | 17853 | if (candidate_ty.childType().isConstPtr()) |
| 17795 | make_the_slice_const = true; | 17854 | seen_const = true; |
| 17796 | | 17855 | |
| 17797 | continue; | 17856 | continue; |
| 17798 | } | 17857 | } |
| ... | @@ -17815,7 +17874,7 @@ fn resolvePeerTypes( | ... | @@ -17815,7 +17874,7 @@ fn resolvePeerTypes( |
| 17815 | | 17874 | |
| 17816 | // If the prev pointer is const then we need to const | 17875 | // If the prev pointer is const then we need to const |
| 17817 | if (chosen_child_ty.isConstPtr()) | 17876 | if (chosen_child_ty.isConstPtr()) |
| 17818 | make_the_slice_const = true; | 17877 | seen_const = true; |
| 17819 | | 17878 | |
| 17820 | continue; | 17879 | continue; |
| 17821 | } | 17880 | } |
| ... | @@ -17851,7 +17910,7 @@ fn resolvePeerTypes( | ... | @@ -17851,7 +17910,7 @@ fn resolvePeerTypes( |
| 17851 | // If one of the pointers is to const data, the slice | 17910 | // If one of the pointers is to const data, the slice |
| 17852 | // must also be const. | 17911 | // must also be const. |
| 17853 | if (candidate_child_ty.isConstPtr() or chosen_child_ty.isConstPtr()) | 17912 | if (candidate_child_ty.isConstPtr() or chosen_child_ty.isConstPtr()) |
| 17854 | make_the_slice_const = true; | 17913 | seen_const = true; |
| 17855 | | 17914 | |
| 17856 | continue; | 17915 | continue; |
| 17857 | } | 17916 | } |
| ... | @@ -17899,9 +17958,26 @@ fn resolvePeerTypes( | ... | @@ -17899,9 +17958,26 @@ fn resolvePeerTypes( |
| 17899 | continue; | 17958 | continue; |
| 17900 | } | 17959 | } |
| 17901 | }, | 17960 | }, |
| | 17961 | .ErrorUnion => { |
| | 17962 | const payload_ty = chosen_ty.errorUnionPayload(); |
| | 17963 | if ((try sema.coerceInMemoryAllowed(block, payload_ty, candidate_ty, false, target, src, src)) == .ok) { |
| | 17964 | continue; |
| | 17965 | } |
| | 17966 | }, |
| 17902 | else => {}, | 17967 | else => {}, |
| 17903 | } | 17968 | } |
| 17904 | | 17969 | |
| | 17970 | // If the candidate can coerce into our chosen type, we're done. |
| | 17971 | // If the chosen type can coerce into the candidate, use that. |
| | 17972 | if ((try sema.coerceInMemoryAllowed(block, chosen_ty, candidate_ty, false, target, src, src)) == .ok) { |
| | 17973 | continue; |
| | 17974 | } |
| | 17975 | if ((try sema.coerceInMemoryAllowed(block, candidate_ty, chosen_ty, false, target, src, src)) == .ok) { |
| | 17976 | chosen = candidate; |
| | 17977 | chosen_i = candidate_i + 1; |
| | 17978 | continue; |
| | 17979 | } |
| | 17980 | |
| 17905 | // At this point, we hit a compile error. We need to recover | 17981 | // At this point, we hit a compile error. We need to recover |
| 17906 | // the source locations. | 17982 | // the source locations. |
| 17907 | const chosen_src = candidate_srcs.resolve( | 17983 | const chosen_src = candidate_srcs.resolve( |
| ... | @@ -17945,23 +18021,49 @@ fn resolvePeerTypes( | ... | @@ -17945,23 +18021,49 @@ fn resolvePeerTypes( |
| 17945 | var info = chosen_ty.ptrInfo(); | 18021 | var info = chosen_ty.ptrInfo(); |
| 17946 | info.data.sentinel = chosen_child_ty.sentinel(); | 18022 | info.data.sentinel = chosen_child_ty.sentinel(); |
| 17947 | info.data.size = .Slice; | 18023 | info.data.size = .Slice; |
| 17948 | info.data.mutable = chosen_child_ty.isConstPtr() or make_the_slice_const; | 18024 | info.data.mutable = seen_const or chosen_child_ty.isConstPtr(); |
| 17949 | info.data.pointee_type = switch (chosen_child_ty.tag()) { | 18025 | info.data.pointee_type = switch (chosen_child_ty.tag()) { |
| 17950 | .array => chosen_child_ty.elemType2(), | 18026 | .array => chosen_child_ty.elemType2(), |
| 17951 | .array_u8, .array_u8_sentinel_0 => Type.initTag(.u8), | 18027 | .array_u8, .array_u8_sentinel_0 => Type.initTag(.u8), |
| 17952 | else => unreachable, | 18028 | else => unreachable, |
| 17953 | }; | 18029 | }; |
| 17954 | | 18030 | |
| 17955 | 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); |
| 17956 | } | 18034 | } |
| 17957 | | 18035 | |
| 17958 | if (make_the_slice_const) { | 18036 | if (seen_const) { |
| 17959 | // turn []T => []const T | 18037 | // turn []T => []const T |
| 17960 | var info = chosen_ty.ptrInfo(); | 18038 | switch (chosen_ty.zigTypeTag()) { |
| 17961 | info.data.mutable = false; | 18039 | .ErrorUnion => { |
| 17962 | 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 | } |
| 17963 | } | 18056 | } |
| 17964 | | 18057 | |
| | 18058 | if (err_set_ty) |ty| switch (chosen_ty.zigTypeTag()) { |
| | 18059 | .ErrorSet => return ty, |
| | 18060 | .ErrorUnion => { |
| | 18061 | const payload_ty = chosen_ty.errorUnionPayload(); |
| | 18062 | return try Module.errorUnionType(sema.arena, ty, payload_ty); |
| | 18063 | }, |
| | 18064 | else => return try Module.errorUnionType(sema.arena, ty, chosen_ty), |
| | 18065 | }; |
| | 18066 | |
| 17965 | return chosen_ty; | 18067 | return chosen_ty; |
| 17966 | } | 18068 | } |
| 17967 | | 18069 | |
| ... | @@ -18248,6 +18350,12 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE | ... | @@ -18248,6 +18350,12 @@ fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredE |
| 18248 | inferred_error_set.is_resolved = true; | 18350 | inferred_error_set.is_resolved = true; |
| 18249 | } | 18351 | } |
| 18250 | | 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 | |
| 18251 | fn semaStructFields( | 18359 | fn semaStructFields( |
| 18252 | mod: *Module, | 18360 | mod: *Module, |
| 18253 | struct_obj: *Module.Struct, | 18361 | struct_obj: *Module.Struct, |