| ... | @@ -5207,9 +5207,6 @@ fn funcCommon( | ... | @@ -5207,9 +5207,6 @@ fn funcCommon( |
| 5207 | .rbrace_line = src_locs.rbrace_line, | 5207 | .rbrace_line = src_locs.rbrace_line, |
| 5208 | .lbrace_column = @truncate(u16, src_locs.columns), | 5208 | .lbrace_column = @truncate(u16, src_locs.columns), |
| 5209 | .rbrace_column = @truncate(u16, src_locs.columns >> 16), | 5209 | .rbrace_column = @truncate(u16, src_locs.columns >> 16), |
| 5210 | .inferred_error_sets = .{ | | |
| 5211 | .first = maybe_inferred_error_set_node, | | |
| 5212 | }, | | |
| 5213 | }; | 5210 | }; |
| 5214 | if (maybe_inferred_error_set_node) |node| { | 5211 | if (maybe_inferred_error_set_node) |node| { |
| 5215 | new_func.inferred_error_sets.prepend(node); | 5212 | new_func.inferred_error_sets.prepend(node); |
| ... | @@ -12193,7 +12190,7 @@ fn coerce( | ... | @@ -12193,7 +12190,7 @@ fn coerce( |
| 12193 | const arena = sema.arena; | 12190 | const arena = sema.arena; |
| 12194 | const target = sema.mod.getTarget(); | 12191 | const target = sema.mod.getTarget(); |
| 12195 | | 12192 | |
| 12196 | const in_memory_result = coerceInMemoryAllowed(dest_ty, inst_ty, false, target); | 12193 | const in_memory_result = try sema.coerceInMemoryAllowed(dest_ty, inst_ty, false, target); |
| 12197 | if (in_memory_result == .ok) { | 12194 | if (in_memory_result == .ok) { |
| 12198 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { | 12195 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { |
| 12199 | // Keep the comptime Value representation; take the new type. | 12196 | // Keep the comptime Value representation; take the new type. |
| ... | @@ -12252,7 +12249,7 @@ fn coerce( | ... | @@ -12252,7 +12249,7 @@ fn coerce( |
| 12252 | if (inst_ty.isConstPtr() and dest_is_mut) break :single_item; | 12249 | if (inst_ty.isConstPtr() and dest_is_mut) break :single_item; |
| 12253 | if (inst_ty.isVolatilePtr() and !dest_info.@"volatile") break :single_item; | 12250 | if (inst_ty.isVolatilePtr() and !dest_info.@"volatile") break :single_item; |
| 12254 | if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :single_item; | 12251 | if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :single_item; |
| 12255 | switch (coerceInMemoryAllowed(array_elem_ty, ptr_elem_ty, dest_is_mut, target)) { | 12252 | switch (try sema.coerceInMemoryAllowed(array_elem_ty, ptr_elem_ty, dest_is_mut, target)) { |
| 12256 | .ok => {}, | 12253 | .ok => {}, |
| 12257 | .no_match => break :single_item, | 12254 | .no_match => break :single_item, |
| 12258 | } | 12255 | } |
| ... | @@ -12271,7 +12268,7 @@ fn coerce( | ... | @@ -12271,7 +12268,7 @@ fn coerce( |
| 12271 | if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :src_array_ptr; | 12268 | if (inst_ty.ptrAddressSpace() != dest_info.@"addrspace") break :src_array_ptr; |
| 12272 | | 12269 | |
| 12273 | const dst_elem_type = dest_info.pointee_type; | 12270 | const dst_elem_type = dest_info.pointee_type; |
| 12274 | switch (coerceInMemoryAllowed(dst_elem_type, array_elem_type, dest_is_mut, target)) { | 12271 | switch (try sema.coerceInMemoryAllowed(dst_elem_type, array_elem_type, dest_is_mut, target)) { |
| 12275 | .ok => {}, | 12272 | .ok => {}, |
| 12276 | .no_match => break :src_array_ptr, | 12273 | .no_match => break :src_array_ptr, |
| 12277 | } | 12274 | } |
| ... | @@ -12310,7 +12307,7 @@ fn coerce( | ... | @@ -12310,7 +12307,7 @@ fn coerce( |
| 12310 | const src_elem_ty = inst_ty.childType(); | 12307 | const src_elem_ty = inst_ty.childType(); |
| 12311 | const dest_is_mut = dest_info.mutable; | 12308 | const dest_is_mut = dest_info.mutable; |
| 12312 | const dst_elem_type = dest_info.pointee_type; | 12309 | const dst_elem_type = dest_info.pointee_type; |
| 12313 | switch (coerceInMemoryAllowed(dst_elem_type, src_elem_ty, dest_is_mut, target)) { | 12310 | switch (try sema.coerceInMemoryAllowed(dst_elem_type, src_elem_ty, dest_is_mut, target)) { |
| 12314 | .ok => {}, | 12311 | .ok => {}, |
| 12315 | .no_match => break :src_c_ptr, | 12312 | .no_match => break :src_c_ptr, |
| 12316 | } | 12313 | } |
| ... | @@ -12453,7 +12450,13 @@ const InMemoryCoercionResult = enum { | ... | @@ -12453,7 +12450,13 @@ const InMemoryCoercionResult = enum { |
| 12453 | /// * sentinel-terminated pointers can coerce into `[*]` | 12450 | /// * sentinel-terminated pointers can coerce into `[*]` |
| 12454 | /// TODO improve this function to report recursive compile errors like it does in stage1. | 12451 | /// TODO improve this function to report recursive compile errors like it does in stage1. |
| 12455 | /// look at the function types_match_const_cast_only | 12452 | /// look at the function types_match_const_cast_only |
| 12456 | fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target: std.Target) InMemoryCoercionResult { | 12453 | fn coerceInMemoryAllowed( |
| | 12454 | sema: *Sema, |
| | 12455 | dest_ty: Type, |
| | 12456 | src_ty: Type, |
| | 12457 | dest_is_mut: bool, |
| | 12458 | target: std.Target |
| | 12459 | ) CompileError!InMemoryCoercionResult { |
| 12457 | if (dest_ty.eql(src_ty)) | 12460 | if (dest_ty.eql(src_ty)) |
| 12458 | return .ok; | 12461 | return .ok; |
| 12459 | | 12462 | |
| ... | @@ -12462,32 +12465,35 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target: | ... | @@ -12462,32 +12465,35 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target: |
| 12462 | var src_buf: Type.Payload.ElemType = undefined; | 12465 | var src_buf: Type.Payload.ElemType = undefined; |
| 12463 | if (dest_ty.ptrOrOptionalPtrTy(&dest_buf)) |dest_ptr_ty| { | 12466 | if (dest_ty.ptrOrOptionalPtrTy(&dest_buf)) |dest_ptr_ty| { |
| 12464 | if (src_ty.ptrOrOptionalPtrTy(&src_buf)) |src_ptr_ty| { | 12467 | if (src_ty.ptrOrOptionalPtrTy(&src_buf)) |src_ptr_ty| { |
| 12465 | return coerceInMemoryAllowedPtrs(dest_ty, src_ty, dest_ptr_ty, src_ptr_ty, dest_is_mut, target); | 12468 | return try sema.coerceInMemoryAllowedPtrs(dest_ty, src_ty, dest_ptr_ty, src_ptr_ty, dest_is_mut, target); |
| 12466 | } | 12469 | } |
| 12467 | } | 12470 | } |
| 12468 | | 12471 | |
| 12469 | // Slices | 12472 | // Slices |
| 12470 | if (dest_ty.isSlice() and src_ty.isSlice()) { | 12473 | if (dest_ty.isSlice() and src_ty.isSlice()) { |
| 12471 | return coerceInMemoryAllowedPtrs(dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target); | 12474 | return try sema.coerceInMemoryAllowedPtrs(dest_ty, src_ty, dest_ty, src_ty, dest_is_mut, target); |
| 12472 | } | 12475 | } |
| 12473 | | 12476 | |
| | 12477 | const dest_tag = dest_ty.zigTypeTag(); |
| | 12478 | const src_tag = src_ty.zigTypeTag(); |
| | 12479 | |
| 12474 | // Functions | 12480 | // Functions |
| 12475 | if (dest_ty.zigTypeTag() == .Fn and src_ty.zigTypeTag() == .Fn) { | 12481 | if (dest_tag == .Fn and src_tag == .Fn) { |
| 12476 | return coerceInMemoryAllowedFns(dest_ty, src_ty, target); | 12482 | return try sema.coerceInMemoryAllowedFns(dest_ty, src_ty, target); |
| 12477 | } | 12483 | } |
| 12478 | | 12484 | |
| 12479 | // Error Unions | 12485 | // Error Unions |
| 12480 | if (dest_ty.zigTypeTag() == .ErrorUnion and src_ty.zigTypeTag() == .ErrorUnion) { | 12486 | if (dest_tag == .ErrorUnion and src_tag == .ErrorUnion) { |
| 12481 | const child = coerceInMemoryAllowed(dest_ty.errorUnionPayload(), src_ty.errorUnionPayload(), dest_is_mut, target); | 12487 | const child = try sema.coerceInMemoryAllowed(dest_ty.errorUnionPayload(), src_ty.errorUnionPayload(), dest_is_mut, target); |
| 12482 | if (child == .no_match) { | 12488 | if (child == .no_match) { |
| 12483 | return child; | 12489 | return child; |
| 12484 | } | 12490 | } |
| 12485 | return coerceInMemoryAllowed(dest_ty.errorUnionSet(), src_ty.errorUnionSet(), dest_is_mut, target); | 12491 | return try sema.coerceInMemoryAllowed(dest_ty.errorUnionSet(), src_ty.errorUnionSet(), dest_is_mut, target); |
| 12486 | } | 12492 | } |
| 12487 | | 12493 | |
| 12488 | // Error Sets | 12494 | // Error Sets |
| 12489 | if (dest_ty.zigTypeTag() == .ErrorSet and src_ty.zigTypeTag() == .ErrorSet) { | 12495 | if (dest_tag == .ErrorSet and src_tag == .ErrorSet) { |
| 12490 | return coerceInMemoryAllowedErrorSets(dest_ty, src_ty); | 12496 | return try sema.coerceInMemoryAllowedErrorSets(dest_ty, src_ty); |
| 12491 | } | 12497 | } |
| 12492 | | 12498 | |
| 12493 | // TODO: arrays | 12499 | // TODO: arrays |
| ... | @@ -12498,14 +12504,16 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target: | ... | @@ -12498,14 +12504,16 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target: |
| 12498 | } | 12504 | } |
| 12499 | | 12505 | |
| 12500 | fn coerceInMemoryAllowedErrorSets( | 12506 | fn coerceInMemoryAllowedErrorSets( |
| | 12507 | sema: *Sema, |
| 12501 | dest_ty: Type, | 12508 | dest_ty: Type, |
| 12502 | src_ty: Type, | 12509 | src_ty: Type, |
| 12503 | ) InMemoryCoercionResult { | 12510 | ) !InMemoryCoercionResult { |
| 12504 | // Coercion to `anyerror`. Note that this check can return false positives | 12511 | // Coercion to `anyerror`. Note that this check can return false negatives |
| 12505 | // in case the error sets did not get resolved. | 12512 | // in case the error sets did not get resolved. |
| 12506 | if (dest_ty.isAnyError()) { | 12513 | if (dest_ty.isAnyError()) { |
| 12507 | return .ok; | 12514 | return .ok; |
| 12508 | } | 12515 | } |
| | 12516 | |
| 12509 | // If both are inferred error sets of functions, and | 12517 | // If both are inferred error sets of functions, and |
| 12510 | // the dest includes the source function, the coercion is OK. | 12518 | // the dest includes the source function, the coercion is OK. |
| 12511 | // This check is important because it works without forcing a full resolution | 12519 | // This check is important because it works without forcing a full resolution |
| ... | @@ -12515,21 +12523,85 @@ fn coerceInMemoryAllowedErrorSets( | ... | @@ -12515,21 +12523,85 @@ fn coerceInMemoryAllowedErrorSets( |
| 12515 | const src_func = src_payload.data.func; | 12523 | const src_func = src_payload.data.func; |
| 12516 | const dst_func = dst_payload.data.func; | 12524 | const dst_func = dst_payload.data.func; |
| 12517 | | 12525 | |
| 12518 | if (src_func == dst_func or dst_payload.data.functions.contains(src_func)) { | 12526 | if (src_func == dst_func or dst_payload.data.inferred_error_sets.contains(src_payload.data)) { |
| 12519 | return .ok; | 12527 | return .ok; |
| 12520 | } | 12528 | } |
| | 12529 | return .no_match; |
| 12521 | } | 12530 | } |
| 12522 | } | 12531 | } |
| 12523 | | 12532 | |
| 12524 | // TODO full error set resolution and compare sets by names. | 12533 | if (dest_ty.castTag(.error_set_inferred)) |payload| { |
| | 12534 | try sema.resolveInferredErrorSet(payload.data); |
| | 12535 | // isAnyError might have changed from a false negative to a true positive after resolution. |
| | 12536 | if (dest_ty.isAnyError()) { |
| | 12537 | return .ok; |
| | 12538 | } |
| | 12539 | } |
| | 12540 | |
| | 12541 | switch (src_ty.tag()) { |
| | 12542 | .error_set_inferred => { |
| | 12543 | const src_data = src_ty.castTag(.error_set_inferred).?.data; |
| | 12544 | |
| | 12545 | try sema.resolveInferredErrorSet(src_data); |
| | 12546 | // src anyerror status might have changed after the resolution. |
| | 12547 | if (src_ty.isAnyError()) { |
| | 12548 | // dest_ty.isAnyError() == true is already checked for at this point. |
| | 12549 | return .no_match; |
| | 12550 | } |
| | 12551 | |
| | 12552 | var it = src_data.errors.keyIterator(); |
| | 12553 | while (it.next()) |name_ptr| { |
| | 12554 | if (!dest_ty.errorSetHasField(name_ptr.*)) { |
| | 12555 | return .no_match; |
| | 12556 | } |
| | 12557 | } |
| | 12558 | |
| | 12559 | return .ok; |
| | 12560 | }, |
| | 12561 | .error_set_single => { |
| | 12562 | const name = src_ty.castTag(.error_set_single).?.data; |
| | 12563 | if (dest_ty.errorSetHasField(name)) { |
| | 12564 | return .ok; |
| | 12565 | } |
| | 12566 | }, |
| | 12567 | .error_set_merged => { |
| | 12568 | const names = src_ty.castTag(.error_set_merged).?.data.keys(); |
| | 12569 | for (names) |name| { |
| | 12570 | if (!dest_ty.errorSetHasField(name)) { |
| | 12571 | return .no_match; |
| | 12572 | } |
| | 12573 | } |
| | 12574 | |
| | 12575 | return .ok; |
| | 12576 | }, |
| | 12577 | .error_set => { |
| | 12578 | const names = src_ty.castTag(.error_set).?.data.names.keys(); |
| | 12579 | for (names) |name| { |
| | 12580 | if (!dest_ty.errorSetHasField(name)) { |
| | 12581 | return .no_match; |
| | 12582 | } |
| | 12583 | } |
| | 12584 | |
| | 12585 | return .ok; |
| | 12586 | }, |
| | 12587 | .anyerror => switch (dest_ty.tag()) { |
| | 12588 | .error_set_inferred => return .no_match, // Caught by dest.isAnyError() above. |
| | 12589 | .error_set_single, .error_set_merged, .error_set => {}, |
| | 12590 | .anyerror => unreachable, // Filtered out above. |
| | 12591 | else => unreachable, |
| | 12592 | }, |
| | 12593 | else => unreachable, |
| | 12594 | } |
| | 12595 | |
| 12525 | return .no_match; | 12596 | return .no_match; |
| 12526 | } | 12597 | } |
| 12527 | | 12598 | |
| 12528 | fn coerceInMemoryAllowedFns( | 12599 | fn coerceInMemoryAllowedFns( |
| | 12600 | sema: *Sema, |
| 12529 | dest_ty: Type, | 12601 | dest_ty: Type, |
| 12530 | src_ty: Type, | 12602 | src_ty: Type, |
| 12531 | target: std.Target, | 12603 | target: std.Target, |
| 12532 | ) InMemoryCoercionResult { | 12604 | ) !InMemoryCoercionResult { |
| 12533 | const dest_info = dest_ty.fnInfo(); | 12605 | const dest_info = dest_ty.fnInfo(); |
| 12534 | const src_info = src_ty.fnInfo(); | 12606 | const src_info = src_ty.fnInfo(); |
| 12535 | | 12607 | |
| ... | @@ -12542,7 +12614,7 @@ fn coerceInMemoryAllowedFns( | ... | @@ -12542,7 +12614,7 @@ fn coerceInMemoryAllowedFns( |
| 12542 | } | 12614 | } |
| 12543 | | 12615 | |
| 12544 | if (!src_info.return_type.isNoReturn()) { | 12616 | if (!src_info.return_type.isNoReturn()) { |
| 12545 | const rt = coerceInMemoryAllowed(dest_info.return_type, src_info.return_type, false, target); | 12617 | const rt = try sema.coerceInMemoryAllowed(dest_info.return_type, src_info.return_type, false, target); |
| 12546 | if (rt == .no_match) { | 12618 | if (rt == .no_match) { |
| 12547 | return rt; | 12619 | return rt; |
| 12548 | } | 12620 | } |
| ... | @@ -12562,7 +12634,7 @@ fn coerceInMemoryAllowedFns( | ... | @@ -12562,7 +12634,7 @@ fn coerceInMemoryAllowedFns( |
| 12562 | // TODO: nolias | 12634 | // TODO: nolias |
| 12563 | | 12635 | |
| 12564 | // Note: Cast direction is reversed here. | 12636 | // Note: Cast direction is reversed here. |
| 12565 | const param = coerceInMemoryAllowed(src_param_ty, dest_param_ty, false, target); | 12637 | const param = try sema.coerceInMemoryAllowed(src_param_ty, dest_param_ty, false, target); |
| 12566 | if (param == .no_match) { | 12638 | if (param == .no_match) { |
| 12567 | return param; | 12639 | return param; |
| 12568 | } | 12640 | } |
| ... | @@ -12576,17 +12648,18 @@ fn coerceInMemoryAllowedFns( | ... | @@ -12576,17 +12648,18 @@ fn coerceInMemoryAllowedFns( |
| 12576 | } | 12648 | } |
| 12577 | | 12649 | |
| 12578 | fn coerceInMemoryAllowedPtrs( | 12650 | fn coerceInMemoryAllowedPtrs( |
| | 12651 | sema: *Sema, |
| 12579 | dest_ty: Type, | 12652 | dest_ty: Type, |
| 12580 | src_ty: Type, | 12653 | src_ty: Type, |
| 12581 | dest_ptr_ty: Type, | 12654 | dest_ptr_ty: Type, |
| 12582 | src_ptr_ty: Type, | 12655 | src_ptr_ty: Type, |
| 12583 | dest_is_mut: bool, | 12656 | dest_is_mut: bool, |
| 12584 | target: std.Target, | 12657 | target: std.Target, |
| 12585 | ) InMemoryCoercionResult { | 12658 | ) !InMemoryCoercionResult { |
| 12586 | const dest_info = dest_ptr_ty.ptrInfo().data; | 12659 | const dest_info = dest_ptr_ty.ptrInfo().data; |
| 12587 | const src_info = src_ptr_ty.ptrInfo().data; | 12660 | const src_info = src_ptr_ty.ptrInfo().data; |
| 12588 | | 12661 | |
| 12589 | const child = coerceInMemoryAllowed(dest_info.pointee_type, src_info.pointee_type, dest_info.mutable, target); | 12662 | const child = try sema.coerceInMemoryAllowed(dest_info.pointee_type, src_info.pointee_type, dest_info.mutable, target); |
| 12590 | if (child == .no_match) { | 12663 | if (child == .no_match) { |
| 12591 | return child; | 12664 | return child; |
| 12592 | } | 12665 | } |
| ... | @@ -13307,7 +13380,7 @@ fn coerceVectorInMemory( | ... | @@ -13307,7 +13380,7 @@ fn coerceVectorInMemory( |
| 13307 | const target = sema.mod.getTarget(); | 13380 | const target = sema.mod.getTarget(); |
| 13308 | const dest_elem_ty = dest_ty.childType(); | 13381 | const dest_elem_ty = dest_ty.childType(); |
| 13309 | const inst_elem_ty = inst_ty.childType(); | 13382 | const inst_elem_ty = inst_ty.childType(); |
| 13310 | const in_memory_result = coerceInMemoryAllowed(dest_elem_ty, inst_elem_ty, false, target); | 13383 | const in_memory_result = try sema.coerceInMemoryAllowed(dest_elem_ty, inst_elem_ty, false, target); |
| 13311 | if (in_memory_result != .ok) { | 13384 | if (in_memory_result != .ok) { |
| 13312 | // TODO recursive error notes for coerceInMemoryAllowed failure | 13385 | // TODO recursive error notes for coerceInMemoryAllowed failure |
| 13313 | return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty }); | 13386 | return sema.fail(block, inst_src, "expected {}, found {}", .{ dest_ty, inst_ty }); |
| ... | @@ -13910,11 +13983,11 @@ fn wrapErrorUnion( | ... | @@ -13910,11 +13983,11 @@ fn wrapErrorUnion( |
| 13910 | } | 13983 | } |
| 13911 | }, | 13984 | }, |
| 13912 | .error_set_inferred => ok: { | 13985 | .error_set_inferred => ok: { |
| | 13986 | const expected_name = val.castTag(.@"error").?.data.name; |
| 13913 | const data = dest_err_set_ty.castTag(.error_set_inferred).?.data; | 13987 | const data = dest_err_set_ty.castTag(.error_set_inferred).?.data; |
| | 13988 | try sema.resolveInferredErrorSet(data); |
| 13914 | if (data.is_anyerror) break :ok; | 13989 | if (data.is_anyerror) break :ok; |
| 13915 | const expected_name = val.castTag(.@"error").?.data.name; | | |
| 13916 | if (data.errors.contains(expected_name)) break :ok; | 13990 | if (data.errors.contains(expected_name)) break :ok; |
| 13917 | // TODO error set resolution here before emitting a compile error | | |
| 13918 | return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); | 13991 | return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty); |
| 13919 | }, | 13992 | }, |
| 13920 | else => unreachable, | 13993 | else => unreachable, |
| ... | @@ -14059,12 +14132,12 @@ fn resolvePeerTypes( | ... | @@ -14059,12 +14132,12 @@ fn resolvePeerTypes( |
| 14059 | .Optional => { | 14132 | .Optional => { |
| 14060 | var opt_child_buf: Type.Payload.ElemType = undefined; | 14133 | var opt_child_buf: Type.Payload.ElemType = undefined; |
| 14061 | const opt_child_ty = candidate_ty.optionalChild(&opt_child_buf); | 14134 | const opt_child_ty = candidate_ty.optionalChild(&opt_child_buf); |
| 14062 | if (coerceInMemoryAllowed(opt_child_ty, chosen_ty, false, target) == .ok) { | 14135 | if ((try sema.coerceInMemoryAllowed(opt_child_ty, chosen_ty, false, target)) == .ok) { |
| 14063 | chosen = candidate; | 14136 | chosen = candidate; |
| 14064 | chosen_i = candidate_i + 1; | 14137 | chosen_i = candidate_i + 1; |
| 14065 | continue; | 14138 | continue; |
| 14066 | } | 14139 | } |
| 14067 | if (coerceInMemoryAllowed(chosen_ty, opt_child_ty, false, target) == .ok) { | 14140 | if ((try sema.coerceInMemoryAllowed(chosen_ty, opt_child_ty, false, target)) == .ok) { |
| 14068 | any_are_null = true; | 14141 | any_are_null = true; |
| 14069 | continue; | 14142 | continue; |
| 14070 | } | 14143 | } |
| ... | @@ -14087,10 +14160,10 @@ fn resolvePeerTypes( | ... | @@ -14087,10 +14160,10 @@ fn resolvePeerTypes( |
| 14087 | .Optional => { | 14160 | .Optional => { |
| 14088 | var opt_child_buf: Type.Payload.ElemType = undefined; | 14161 | var opt_child_buf: Type.Payload.ElemType = undefined; |
| 14089 | const opt_child_ty = chosen_ty.optionalChild(&opt_child_buf); | 14162 | const opt_child_ty = chosen_ty.optionalChild(&opt_child_buf); |
| 14090 | if (coerceInMemoryAllowed(opt_child_ty, candidate_ty, false, target) == .ok) { | 14163 | if ((try sema.coerceInMemoryAllowed(opt_child_ty, candidate_ty, false, target)) == .ok) { |
| 14091 | continue; | 14164 | continue; |
| 14092 | } | 14165 | } |
| 14093 | if (coerceInMemoryAllowed(candidate_ty, opt_child_ty, false, target) == .ok) { | 14166 | if ((try sema.coerceInMemoryAllowed(candidate_ty, opt_child_ty, false, target)) == .ok) { |
| 14094 | any_are_null = true; | 14167 | any_are_null = true; |
| 14095 | chosen = candidate; | 14168 | chosen = candidate; |
| 14096 | chosen_i = candidate_i + 1; | 14169 | chosen_i = candidate_i + 1; |
| ... | @@ -14256,6 +14329,42 @@ fn resolveBuiltinTypeFields( | ... | @@ -14256,6 +14329,42 @@ fn resolveBuiltinTypeFields( |
| 14256 | return sema.resolveTypeFields(block, src, resolved_ty); | 14329 | return sema.resolveTypeFields(block, src, resolved_ty); |
| 14257 | } | 14330 | } |
| 14258 | | 14331 | |
| | 14332 | fn resolveInferredErrorSet(sema: *Sema, inferred_error_set: *Module.Fn.InferredErrorSet) CompileError!void { |
| | 14333 | // Ensuring that a particular decl is analyzed does not neccesarily mean that |
| | 14334 | // it's error set is inferred, so traverse all of them to get the complete |
| | 14335 | // picture. |
| | 14336 | // Note: We want to skip re-resolving the current function, as recursion |
| | 14337 | // doesn't change the error set. We can just check for state == .in_progress for this. |
| | 14338 | // TODO: Is that correct? |
| | 14339 | |
| | 14340 | if (inferred_error_set.is_resolved) { |
| | 14341 | return; |
| | 14342 | } |
| | 14343 | |
| | 14344 | var it = inferred_error_set.inferred_error_sets.keyIterator(); |
| | 14345 | while (it.next()) |other_error_set_ptr| { |
| | 14346 | const func = other_error_set_ptr.*.func; |
| | 14347 | const decl = func.*.owner_decl; |
| | 14348 | |
| | 14349 | if (func.*.state == .in_progress) { |
| | 14350 | // Recursion, doesn't alter current error set, keep going. |
| | 14351 | continue; |
| | 14352 | } |
| | 14353 | |
| | 14354 | try sema.ensureDeclAnalyzed(decl); // To ensure that all dependencies are properly added to the set. |
| | 14355 | try sema.resolveInferredErrorSet(other_error_set_ptr.*); |
| | 14356 | |
| | 14357 | var error_it = other_error_set_ptr.*.errors.keyIterator(); |
| | 14358 | while (error_it.next()) |entry| { |
| | 14359 | try inferred_error_set.errors.put(sema.gpa, entry.*, {}); |
| | 14360 | } |
| | 14361 | if (other_error_set_ptr.*.is_anyerror) |
| | 14362 | inferred_error_set.is_anyerror = true; |
| | 14363 | } |
| | 14364 | |
| | 14365 | inferred_error_set.is_resolved = true; |
| | 14366 | } |
| | 14367 | |
| 14259 | fn semaStructFields( | 14368 | fn semaStructFields( |
| 14260 | mod: *Module, | 14369 | mod: *Module, |
| 14261 | struct_obj: *Module.Struct, | 14370 | struct_obj: *Module.Struct, |
| ... | @@ -15218,8 +15327,8 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr | ... | @@ -15218,8 +15327,8 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr |
| 15218 | // We have a Value that lines up in virtual memory exactly with what we want to load. | 15327 | // We have a Value that lines up in virtual memory exactly with what we want to load. |
| 15219 | // If the Type is in-memory coercable to `load_ty`, it may be returned without modifications. | 15328 | // If the Type is in-memory coercable to `load_ty`, it may be returned without modifications. |
| 15220 | const coerce_in_mem_ok = | 15329 | const coerce_in_mem_ok = |
| 15221 | coerceInMemoryAllowed(load_ty, parent.ty, false, target) == .ok or | 15330 | (try sema.coerceInMemoryAllowed(load_ty, parent.ty, false, target)) == .ok or |
| 15222 | coerceInMemoryAllowed(parent.ty, load_ty, false, target) == .ok; | 15331 | (try sema.coerceInMemoryAllowed(parent.ty, load_ty, false, target)) == .ok; |
| 15223 | if (coerce_in_mem_ok) { | 15332 | if (coerce_in_mem_ok) { |
| 15224 | if (parent.is_mutable) { | 15333 | if (parent.is_mutable) { |
| 15225 | // The decl whose value we are obtaining here may be overwritten with | 15334 | // The decl whose value we are obtaining here may be overwritten with |