| ... | @@ -53,172 +53,230 @@ const InnerError = Module.InnerError; | ... | @@ -53,172 +53,230 @@ const InnerError = Module.InnerError; |
| 53 | const Decl = Module.Decl; | 53 | const Decl = Module.Decl; |
| 54 | const LazySrcLoc = Module.LazySrcLoc; | 54 | const LazySrcLoc = Module.LazySrcLoc; |
| 55 | | 55 | |
| 56 | pub fn root(sema: *Sema, root_block: *Scope.Block) !void { | 56 | pub fn root(sema: *Sema, root_block: *Scope.Block) !zir.Inst.Ref { |
| 57 | const root_body = sema.code.extra[sema.code.root_start..][0..sema.code.root_len]; | 57 | const root_body = sema.code.extra[sema.code.root_start..][0..sema.code.root_len]; |
| 58 | return sema.analyzeBody(root_block, root_body); | 58 | return sema.analyzeBody(root_block, root_body); |
| 59 | } | 59 | } |
| 60 | | 60 | |
| 61 | pub fn rootAsType(sema: *Sema, root_block: *Scope.Block, result_inst: zir.Inst.Ref) !Type { | 61 | /// Assumes that `root_block` ends with `break_flat`. |
| 62 | const root_body = sema.code.extra[sema.code.root_start..][0..sema.code.root_len]; | 62 | pub fn rootAsType(sema: *Sema, root_block: *Scope.Block) !Type { |
| 63 | try sema.analyzeBody(root_block, root_body); | 63 | const zir_inst_ref = try sema.root(root_block); |
| 64 | | | |
| 65 | // Source location is unneeded because resolveConstValue must have already | 64 | // Source location is unneeded because resolveConstValue must have already |
| 66 | // been successfully called when coercing the value to a type, from the | 65 | // been successfully called when coercing the value to a type, from the |
| 67 | // result location. | 66 | // result location. |
| 68 | return sema.resolveType(root_block, .unneeded, result_inst); | 67 | return sema.resolveType(root_block, .unneeded, zir_inst_ref); |
| 69 | } | 68 | } |
| 70 | | 69 | |
| 71 | pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Index) !void { | 70 | /// ZIR instructions which are always `noreturn` return this. This matches the |
| 72 | const tracy = trace(@src()); | 71 | /// return type of `analyzeBody` so that we can tail call them. |
| 73 | defer tracy.end(); | 72 | /// Only appropriate to return when the instruction is known to be NoReturn |
| | 73 | /// solely based on the ZIR tag. |
| | 74 | const always_noreturn: InnerError!zir.Inst.Ref = @as(zir.Inst.Index, 0); |
| | 75 | |
| | 76 | /// This function is the main loop of `Sema` and it can be used in two different ways: |
| | 77 | /// * The traditional way where there are N breaks out of the block and peer type |
| | 78 | /// resolution is done on the break operands. In this case, the `zir.Inst.Index` |
| | 79 | /// part of the return value will be `undefined`, and callsites should ignore it, |
| | 80 | /// finding the block result value via the block scope. |
| | 81 | /// * The "flat" way. There is only 1 break out of the block, and it is with a `break_flat` |
| | 82 | /// instruction. In this case, the `zir.Inst.Index` part of the return value will be |
| | 83 | /// the block result value. No block scope needs to be created for this strategy. |
| | 84 | pub fn analyzeBody(sema: *Sema, block: *Scope.Block, body: []const zir.Inst.Index) !zir.Inst.Index { |
| | 85 | // No tracy calls here, to avoid interfering with the tail call mechanism. |
| 74 | | 86 | |
| 75 | const map = block.sema.inst_map; | 87 | const map = block.sema.inst_map; |
| 76 | const tags = block.sema.code.instructions.items(.tag); | 88 | const tags = block.sema.code.instructions.items(.tag); |
| 77 | | 89 | |
| 78 | // TODO: As an optimization, look into making these switch prongs directly jump | 90 | // We use a while(true) loop here to avoid a redundant way of breaking out of |
| 79 | // to the next one, rather than detouring through the loop condition. | 91 | // the loop. The only way to break out of the loop is with a `noreturn` |
| 80 | // Also, look into leaving only the "noreturn" loop break condition, and removing | 92 | // instruction. |
| 81 | // the iteration based one. Better yet, have an extra entry in the tags array as a | 93 | // TODO: As an optimization, make sure the codegen for these switch prongs |
| 82 | // sentinel, so that exiting the loop is just another jump table prong. | 94 | // directly jump to the next one, rather than detouring through the loop |
| 83 | // Related: https://github.com/ziglang/zig/issues/8220 | 95 | // continue expression. Related: https://github.com/ziglang/zig/issues/8220 |
| 84 | for (body) |zir_inst| { | 96 | var i: usize = 0; |
| 85 | map[zir_inst] = switch (tags[zir_inst]) { | 97 | while (true) : (i += 1) { |
| 86 | .alloc => try sema.zirAlloc(block, zir_inst), | 98 | const inst = body[i]; |
| 87 | .alloc_mut => try sema.zirAllocMut(block, zir_inst), | 99 | map[inst] = switch (tags[inst]) { |
| 88 | .alloc_inferred => try sema.zirAllocInferred(block, zir_inst, Type.initTag(.inferred_alloc_const)), | | |
| 89 | .alloc_inferred_mut => try sema.zirAllocInferred(block, zir_inst, Type.initTag(.inferred_alloc_mut)), | | |
| 90 | .bitcast_ref => try sema.zirBitcastRef(block, zir_inst), | | |
| 91 | .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, zir_inst), | | |
| 92 | .block => try sema.zirBlock(block, zir_inst, false), | | |
| 93 | .block_comptime => try sema.zirBlock(block, zir_inst, true), | | |
| 94 | .block_flat => try sema.zirBlockFlat(block, zir_inst, false), | | |
| 95 | .block_comptime_flat => try sema.zirBlockFlat(block, zir_inst, true), | | |
| 96 | .@"break" => try sema.zirBreak(block, zir_inst), | | |
| 97 | .break_void_tok => try sema.zirBreakVoidTok(block, zir_inst), | | |
| 98 | .breakpoint => try sema.zirBreakpoint(block, zir_inst), | | |
| 99 | .call => try sema.zirCall(block, zir_inst, .auto), | | |
| 100 | .call_compile_time => try sema.zirCall(block, zir_inst, .compile_time), | | |
| 101 | .call_none => try sema.zirCallNone(block, zir_inst), | | |
| 102 | .coerce_result_ptr => try sema.zirCoerceResultPtr(block, zir_inst), | | |
| 103 | .compile_error => try sema.zirCompileError(block, zir_inst), | | |
| 104 | .compile_log => try sema.zirCompileLog(block, zir_inst), | | |
| 105 | .@"const" => try sema.zirConst(block, zir_inst), | | |
| 106 | .dbg_stmt_node => try sema.zirDbgStmtNode(block, zir_inst), | | |
| 107 | .decl_ref => try sema.zirDeclRef(block, zir_inst), | | |
| 108 | .decl_val => try sema.zirDeclVal(block, zir_inst), | | |
| 109 | .elided => continue, | 100 | .elided => continue, |
| 110 | .ensure_result_used => try sema.zirEnsureResultUsed(block, zir_inst), | 101 | |
| 111 | .ensure_result_non_error => try sema.zirEnsureResultNonError(block, zir_inst), | 102 | .add => try sema.zirArithmetic(block, inst), |
| 112 | .indexable_ptr_len => try sema.zirIndexablePtrLen(block, zir_inst), | 103 | .addwrap => try sema.zirArithmetic(block, inst), |
| 113 | .ref => try sema.zirRef(block, zir_inst), | 104 | .alloc => try sema.zirAlloc(block, inst), |
| 114 | .resolve_inferred_alloc => try sema.zirResolveInferredAlloc(block, zir_inst), | 105 | .alloc_inferred => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_const)), |
| 115 | .ret_ptr => try sema.zirRetPtr(block, zir_inst), | 106 | .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_mut)), |
| 116 | .ret_type => try sema.zirRetType(block, zir_inst), | 107 | .alloc_mut => try sema.zirAllocMut(block, inst), |
| 117 | .store_to_block_ptr => try sema.zirStoreToBlockPtr(block, zir_inst), | 108 | .array_cat => try sema.zirArrayCat(block, inst), |
| 118 | .store_to_inferred_ptr => try sema.zirStoreToInferredPtr(block, zir_inst), | 109 | .array_mul => try sema.zirArrayMul(block, inst), |
| 119 | .ptr_type_simple => try sema.zirPtrTypeSimple(block, zir_inst), | 110 | .array_type => try sema.zirArrayType(block, inst), |
| 120 | .ptr_type => try sema.zirPtrType(block, zir_inst), | 111 | .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst), |
| 121 | .store => try sema.zirStore(block, zir_inst), | 112 | .as => try sema.zirAs(block, inst), |
| 122 | .set_eval_branch_quota => try sema.zirSetEvalBranchQuota(block, zir_inst), | 113 | .as_node => try sema.zirAsNode(block, inst), |
| 123 | .str => try sema.zirStr(block, zir_inst), | 114 | .@"asm" => try sema.zirAsm(block, inst, false), |
| 124 | .int => try sema.zirInt(block, zir_inst), | 115 | .asm_volatile => try sema.zirAsm(block, inst, true), |
| 125 | .int_type => try sema.zirIntType(block, zir_inst), | 116 | .bit_and => try sema.zirBitwise(block, inst), |
| 126 | .loop => try sema.zirLoop(block, zir_inst), | 117 | .bit_not => try sema.zirBitNot(block, inst), |
| 127 | .param_type => try sema.zirParamType(block, zir_inst), | 118 | .bit_or => try sema.zirBitwise(block, inst), |
| 128 | .ptrtoint => try sema.zirPtrtoint(block, zir_inst), | 119 | .bitcast => try sema.zirBitcast(block, inst), |
| 129 | .field_ptr => try sema.zirFieldPtr(block, zir_inst), | 120 | .bitcast_ref => try sema.zirBitcastRef(block, inst), |
| 130 | .field_val => try sema.zirFieldVal(block, zir_inst), | 121 | .bitcast_result_ptr => try sema.zirBitcastResultPtr(block, inst), |
| 131 | .field_ptr_named => try sema.zirFieldPtrNamed(block, zir_inst), | 122 | .block => try sema.zirBlock(block, inst, false), |
| 132 | .field_val_named => try sema.zirFieldValNamed(block, zir_inst), | 123 | .block_comptime => try sema.zirBlock(block, inst, true), |
| 133 | .deref_node => try sema.zirDerefNode(block, zir_inst), | 124 | .bool_not => try sema.zirBoolNot(block, inst), |
| 134 | .as => try sema.zirAs(block, zir_inst), | 125 | .bool_and => try sema.zirBoolOp(block, inst, false), |
| 135 | .as_node => try sema.zirAsNode(block, zir_inst), | 126 | .bool_or => try sema.zirBoolOp(block, inst, true), |
| 136 | .@"asm" => try sema.zirAsm(block, zir_inst, false), | 127 | .bool_br_and => try sema.zirBoolBr(block, inst, false), |
| 137 | .asm_volatile => try sema.zirAsm(block, zir_inst, true), | 128 | .bool_br_or => try sema.zirBoolBr(block, inst, true), |
| 138 | .@"unreachable" => try sema.zirUnreachable(block, zir_inst), | 129 | .call => try sema.zirCall(block, inst, .auto), |
| 139 | .ret_coerce => try sema.zirRetTok(block, zir_inst, true), | 130 | .call_compile_time => try sema.zirCall(block, inst, .compile_time), |
| 140 | .ret_tok => try sema.zirRetTok(block, zir_inst, false), | 131 | .call_none => try sema.zirCallNone(block, inst), |
| 141 | .ret_node => try sema.zirRetNode(block, zir_inst), | 132 | .cmp_eq => try sema.zirCmp(block, inst, .eq), |
| 142 | .fn_type => try sema.zirFnType(block, zir_inst, false), | 133 | .cmp_gt => try sema.zirCmp(block, inst, .gt), |
| 143 | .fn_type_cc => try sema.zirFnTypeCc(block, zir_inst, false), | 134 | .cmp_gte => try sema.zirCmp(block, inst, .gte), |
| 144 | .fn_type_var_args => try sema.zirFnType(block, zir_inst, true), | 135 | .cmp_lt => try sema.zirCmp(block, inst, .lt), |
| 145 | .fn_type_cc_var_args => try sema.zirFnTypeCc(block, zir_inst, true), | 136 | .cmp_lte => try sema.zirCmp(block, inst, .lte), |
| 146 | .intcast => try sema.zirIntcast(block, zir_inst), | 137 | .cmp_neq => try sema.zirCmp(block, inst, .neq), |
| 147 | .bitcast => try sema.zirBitcast(block, zir_inst), | 138 | .coerce_result_ptr => try sema.zirCoerceResultPtr(block, inst), |
| 148 | .floatcast => try sema.zirFloatcast(block, zir_inst), | 139 | .@"const" => try sema.zirConst(block, inst), |
| 149 | .elem_ptr => try sema.zirElemPtr(block, zir_inst), | 140 | .decl_ref => try sema.zirDeclRef(block, inst), |
| 150 | .elem_ptr_node => try sema.zirElemPtrNode(block, zir_inst), | 141 | .decl_val => try sema.zirDeclVal(block, inst), |
| 151 | .elem_val => try sema.zirElemVal(block, zir_inst), | 142 | .deref_node => try sema.zirDerefNode(block, inst), |
| 152 | .elem_val_node => try sema.zirElemValNode(block, zir_inst), | 143 | .div => try sema.zirArithmetic(block, inst), |
| 153 | .add => try sema.zirArithmetic(block, zir_inst), | 144 | .elem_ptr => try sema.zirElemPtr(block, inst), |
| 154 | .addwrap => try sema.zirArithmetic(block, zir_inst), | 145 | .elem_ptr_node => try sema.zirElemPtrNode(block, inst), |
| 155 | .sub => try sema.zirArithmetic(block, zir_inst), | 146 | .elem_val => try sema.zirElemVal(block, inst), |
| 156 | .subwrap => try sema.zirArithmetic(block, zir_inst), | 147 | .elem_val_node => try sema.zirElemValNode(block, inst), |
| | 148 | .enum_literal => try sema.zirEnumLiteral(block, inst), |
| | 149 | .enum_literal_small => try sema.zirEnumLiteralSmall(block, inst), |
| | 150 | .err_union_code => try sema.zirErrUnionCode(block, inst), |
| | 151 | .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst), |
| | 152 | .err_union_payload_safe => try sema.zirErrUnionPayload(block, inst, true), |
| | 153 | .err_union_payload_safe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, true), |
| | 154 | .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst, false), |
| | 155 | .err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, inst, false), |
| | 156 | .error_set => try sema.zirErrorSet(block, inst), |
| | 157 | .error_union_type => try sema.zirErrorUnionType(block, inst), |
| | 158 | .error_value => try sema.zirErrorValue(block, inst), |
| | 159 | .field_ptr => try sema.zirFieldPtr(block, inst), |
| | 160 | .field_ptr_named => try sema.zirFieldPtrNamed(block, inst), |
| | 161 | .field_val => try sema.zirFieldVal(block, inst), |
| | 162 | .field_val_named => try sema.zirFieldValNamed(block, inst), |
| | 163 | .floatcast => try sema.zirFloatcast(block, inst), |
| | 164 | .fn_type => try sema.zirFnType(block, inst, false), |
| | 165 | .fn_type_cc => try sema.zirFnTypeCc(block, inst, false), |
| | 166 | .fn_type_cc_var_args => try sema.zirFnTypeCc(block, inst, true), |
| | 167 | .fn_type_var_args => try sema.zirFnType(block, inst, true), |
| | 168 | .import => try sema.zirImport(block, inst), |
| | 169 | .indexable_ptr_len => try sema.zirIndexablePtrLen(block, inst), |
| | 170 | .int => try sema.zirInt(block, inst), |
| | 171 | .int_type => try sema.zirIntType(block, inst), |
| | 172 | .intcast => try sema.zirIntcast(block, inst), |
| | 173 | .is_err => try sema.zirIsErr(block, inst), |
| | 174 | .is_err_ptr => try sema.zirIsErrPtr(block, inst), |
| | 175 | .is_non_null => try sema.zirIsNull(block, inst, true), |
| | 176 | .is_non_null_ptr => try sema.zirIsNullPtr(block, inst, true), |
| | 177 | .is_null => try sema.zirIsNull(block, inst, false), |
| | 178 | .is_null_ptr => try sema.zirIsNullPtr(block, inst, false), |
| | 179 | .merge_error_sets => try sema.zirMergeErrorSets(block, inst), |
| | 180 | .mod_rem => try sema.zirArithmetic(block, inst), |
| | 181 | .mul => try sema.zirArithmetic(block, inst), |
| | 182 | .mulwrap => try sema.zirArithmetic(block, inst), |
| 157 | .negate => @panic("TODO"), | 183 | .negate => @panic("TODO"), |
| 158 | .negate_wrap => @panic("TODO"), | 184 | .negate_wrap => @panic("TODO"), |
| 159 | .mul => try sema.zirArithmetic(block, zir_inst), | 185 | .optional_payload_safe => try sema.zirOptionalPayload(block, inst, true), |
| 160 | .mulwrap => try sema.zirArithmetic(block, zir_inst), | 186 | .optional_payload_safe_ptr => try sema.zirOptionalPayloadPtr(block, inst, true), |
| 161 | .div => try sema.zirArithmetic(block, zir_inst), | 187 | .optional_payload_unsafe => try sema.zirOptionalPayload(block, inst, false), |
| 162 | .mod_rem => try sema.zirArithmetic(block, zir_inst), | 188 | .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, inst, false), |
| 163 | .array_cat => try sema.zirArrayCat(block, zir_inst), | 189 | .optional_type => try sema.zirOptionalType(block, inst), |
| 164 | .array_mul => try sema.zirArrayMul(block, zir_inst), | 190 | .optional_type_from_ptr_elem => try sema.zirOptionalTypeFromPtrElem(block, inst), |
| 165 | .bit_and => try sema.zirBitwise(block, zir_inst), | 191 | .param_type => try sema.zirParamType(block, inst), |
| 166 | .bit_not => try sema.zirBitNot(block, zir_inst), | 192 | .ptr_type => try sema.zirPtrType(block, inst), |
| 167 | .bit_or => try sema.zirBitwise(block, zir_inst), | 193 | .ptr_type_simple => try sema.zirPtrTypeSimple(block, inst), |
| 168 | .xor => try sema.zirBitwise(block, zir_inst), | 194 | .ptrtoint => try sema.zirPtrtoint(block, inst), |
| 169 | .shl => try sema.zirShl(block, zir_inst), | 195 | .ref => try sema.zirRef(block, inst), |
| 170 | .shr => try sema.zirShr(block, zir_inst), | 196 | .ret_ptr => try sema.zirRetPtr(block, inst), |
| 171 | .cmp_lt => try sema.zirCmp(block, zir_inst, .lt), | 197 | .ret_type => try sema.zirRetType(block, inst), |
| 172 | .cmp_lte => try sema.zirCmp(block, zir_inst, .lte), | 198 | .shl => try sema.zirShl(block, inst), |
| 173 | .cmp_eq => try sema.zirCmp(block, zir_inst, .eq), | 199 | .shr => try sema.zirShr(block, inst), |
| 174 | .cmp_gte => try sema.zirCmp(block, zir_inst, .gte), | 200 | .slice_end => try sema.zirSliceEnd(block, inst), |
| 175 | .cmp_gt => try sema.zirCmp(block, zir_inst, .gt), | 201 | .slice_sentinel => try sema.zirSliceSentinel(block, inst), |
| 176 | .cmp_neq => try sema.zirCmp(block, zir_inst, .neq), | 202 | .slice_start => try sema.zirSliceStart(block, inst), |
| 177 | .condbr => try sema.zirCondbr(block, zir_inst), | 203 | .str => try sema.zirStr(block, inst), |
| 178 | .is_null => try sema.zirIsNull(block, zir_inst, false), | 204 | .sub => try sema.zirArithmetic(block, inst), |
| 179 | .is_non_null => try sema.zirIsNull(block, zir_inst, true), | 205 | .subwrap => try sema.zirArithmetic(block, inst), |
| 180 | .is_null_ptr => try sema.zirIsNullPtr(block, zir_inst, false), | 206 | .typeof => try sema.zirTypeof(block, inst), |
| 181 | .is_non_null_ptr => try sema.zirIsNullPtr(block, zir_inst, true), | 207 | .typeof_peer => try sema.zirTypeofPeer(block, inst), |
| 182 | .is_err => try sema.zirIsErr(block, zir_inst), | 208 | .xor => try sema.zirBitwise(block, inst), |
| 183 | .is_err_ptr => try sema.zirIsErrPtr(block, zir_inst), | | |
| 184 | .bool_not => try sema.zirBoolNot(block, zir_inst), | | |
| 185 | .typeof => try sema.zirTypeof(block, zir_inst), | | |
| 186 | .typeof_peer => try sema.zirTypeofPeer(block, zir_inst), | | |
| 187 | .optional_type => try sema.zirOptionalType(block, zir_inst), | | |
| 188 | .optional_type_from_ptr_elem => try sema.zirOptionalTypeFromPtrElem(block, zir_inst), | | |
| 189 | .optional_payload_safe => try sema.zirOptionalPayload(block, zir_inst, true), | | |
| 190 | .optional_payload_unsafe => try sema.zirOptionalPayload(block, zir_inst, false), | | |
| 191 | .optional_payload_safe_ptr => try sema.zirOptionalPayloadPtr(block, zir_inst, true), | | |
| 192 | .optional_payload_unsafe_ptr => try sema.zirOptionalPayloadPtr(block, zir_inst, false), | | |
| 193 | .err_union_payload_safe => try sema.zirErrUnionPayload(block, zir_inst, true), | | |
| 194 | .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, zir_inst, false), | | |
| 195 | .err_union_payload_safe_ptr => try sema.zirErrUnionPayloadPtr(block, zir_inst, true), | | |
| 196 | .err_union_payload_unsafe_ptr => try sema.zirErrUnionPayloadPtr(block, zir_inst, false), | | |
| 197 | .err_union_code => try sema.zirErrUnionCode(block, zir_inst), | | |
| 198 | .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, zir_inst), | | |
| 199 | .ensure_err_payload_void => try sema.zirEnsureErrPayloadVoid(block, zir_inst), | | |
| 200 | .array_type => try sema.zirArrayType(block, zir_inst), | | |
| 201 | .array_type_sentinel => try sema.zirArrayTypeSentinel(block, zir_inst), | | |
| 202 | .enum_literal => try sema.zirEnumLiteral(block, zir_inst), | | |
| 203 | .enum_literal_small => try sema.zirEnumLiteralSmall(block, zir_inst), | | |
| 204 | .merge_error_sets => try sema.zirMergeErrorSets(block, zir_inst), | | |
| 205 | .error_union_type => try sema.zirErrorUnionType(block, zir_inst), | | |
| 206 | .error_set => try sema.zirErrorSet(block, zir_inst), | | |
| 207 | .error_value => try sema.zirErrorValue(block, zir_inst), | | |
| 208 | .slice_start => try sema.zirSliceStart(block, zir_inst), | | |
| 209 | .slice_end => try sema.zirSliceEnd(block, zir_inst), | | |
| 210 | .slice_sentinel => try sema.zirSliceSentinel(block, zir_inst), | | |
| 211 | .import => try sema.zirImport(block, zir_inst), | | |
| 212 | .bool_and => try sema.zirBoolOp(block, zir_inst, false), | | |
| 213 | .bool_or => try sema.zirBoolOp(block, zir_inst, true), | | |
| 214 | // TODO | 209 | // TODO |
| 215 | //.switchbr => try sema.zirSwitchBr(block, zir_inst, false), | 210 | //.switchbr => try sema.zirSwitchBr(block, inst, false), |
| 216 | //.switchbr_ref => try sema.zirSwitchBr(block, zir_inst, true), | 211 | //.switchbr_ref => try sema.zirSwitchBr(block, inst, true), |
| 217 | //.switch_range => try sema.zirSwitchRange(block, zir_inst), | 212 | //.switch_range => try sema.zirSwitchRange(block, inst), |
| | 213 | |
| | 214 | // Instructions that we know to *always* be noreturn based solely on their tag. |
| | 215 | // These functions match the return type of analyzeBody so that we can |
| | 216 | // tail call them here. |
| | 217 | .condbr => return sema.zirCondbr(block, inst), |
| | 218 | .@"break" => return sema.zirBreak(block, inst), |
| | 219 | .break_void_tok => return sema.zirBreakVoidTok(block, inst), |
| | 220 | .break_flat => return sema.code.instructions.items(.data)[inst].un_node.operand, |
| | 221 | .compile_error => return sema.zirCompileError(block, inst), |
| | 222 | .ret_coerce => return sema.zirRetTok(block, inst, true), |
| | 223 | .ret_node => return sema.zirRetNode(block, inst), |
| | 224 | .ret_tok => return sema.zirRetTok(block, inst, false), |
| | 225 | .@"unreachable" => return sema.zirUnreachable(block, inst), |
| | 226 | .loop => return sema.zirLoop(block, inst), |
| | 227 | |
| | 228 | // Instructions that we know can *never* be noreturn based solely on |
| | 229 | // their tag. We avoid needlessly checking if they are noreturn and |
| | 230 | // continue the loop. |
| | 231 | // We also know that they cannot be referenced later, so we avoid |
| | 232 | // putting them into the map. |
| | 233 | .breakpoint => { |
| | 234 | try sema.zirBreakpoint(block, inst); |
| | 235 | continue; |
| | 236 | }, |
| | 237 | .dbg_stmt_node => { |
| | 238 | try sema.zirDbgStmtNode(block, inst); |
| | 239 | continue; |
| | 240 | }, |
| | 241 | .ensure_err_payload_void => { |
| | 242 | try sema.zirEnsureErrPayloadVoid(block, inst); |
| | 243 | continue; |
| | 244 | }, |
| | 245 | .ensure_result_non_error => { |
| | 246 | try sema.zirEnsureResultNonError(block, inst); |
| | 247 | continue; |
| | 248 | }, |
| | 249 | .ensure_result_used => { |
| | 250 | try sema.zirEnsureResultUsed(block, inst); |
| | 251 | continue; |
| | 252 | }, |
| | 253 | .compile_log => { |
| | 254 | try sema.zirCompileLog(block, inst); |
| | 255 | continue; |
| | 256 | }, |
| | 257 | .set_eval_branch_quota => { |
| | 258 | try sema.zirSetEvalBranchQuota(block, inst); |
| | 259 | continue; |
| | 260 | }, |
| | 261 | .store => { |
| | 262 | try sema.zirStore(block, inst); |
| | 263 | continue; |
| | 264 | }, |
| | 265 | .store_to_block_ptr => { |
| | 266 | try sema.zirStoreToBlockPtr(block, inst); |
| | 267 | continue; |
| | 268 | }, |
| | 269 | .store_to_inferred_ptr => { |
| | 270 | try sema.zirStoreToInferredPtr(block, inst); |
| | 271 | continue; |
| | 272 | }, |
| | 273 | .resolve_inferred_alloc => { |
| | 274 | try sema.zirResolveInferredAlloc(block, inst); |
| | 275 | continue; |
| | 276 | }, |
| 218 | }; | 277 | }; |
| 219 | if (map[zir_inst].ty.isNoReturn()) { | 278 | if (map[inst].ty.isNoReturn()) |
| 220 | break; | 279 | return always_noreturn; |
| 221 | } | | |
| 222 | } | 280 | } |
| 223 | } | 281 | } |
| 224 | | 282 | |
| ... | @@ -392,7 +450,7 @@ fn zirRetType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError | ... | @@ -392,7 +450,7 @@ fn zirRetType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError |
| 392 | return sema.mod.constType(sema.arena, src, ret_type); | 450 | return sema.mod.constType(sema.arena, src, ret_type); |
| 393 | } | 451 | } |
| 394 | | 452 | |
| 395 | fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 453 | fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 396 | const tracy = trace(@src()); | 454 | const tracy = trace(@src()); |
| 397 | defer tracy.end(); | 455 | defer tracy.end(); |
| 398 | | 456 | |
| ... | @@ -400,12 +458,12 @@ fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) I | ... | @@ -400,12 +458,12 @@ fn zirEnsureResultUsed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) I |
| 400 | const operand = try sema.resolveInst(inst_data.operand); | 458 | const operand = try sema.resolveInst(inst_data.operand); |
| 401 | const src = inst_data.src(); | 459 | const src = inst_data.src(); |
| 402 | switch (operand.ty.zigTypeTag()) { | 460 | switch (operand.ty.zigTypeTag()) { |
| 403 | .Void, .NoReturn => return sema.mod.constVoid(sema.arena, .unneeded), | 461 | .Void, .NoReturn => return, |
| 404 | else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}), | 462 | else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}), |
| 405 | } | 463 | } |
| 406 | } | 464 | } |
| 407 | | 465 | |
| 408 | fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 466 | fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 409 | const tracy = trace(@src()); | 467 | const tracy = trace(@src()); |
| 410 | defer tracy.end(); | 468 | defer tracy.end(); |
| 411 | | 469 | |
| ... | @@ -414,7 +472,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde | ... | @@ -414,7 +472,7 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde |
| 414 | const src = inst_data.src(); | 472 | const src = inst_data.src(); |
| 415 | switch (operand.ty.zigTypeTag()) { | 473 | switch (operand.ty.zigTypeTag()) { |
| 416 | .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}), | 474 | .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}), |
| 417 | else => return sema.mod.constVoid(sema.arena, .unneeded), | 475 | else => return, |
| 418 | } | 476 | } |
| 419 | } | 477 | } |
| 420 | | 478 | |
| ... | @@ -508,11 +566,7 @@ fn zirAllocInferred( | ... | @@ -508,11 +566,7 @@ fn zirAllocInferred( |
| 508 | return result; | 566 | return result; |
| 509 | } | 567 | } |
| 510 | | 568 | |
| 511 | fn zirResolveInferredAlloc( | 569 | fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 512 | sema: *Sema, | | |
| 513 | block: *Scope.Block, | | |
| 514 | inst: zir.Inst.Index, | | |
| 515 | ) InnerError!*Inst { | | |
| 516 | const tracy = trace(@src()); | 570 | const tracy = trace(@src()); |
| 517 | defer tracy.end(); | 571 | defer tracy.end(); |
| 518 | | 572 | |
| ... | @@ -536,15 +590,9 @@ fn zirResolveInferredAlloc( | ... | @@ -536,15 +590,9 @@ fn zirResolveInferredAlloc( |
| 536 | // Change it to a normal alloc. | 590 | // Change it to a normal alloc. |
| 537 | ptr.ty = final_ptr_ty; | 591 | ptr.ty = final_ptr_ty; |
| 538 | ptr.tag = .alloc; | 592 | ptr.tag = .alloc; |
| 539 | | | |
| 540 | return sema.mod.constVoid(sema.arena, .unneeded); | | |
| 541 | } | 593 | } |
| 542 | | 594 | |
| 543 | fn zirStoreToBlockPtr( | 595 | fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 544 | sema: *Sema, | | |
| 545 | block: *Scope.Block, | | |
| 546 | inst: zir.Inst.Index, | | |
| 547 | ) InnerError!*Inst { | | |
| 548 | const tracy = trace(@src()); | 596 | const tracy = trace(@src()); |
| 549 | defer tracy.end(); | 597 | defer tracy.end(); |
| 550 | | 598 | |
| ... | @@ -560,11 +608,7 @@ fn zirStoreToBlockPtr( | ... | @@ -560,11 +608,7 @@ fn zirStoreToBlockPtr( |
| 560 | return sema.storePtr(block, src, bitcasted_ptr, value); | 608 | return sema.storePtr(block, src, bitcasted_ptr, value); |
| 561 | } | 609 | } |
| 562 | | 610 | |
| 563 | fn zirStoreToInferredPtr( | 611 | fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 564 | sema: *Sema, | | |
| 565 | block: *Scope.Block, | | |
| 566 | inst: zir.Inst.Index, | | |
| 567 | ) InnerError!*Inst { | | |
| 568 | const tracy = trace(@src()); | 612 | const tracy = trace(@src()); |
| 569 | defer tracy.end(); | 613 | defer tracy.end(); |
| 570 | | 614 | |
| ... | @@ -583,21 +627,16 @@ fn zirStoreToInferredPtr( | ... | @@ -583,21 +627,16 @@ fn zirStoreToInferredPtr( |
| 583 | return sema.storePtr(block, src, bitcasted_ptr, value); | 627 | return sema.storePtr(block, src, bitcasted_ptr, value); |
| 584 | } | 628 | } |
| 585 | | 629 | |
| 586 | fn zirSetEvalBranchQuota( | 630 | fn zirSetEvalBranchQuota(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 587 | sema: *Sema, | | |
| 588 | block: *Scope.Block, | | |
| 589 | inst: zir.Inst.Index, | | |
| 590 | ) InnerError!*Inst { | | |
| 591 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 631 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 592 | const src = inst_data.src(); | 632 | const src = inst_data.src(); |
| 593 | try sema.requireFunctionBlock(block, src); | 633 | try sema.requireFunctionBlock(block, src); |
| 594 | const quota = try sema.resolveAlreadyCoercedInt(block, src, inst_data.operand, u32); | 634 | const quota = try sema.resolveAlreadyCoercedInt(block, src, inst_data.operand, u32); |
| 595 | if (sema.branch_quota < quota) | 635 | if (sema.branch_quota < quota) |
| 596 | sema.branch_quota = quota; | 636 | sema.branch_quota = quota; |
| 597 | return sema.mod.constVoid(sema.arena, .unneeded); | | |
| 598 | } | 637 | } |
| 599 | | 638 | |
| 600 | fn zirStore(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 639 | fn zirStore(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 601 | const tracy = trace(@src()); | 640 | const tracy = trace(@src()); |
| 602 | defer tracy.end(); | 641 | defer tracy.end(); |
| 603 | | 642 | |
| ... | @@ -677,7 +716,7 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*In | ... | @@ -677,7 +716,7 @@ fn zirInt(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*In |
| 677 | return sema.mod.constIntUnsigned(sema.arena, .unneeded, Type.initTag(.comptime_int), int); | 716 | return sema.mod.constIntUnsigned(sema.arena, .unneeded, Type.initTag(.comptime_int), int); |
| 678 | } | 717 | } |
| 679 | | 718 | |
| 680 | fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 719 | fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!zir.Inst.Index { |
| 681 | const tracy = trace(@src()); | 720 | const tracy = trace(@src()); |
| 682 | defer tracy.end(); | 721 | defer tracy.end(); |
| 683 | | 722 | |
| ... | @@ -688,7 +727,7 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner | ... | @@ -688,7 +727,7 @@ fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) Inner |
| 688 | return sema.mod.fail(&block.base, src, "{s}", .{msg}); | 727 | return sema.mod.fail(&block.base, src, "{s}", .{msg}); |
| 689 | } | 728 | } |
| 690 | | 729 | |
| 691 | fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 730 | fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 692 | var managed = sema.mod.compile_log_text.toManaged(sema.gpa); | 731 | var managed = sema.mod.compile_log_text.toManaged(sema.gpa); |
| 693 | defer sema.mod.compile_log_text = managed.moveToUnmanaged(); | 732 | defer sema.mod.compile_log_text = managed.moveToUnmanaged(); |
| 694 | const writer = managed.writer(); | 733 | const writer = managed.writer(); |
| ... | @@ -711,10 +750,9 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr | ... | @@ -711,10 +750,9 @@ fn zirCompileLog(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerEr |
| 711 | if (!gop.found_existing) { | 750 | if (!gop.found_existing) { |
| 712 | gop.entry.value = inst_data.src().toSrcLoc(&block.base); | 751 | gop.entry.value = inst_data.src().toSrcLoc(&block.base); |
| 713 | } | 752 | } |
| 714 | return sema.mod.constVoid(sema.arena, .unneeded); | | |
| 715 | } | 753 | } |
| 716 | | 754 | |
| 717 | fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 755 | fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!zir.Inst.Ref { |
| 718 | const tracy = trace(@src()); | 756 | const tracy = trace(@src()); |
| 719 | defer tracy.end(); | 757 | defer tracy.end(); |
| 720 | | 758 | |
| ... | @@ -746,41 +784,13 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE | ... | @@ -746,41 +784,13 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerE |
| 746 | }; | 784 | }; |
| 747 | defer child_block.instructions.deinit(sema.gpa); | 785 | defer child_block.instructions.deinit(sema.gpa); |
| 748 | | 786 | |
| 749 | try sema.analyzeBody(&child_block, body); | 787 | _ = try sema.analyzeBody(&child_block, body); |
| 750 | | 788 | |
| 751 | // Loop repetition is implied so the last instruction may or may not be a noreturn instruction. | 789 | // Loop repetition is implied so the last instruction may or may not be a noreturn instruction. |
| 752 | | 790 | |
| 753 | try parent_block.instructions.append(sema.gpa, &loop_inst.base); | 791 | try parent_block.instructions.append(sema.gpa, &loop_inst.base); |
| 754 | loop_inst.body = .{ .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items) }; | 792 | loop_inst.body = .{ .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items) }; |
| 755 | return &loop_inst.base; | 793 | return always_noreturn; |
| 756 | } | | |
| 757 | | | |
| 758 | fn zirBlockFlat( | | |
| 759 | sema: *Sema, | | |
| 760 | parent_block: *Scope.Block, | | |
| 761 | inst: zir.Inst.Index, | | |
| 762 | is_comptime: bool, | | |
| 763 | ) InnerError!*Inst { | | |
| 764 | const tracy = trace(@src()); | | |
| 765 | defer tracy.end(); | | |
| 766 | | | |
| 767 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | | |
| 768 | const src = inst_data.src(); | | |
| 769 | const extra = sema.code.extraData(zir.Inst.MultiOp, inst_data.payload_index); | | |
| 770 | const body = sema.code.extra[extra.end..][0..extra.data.operands_len]; | | |
| 771 | | | |
| 772 | var child_block = parent_block.makeSubBlock(); | | |
| 773 | defer child_block.instructions.deinit(sema.gpa); | | |
| 774 | child_block.is_comptime = child_block.is_comptime or is_comptime; | | |
| 775 | | | |
| 776 | try sema.analyzeBody(&child_block, body); | | |
| 777 | | | |
| 778 | // Move the analyzed instructions into the parent block arena. | | |
| 779 | const copied_instructions = try sema.arena.dupe(*Inst, child_block.instructions.items); | | |
| 780 | try parent_block.instructions.appendSlice(sema.gpa, copied_instructions); | | |
| 781 | | | |
| 782 | // The result of a flat block is the last instruction. | | |
| 783 | return sema.inst_map[body[body.len - 1]]; | | |
| 784 | } | 794 | } |
| 785 | | 795 | |
| 786 | fn zirBlock( | 796 | fn zirBlock( |
| ... | @@ -794,8 +804,8 @@ fn zirBlock( | ... | @@ -794,8 +804,8 @@ fn zirBlock( |
| 794 | | 804 | |
| 795 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 805 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 796 | const src = inst_data.src(); | 806 | const src = inst_data.src(); |
| 797 | const extra = sema.code.extraData(zir.Inst.MultiOp, inst_data.payload_index); | 807 | const extra = sema.code.extraData(zir.Inst.Block, inst_data.payload_index); |
| 798 | const body = sema.code.extra[extra.end..][0..extra.data.operands_len]; | 808 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 799 | | 809 | |
| 800 | // Reserve space for a Block instruction so that generated Break instructions can | 810 | // Reserve space for a Block instruction so that generated Break instructions can |
| 801 | // point to it, even if it doesn't end up getting used because the code ends up being | 811 | // point to it, even if it doesn't end up getting used because the code ends up being |
| ... | @@ -833,7 +843,7 @@ fn zirBlock( | ... | @@ -833,7 +843,7 @@ fn zirBlock( |
| 833 | defer merges.results.deinit(sema.gpa); | 843 | defer merges.results.deinit(sema.gpa); |
| 834 | defer merges.br_list.deinit(sema.gpa); | 844 | defer merges.br_list.deinit(sema.gpa); |
| 835 | | 845 | |
| 836 | try sema.analyzeBody(&child_block, body); | 846 | _ = try sema.analyzeBody(&child_block, body); |
| 837 | | 847 | |
| 838 | return sema.analyzeBlockBody(parent_block, &child_block, merges); | 848 | return sema.analyzeBlockBody(parent_block, &child_block, merges); |
| 839 | } | 849 | } |
| ... | @@ -919,17 +929,17 @@ fn analyzeBlockBody( | ... | @@ -919,17 +929,17 @@ fn analyzeBlockBody( |
| 919 | return &merges.block_inst.base; | 929 | return &merges.block_inst.base; |
| 920 | } | 930 | } |
| 921 | | 931 | |
| 922 | fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 932 | fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 923 | const tracy = trace(@src()); | 933 | const tracy = trace(@src()); |
| 924 | defer tracy.end(); | 934 | defer tracy.end(); |
| 925 | | 935 | |
| 926 | const src_node = sema.code.instructions.items(.data)[inst].node; | 936 | const src_node = sema.code.instructions.items(.data)[inst].node; |
| 927 | const src: LazySrcLoc = .{ .node_offset = src_node }; | 937 | const src: LazySrcLoc = .{ .node_offset = src_node }; |
| 928 | try sema.requireRuntimeBlock(block, src); | 938 | try sema.requireRuntimeBlock(block, src); |
| 929 | return block.addNoOp(src, Type.initTag(.void), .breakpoint); | 939 | _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint); |
| 930 | } | 940 | } |
| 931 | | 941 | |
| 932 | fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 942 | fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!zir.Inst.Index { |
| 933 | const tracy = trace(@src()); | 943 | const tracy = trace(@src()); |
| 934 | defer tracy.end(); | 944 | defer tracy.end(); |
| 935 | | 945 | |
| ... | @@ -939,7 +949,7 @@ fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!* | ... | @@ -939,7 +949,7 @@ fn zirBreak(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!* |
| 939 | return sema.analyzeBreak(block, sema.src, zir_block, operand); | 949 | return sema.analyzeBreak(block, sema.src, zir_block, operand); |
| 940 | } | 950 | } |
| 941 | | 951 | |
| 942 | fn zirBreakVoidTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 952 | fn zirBreakVoidTok(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!zir.Inst.Index { |
| 943 | const tracy = trace(@src()); | 953 | const tracy = trace(@src()); |
| 944 | defer tracy.end(); | 954 | defer tracy.end(); |
| 945 | | 955 | |
| ... | @@ -955,7 +965,7 @@ fn analyzeBreak( | ... | @@ -955,7 +965,7 @@ fn analyzeBreak( |
| 955 | src: LazySrcLoc, | 965 | src: LazySrcLoc, |
| 956 | zir_block: zir.Inst.Index, | 966 | zir_block: zir.Inst.Index, |
| 957 | operand: *Inst, | 967 | operand: *Inst, |
| 958 | ) InnerError!*Inst { | 968 | ) InnerError!zir.Inst.Ref { |
| 959 | var block = start_block; | 969 | var block = start_block; |
| 960 | while (true) { | 970 | while (true) { |
| 961 | if (block.label) |*label| { | 971 | if (block.label) |*label| { |
| ... | @@ -981,26 +991,24 @@ fn analyzeBreak( | ... | @@ -981,26 +991,24 @@ fn analyzeBreak( |
| 981 | try block.instructions.append(sema.gpa, &br.base); | 991 | try block.instructions.append(sema.gpa, &br.base); |
| 982 | try label.merges.results.append(sema.gpa, operand); | 992 | try label.merges.results.append(sema.gpa, operand); |
| 983 | try label.merges.br_list.append(sema.gpa, br); | 993 | try label.merges.br_list.append(sema.gpa, br); |
| 984 | return &br.base; | 994 | return always_noreturn; |
| 985 | } | 995 | } |
| 986 | } | 996 | } |
| 987 | block = block.parent.?; | 997 | block = block.parent.?; |
| 988 | } | 998 | } |
| 989 | } | 999 | } |
| 990 | | 1000 | |
| 991 | fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 1001 | fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 992 | const tracy = trace(@src()); | 1002 | const tracy = trace(@src()); |
| 993 | defer tracy.end(); | 1003 | defer tracy.end(); |
| 994 | | 1004 | |
| 995 | if (block.is_comptime) { | 1005 | if (block.is_comptime) return; |
| 996 | return sema.mod.constVoid(sema.arena, .unneeded); | | |
| 997 | } | | |
| 998 | | 1006 | |
| 999 | const src_node = sema.code.instructions.items(.data)[inst].node; | 1007 | const src_node = sema.code.instructions.items(.data)[inst].node; |
| 1000 | const src: LazySrcLoc = .{ .node_offset = src_node }; | 1008 | const src: LazySrcLoc = .{ .node_offset = src_node }; |
| 1001 | const src_loc = src.toSrcLoc(&block.base); | 1009 | const src_loc = src.toSrcLoc(&block.base); |
| 1002 | const abs_byte_off = try src_loc.byteOffset(); | 1010 | const abs_byte_off = try src_loc.byteOffset(); |
| 1003 | return block.addDbgStmt(src, abs_byte_off); | 1011 | _ = try block.addDbgStmt(src, abs_byte_off); |
| 1004 | } | 1012 | } |
| 1005 | | 1013 | |
| 1006 | fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 1014 | fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { |
| ... | @@ -1185,7 +1193,7 @@ fn analyzeCall( | ... | @@ -1185,7 +1193,7 @@ fn analyzeCall( |
| 1185 | | 1193 | |
| 1186 | // This will have return instructions analyzed as break instructions to | 1194 | // This will have return instructions analyzed as break instructions to |
| 1187 | // the block_inst above. | 1195 | // the block_inst above. |
| 1188 | try sema.root(&child_block); | 1196 | _ = try sema.root(&child_block); |
| 1189 | | 1197 | |
| 1190 | return sema.analyzeBlockBody(block, &child_block, merges); | 1198 | return sema.analyzeBlockBody(block, &child_block, merges); |
| 1191 | } | 1199 | } |
| ... | @@ -1638,7 +1646,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In | ... | @@ -1638,7 +1646,7 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) In |
| 1638 | return block.addUnOp(src, operand.ty.castTag(.error_union).?.data.payload, .unwrap_errunion_err_ptr, operand); | 1646 | return block.addUnOp(src, operand.ty.castTag(.error_union).?.data.payload, .unwrap_errunion_err_ptr, operand); |
| 1639 | } | 1647 | } |
| 1640 | | 1648 | |
| 1641 | fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 1649 | fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!void { |
| 1642 | const tracy = trace(@src()); | 1650 | const tracy = trace(@src()); |
| 1643 | defer tracy.end(); | 1651 | defer tracy.end(); |
| 1644 | | 1652 | |
| ... | @@ -1650,7 +1658,6 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde | ... | @@ -1650,7 +1658,6 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Inde |
| 1650 | if (operand.ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) { | 1658 | if (operand.ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) { |
| 1651 | return sema.mod.fail(&block.base, src, "expression value is ignored", .{}); | 1659 | return sema.mod.fail(&block.base, src, "expression value is ignored", .{}); |
| 1652 | } | 1660 | } |
| 1653 | return sema.mod.constVoid(sema.arena, .unneeded); | | |
| 1654 | } | 1661 | } |
| 1655 | | 1662 | |
| 1656 | fn zirFnType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: bool) InnerError!*Inst { | 1663 | fn zirFnType(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index, var_args: bool) InnerError!*Inst { |
| ... | @@ -2067,7 +2074,7 @@ fn zirSwitchBr( | ... | @@ -2067,7 +2074,7 @@ fn zirSwitchBr( |
| 2067 | parent_block: *Scope.Block, | 2074 | parent_block: *Scope.Block, |
| 2068 | inst: zir.Inst.Index, | 2075 | inst: zir.Inst.Index, |
| 2069 | ref: bool, | 2076 | ref: bool, |
| 2070 | ) InnerError!*Inst { | 2077 | ) InnerError!zir.Inst.Ref { |
| 2071 | const tracy = trace(@src()); | 2078 | const tracy = trace(@src()); |
| 2072 | defer tracy.end(); | 2079 | defer tracy.end(); |
| 2073 | | 2080 | |
| ... | @@ -2087,18 +2094,18 @@ fn zirSwitchBr( | ... | @@ -2087,18 +2094,18 @@ fn zirSwitchBr( |
| 2087 | const item = try sema.resolveConstValue(parent_block, case_src, casted); | 2094 | const item = try sema.resolveConstValue(parent_block, case_src, casted); |
| 2088 | | 2095 | |
| 2089 | if (target_val.eql(item)) { | 2096 | if (target_val.eql(item)) { |
| 2090 | try sema.analyzeBody(parent_block, case.body); | 2097 | _ = try sema.analyzeBody(parent_block, case.body); |
| 2091 | return sema.mod.constNoReturn(sema.arena, inst.base.src); | 2098 | return always_noreturn; |
| 2092 | } | 2099 | } |
| 2093 | } | 2100 | } |
| 2094 | try sema.analyzeBody(parent_block, inst.positionals.else_body); | 2101 | _ = try sema.analyzeBody(parent_block, inst.positionals.else_body); |
| 2095 | return sema.mod.constNoReturn(sema.arena, inst.base.src); | 2102 | return always_noreturn; |
| 2096 | } | 2103 | } |
| 2097 | | 2104 | |
| 2098 | if (inst.positionals.cases.len == 0) { | 2105 | if (inst.positionals.cases.len == 0) { |
| 2099 | // no cases just analyze else_branch | 2106 | // no cases just analyze else_branch |
| 2100 | try sema.analyzeBody(parent_block, inst.positionals.else_body); | 2107 | _ = try sema.analyzeBody(parent_block, inst.positionals.else_body); |
| 2101 | return sema.mod.constNoReturn(sema.arena, inst.base.src); | 2108 | return always_noreturn; |
| 2102 | } | 2109 | } |
| 2103 | | 2110 | |
| 2104 | try sema.requireRuntimeBlock(parent_block, inst.base.src); | 2111 | try sema.requireRuntimeBlock(parent_block, inst.base.src); |
| ... | @@ -2122,7 +2129,7 @@ fn zirSwitchBr( | ... | @@ -2122,7 +2129,7 @@ fn zirSwitchBr( |
| 2122 | const casted = try sema.coerce(block, target.ty, resolved, resolved_src); | 2129 | const casted = try sema.coerce(block, target.ty, resolved, resolved_src); |
| 2123 | const item = try sema.resolveConstValue(parent_block, case_src, casted); | 2130 | const item = try sema.resolveConstValue(parent_block, case_src, casted); |
| 2124 | | 2131 | |
| 2125 | try sema.analyzeBody(&case_block, case.body); | 2132 | _ = try sema.analyzeBody(&case_block, case.body); |
| 2126 | | 2133 | |
| 2127 | cases[i] = .{ | 2134 | cases[i] = .{ |
| 2128 | .item = item, | 2135 | .item = item, |
| ... | @@ -2131,7 +2138,7 @@ fn zirSwitchBr( | ... | @@ -2131,7 +2138,7 @@ fn zirSwitchBr( |
| 2131 | } | 2138 | } |
| 2132 | | 2139 | |
| 2133 | case_block.instructions.items.len = 0; | 2140 | case_block.instructions.items.len = 0; |
| 2134 | try sema.analyzeBody(&case_block, inst.positionals.else_body); | 2141 | _ = try sema.analyzeBody(&case_block, inst.positionals.else_body); |
| 2135 | | 2142 | |
| 2136 | const else_body: ir.Body = .{ | 2143 | const else_body: ir.Body = .{ |
| 2137 | .instructions = try sema.arena.dupe(*Inst, case_block.instructions.items), | 2144 | .instructions = try sema.arena.dupe(*Inst, case_block.instructions.items), |
| ... | @@ -2719,6 +2726,75 @@ fn zirBoolOp( | ... | @@ -2719,6 +2726,75 @@ fn zirBoolOp( |
| 2719 | return block.addBinOp(src, bool_type, tag, lhs, rhs); | 2726 | return block.addBinOp(src, bool_type, tag, lhs, rhs); |
| 2720 | } | 2727 | } |
| 2721 | | 2728 | |
| | 2729 | fn zirBoolBr( |
| | 2730 | sema: *Sema, |
| | 2731 | parent_block: *Scope.Block, |
| | 2732 | inst: zir.Inst.Index, |
| | 2733 | is_bool_or: bool, |
| | 2734 | ) InnerError!*Inst { |
| | 2735 | const tracy = trace(@src()); |
| | 2736 | defer tracy.end(); |
| | 2737 | |
| | 2738 | const inst_data = sema.code.instructions.items(.data)[inst].bool_br; |
| | 2739 | const src: LazySrcLoc = .unneeded; |
| | 2740 | const lhs = try sema.resolveInst(inst_data.lhs); |
| | 2741 | const extra = sema.code.extraData(zir.Inst.Block, inst_data.payload_index); |
| | 2742 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| | 2743 | |
| | 2744 | if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| { |
| | 2745 | if (lhs_val.toBool() == is_bool_or) { |
| | 2746 | return sema.mod.constBool(sema.arena, src, is_bool_or); |
| | 2747 | } |
| | 2748 | // comptime-known left-hand side. No need for a block here; the result |
| | 2749 | // is simply the rhs expression. Here we rely on there only being 1 |
| | 2750 | // break instruction (`break_flat`). |
| | 2751 | const zir_inst_ref = try sema.analyzeBody(parent_block, body); |
| | 2752 | return sema.resolveInst(zir_inst_ref); |
| | 2753 | } |
| | 2754 | |
| | 2755 | const block_inst = try sema.arena.create(Inst.Block); |
| | 2756 | block_inst.* = .{ |
| | 2757 | .base = .{ |
| | 2758 | .tag = Inst.Block.base_tag, |
| | 2759 | .ty = Type.initTag(.bool), |
| | 2760 | .src = src, |
| | 2761 | }, |
| | 2762 | .body = undefined, |
| | 2763 | }; |
| | 2764 | |
| | 2765 | var child_block = parent_block.makeSubBlock(); |
| | 2766 | defer child_block.instructions.deinit(sema.gpa); |
| | 2767 | |
| | 2768 | var then_block = child_block.makeSubBlock(); |
| | 2769 | defer then_block.instructions.deinit(sema.gpa); |
| | 2770 | |
| | 2771 | var else_block = child_block.makeSubBlock(); |
| | 2772 | defer else_block.instructions.deinit(sema.gpa); |
| | 2773 | |
| | 2774 | const lhs_block = if (is_bool_or) &then_block else &else_block; |
| | 2775 | const rhs_block = if (is_bool_or) &else_block else &then_block; |
| | 2776 | |
| | 2777 | const lhs_result = try sema.mod.constInst(sema.arena, src, .{ |
| | 2778 | .ty = Type.initTag(.bool), |
| | 2779 | .val = if (is_bool_or) Value.initTag(.bool_true) else Value.initTag(.bool_false), |
| | 2780 | }); |
| | 2781 | _ = try lhs_block.addBr(src, block_inst, lhs_result); |
| | 2782 | |
| | 2783 | const rhs_result_zir_ref = try sema.analyzeBody(rhs_block, body); |
| | 2784 | const rhs_result = try sema.resolveInst(rhs_result_zir_ref); |
| | 2785 | _ = try rhs_block.addBr(src, block_inst, rhs_result); |
| | 2786 | |
| | 2787 | const tzir_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, then_block.instructions.items) }; |
| | 2788 | const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, rhs_block.instructions.items) }; |
| | 2789 | _ = try child_block.addCondBr(src, lhs, tzir_then_body, tzir_else_body); |
| | 2790 | |
| | 2791 | block_inst.body = .{ |
| | 2792 | .instructions = try sema.arena.dupe(*Inst, child_block.instructions.items), |
| | 2793 | }; |
| | 2794 | try parent_block.instructions.append(sema.gpa, &block_inst.base); |
| | 2795 | return &block_inst.base; |
| | 2796 | } |
| | 2797 | |
| 2722 | fn zirIsNull( | 2798 | fn zirIsNull( |
| 2723 | sema: *Sema, | 2799 | sema: *Sema, |
| 2724 | block: *Scope.Block, | 2800 | block: *Scope.Block, |
| ... | @@ -2770,7 +2846,11 @@ fn zirIsErrPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro | ... | @@ -2770,7 +2846,11 @@ fn zirIsErrPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro |
| 2770 | return sema.analyzeIsErr(block, src, loaded); | 2846 | return sema.analyzeIsErr(block, src, loaded); |
| 2771 | } | 2847 | } |
| 2772 | | 2848 | |
| 2773 | fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 2849 | fn zirCondbr( |
| | 2850 | sema: *Sema, |
| | 2851 | parent_block: *Scope.Block, |
| | 2852 | inst: zir.Inst.Index, |
| | 2853 | ) InnerError!zir.Inst.Ref { |
| 2774 | const tracy = trace(@src()); | 2854 | const tracy = trace(@src()); |
| 2775 | defer tracy.end(); | 2855 | defer tracy.end(); |
| 2776 | | 2856 | |
| ... | @@ -2787,8 +2867,8 @@ fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inne | ... | @@ -2787,8 +2867,8 @@ fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inne |
| 2787 | | 2867 | |
| 2788 | if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| { | 2868 | if (try sema.resolveDefinedValue(parent_block, src, cond)) |cond_val| { |
| 2789 | const body = if (cond_val.toBool()) then_body else else_body; | 2869 | const body = if (cond_val.toBool()) then_body else else_body; |
| 2790 | try sema.analyzeBody(parent_block, body); | 2870 | _ = try sema.analyzeBody(parent_block, body); |
| 2791 | return sema.mod.constNoReturn(sema.arena, src); | 2871 | return always_noreturn; |
| 2792 | } | 2872 | } |
| 2793 | | 2873 | |
| 2794 | var true_block: Scope.Block = .{ | 2874 | var true_block: Scope.Block = .{ |
| ... | @@ -2800,7 +2880,7 @@ fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inne | ... | @@ -2800,7 +2880,7 @@ fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inne |
| 2800 | .is_comptime = parent_block.is_comptime, | 2880 | .is_comptime = parent_block.is_comptime, |
| 2801 | }; | 2881 | }; |
| 2802 | defer true_block.instructions.deinit(sema.gpa); | 2882 | defer true_block.instructions.deinit(sema.gpa); |
| 2803 | try sema.analyzeBody(&true_block, then_body); | 2883 | _ = try sema.analyzeBody(&true_block, then_body); |
| 2804 | | 2884 | |
| 2805 | var false_block: Scope.Block = .{ | 2885 | var false_block: Scope.Block = .{ |
| 2806 | .parent = parent_block, | 2886 | .parent = parent_block, |
| ... | @@ -2811,14 +2891,15 @@ fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inne | ... | @@ -2811,14 +2891,15 @@ fn zirCondbr(sema: *Sema, parent_block: *Scope.Block, inst: zir.Inst.Index) Inne |
| 2811 | .is_comptime = parent_block.is_comptime, | 2891 | .is_comptime = parent_block.is_comptime, |
| 2812 | }; | 2892 | }; |
| 2813 | defer false_block.instructions.deinit(sema.gpa); | 2893 | defer false_block.instructions.deinit(sema.gpa); |
| 2814 | try sema.analyzeBody(&false_block, else_body); | 2894 | _ = try sema.analyzeBody(&false_block, else_body); |
| 2815 | | 2895 | |
| 2816 | const tzir_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, true_block.instructions.items) }; | 2896 | const tzir_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, true_block.instructions.items) }; |
| 2817 | const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, false_block.instructions.items) }; | 2897 | const tzir_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(*Inst, false_block.instructions.items) }; |
| 2818 | return parent_block.addCondBr(src, cond, tzir_then_body, tzir_else_body); | 2898 | _ = try parent_block.addCondBr(src, cond, tzir_then_body, tzir_else_body); |
| | 2899 | return always_noreturn; |
| 2819 | } | 2900 | } |
| 2820 | | 2901 | |
| 2821 | fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 2902 | fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!zir.Inst.Ref { |
| 2822 | const tracy = trace(@src()); | 2903 | const tracy = trace(@src()); |
| 2823 | defer tracy.end(); | 2904 | defer tracy.end(); |
| 2824 | | 2905 | |
| ... | @@ -2830,7 +2911,8 @@ fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE | ... | @@ -2830,7 +2911,8 @@ fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE |
| 2830 | if (safety_check and block.wantSafety()) { | 2911 | if (safety_check and block.wantSafety()) { |
| 2831 | return sema.safetyPanic(block, src, .unreach); | 2912 | return sema.safetyPanic(block, src, .unreach); |
| 2832 | } else { | 2913 | } else { |
| 2833 | return block.addNoOp(src, Type.initTag(.noreturn), .unreach); | 2914 | _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach); |
| | 2915 | return always_noreturn; |
| 2834 | } | 2916 | } |
| 2835 | } | 2917 | } |
| 2836 | | 2918 | |
| ... | @@ -2839,7 +2921,7 @@ fn zirRetTok( | ... | @@ -2839,7 +2921,7 @@ fn zirRetTok( |
| 2839 | block: *Scope.Block, | 2921 | block: *Scope.Block, |
| 2840 | inst: zir.Inst.Index, | 2922 | inst: zir.Inst.Index, |
| 2841 | need_coercion: bool, | 2923 | need_coercion: bool, |
| 2842 | ) InnerError!*Inst { | 2924 | ) InnerError!zir.Inst.Ref { |
| 2843 | const tracy = trace(@src()); | 2925 | const tracy = trace(@src()); |
| 2844 | defer tracy.end(); | 2926 | defer tracy.end(); |
| 2845 | | 2927 | |
| ... | @@ -2850,7 +2932,7 @@ fn zirRetTok( | ... | @@ -2850,7 +2932,7 @@ fn zirRetTok( |
| 2850 | return sema.analyzeRet(block, operand, src, need_coercion); | 2932 | return sema.analyzeRet(block, operand, src, need_coercion); |
| 2851 | } | 2933 | } |
| 2852 | | 2934 | |
| 2853 | fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { | 2935 | fn zirRetNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!zir.Inst.Ref { |
| 2854 | const tracy = trace(@src()); | 2936 | const tracy = trace(@src()); |
| 2855 | defer tracy.end(); | 2937 | defer tracy.end(); |
| 2856 | | 2938 | |
| ... | @@ -2867,22 +2949,24 @@ fn analyzeRet( | ... | @@ -2867,22 +2949,24 @@ fn analyzeRet( |
| 2867 | operand: *Inst, | 2949 | operand: *Inst, |
| 2868 | src: LazySrcLoc, | 2950 | src: LazySrcLoc, |
| 2869 | need_coercion: bool, | 2951 | need_coercion: bool, |
| 2870 | ) InnerError!*Inst { | 2952 | ) InnerError!zir.Inst.Ref { |
| 2871 | if (block.inlining) |inlining| { | 2953 | if (block.inlining) |inlining| { |
| 2872 | // We are inlining a function call; rewrite the `ret` as a `break`. | 2954 | // We are inlining a function call; rewrite the `ret` as a `break`. |
| 2873 | try inlining.merges.results.append(sema.gpa, operand); | 2955 | try inlining.merges.results.append(sema.gpa, operand); |
| 2874 | const br = try block.addBr(src, inlining.merges.block_inst, operand); | 2956 | _ = try block.addBr(src, inlining.merges.block_inst, operand); |
| 2875 | return &br.base; | 2957 | return always_noreturn; |
| 2876 | } | 2958 | } |
| 2877 | | 2959 | |
| 2878 | if (need_coercion) { | 2960 | if (need_coercion) { |
| 2879 | if (sema.func) |func| { | 2961 | if (sema.func) |func| { |
| 2880 | const fn_ty = func.owner_decl.typed_value.most_recent.typed_value.ty; | 2962 | const fn_ty = func.owner_decl.typed_value.most_recent.typed_value.ty; |
| 2881 | const casted_operand = try sema.coerce(block, fn_ty.fnReturnType(), operand, src); | 2963 | const casted_operand = try sema.coerce(block, fn_ty.fnReturnType(), operand, src); |
| 2882 | return block.addUnOp(src, Type.initTag(.noreturn), .ret, casted_operand); | 2964 | _ = try block.addUnOp(src, Type.initTag(.noreturn), .ret, casted_operand); |
| | 2965 | return always_noreturn; |
| 2883 | } | 2966 | } |
| 2884 | } | 2967 | } |
| 2885 | return block.addUnOp(src, Type.initTag(.noreturn), .ret, operand); | 2968 | _ = try block.addUnOp(src, Type.initTag(.noreturn), .ret, operand); |
| | 2969 | return always_noreturn; |
| 2886 | } | 2970 | } |
| 2887 | | 2971 | |
| 2888 | fn floatOpAllowed(tag: zir.Inst.Tag) bool { | 2972 | fn floatOpAllowed(tag: zir.Inst.Tag) bool { |
| ... | @@ -3051,10 +3135,11 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: *Inst, panic_id: | ... | @@ -3051,10 +3135,11 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: *Inst, panic_id: |
| 3051 | try parent_block.instructions.append(sema.gpa, &block_inst.base); | 3135 | try parent_block.instructions.append(sema.gpa, &block_inst.base); |
| 3052 | } | 3136 | } |
| 3053 | | 3137 | |
| 3054 | fn safetyPanic(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, panic_id: PanicId) !*Inst { | 3138 | fn safetyPanic(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, panic_id: PanicId) !zir.Inst.Ref { |
| 3055 | // TODO Once we have a panic function to call, call it here instead of breakpoint. | 3139 | // TODO Once we have a panic function to call, call it here instead of breakpoint. |
| 3056 | _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint); | 3140 | _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint); |
| 3057 | return block.addNoOp(src, Type.initTag(.noreturn), .unreach); | 3141 | _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach); |
| | 3142 | return always_noreturn; |
| 3058 | } | 3143 | } |
| 3059 | | 3144 | |
| 3060 | fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { | 3145 | fn emitBackwardBranch(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void { |
| ... | @@ -3405,20 +3490,20 @@ fn storePtr( | ... | @@ -3405,20 +3490,20 @@ fn storePtr( |
| 3405 | src: LazySrcLoc, | 3490 | src: LazySrcLoc, |
| 3406 | ptr: *Inst, | 3491 | ptr: *Inst, |
| 3407 | uncasted_value: *Inst, | 3492 | uncasted_value: *Inst, |
| 3408 | ) !*Inst { | 3493 | ) !void { |
| 3409 | if (ptr.ty.isConstPtr()) | 3494 | if (ptr.ty.isConstPtr()) |
| 3410 | return sema.mod.fail(&block.base, src, "cannot assign to constant", .{}); | 3495 | return sema.mod.fail(&block.base, src, "cannot assign to constant", .{}); |
| 3411 | | 3496 | |
| 3412 | const elem_ty = ptr.ty.elemType(); | 3497 | const elem_ty = ptr.ty.elemType(); |
| 3413 | const value = try sema.coerce(block, elem_ty, uncasted_value, uncasted_value.src); | 3498 | const value = try sema.coerce(block, elem_ty, uncasted_value, uncasted_value.src); |
| 3414 | if (elem_ty.onePossibleValue() != null) | 3499 | if (elem_ty.onePossibleValue() != null) |
| 3415 | return sema.mod.constVoid(sema.arena, .unneeded); | 3500 | return; |
| 3416 | | 3501 | |
| 3417 | // TODO handle comptime pointer writes | 3502 | // TODO handle comptime pointer writes |
| 3418 | // TODO handle if the element type requires comptime | 3503 | // TODO handle if the element type requires comptime |
| 3419 | | 3504 | |
| 3420 | try sema.requireRuntimeBlock(block, src); | 3505 | try sema.requireRuntimeBlock(block, src); |
| 3421 | return block.addBinOp(src, Type.initTag(.void), .store, ptr, value); | 3506 | _ = try block.addBinOp(src, Type.initTag(.void), .store, ptr, value); |
| 3422 | } | 3507 | } |
| 3423 | | 3508 | |
| 3424 | fn bitcast(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst { | 3509 | fn bitcast(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: *Inst) !*Inst { |