| ... | @@ -372,14 +372,14 @@ pub fn analyzeBody( | ... | @@ -372,14 +372,14 @@ pub fn analyzeBody( |
| 372 | //.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon), | 372 | //.error_set_decl_anon => try sema.zirErrorSetDecl(block, inst, .anon), |
| 373 | //.error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func), | 373 | //.error_set_decl_func => try sema.zirErrorSetDecl(block, inst, .func), |
| 374 | | 374 | |
| 375 | //.add => try sema.zirArithmetic(block, inst), | 375 | .add => try sema.zirArithmetic(block, inst), |
| 376 | //.addwrap => try sema.zirArithmetic(block, inst), | 376 | .addwrap => try sema.zirArithmetic(block, inst), |
| 377 | //.div => try sema.zirArithmetic(block, inst), | 377 | .div => try sema.zirArithmetic(block, inst), |
| 378 | //.mod_rem => try sema.zirArithmetic(block, inst), | 378 | .mod_rem => try sema.zirArithmetic(block, inst), |
| 379 | //.mul => try sema.zirArithmetic(block, inst), | 379 | .mul => try sema.zirArithmetic(block, inst), |
| 380 | //.mulwrap => try sema.zirArithmetic(block, inst), | 380 | .mulwrap => try sema.zirArithmetic(block, inst), |
| 381 | //.sub => try sema.zirArithmetic(block, inst), | 381 | .sub => try sema.zirArithmetic(block, inst), |
| 382 | //.subwrap => try sema.zirArithmetic(block, inst), | 382 | .subwrap => try sema.zirArithmetic(block, inst), |
| 383 | | 383 | |
| 384 | //// Instructions that we know to *always* be noreturn based solely on their tag. | 384 | //// Instructions that we know to *always* be noreturn based solely on their tag. |
| 385 | //// These functions match the return type of analyzeBody so that we can | 385 | //// These functions match the return type of analyzeBody so that we can |
| ... | @@ -505,35 +505,35 @@ pub fn analyzeBody( | ... | @@ -505,35 +505,35 @@ pub fn analyzeBody( |
| 505 | i = 0; | 505 | i = 0; |
| 506 | continue; | 506 | continue; |
| 507 | }, | 507 | }, |
| 508 | //.block_inline => blk: { | 508 | .block_inline => blk: { |
| 509 | // // Directly analyze the block body without introducing a new block. | 509 | // Directly analyze the block body without introducing a new block. |
| 510 | // const inst_data = datas[inst].pl_node; | 510 | const inst_data = datas[inst].pl_node; |
| 511 | // const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); | 511 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 512 | // const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len]; | 512 | const inline_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 513 | // const break_inst = try sema.analyzeBody(block, inline_body); | 513 | const break_inst = try sema.analyzeBody(block, inline_body); |
| 514 | // const break_data = datas[break_inst].@"break"; | 514 | const break_data = datas[break_inst].@"break"; |
| 515 | // if (inst == break_data.block_inst) { | 515 | if (inst == break_data.block_inst) { |
| 516 | // break :blk sema.resolveInst(break_data.operand); | 516 | break :blk sema.resolveInst(break_data.operand); |
| 517 | // } else { | 517 | } else { |
| 518 | // return break_inst; | 518 | return break_inst; |
| 519 | // } | 519 | } |
| 520 | //}, | 520 | }, |
| 521 | //.condbr_inline => blk: { | 521 | .condbr_inline => blk: { |
| 522 | // const inst_data = datas[inst].pl_node; | 522 | const inst_data = datas[inst].pl_node; |
| 523 | // const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node }; | 523 | const cond_src: LazySrcLoc = .{ .node_offset_if_cond = inst_data.src_node }; |
| 524 | // const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); | 524 | const extra = sema.code.extraData(Zir.Inst.CondBr, inst_data.payload_index); |
| 525 | // const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; | 525 | const then_body = sema.code.extra[extra.end..][0..extra.data.then_body_len]; |
| 526 | // const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; | 526 | const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len]; |
| 527 | // const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition); | 527 | const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition); |
| 528 | // const inline_body = if (cond.val.toBool()) then_body else else_body; | 528 | const inline_body = if (cond.val.toBool()) then_body else else_body; |
| 529 | // const break_inst = try sema.analyzeBody(block, inline_body); | 529 | const break_inst = try sema.analyzeBody(block, inline_body); |
| 530 | // const break_data = datas[break_inst].@"break"; | 530 | const break_data = datas[break_inst].@"break"; |
| 531 | // if (inst == break_data.block_inst) { | 531 | if (inst == break_data.block_inst) { |
| 532 | // break :blk sema.resolveInst(break_data.operand); | 532 | break :blk sema.resolveInst(break_data.operand); |
| 533 | // } else { | 533 | } else { |
| 534 | // return break_inst; | 534 | return break_inst; |
| 535 | // } | 535 | } |
| 536 | //}, | 536 | }, |
| 537 | else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"), | 537 | else => @panic("TODO finish updating Sema for AIR memory layout changes and then remove this else prong"), |
| 538 | }; | 538 | }; |
| 539 | if (sema.getTypeOf(air_inst).isNoReturn()) | 539 | if (sema.getTypeOf(air_inst).isNoReturn()) |
| ... | @@ -1186,7 +1186,7 @@ fn zirRetPtr( | ... | @@ -1186,7 +1186,7 @@ fn zirRetPtr( |
| 1186 | const fn_ty = sema.func.?.owner_decl.ty; | 1186 | const fn_ty = sema.func.?.owner_decl.ty; |
| 1187 | const ret_type = fn_ty.fnReturnType(); | 1187 | const ret_type = fn_ty.fnReturnType(); |
| 1188 | const ptr_type = try Module.simplePtrType(sema.arena, ret_type, true, .One); | 1188 | const ptr_type = try Module.simplePtrType(sema.arena, ret_type, true, .One); |
| 1189 | return block.addNoOp(src, ptr_type, .alloc); | 1189 | return block.addTy(.alloc, ptr_type); |
| 1190 | } | 1190 | } |
| 1191 | | 1191 | |
| 1192 | fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 1192 | fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -1230,7 +1230,8 @@ fn ensureResultUsed( | ... | @@ -1230,7 +1230,8 @@ fn ensureResultUsed( |
| 1230 | operand: Air.Inst.Ref, | 1230 | operand: Air.Inst.Ref, |
| 1231 | src: LazySrcLoc, | 1231 | src: LazySrcLoc, |
| 1232 | ) CompileError!void { | 1232 | ) CompileError!void { |
| 1233 | switch (operand.ty.zigTypeTag()) { | 1233 | const operand_ty = sema.getTypeOf(operand); |
| | 1234 | switch (operand_ty.zigTypeTag()) { |
| 1234 | .Void, .NoReturn => return, | 1235 | .Void, .NoReturn => return, |
| 1235 | else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}), | 1236 | else => return sema.mod.fail(&block.base, src, "expression value is ignored", .{}), |
| 1236 | } | 1237 | } |
| ... | @@ -1243,7 +1244,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde | ... | @@ -1243,7 +1244,8 @@ fn zirEnsureResultNonError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 1243 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 1244 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 1244 | const operand = sema.resolveInst(inst_data.operand); | 1245 | const operand = sema.resolveInst(inst_data.operand); |
| 1245 | const src = inst_data.src(); | 1246 | const src = inst_data.src(); |
| 1246 | switch (operand.ty.zigTypeTag()) { | 1247 | const operand_ty = sema.getTypeOf(operand); |
| | 1248 | switch (operand_ty.zigTypeTag()) { |
| 1247 | .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}), | 1249 | .ErrorSet, .ErrorUnion => return sema.mod.fail(&block.base, src, "error is discarded", .{}), |
| 1248 | else => return, | 1250 | else => return, |
| 1249 | } | 1251 | } |
| ... | @@ -1257,7 +1259,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co | ... | @@ -1257,7 +1259,7 @@ fn zirIndexablePtrLen(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co |
| 1257 | const src = inst_data.src(); | 1259 | const src = inst_data.src(); |
| 1258 | const array_ptr = sema.resolveInst(inst_data.operand); | 1260 | const array_ptr = sema.resolveInst(inst_data.operand); |
| 1259 | | 1261 | |
| 1260 | const elem_ty = array_ptr.ty.elemType(); | 1262 | const elem_ty = sema.getTypeOf(array_ptr).elemType(); |
| 1261 | if (!elem_ty.isIndexable()) { | 1263 | if (!elem_ty.isIndexable()) { |
| 1262 | const cond_src: LazySrcLoc = .{ .node_offset_for_cond = inst_data.src_node }; | 1264 | const cond_src: LazySrcLoc = .{ .node_offset_for_cond = inst_data.src_node }; |
| 1263 | const msg = msg: { | 1265 | const msg = msg: { |
| ... | @@ -1317,7 +1319,6 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp | ... | @@ -1317,7 +1319,6 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp |
| 1317 | defer tracy.end(); | 1319 | defer tracy.end(); |
| 1318 | | 1320 | |
| 1319 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 1321 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 1320 | const src = inst_data.src(); | | |
| 1321 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; | 1322 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node }; |
| 1322 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); | 1323 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); |
| 1323 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); | 1324 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); |
| ... | @@ -1329,10 +1330,7 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp | ... | @@ -1329,10 +1330,7 @@ fn zirAllocComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp |
| 1329 | .val = undefined, // astgen guarantees there will be a store before the first load | 1330 | .val = undefined, // astgen guarantees there will be a store before the first load |
| 1330 | }, | 1331 | }, |
| 1331 | }; | 1332 | }; |
| 1332 | return sema.mod.constInst(sema.arena, src, .{ | 1333 | return sema.addConstant(ptr_type, Value.initPayload(&val_payload.base)); |
| 1333 | .ty = ptr_type, | | |
| 1334 | .val = Value.initPayload(&val_payload.base), | | |
| 1335 | }); | | |
| 1336 | } | 1334 | } |
| 1337 | | 1335 | |
| 1338 | fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 1336 | fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -1351,7 +1349,7 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError | ... | @@ -1351,7 +1349,7 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError |
| 1351 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); | 1349 | const var_type = try sema.resolveType(block, ty_src, inst_data.operand); |
| 1352 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); | 1350 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); |
| 1353 | try sema.requireRuntimeBlock(block, var_decl_src); | 1351 | try sema.requireRuntimeBlock(block, var_decl_src); |
| 1354 | return block.addNoOp(var_decl_src, ptr_type, .alloc); | 1352 | return block.addTy(.alloc, ptr_type); |
| 1355 | } | 1353 | } |
| 1356 | | 1354 | |
| 1357 | fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 1355 | fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -1365,7 +1363,7 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -1365,7 +1363,7 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 1365 | try sema.validateVarType(block, ty_src, var_type); | 1363 | try sema.validateVarType(block, ty_src, var_type); |
| 1366 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); | 1364 | const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One); |
| 1367 | try sema.requireRuntimeBlock(block, var_decl_src); | 1365 | try sema.requireRuntimeBlock(block, var_decl_src); |
| 1368 | return block.addNoOp(var_decl_src, ptr_type, .alloc); | 1366 | return block.addTy(.alloc, ptr_type); |
| 1369 | } | 1367 | } |
| 1370 | | 1368 | |
| 1371 | fn zirAllocInferred( | 1369 | fn zirAllocInferred( |
| ... | @@ -1388,12 +1386,9 @@ fn zirAllocInferred( | ... | @@ -1388,12 +1386,9 @@ fn zirAllocInferred( |
| 1388 | // not needed in the case of constant values. However here, we plan to "downgrade" | 1386 | // not needed in the case of constant values. However here, we plan to "downgrade" |
| 1389 | // to a normal instruction when we hit `resolve_inferred_alloc`. So we append | 1387 | // to a normal instruction when we hit `resolve_inferred_alloc`. So we append |
| 1390 | // to the block even though it is currently a `.constant`. | 1388 | // to the block even though it is currently a `.constant`. |
| 1391 | const result = try sema.mod.constInst(sema.arena, src, .{ | 1389 | const result = try sema.addConstant(inferred_alloc_ty, Value.initPayload(&val_payload.base)); |
| 1392 | .ty = inferred_alloc_ty, | | |
| 1393 | .val = Value.initPayload(&val_payload.base), | | |
| 1394 | }); | | |
| 1395 | try sema.requireFunctionBlock(block, src); | 1390 | try sema.requireFunctionBlock(block, src); |
| 1396 | try block.instructions.append(sema.gpa, result); | 1391 | try block.instructions.append(sema.gpa, refToIndex(result).?); |
| 1397 | return result; | 1392 | return result; |
| 1398 | } | 1393 | } |
| 1399 | | 1394 | |
| ... | @@ -1630,18 +1625,21 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -1630,18 +1625,21 @@ fn zirParamType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 1630 | const tracy = trace(@src()); | 1625 | const tracy = trace(@src()); |
| 1631 | defer tracy.end(); | 1626 | defer tracy.end(); |
| 1632 | | 1627 | |
| 1633 | const src: LazySrcLoc = .unneeded; | 1628 | const src = sema.src; |
| | 1629 | const fn_inst_src = sema.src; |
| | 1630 | |
| 1634 | const inst_data = sema.code.instructions.items(.data)[inst].param_type; | 1631 | const inst_data = sema.code.instructions.items(.data)[inst].param_type; |
| 1635 | const fn_inst = sema.resolveInst(inst_data.callee); | 1632 | const fn_inst = sema.resolveInst(inst_data.callee); |
| | 1633 | const fn_inst_ty = sema.getTypeOf(fn_inst); |
| 1636 | const param_index = inst_data.param_index; | 1634 | const param_index = inst_data.param_index; |
| 1637 | | 1635 | |
| 1638 | const fn_ty: Type = switch (fn_inst.ty.zigTypeTag()) { | 1636 | const fn_ty: Type = switch (fn_inst_ty.zigTypeTag()) { |
| 1639 | .Fn => fn_inst.ty, | 1637 | .Fn => fn_inst_ty, |
| 1640 | .BoundFn => { | 1638 | .BoundFn => { |
| 1641 | return sema.mod.fail(&block.base, fn_inst.src, "TODO implement zirParamType for method call syntax", .{}); | 1639 | return sema.mod.fail(&block.base, fn_inst_src, "TODO implement zirParamType for method call syntax", .{}); |
| 1642 | }, | 1640 | }, |
| 1643 | else => { | 1641 | else => { |
| 1644 | return sema.mod.fail(&block.base, fn_inst.src, "expected function, found '{}'", .{fn_inst.ty}); | 1642 | return sema.mod.fail(&block.base, fn_inst_src, "expected function, found '{}'", .{fn_inst_ty}); |
| 1645 | }, | 1643 | }, |
| 1646 | }; | 1644 | }; |
| 1647 | | 1645 | |
| ... | @@ -1711,23 +1709,20 @@ fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -1711,23 +1709,20 @@ fn zirIntBig(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro |
| 1711 | const limbs = try arena.alloc(std.math.big.Limb, int.len); | 1709 | const limbs = try arena.alloc(std.math.big.Limb, int.len); |
| 1712 | mem.copy(u8, mem.sliceAsBytes(limbs), limb_bytes); | 1710 | mem.copy(u8, mem.sliceAsBytes(limbs), limb_bytes); |
| 1713 | | 1711 | |
| 1714 | return sema.mod.constInst(arena, .unneeded, .{ | 1712 | return sema.addConstant( |
| 1715 | .ty = Type.initTag(.comptime_int), | 1713 | Type.initTag(.comptime_int), |
| 1716 | .val = try Value.Tag.int_big_positive.create(arena, limbs), | 1714 | try Value.Tag.int_big_positive.create(arena, limbs), |
| 1717 | }); | 1715 | ); |
| 1718 | } | 1716 | } |
| 1719 | | 1717 | |
| 1720 | fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 1718 | fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 1721 | _ = block; | 1719 | _ = block; |
| 1722 | const arena = sema.arena; | 1720 | const arena = sema.arena; |
| 1723 | const inst_data = sema.code.instructions.items(.data)[inst].float; | 1721 | const number = sema.code.instructions.items(.data)[inst].float; |
| 1724 | const src = inst_data.src(); | 1722 | return sema.addConstant( |
| 1725 | const number = inst_data.number; | 1723 | Type.initTag(.comptime_float), |
| 1726 | | 1724 | try Value.Tag.float_64.create(arena, number), |
| 1727 | return sema.mod.constInst(arena, src, .{ | 1725 | ); |
| 1728 | .ty = Type.initTag(.comptime_float), | | |
| 1729 | .val = try Value.Tag.float_32.create(arena, number), | | |
| 1730 | }); | | |
| 1731 | } | 1726 | } |
| 1732 | | 1727 | |
| 1733 | fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 1728 | fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -1735,13 +1730,11 @@ fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -1735,13 +1730,11 @@ fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 1735 | const arena = sema.arena; | 1730 | const arena = sema.arena; |
| 1736 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 1731 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 1737 | const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; | 1732 | const extra = sema.code.extraData(Zir.Inst.Float128, inst_data.payload_index).data; |
| 1738 | const src = inst_data.src(); | | |
| 1739 | const number = extra.get(); | 1733 | const number = extra.get(); |
| 1740 | | 1734 | return sema.addConstant( |
| 1741 | return sema.mod.constInst(arena, src, .{ | 1735 | Type.initTag(.comptime_float), |
| 1742 | .ty = Type.initTag(.comptime_float), | 1736 | try Value.Tag.float_128.create(arena, number), |
| 1743 | .val = try Value.Tag.float_128.create(arena, number), | 1737 | ); |
| 1744 | }); | | |
| 1745 | } | 1738 | } |
| 1746 | | 1739 | |
| 1747 | fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { | 1740 | fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| ... | @@ -1785,10 +1778,7 @@ fn zirCompileLog( | ... | @@ -1785,10 +1778,7 @@ fn zirCompileLog( |
| 1785 | if (!gop.found_existing) { | 1778 | if (!gop.found_existing) { |
| 1786 | gop.value_ptr.* = src_node; | 1779 | gop.value_ptr.* = src_node; |
| 1787 | } | 1780 | } |
| 1788 | return sema.mod.constInst(sema.arena, src, .{ | 1781 | return Air.Inst.Ref.void_value; |
| 1789 | .ty = Type.initTag(.void), | | |
| 1790 | .val = Value.initTag(.void_value), | | |
| 1791 | }); | | |
| 1792 | } | 1782 | } |
| 1793 | | 1783 | |
| 1794 | fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { | 1784 | fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index { |
| ... | @@ -1817,18 +1807,26 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil | ... | @@ -1817,18 +1807,26 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 1817 | const src = inst_data.src(); | 1807 | const src = inst_data.src(); |
| 1818 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); | 1808 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 1819 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; | 1809 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| | 1810 | const gpa = sema.gpa; |
| 1820 | | 1811 | |
| 1821 | // AIR expects a block outside the loop block too. | 1812 | // AIR expects a block outside the loop block too. |
| 1822 | const block_inst = try sema.arena.create(Inst.Block); | 1813 | // Reserve space for a Loop instruction so that generated Break instructions can |
| 1823 | block_inst.* = .{ | 1814 | // point to it, even if it doesn't end up getting used because the code ends up being |
| 1824 | .base = .{ | 1815 | // comptime evaluated. |
| 1825 | .tag = Inst.Block.base_tag, | 1816 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 1826 | .ty = undefined, | 1817 | const loop_inst = block_inst + 1; |
| 1827 | .src = src, | 1818 | try sema.air_instructions.ensureUnusedCapacity(gpa, 2); |
| 1828 | }, | 1819 | sema.air_instructions.appendAssumeCapacity(.{ |
| 1829 | .body = undefined, | 1820 | .tag = .block, |
| 1830 | }; | 1821 | .data = undefined, |
| 1831 | | 1822 | }); |
| | 1823 | sema.air_instructions.appendAssumeCapacity(.{ |
| | 1824 | .tag = .loop, |
| | 1825 | .data = .{ .ty_pl = .{ |
| | 1826 | .ty = .noreturn_type, |
| | 1827 | .payload = undefined, |
| | 1828 | } }, |
| | 1829 | }); |
| 1832 | var label: Scope.Block.Label = .{ | 1830 | var label: Scope.Block.Label = .{ |
| 1833 | .zir_block = inst, | 1831 | .zir_block = inst, |
| 1834 | .merges = .{ | 1832 | .merges = .{ |
| ... | @@ -1844,33 +1842,24 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil | ... | @@ -1844,33 +1842,24 @@ fn zirLoop(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 1844 | child_block.runtime_index += 1; | 1842 | child_block.runtime_index += 1; |
| 1845 | const merges = &child_block.label.?.merges; | 1843 | const merges = &child_block.label.?.merges; |
| 1846 | | 1844 | |
| 1847 | defer child_block.instructions.deinit(sema.gpa); | 1845 | defer child_block.instructions.deinit(gpa); |
| 1848 | defer merges.results.deinit(sema.gpa); | 1846 | defer merges.results.deinit(gpa); |
| 1849 | defer merges.br_list.deinit(sema.gpa); | 1847 | defer merges.br_list.deinit(gpa); |
| 1850 | | | |
| 1851 | // Reserve space for a Loop instruction so that generated Break instructions can | | |
| 1852 | // point to it, even if it doesn't end up getting used because the code ends up being | | |
| 1853 | // comptime evaluated. | | |
| 1854 | const loop_inst = try sema.arena.create(Inst.Loop); | | |
| 1855 | loop_inst.* = .{ | | |
| 1856 | .base = .{ | | |
| 1857 | .tag = Inst.Loop.base_tag, | | |
| 1858 | .ty = Type.initTag(.noreturn), | | |
| 1859 | .src = src, | | |
| 1860 | }, | | |
| 1861 | .body = undefined, | | |
| 1862 | }; | | |
| 1863 | | 1848 | |
| 1864 | var loop_block = child_block.makeSubBlock(); | 1849 | var loop_block = child_block.makeSubBlock(); |
| 1865 | defer loop_block.instructions.deinit(sema.gpa); | 1850 | defer loop_block.instructions.deinit(gpa); |
| 1866 | | 1851 | |
| 1867 | _ = try sema.analyzeBody(&loop_block, body); | 1852 | _ = try sema.analyzeBody(&loop_block, body); |
| 1868 | | 1853 | |
| 1869 | // Loop repetition is implied so the last instruction may or may not be a noreturn instruction. | 1854 | // Loop repetition is implied so the last instruction may or may not be a noreturn instruction. |
| | 1855 | try child_block.instructions.append(gpa, loop_inst); |
| 1870 | | 1856 | |
| 1871 | try child_block.instructions.append(sema.gpa, &loop_inst.base); | 1857 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 1872 | loop_inst.body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, loop_block.instructions.items) }; | 1858 | loop_block.instructions.items.len); |
| 1873 | | 1859 | sema.air_instructions.items(.data)[loop_inst].ty_pl.payload = sema.addExtraAssumeCapacity( |
| | 1860 | Air.Block{ .body_len = @intCast(u32, loop_block.instructions.items.len) }, |
| | 1861 | ); |
| | 1862 | sema.air_extra.appendAssumeCapacity(loop_block.instructions.items); |
| 1874 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); | 1863 | return sema.analyzeBlockBody(parent_block, src, &child_block, merges); |
| 1875 | } | 1864 | } |
| 1876 | | 1865 | |
| ... | @@ -1890,27 +1879,28 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index | ... | @@ -1890,27 +1879,28 @@ fn zirSuspendBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index |
| 1890 | return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirSuspendBlock", .{}); | 1879 | return sema.mod.fail(&parent_block.base, src, "TODO: implement Sema.zirSuspendBlock", .{}); |
| 1891 | } | 1880 | } |
| 1892 | | 1881 | |
| 1893 | fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 1882 | fn zirBlock( |
| | 1883 | sema: *Sema, |
| | 1884 | parent_block: *Scope.Block, |
| | 1885 | inst: Zir.Inst.Index, |
| | 1886 | ) CompileError!Air.Inst.Ref { |
| 1894 | const tracy = trace(@src()); | 1887 | const tracy = trace(@src()); |
| 1895 | defer tracy.end(); | 1888 | defer tracy.end(); |
| 1896 | | 1889 | |
| 1897 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 1890 | const pl_node = sema.code.instructions.items(.data)[inst].pl_node; |
| 1898 | const src = inst_data.src(); | 1891 | const src = pl_node.src(); |
| 1899 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); | 1892 | const extra = sema.code.extraData(Zir.Inst.Block, pl_node.payload_index); |
| 1900 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; | 1893 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| | 1894 | const gpa = sema.gpa; |
| 1901 | | 1895 | |
| 1902 | // Reserve space for a Block instruction so that generated Break instructions can | 1896 | // Reserve space for a Block instruction so that generated Break instructions can |
| 1903 | // point to it, even if it doesn't end up getting used because the code ends up being | 1897 | // point to it, even if it doesn't end up getting used because the code ends up being |
| 1904 | // comptime evaluated. | 1898 | // comptime evaluated. |
| 1905 | const block_inst = try sema.arena.create(Inst.Block); | 1899 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 1906 | block_inst.* = .{ | 1900 | try sema.air_instructions.append(gpa, .{ |
| 1907 | .base = .{ | 1901 | .tag = .block, |
| 1908 | .tag = Inst.Block.base_tag, | 1902 | .data = undefined, |
| 1909 | .ty = undefined, // Set after analysis. | 1903 | }); |
| 1910 | .src = src, | | |
| 1911 | }, | | |
| 1912 | .body = undefined, | | |
| 1913 | }; | | |
| 1914 | | 1904 | |
| 1915 | var label: Scope.Block.Label = .{ | 1905 | var label: Scope.Block.Label = .{ |
| 1916 | .zir_block = inst, | 1906 | .zir_block = inst, |
| ... | @@ -1932,9 +1922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compi | ... | @@ -1932,9 +1922,9 @@ fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) Compi |
| 1932 | }; | 1922 | }; |
| 1933 | const merges = &child_block.label.?.merges; | 1923 | const merges = &child_block.label.?.merges; |
| 1934 | | 1924 | |
| 1935 | defer child_block.instructions.deinit(sema.gpa); | 1925 | defer child_block.instructions.deinit(gpa); |
| 1936 | defer merges.results.deinit(sema.gpa); | 1926 | defer merges.results.deinit(gpa); |
| 1937 | defer merges.br_list.deinit(sema.gpa); | 1927 | defer merges.br_list.deinit(gpa); |
| 1938 | | 1928 | |
| 1939 | _ = try sema.analyzeBody(&child_block, body); | 1929 | _ = try sema.analyzeBody(&child_block, body); |
| 1940 | | 1930 | |
| ... | @@ -1963,6 +1953,8 @@ fn analyzeBlockBody( | ... | @@ -1963,6 +1953,8 @@ fn analyzeBlockBody( |
| 1963 | const tracy = trace(@src()); | 1953 | const tracy = trace(@src()); |
| 1964 | defer tracy.end(); | 1954 | defer tracy.end(); |
| 1965 | | 1955 | |
| | 1956 | const gpa = sema.gpa; |
| | 1957 | |
| 1966 | // Blocks must terminate with noreturn instruction. | 1958 | // Blocks must terminate with noreturn instruction. |
| 1967 | assert(child_block.instructions.items.len != 0); | 1959 | assert(child_block.instructions.items.len != 0); |
| 1968 | assert(child_block.instructions.items[child_block.instructions.items.len - 1].ty.isNoReturn()); | 1960 | assert(child_block.instructions.items[child_block.instructions.items.len - 1].ty.isNoReturn()); |
| ... | @@ -1971,7 +1963,7 @@ fn analyzeBlockBody( | ... | @@ -1971,7 +1963,7 @@ fn analyzeBlockBody( |
| 1971 | // No need for a block instruction. We can put the new instructions | 1963 | // No need for a block instruction. We can put the new instructions |
| 1972 | // directly into the parent block. | 1964 | // directly into the parent block. |
| 1973 | const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items); | 1965 | const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items); |
| 1974 | try parent_block.instructions.appendSlice(sema.gpa, copied_instructions); | 1966 | try parent_block.instructions.appendSlice(gpa, copied_instructions); |
| 1975 | return copied_instructions[copied_instructions.len - 1]; | 1967 | return copied_instructions[copied_instructions.len - 1]; |
| 1976 | } | 1968 | } |
| 1977 | if (merges.results.items.len == 1) { | 1969 | if (merges.results.items.len == 1) { |
| ... | @@ -1982,7 +1974,7 @@ fn analyzeBlockBody( | ... | @@ -1982,7 +1974,7 @@ fn analyzeBlockBody( |
| 1982 | // No need for a block instruction. We can put the new instructions directly | 1974 | // No need for a block instruction. We can put the new instructions directly |
| 1983 | // into the parent block. Here we omit the break instruction. | 1975 | // into the parent block. Here we omit the break instruction. |
| 1984 | const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items[0..last_inst_index]); | 1976 | const copied_instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items[0..last_inst_index]); |
| 1985 | try parent_block.instructions.appendSlice(sema.gpa, copied_instructions); | 1977 | try parent_block.instructions.appendSlice(gpa, copied_instructions); |
| 1986 | return merges.results.items[0]; | 1978 | return merges.results.items[0]; |
| 1987 | } | 1979 | } |
| 1988 | } | 1980 | } |
| ... | @@ -1992,21 +1984,26 @@ fn analyzeBlockBody( | ... | @@ -1992,21 +1984,26 @@ fn analyzeBlockBody( |
| 1992 | | 1984 | |
| 1993 | // Need to set the type and emit the Block instruction. This allows machine code generation | 1985 | // Need to set the type and emit the Block instruction. This allows machine code generation |
| 1994 | // to emit a jump instruction to after the block when it encounters the break. | 1986 | // to emit a jump instruction to after the block when it encounters the break. |
| 1995 | try parent_block.instructions.append(sema.gpa, &merges.block_inst.base); | 1987 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 1996 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items); | 1988 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items); |
| 1997 | merges.block_inst.base.ty = resolved_ty; | 1989 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 1998 | merges.block_inst.body = .{ | 1990 | child_block.instructions.items.len); |
| 1999 | .instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items), | 1991 | sema.air_instructions.items(.data)[merges.block_inst] = .{ .ty_pl = .{ |
| 2000 | }; | 1992 | .ty = try sema.addType(resolved_ty), |
| | 1993 | .payload = sema.addExtraAssumeCapacity(Air.Block{ |
| | 1994 | .body_len = @intCast(u32, child_block.instructions.items.len), |
| | 1995 | }), |
| | 1996 | } }; |
| | 1997 | sema.air_extra.appendSliceAssumeCapacity(child_block.instructions.items); |
| 2001 | // Now that the block has its type resolved, we need to go back into all the break | 1998 | // Now that the block has its type resolved, we need to go back into all the break |
| 2002 | // instructions, and insert type coercion on the operands. | 1999 | // instructions, and insert type coercion on the operands. |
| 2003 | for (merges.br_list.items) |br| { | 2000 | for (merges.br_list.items) |br| { |
| 2004 | if (br.operand.ty.eql(resolved_ty)) { | 2001 | if (sema.getTypeOf(br.operand).eql(resolved_ty)) { |
| 2005 | // No type coercion needed. | 2002 | // No type coercion needed. |
| 2006 | continue; | 2003 | continue; |
| 2007 | } | 2004 | } |
| 2008 | var coerce_block = parent_block.makeSubBlock(); | 2005 | var coerce_block = parent_block.makeSubBlock(); |
| 2009 | defer coerce_block.instructions.deinit(sema.gpa); | 2006 | defer coerce_block.instructions.deinit(gpa); |
| 2010 | const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, br.operand.src); | 2007 | const coerced_operand = try sema.coerce(&coerce_block, resolved_ty, br.operand, br.operand.src); |
| 2011 | // If no instructions were produced, such as in the case of a coercion of a | 2008 | // If no instructions were produced, such as in the case of a coercion of a |
| 2012 | // constant value to a new type, we can simply point the br operand to it. | 2009 | // constant value to a new type, we can simply point the br operand to it. |
| ... | @@ -2032,7 +2029,7 @@ fn analyzeBlockBody( | ... | @@ -2032,7 +2029,7 @@ fn analyzeBlockBody( |
| 2032 | }, | 2029 | }, |
| 2033 | }; | 2030 | }; |
| 2034 | } | 2031 | } |
| 2035 | return &merges.block_inst.base; | 2032 | return indexToRef(merges.block_inst); |
| 2036 | } | 2033 | } |
| 2037 | | 2034 | |
| 2038 | fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { | 2035 | fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | @@ -2104,7 +2101,7 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile | ... | @@ -2104,7 +2101,7 @@ fn zirBreakpoint(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2104 | const src_node = sema.code.instructions.items(.data)[inst].node; | 2101 | const src_node = sema.code.instructions.items(.data)[inst].node; |
| 2105 | const src: LazySrcLoc = .{ .node_offset = src_node }; | 2102 | const src: LazySrcLoc = .{ .node_offset = src_node }; |
| 2106 | try sema.requireRuntimeBlock(block, src); | 2103 | try sema.requireRuntimeBlock(block, src); |
| 2107 | _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint); | 2104 | _ = try block.addNoOp(.breakpoint); |
| 2108 | } | 2105 | } |
| 2109 | | 2106 | |
| 2110 | fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { | 2107 | fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void { |
| ... | @@ -2311,6 +2308,8 @@ fn analyzeCall( | ... | @@ -2311,6 +2308,8 @@ fn analyzeCall( |
| 2311 | }), | 2308 | }), |
| 2312 | } | 2309 | } |
| 2313 | | 2310 | |
| | 2311 | const gpa = sema.gpa; |
| | 2312 | |
| 2314 | const ret_type = func.ty.fnReturnType(); | 2313 | const ret_type = func.ty.fnReturnType(); |
| 2315 | | 2314 | |
| 2316 | const is_comptime_call = block.is_comptime or modifier == .compile_time; | 2315 | const is_comptime_call = block.is_comptime or modifier == .compile_time; |
| ... | @@ -2331,15 +2330,11 @@ fn analyzeCall( | ... | @@ -2331,15 +2330,11 @@ fn analyzeCall( |
| 2331 | // set to in the `Scope.Block`. | 2330 | // set to in the `Scope.Block`. |
| 2332 | // This block instruction will be used to capture the return value from the | 2331 | // This block instruction will be used to capture the return value from the |
| 2333 | // inlined function. | 2332 | // inlined function. |
| 2334 | const block_inst = try sema.arena.create(Inst.Block); | 2333 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 2335 | block_inst.* = .{ | 2334 | try sema.air_instructions.append(gpa, .{ |
| 2336 | .base = .{ | 2335 | .tag = .block, |
| 2337 | .tag = Inst.Block.base_tag, | 2336 | .data = undefined, |
| 2338 | .ty = ret_type, | 2337 | }); |
| 2339 | .src = call_src, | | |
| 2340 | }, | | |
| 2341 | .body = undefined, | | |
| 2342 | }; | | |
| 2343 | // This one is shared among sub-blocks within the same callee, but not | 2338 | // This one is shared among sub-blocks within the same callee, but not |
| 2344 | // shared among the entire inline/comptime call stack. | 2339 | // shared among the entire inline/comptime call stack. |
| 2345 | var inlining: Scope.Block.Inlining = .{ | 2340 | var inlining: Scope.Block.Inlining = .{ |
| ... | @@ -2358,7 +2353,7 @@ fn analyzeCall( | ... | @@ -2358,7 +2353,7 @@ fn analyzeCall( |
| 2358 | const parent_inst_map = sema.inst_map; | 2353 | const parent_inst_map = sema.inst_map; |
| 2359 | sema.inst_map = .{}; | 2354 | sema.inst_map = .{}; |
| 2360 | defer { | 2355 | defer { |
| 2361 | sema.inst_map.deinit(sema.gpa); | 2356 | sema.inst_map.deinit(gpa); |
| 2362 | sema.inst_map = parent_inst_map; | 2357 | sema.inst_map = parent_inst_map; |
| 2363 | } | 2358 | } |
| 2364 | | 2359 | |
| ... | @@ -2390,9 +2385,9 @@ fn analyzeCall( | ... | @@ -2390,9 +2385,9 @@ fn analyzeCall( |
| 2390 | | 2385 | |
| 2391 | const merges = &child_block.inlining.?.merges; | 2386 | const merges = &child_block.inlining.?.merges; |
| 2392 | | 2387 | |
| 2393 | defer child_block.instructions.deinit(sema.gpa); | 2388 | defer child_block.instructions.deinit(gpa); |
| 2394 | defer merges.results.deinit(sema.gpa); | 2389 | defer merges.results.deinit(gpa); |
| 2395 | defer merges.br_list.deinit(sema.gpa); | 2390 | defer merges.br_list.deinit(gpa); |
| 2396 | | 2391 | |
| 2397 | try sema.emitBackwardBranch(&child_block, call_src); | 2392 | try sema.emitBackwardBranch(&child_block, call_src); |
| 2398 | | 2393 | |
| ... | @@ -2525,17 +2520,16 @@ fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile | ... | @@ -2525,17 +2520,16 @@ fn zirErrorValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2525 | defer tracy.end(); | 2520 | defer tracy.end(); |
| 2526 | | 2521 | |
| 2527 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; | 2522 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 2528 | const src = inst_data.src(); | | |
| 2529 | | 2523 | |
| 2530 | // Create an anonymous error set type with only this error value, and return the value. | 2524 | // Create an anonymous error set type with only this error value, and return the value. |
| 2531 | const kv = try sema.mod.getErrorValue(inst_data.get(sema.code)); | 2525 | const kv = try sema.mod.getErrorValue(inst_data.get(sema.code)); |
| 2532 | const result_type = try Type.Tag.error_set_single.create(sema.arena, kv.key); | 2526 | const result_type = try Type.Tag.error_set_single.create(sema.arena, kv.key); |
| 2533 | return sema.mod.constInst(sema.arena, src, .{ | 2527 | return sema.addConstant( |
| 2534 | .ty = result_type, | 2528 | result_type, |
| 2535 | .val = try Value.Tag.@"error".create(sema.arena, .{ | 2529 | try Value.Tag.@"error".create(sema.arena, .{ |
| 2536 | .name = kv.key, | 2530 | .name = kv.key, |
| 2537 | }), | 2531 | }), |
| 2538 | }); | 2532 | ); |
| 2539 | } | 2533 | } |
| 2540 | | 2534 | |
| 2541 | fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 2535 | fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -2558,10 +2552,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile | ... | @@ -2558,10 +2552,7 @@ fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2558 | .base = .{ .tag = .int_u64 }, | 2552 | .base = .{ .tag = .int_u64 }, |
| 2559 | .data = (try sema.mod.getErrorValue(val.castTag(.@"error").?.data.name)).value, | 2553 | .data = (try sema.mod.getErrorValue(val.castTag(.@"error").?.data.name)).value, |
| 2560 | }; | 2554 | }; |
| 2561 | return sema.mod.constInst(sema.arena, src, .{ | 2555 | return sema.addConstant(result_ty, Value.initPayload(&payload.base)); |
| 2562 | .ty = result_ty, | | |
| 2563 | .val = Value.initPayload(&payload.base), | | |
| 2564 | }); | | |
| 2565 | } | 2556 | } |
| 2566 | | 2557 | |
| 2567 | try sema.requireRuntimeBlock(block, src); | 2558 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -2587,10 +2578,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile | ... | @@ -2587,10 +2578,7 @@ fn zirIntToError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compile |
| 2587 | .base = .{ .tag = .@"error" }, | 2578 | .base = .{ .tag = .@"error" }, |
| 2588 | .data = .{ .name = sema.mod.error_name_list.items[@intCast(usize, int)] }, | 2579 | .data = .{ .name = sema.mod.error_name_list.items[@intCast(usize, int)] }, |
| 2589 | }; | 2580 | }; |
| 2590 | return sema.mod.constInst(sema.arena, src, .{ | 2581 | return sema.addConstant(Type.initTag(.anyerror), Value.initPayload(&payload.base)); |
| 2591 | .ty = Type.initTag(.anyerror), | | |
| 2592 | .val = Value.initPayload(&payload.base), | | |
| 2593 | }); | | |
| 2594 | } | 2582 | } |
| 2595 | try sema.requireRuntimeBlock(block, src); | 2583 | try sema.requireRuntimeBlock(block, src); |
| 2596 | if (block.wantSafety()) { | 2584 | if (block.wantSafety()) { |
| ... | @@ -2630,10 +2618,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com | ... | @@ -2630,10 +2618,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com |
| 2630 | | 2618 | |
| 2631 | // Anything merged with anyerror is anyerror. | 2619 | // Anything merged with anyerror is anyerror. |
| 2632 | if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) { | 2620 | if (lhs_ty.tag() == .anyerror or rhs_ty.tag() == .anyerror) { |
| 2633 | return sema.mod.constInst(sema.arena, src, .{ | 2621 | return Air.Inst.Ref.anyerror_type; |
| 2634 | .ty = Type.initTag(.type), | | |
| 2635 | .val = Value.initTag(.anyerror_type), | | |
| 2636 | }); | | |
| 2637 | } | 2622 | } |
| 2638 | // When we support inferred error sets, we'll want to use a data structure that can | 2623 | // When we support inferred error sets, we'll want to use a data structure that can |
| 2639 | // represent a merged set of errors without forcing them to be resolved here. Until then | 2624 | // represent a merged set of errors without forcing them to be resolved here. Until then |
| ... | @@ -2685,10 +2670,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com | ... | @@ -2685,10 +2670,7 @@ fn zirMergeErrorSets(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Com |
| 2685 | .names_len = @intCast(u32, new_names.len), | 2670 | .names_len = @intCast(u32, new_names.len), |
| 2686 | }; | 2671 | }; |
| 2687 | const error_set_ty = try Type.Tag.error_set.create(sema.arena, new_error_set); | 2672 | const error_set_ty = try Type.Tag.error_set.create(sema.arena, new_error_set); |
| 2688 | return sema.mod.constInst(sema.arena, src, .{ | 2673 | return sema.addConstant(Type.initTag(.type), try Value.Tag.ty.create(sema.arena, error_set_ty)); |
| 2689 | .ty = Type.initTag(.type), | | |
| 2690 | .val = try Value.Tag.ty.create(sema.arena, error_set_ty), | | |
| 2691 | }); | | |
| 2692 | } | 2674 | } |
| 2693 | | 2675 | |
| 2694 | fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 2676 | fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -2697,12 +2679,11 @@ fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil | ... | @@ -2697,12 +2679,11 @@ fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 2697 | defer tracy.end(); | 2679 | defer tracy.end(); |
| 2698 | | 2680 | |
| 2699 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; | 2681 | const inst_data = sema.code.instructions.items(.data)[inst].str_tok; |
| 2700 | const src = inst_data.src(); | | |
| 2701 | const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code)); | 2682 | const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code)); |
| 2702 | return sema.mod.constInst(sema.arena, src, .{ | 2683 | return sema.addConstant( |
| 2703 | .ty = Type.initTag(.enum_literal), | 2684 | Type.initTag(.enum_literal), |
| 2704 | .val = try Value.Tag.enum_literal.create(sema.arena, duped_name), | 2685 | try Value.Tag.enum_literal.create(sema.arena, duped_name), |
| 2705 | }); | 2686 | ); |
| 2706 | } | 2687 | } |
| 2707 | | 2688 | |
| 2708 | fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 2689 | fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -2712,11 +2693,12 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2712,11 +2693,12 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2712 | const src = inst_data.src(); | 2693 | const src = inst_data.src(); |
| 2713 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 2694 | const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 2714 | const operand = sema.resolveInst(inst_data.operand); | 2695 | const operand = sema.resolveInst(inst_data.operand); |
| | 2696 | const operand_ty = sema.getTypeOf(operand); |
| 2715 | | 2697 | |
| 2716 | const enum_tag: Air.Inst.Ref = switch (operand.ty.zigTypeTag()) { | 2698 | const enum_tag: Air.Inst.Ref = switch (operand_ty.zigTypeTag()) { |
| 2717 | .Enum => operand, | 2699 | .Enum => operand, |
| 2718 | .Union => { | 2700 | .Union => { |
| 2719 | //if (!operand.ty.unionHasTag()) { | 2701 | //if (!operand_ty.unionHasTag()) { |
| 2720 | // return mod.fail( | 2702 | // return mod.fail( |
| 2721 | // &block.base, | 2703 | // &block.base, |
| 2722 | // operand_src, | 2704 | // operand_src, |
| ... | @@ -2728,58 +2710,44 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2728,58 +2710,44 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2728 | }, | 2710 | }, |
| 2729 | else => { | 2711 | else => { |
| 2730 | return mod.fail(&block.base, operand_src, "expected enum or tagged union, found {}", .{ | 2712 | return mod.fail(&block.base, operand_src, "expected enum or tagged union, found {}", .{ |
| 2731 | operand.ty, | 2713 | operand_ty, |
| 2732 | }); | 2714 | }); |
| 2733 | }, | 2715 | }, |
| 2734 | }; | 2716 | }; |
| | 2717 | const enum_tag_ty = sema.getTypeOf(enum_tag); |
| 2735 | | 2718 | |
| 2736 | var int_tag_type_buffer: Type.Payload.Bits = undefined; | 2719 | var int_tag_type_buffer: Type.Payload.Bits = undefined; |
| 2737 | const int_tag_ty = try enum_tag.ty.intTagType(&int_tag_type_buffer).copy(arena); | 2720 | const int_tag_ty = try enum_tag_ty.intTagType(&int_tag_type_buffer).copy(arena); |
| 2738 | | 2721 | |
| 2739 | if (try sema.typeHasOnePossibleValue(block, src, enum_tag.ty)) |opv| { | 2722 | if (try sema.typeHasOnePossibleValue(block, src, enum_tag_ty)) |opv| { |
| 2740 | return mod.constInst(arena, src, .{ | 2723 | return sema.addConstant(int_tag_ty, opv); |
| 2741 | .ty = int_tag_ty, | | |
| 2742 | .val = opv, | | |
| 2743 | }); | | |
| 2744 | } | 2724 | } |
| 2745 | | 2725 | |
| 2746 | if (try sema.resolvePossiblyUndefinedValue(block, operand_src, enum_tag)) |enum_tag_val| { | 2726 | if (try sema.resolvePossiblyUndefinedValue(block, operand_src, enum_tag)) |enum_tag_val| { |
| 2747 | if (enum_tag_val.castTag(.enum_field_index)) |enum_field_payload| { | 2727 | if (enum_tag_val.castTag(.enum_field_index)) |enum_field_payload| { |
| 2748 | const field_index = enum_field_payload.data; | 2728 | const field_index = enum_field_payload.data; |
| 2749 | switch (enum_tag.ty.tag()) { | 2729 | switch (enum_tag_ty.tag()) { |
| 2750 | .enum_full => { | 2730 | .enum_full => { |
| 2751 | const enum_full = enum_tag.ty.castTag(.enum_full).?.data; | 2731 | const enum_full = enum_tag_ty.castTag(.enum_full).?.data; |
| 2752 | if (enum_full.values.count() != 0) { | 2732 | if (enum_full.values.count() != 0) { |
| 2753 | const val = enum_full.values.keys()[field_index]; | 2733 | const val = enum_full.values.keys()[field_index]; |
| 2754 | return mod.constInst(arena, src, .{ | 2734 | return sema.addConstant(int_tag_ty, val); |
| 2755 | .ty = int_tag_ty, | | |
| 2756 | .val = val, | | |
| 2757 | }); | | |
| 2758 | } else { | 2735 | } else { |
| 2759 | // Field index and integer values are the same. | 2736 | // Field index and integer values are the same. |
| 2760 | const val = try Value.Tag.int_u64.create(arena, field_index); | 2737 | const val = try Value.Tag.int_u64.create(arena, field_index); |
| 2761 | return mod.constInst(arena, src, .{ | 2738 | return sema.addConstant(int_tag_ty, val); |
| 2762 | .ty = int_tag_ty, | | |
| 2763 | .val = val, | | |
| 2764 | }); | | |
| 2765 | } | 2739 | } |
| 2766 | }, | 2740 | }, |
| 2767 | .enum_simple => { | 2741 | .enum_simple => { |
| 2768 | // Field index and integer values are the same. | 2742 | // Field index and integer values are the same. |
| 2769 | const val = try Value.Tag.int_u64.create(arena, field_index); | 2743 | const val = try Value.Tag.int_u64.create(arena, field_index); |
| 2770 | return mod.constInst(arena, src, .{ | 2744 | return sema.addConstant(int_tag_ty, val); |
| 2771 | .ty = int_tag_ty, | | |
| 2772 | .val = val, | | |
| 2773 | }); | | |
| 2774 | }, | 2745 | }, |
| 2775 | else => unreachable, | 2746 | else => unreachable, |
| 2776 | } | 2747 | } |
| 2777 | } else { | 2748 | } else { |
| 2778 | // Assume it is already an integer and return it directly. | 2749 | // Assume it is already an integer and return it directly. |
| 2779 | return mod.constInst(arena, src, .{ | 2750 | return sema.addConstant(int_tag_ty, enum_tag_val); |
| 2780 | .ty = int_tag_ty, | | |
| 2781 | .val = enum_tag_val, | | |
| 2782 | }); | | |
| 2783 | } | 2751 | } |
| 2784 | } | 2752 | } |
| 2785 | | 2753 | |
| ... | @@ -2790,7 +2758,6 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2790,7 +2758,6 @@ fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2790 | fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 2758 | fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 2791 | const mod = sema.mod; | 2759 | const mod = sema.mod; |
| 2792 | const target = mod.getTarget(); | 2760 | const target = mod.getTarget(); |
| 2793 | const arena = sema.arena; | | |
| 2794 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 2761 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 2795 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 2762 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 2796 | const src = inst_data.src(); | 2763 | const src = inst_data.src(); |
| ... | @@ -2805,10 +2772,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2805,10 +2772,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2805 | | 2772 | |
| 2806 | if (try sema.resolvePossiblyUndefinedValue(block, operand_src, operand)) |int_val| { | 2773 | if (try sema.resolvePossiblyUndefinedValue(block, operand_src, operand)) |int_val| { |
| 2807 | if (dest_ty.isNonexhaustiveEnum()) { | 2774 | if (dest_ty.isNonexhaustiveEnum()) { |
| 2808 | return mod.constInst(arena, src, .{ | 2775 | return sema.addConstant(dest_ty, int_val); |
| 2809 | .ty = dest_ty, | | |
| 2810 | .val = int_val, | | |
| 2811 | }); | | |
| 2812 | } | 2776 | } |
| 2813 | if (int_val.isUndef()) { | 2777 | if (int_val.isUndef()) { |
| 2814 | return sema.failWithUseOfUndef(block, operand_src); | 2778 | return sema.failWithUseOfUndef(block, operand_src); |
| ... | @@ -2832,10 +2796,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -2832,10 +2796,7 @@ fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 2832 | }; | 2796 | }; |
| 2833 | return mod.failWithOwnedErrorMsg(&block.base, msg); | 2797 | return mod.failWithOwnedErrorMsg(&block.base, msg); |
| 2834 | } | 2798 | } |
| 2835 | return mod.constInst(arena, src, .{ | 2799 | return sema.addConstant(dest_ty, int_val); |
| 2836 | .ty = dest_ty, | | |
| 2837 | .val = int_val, | | |
| 2838 | }); | | |
| 2839 | } | 2800 | } |
| 2840 | | 2801 | |
| 2841 | try sema.requireRuntimeBlock(block, src); | 2802 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -2854,16 +2815,17 @@ fn zirOptionalPayloadPtr( | ... | @@ -2854,16 +2815,17 @@ fn zirOptionalPayloadPtr( |
| 2854 | | 2815 | |
| 2855 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 2816 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2856 | const optional_ptr = sema.resolveInst(inst_data.operand); | 2817 | const optional_ptr = sema.resolveInst(inst_data.operand); |
| 2857 | assert(optional_ptr.ty.zigTypeTag() == .Pointer); | 2818 | const optional_ptr_ty = sema.getTypeOf(optional_ptr); |
| | 2819 | assert(optional_ptr_ty.zigTypeTag() == .Pointer); |
| 2858 | const src = inst_data.src(); | 2820 | const src = inst_data.src(); |
| 2859 | | 2821 | |
| 2860 | const opt_type = optional_ptr.ty.elemType(); | 2822 | const opt_type = optional_ptr_ty.elemType(); |
| 2861 | if (opt_type.zigTypeTag() != .Optional) { | 2823 | if (opt_type.zigTypeTag() != .Optional) { |
| 2862 | return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); | 2824 | return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); |
| 2863 | } | 2825 | } |
| 2864 | | 2826 | |
| 2865 | const child_type = try opt_type.optionalChildAlloc(sema.arena); | 2827 | const child_type = try opt_type.optionalChildAlloc(sema.arena); |
| 2866 | const child_pointer = try Module.simplePtrType(sema.arena, child_type, !optional_ptr.ty.isConstPtr(), .One); | 2828 | const child_pointer = try Module.simplePtrType(sema.arena, child_type, !optional_ptr_ty.isConstPtr(), .One); |
| 2867 | | 2829 | |
| 2868 | if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| { | 2830 | if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| { |
| 2869 | const val = try pointer_val.pointerDeref(sema.arena); | 2831 | const val = try pointer_val.pointerDeref(sema.arena); |
| ... | @@ -2871,10 +2833,7 @@ fn zirOptionalPayloadPtr( | ... | @@ -2871,10 +2833,7 @@ fn zirOptionalPayloadPtr( |
| 2871 | return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); | 2833 | return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); |
| 2872 | } | 2834 | } |
| 2873 | // The same Value represents the pointer to the optional and the payload. | 2835 | // The same Value represents the pointer to the optional and the payload. |
| 2874 | return sema.mod.constInst(sema.arena, src, .{ | 2836 | return sema.addConstant(child_pointer, pointer_val); |
| 2875 | .ty = child_pointer, | | |
| 2876 | .val = pointer_val, | | |
| 2877 | }); | | |
| 2878 | } | 2837 | } |
| 2879 | | 2838 | |
| 2880 | try sema.requireRuntimeBlock(block, src); | 2839 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -2898,7 +2857,8 @@ fn zirOptionalPayload( | ... | @@ -2898,7 +2857,8 @@ fn zirOptionalPayload( |
| 2898 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 2857 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2899 | const src = inst_data.src(); | 2858 | const src = inst_data.src(); |
| 2900 | const operand = sema.resolveInst(inst_data.operand); | 2859 | const operand = sema.resolveInst(inst_data.operand); |
| 2901 | const opt_type = operand.ty; | 2860 | const operand_ty = sema.getTypeOf(operand); |
| | 2861 | const opt_type = operand_ty; |
| 2902 | if (opt_type.zigTypeTag() != .Optional) { | 2862 | if (opt_type.zigTypeTag() != .Optional) { |
| 2903 | return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); | 2863 | return sema.mod.fail(&block.base, src, "expected optional type, found {}", .{opt_type}); |
| 2904 | } | 2864 | } |
| ... | @@ -2909,10 +2869,7 @@ fn zirOptionalPayload( | ... | @@ -2909,10 +2869,7 @@ fn zirOptionalPayload( |
| 2909 | if (val.isNull()) { | 2869 | if (val.isNull()) { |
| 2910 | return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); | 2870 | return sema.mod.fail(&block.base, src, "unable to unwrap null", .{}); |
| 2911 | } | 2871 | } |
| 2912 | return sema.mod.constInst(sema.arena, src, .{ | 2872 | return sema.addConstant(child_type, val); |
| 2913 | .ty = child_type, | | |
| 2914 | .val = val, | | |
| 2915 | }); | | |
| 2916 | } | 2873 | } |
| 2917 | | 2874 | |
| 2918 | try sema.requireRuntimeBlock(block, src); | 2875 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -2936,25 +2893,27 @@ fn zirErrUnionPayload( | ... | @@ -2936,25 +2893,27 @@ fn zirErrUnionPayload( |
| 2936 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 2893 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2937 | const src = inst_data.src(); | 2894 | const src = inst_data.src(); |
| 2938 | const operand = sema.resolveInst(inst_data.operand); | 2895 | const operand = sema.resolveInst(inst_data.operand); |
| 2939 | if (operand.ty.zigTypeTag() != .ErrorUnion) | 2896 | const operand_src = src; |
| 2940 | return sema.mod.fail(&block.base, operand.src, "expected error union type, found '{}'", .{operand.ty}); | 2897 | const operand_ty = sema.getTypeOf(operand); |
| | 2898 | if (operand_ty.zigTypeTag() != .ErrorUnion) |
| | 2899 | return sema.mod.fail(&block.base, operand_src, "expected error union type, found '{}'", .{operand_ty}); |
| 2941 | | 2900 | |
| 2942 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { | 2901 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 2943 | if (val.getError()) |name| { | 2902 | if (val.getError()) |name| { |
| 2944 | return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name}); | 2903 | return sema.mod.fail(&block.base, src, "caught unexpected error '{s}'", .{name}); |
| 2945 | } | 2904 | } |
| 2946 | const data = val.castTag(.error_union).?.data; | 2905 | const data = val.castTag(.error_union).?.data; |
| 2947 | return sema.mod.constInst(sema.arena, src, .{ | 2906 | return sema.addConstant( |
| 2948 | .ty = operand.ty.castTag(.error_union).?.data.payload, | 2907 | operand_ty.castTag(.error_union).?.data.payload, |
| 2949 | .val = data, | 2908 | data, |
| 2950 | }); | 2909 | ); |
| 2951 | } | 2910 | } |
| 2952 | try sema.requireRuntimeBlock(block, src); | 2911 | try sema.requireRuntimeBlock(block, src); |
| 2953 | if (safety_check and block.wantSafety()) { | 2912 | if (safety_check and block.wantSafety()) { |
| 2954 | const is_non_err = try block.addUnOp(.is_err, operand); | 2913 | const is_non_err = try block.addUnOp(.is_err, operand); |
| 2955 | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); | 2914 | try sema.addSafetyCheck(block, is_non_err, .unwrap_errunion); |
| 2956 | } | 2915 | } |
| 2957 | const result_ty = operand.ty.castTag(.error_union).?.data.payload; | 2916 | const result_ty = operand_ty.castTag(.error_union).?.data.payload; |
| 2958 | return block.addTyOp(.unwrap_errunion_payload, result_ty, operand); | 2917 | return block.addTyOp(.unwrap_errunion_payload, result_ty, operand); |
| 2959 | } | 2918 | } |
| 2960 | | 2919 | |
| ... | @@ -2971,12 +2930,13 @@ fn zirErrUnionPayloadPtr( | ... | @@ -2971,12 +2930,13 @@ fn zirErrUnionPayloadPtr( |
| 2971 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 2930 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 2972 | const src = inst_data.src(); | 2931 | const src = inst_data.src(); |
| 2973 | const operand = sema.resolveInst(inst_data.operand); | 2932 | const operand = sema.resolveInst(inst_data.operand); |
| 2974 | assert(operand.ty.zigTypeTag() == .Pointer); | 2933 | const operand_ty = sema.getTypeOf(operand); |
| | 2934 | assert(operand_ty.zigTypeTag() == .Pointer); |
| 2975 | | 2935 | |
| 2976 | if (operand.ty.elemType().zigTypeTag() != .ErrorUnion) | 2936 | if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) |
| 2977 | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand.ty.elemType()}); | 2937 | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()}); |
| 2978 | | 2938 | |
| 2979 | const operand_pointer_ty = try Module.simplePtrType(sema.arena, operand.ty.elemType().castTag(.error_union).?.data.payload, !operand.ty.isConstPtr(), .One); | 2939 | const operand_pointer_ty = try Module.simplePtrType(sema.arena, operand_ty.elemType().castTag(.error_union).?.data.payload, !operand_ty.isConstPtr(), .One); |
| 2980 | | 2940 | |
| 2981 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { | 2941 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 2982 | const val = try pointer_val.pointerDeref(sema.arena); | 2942 | const val = try pointer_val.pointerDeref(sema.arena); |
| ... | @@ -2985,13 +2945,13 @@ fn zirErrUnionPayloadPtr( | ... | @@ -2985,13 +2945,13 @@ fn zirErrUnionPayloadPtr( |
| 2985 | } | 2945 | } |
| 2986 | const data = val.castTag(.error_union).?.data; | 2946 | const data = val.castTag(.error_union).?.data; |
| 2987 | // The same Value represents the pointer to the error union and the payload. | 2947 | // The same Value represents the pointer to the error union and the payload. |
| 2988 | return sema.mod.constInst(sema.arena, src, .{ | 2948 | return sema.addConstant( |
| 2989 | .ty = operand_pointer_ty, | 2949 | operand_pointer_ty, |
| 2990 | .val = try Value.Tag.ref_val.create( | 2950 | try Value.Tag.ref_val.create( |
| 2991 | sema.arena, | 2951 | sema.arena, |
| 2992 | data, | 2952 | data, |
| 2993 | ), | 2953 | ), |
| 2994 | }); | 2954 | ); |
| 2995 | } | 2955 | } |
| 2996 | | 2956 | |
| 2997 | try sema.requireRuntimeBlock(block, src); | 2957 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -3010,18 +2970,16 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi | ... | @@ -3010,18 +2970,16 @@ fn zirErrUnionCode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compi |
| 3010 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 2970 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 3011 | const src = inst_data.src(); | 2971 | const src = inst_data.src(); |
| 3012 | const operand = sema.resolveInst(inst_data.operand); | 2972 | const operand = sema.resolveInst(inst_data.operand); |
| 3013 | if (operand.ty.zigTypeTag() != .ErrorUnion) | 2973 | const operand_ty = sema.getTypeOf(operand); |
| 3014 | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty}); | 2974 | if (operand_ty.zigTypeTag() != .ErrorUnion) |
| | 2975 | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty}); |
| 3015 | | 2976 | |
| 3016 | const result_ty = operand.ty.castTag(.error_union).?.data.error_set; | 2977 | const result_ty = operand_ty.castTag(.error_union).?.data.error_set; |
| 3017 | | 2978 | |
| 3018 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { | 2979 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 3019 | assert(val.getError() != null); | 2980 | assert(val.getError() != null); |
| 3020 | const data = val.castTag(.error_union).?.data; | 2981 | const data = val.castTag(.error_union).?.data; |
| 3021 | return sema.mod.constInst(sema.arena, src, .{ | 2982 | return sema.addConstant(result_ty, data); |
| 3022 | .ty = result_ty, | | |
| 3023 | .val = data, | | |
| 3024 | }); | | |
| 3025 | } | 2983 | } |
| 3026 | | 2984 | |
| 3027 | try sema.requireRuntimeBlock(block, src); | 2985 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -3036,21 +2994,19 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co | ... | @@ -3036,21 +2994,19 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co |
| 3036 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 2994 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 3037 | const src = inst_data.src(); | 2995 | const src = inst_data.src(); |
| 3038 | const operand = sema.resolveInst(inst_data.operand); | 2996 | const operand = sema.resolveInst(inst_data.operand); |
| 3039 | assert(operand.ty.zigTypeTag() == .Pointer); | 2997 | const operand_ty = sema.getTypeOf(operand); |
| | 2998 | assert(operand_ty.zigTypeTag() == .Pointer); |
| 3040 | | 2999 | |
| 3041 | if (operand.ty.elemType().zigTypeTag() != .ErrorUnion) | 3000 | if (operand_ty.elemType().zigTypeTag() != .ErrorUnion) |
| 3042 | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand.ty.elemType()}); | 3001 | return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()}); |
| 3043 | | 3002 | |
| 3044 | const result_ty = operand.ty.elemType().castTag(.error_union).?.data.error_set; | 3003 | const result_ty = operand_ty.elemType().castTag(.error_union).?.data.error_set; |
| 3045 | | 3004 | |
| 3046 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { | 3005 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 3047 | const val = try pointer_val.pointerDeref(sema.arena); | 3006 | const val = try pointer_val.pointerDeref(sema.arena); |
| 3048 | assert(val.getError() != null); | 3007 | assert(val.getError() != null); |
| 3049 | const data = val.castTag(.error_union).?.data; | 3008 | const data = val.castTag(.error_union).?.data; |
| 3050 | return sema.mod.constInst(sema.arena, src, .{ | 3009 | return sema.addConstant(result_ty, data); |
| 3051 | .ty = result_ty, | | |
| 3052 | .val = data, | | |
| 3053 | }); | | |
| 3054 | } | 3010 | } |
| 3055 | | 3011 | |
| 3056 | try sema.requireRuntimeBlock(block, src); | 3012 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -3064,9 +3020,10 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde | ... | @@ -3064,9 +3020,10 @@ fn zirEnsureErrPayloadVoid(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde |
| 3064 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; | 3020 | const inst_data = sema.code.instructions.items(.data)[inst].un_tok; |
| 3065 | const src = inst_data.src(); | 3021 | const src = inst_data.src(); |
| 3066 | const operand = sema.resolveInst(inst_data.operand); | 3022 | const operand = sema.resolveInst(inst_data.operand); |
| 3067 | if (operand.ty.zigTypeTag() != .ErrorUnion) | 3023 | const operand_ty = sema.getTypeOf(operand); |
| 3068 | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand.ty}); | 3024 | if (operand_ty.zigTypeTag() != .ErrorUnion) |
| 3069 | if (operand.ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) { | 3025 | return sema.mod.fail(&block.base, src, "expected error union type, found '{}'", .{operand_ty}); |
| | 3026 | if (operand_ty.castTag(.error_union).?.data.payload.zigTypeTag() != .Void) { |
| 3070 | return sema.mod.fail(&block.base, src, "expression value is ignored", .{}); | 3027 | return sema.mod.fail(&block.base, src, "expression value is ignored", .{}); |
| 3071 | } | 3028 | } |
| 3072 | } | 3029 | } |
| ... | @@ -3233,10 +3190,10 @@ fn funcCommon( | ... | @@ -3233,10 +3190,10 @@ fn funcCommon( |
| 3233 | } | 3190 | } |
| 3234 | | 3191 | |
| 3235 | if (is_extern) { | 3192 | if (is_extern) { |
| 3236 | return sema.mod.constInst(sema.arena, src, .{ | 3193 | return sema.addConstant( |
| 3237 | .ty = fn_ty, | 3194 | fn_ty, |
| 3238 | .val = try Value.Tag.extern_fn.create(sema.arena, sema.owner_decl), | 3195 | try Value.Tag.extern_fn.create(sema.arena, sema.owner_decl), |
| 3239 | }); | 3196 | ); |
| 3240 | } | 3197 | } |
| 3241 | | 3198 | |
| 3242 | if (body_inst == 0) { | 3199 | if (body_inst == 0) { |
| ... | @@ -3261,11 +3218,7 @@ fn funcCommon( | ... | @@ -3261,11 +3218,7 @@ fn funcCommon( |
| 3261 | .base = .{ .tag = .function }, | 3218 | .base = .{ .tag = .function }, |
| 3262 | .data = new_func, | 3219 | .data = new_func, |
| 3263 | }; | 3220 | }; |
| 3264 | const result = try sema.mod.constInst(sema.arena, src, .{ | 3221 | return sema.addConstant(fn_ty, Value.initPayload(&fn_payload.base)); |
| 3265 | .ty = fn_ty, | | |
| 3266 | .val = Value.initPayload(&fn_payload.base), | | |
| 3267 | }); | | |
| 3268 | return result; | | |
| 3269 | } | 3222 | } |
| 3270 | | 3223 | |
| 3271 | fn zirAs(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 3224 | fn zirAs(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -3324,7 +3277,7 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -3324,7 +3277,7 @@ fn zirFieldVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 3324 | const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; | 3277 | const extra = sema.code.extraData(Zir.Inst.Field, inst_data.payload_index).data; |
| 3325 | const field_name = sema.code.nullTerminatedString(extra.field_name_start); | 3278 | const field_name = sema.code.nullTerminatedString(extra.field_name_start); |
| 3326 | const object = sema.resolveInst(extra.lhs); | 3279 | const object = sema.resolveInst(extra.lhs); |
| 3327 | const object_ptr = if (object.ty.zigTypeTag() == .Pointer) | 3280 | const object_ptr = if (sema.getTypeOf(object).zigTypeTag() == .Pointer) |
| 3328 | object | 3281 | object |
| 3329 | else | 3282 | else |
| 3330 | try sema.analyzeRef(block, src, object); | 3283 | try sema.analyzeRef(block, src, object); |
| ... | @@ -3397,13 +3350,14 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -3397,13 +3350,14 @@ fn zirIntCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 3397 | ), | 3350 | ), |
| 3398 | }; | 3351 | }; |
| 3399 | | 3352 | |
| 3400 | switch (operand.ty.zigTypeTag()) { | 3353 | const operand_ty = sema.getTypeOf(operand); |
| | 3354 | switch (operand_ty.zigTypeTag()) { |
| 3401 | .ComptimeInt, .Int => {}, | 3355 | .ComptimeInt, .Int => {}, |
| 3402 | else => return sema.mod.fail( | 3356 | else => return sema.mod.fail( |
| 3403 | &block.base, | 3357 | &block.base, |
| 3404 | operand_src, | 3358 | operand_src, |
| 3405 | "expected integer type, found '{}'", | 3359 | "expected integer type, found '{}'", |
| 3406 | .{operand.ty}, | 3360 | .{operand_ty}, |
| 3407 | ), | 3361 | ), |
| 3408 | } | 3362 | } |
| 3409 | | 3363 | |
| ... | @@ -3454,13 +3408,14 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE | ... | @@ -3454,13 +3408,14 @@ fn zirFloatCast(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileE |
| 3454 | ), | 3408 | ), |
| 3455 | }; | 3409 | }; |
| 3456 | | 3410 | |
| 3457 | switch (operand.ty.zigTypeTag()) { | 3411 | const operand_ty = sema.getTypeOf(operand); |
| | 3412 | switch (operand_ty.zigTypeTag()) { |
| 3458 | .ComptimeFloat, .Float, .ComptimeInt => {}, | 3413 | .ComptimeFloat, .Float, .ComptimeInt => {}, |
| 3459 | else => return sema.mod.fail( | 3414 | else => return sema.mod.fail( |
| 3460 | &block.base, | 3415 | &block.base, |
| 3461 | operand_src, | 3416 | operand_src, |
| 3462 | "expected float type, found '{}'", | 3417 | "expected float type, found '{}'", |
| 3463 | .{operand.ty}, | 3418 | .{operand_ty}, |
| 3464 | ), | 3419 | ), |
| 3465 | } | 3420 | } |
| 3466 | | 3421 | |
| ... | @@ -3479,7 +3434,8 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -3479,7 +3434,8 @@ fn zirElemVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 3479 | | 3434 | |
| 3480 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; | 3435 | const bin_inst = sema.code.instructions.items(.data)[inst].bin; |
| 3481 | const array = sema.resolveInst(bin_inst.lhs); | 3436 | const array = sema.resolveInst(bin_inst.lhs); |
| 3482 | const array_ptr = if (array.ty.zigTypeTag() == .Pointer) | 3437 | const array_ty = sema.getTypeOf(array); |
| | 3438 | const array_ptr = if (array_ty.zigTypeTag() == .Pointer) |
| 3483 | array | 3439 | array |
| 3484 | else | 3440 | else |
| 3485 | try sema.analyzeRef(block, sema.src, array); | 3441 | try sema.analyzeRef(block, sema.src, array); |
| ... | @@ -3497,7 +3453,8 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil | ... | @@ -3497,7 +3453,8 @@ fn zirElemValNode(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 3497 | const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node }; | 3453 | const elem_index_src: LazySrcLoc = .{ .node_offset_array_access_index = inst_data.src_node }; |
| 3498 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 3454 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 3499 | const array = sema.resolveInst(extra.lhs); | 3455 | const array = sema.resolveInst(extra.lhs); |
| 3500 | const array_ptr = if (array.ty.zigTypeTag() == .Pointer) | 3456 | const array_ty = sema.getTypeOf(array); |
| | 3457 | const array_ptr = if (array_ty.zigTypeTag() == .Pointer) |
| 3501 | array | 3458 | array |
| 3502 | else | 3459 | else |
| 3503 | try sema.analyzeRef(block, src, array); | 3460 | try sema.analyzeRef(block, src, array); |
| ... | @@ -3705,9 +3662,10 @@ fn analyzeSwitch( | ... | @@ -3705,9 +3662,10 @@ fn analyzeSwitch( |
| 3705 | const src: LazySrcLoc = .{ .node_offset = src_node_offset }; | 3662 | const src: LazySrcLoc = .{ .node_offset = src_node_offset }; |
| 3706 | const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset }; | 3663 | const special_prong_src: LazySrcLoc = .{ .node_offset_switch_special_prong = src_node_offset }; |
| 3707 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset }; | 3664 | const operand_src: LazySrcLoc = .{ .node_offset_switch_operand = src_node_offset }; |
| | 3665 | const operand_ty = sema.getTypeOf(operand); |
| 3708 | | 3666 | |
| 3709 | // Validate usage of '_' prongs. | 3667 | // Validate usage of '_' prongs. |
| 3710 | if (special_prong == .under and !operand.ty.isNonexhaustiveEnum()) { | 3668 | if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { |
| 3711 | const msg = msg: { | 3669 | const msg = msg: { |
| 3712 | const msg = try mod.errMsg( | 3670 | const msg = try mod.errMsg( |
| 3713 | &block.base, | 3671 | &block.base, |
| ... | @@ -3729,9 +3687,9 @@ fn analyzeSwitch( | ... | @@ -3729,9 +3687,9 @@ fn analyzeSwitch( |
| 3729 | } | 3687 | } |
| 3730 | | 3688 | |
| 3731 | // Validate for duplicate items, missing else prong, and invalid range. | 3689 | // Validate for duplicate items, missing else prong, and invalid range. |
| 3732 | switch (operand.ty.zigTypeTag()) { | 3690 | switch (operand_ty.zigTypeTag()) { |
| 3733 | .Enum => { | 3691 | .Enum => { |
| 3734 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand.ty.enumFieldCount()); | 3692 | var seen_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount()); |
| 3735 | defer gpa.free(seen_fields); | 3693 | defer gpa.free(seen_fields); |
| 3736 | | 3694 | |
| 3737 | mem.set(?Module.SwitchProngSrc, seen_fields, null); | 3695 | mem.set(?Module.SwitchProngSrc, seen_fields, null); |
| ... | @@ -3777,7 +3735,7 @@ fn analyzeSwitch( | ... | @@ -3777,7 +3735,7 @@ fn analyzeSwitch( |
| 3777 | ); | 3735 | ); |
| 3778 | } | 3736 | } |
| 3779 | | 3737 | |
| 3780 | try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset); | 3738 | try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset); |
| 3781 | } | 3739 | } |
| 3782 | } | 3740 | } |
| 3783 | const all_tags_handled = for (seen_fields) |seen_src| { | 3741 | const all_tags_handled = for (seen_fields) |seen_src| { |
| ... | @@ -3798,7 +3756,7 @@ fn analyzeSwitch( | ... | @@ -3798,7 +3756,7 @@ fn analyzeSwitch( |
| 3798 | for (seen_fields) |seen_src, i| { | 3756 | for (seen_fields) |seen_src, i| { |
| 3799 | if (seen_src != null) continue; | 3757 | if (seen_src != null) continue; |
| 3800 | | 3758 | |
| 3801 | const field_name = operand.ty.enumFieldName(i); | 3759 | const field_name = operand_ty.enumFieldName(i); |
| 3802 | | 3760 | |
| 3803 | // TODO have this point to the tag decl instead of here | 3761 | // TODO have this point to the tag decl instead of here |
| 3804 | try mod.errNote( | 3762 | try mod.errNote( |
| ... | @@ -3810,10 +3768,10 @@ fn analyzeSwitch( | ... | @@ -3810,10 +3768,10 @@ fn analyzeSwitch( |
| 3810 | ); | 3768 | ); |
| 3811 | } | 3769 | } |
| 3812 | try mod.errNoteNonLazy( | 3770 | try mod.errNoteNonLazy( |
| 3813 | operand.ty.declSrcLoc(), | 3771 | operand_ty.declSrcLoc(), |
| 3814 | msg, | 3772 | msg, |
| 3815 | "enum '{}' declared here", | 3773 | "enum '{}' declared here", |
| 3816 | .{operand.ty}, | 3774 | .{operand_ty}, |
| 3817 | ); | 3775 | ); |
| 3818 | break :msg msg; | 3776 | break :msg msg; |
| 3819 | }; | 3777 | }; |
| ... | @@ -3908,12 +3866,12 @@ fn analyzeSwitch( | ... | @@ -3908,12 +3866,12 @@ fn analyzeSwitch( |
| 3908 | } | 3866 | } |
| 3909 | | 3867 | |
| 3910 | check_range: { | 3868 | check_range: { |
| 3911 | if (operand.ty.zigTypeTag() == .Int) { | 3869 | if (operand_ty.zigTypeTag() == .Int) { |
| 3912 | var arena = std.heap.ArenaAllocator.init(gpa); | 3870 | var arena = std.heap.ArenaAllocator.init(gpa); |
| 3913 | defer arena.deinit(); | 3871 | defer arena.deinit(); |
| 3914 | | 3872 | |
| 3915 | const min_int = try operand.ty.minInt(&arena, mod.getTarget()); | 3873 | const min_int = try operand_ty.minInt(&arena, mod.getTarget()); |
| 3916 | const max_int = try operand.ty.maxInt(&arena, mod.getTarget()); | 3874 | const max_int = try operand_ty.maxInt(&arena, mod.getTarget()); |
| 3917 | if (try range_set.spans(min_int, max_int)) { | 3875 | if (try range_set.spans(min_int, max_int)) { |
| 3918 | if (special_prong == .@"else") { | 3876 | if (special_prong == .@"else") { |
| 3919 | return mod.fail( | 3877 | return mod.fail( |
| ... | @@ -3983,7 +3941,7 @@ fn analyzeSwitch( | ... | @@ -3983,7 +3941,7 @@ fn analyzeSwitch( |
| 3983 | ); | 3941 | ); |
| 3984 | } | 3942 | } |
| 3985 | | 3943 | |
| 3986 | try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset); | 3944 | try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset); |
| 3987 | } | 3945 | } |
| 3988 | } | 3946 | } |
| 3989 | switch (special_prong) { | 3947 | switch (special_prong) { |
| ... | @@ -4015,7 +3973,7 @@ fn analyzeSwitch( | ... | @@ -4015,7 +3973,7 @@ fn analyzeSwitch( |
| 4015 | &block.base, | 3973 | &block.base, |
| 4016 | src, | 3974 | src, |
| 4017 | "else prong required when switching on type '{}'", | 3975 | "else prong required when switching on type '{}'", |
| 4018 | .{operand.ty}, | 3976 | .{operand_ty}, |
| 4019 | ); | 3977 | ); |
| 4020 | } | 3978 | } |
| 4021 | | 3979 | |
| ... | @@ -4063,7 +4021,7 @@ fn analyzeSwitch( | ... | @@ -4063,7 +4021,7 @@ fn analyzeSwitch( |
| 4063 | ); | 4021 | ); |
| 4064 | } | 4022 | } |
| 4065 | | 4023 | |
| 4066 | try sema.validateSwitchNoRange(block, ranges_len, operand.ty, src_node_offset); | 4024 | try sema.validateSwitchNoRange(block, ranges_len, operand_ty, src_node_offset); |
| 4067 | } | 4025 | } |
| 4068 | } | 4026 | } |
| 4069 | }, | 4027 | }, |
| ... | @@ -4083,20 +4041,15 @@ fn analyzeSwitch( | ... | @@ -4083,20 +4041,15 @@ fn analyzeSwitch( |
| 4083 | .ComptimeFloat, | 4041 | .ComptimeFloat, |
| 4084 | .Float, | 4042 | .Float, |
| 4085 | => return mod.fail(&block.base, operand_src, "invalid switch operand type '{}'", .{ | 4043 | => return mod.fail(&block.base, operand_src, "invalid switch operand type '{}'", .{ |
| 4086 | operand.ty, | 4044 | operand_ty, |
| 4087 | }), | 4045 | }), |
| 4088 | } | 4046 | } |
| 4089 | | 4047 | |
| 4090 | const block_inst = try sema.arena.create(Inst.Block); | 4048 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 4091 | block_inst.* = .{ | 4049 | try sema.air_instructions.append(gpa, .{ |
| 4092 | .base = .{ | 4050 | .tag = .block, |
| 4093 | .tag = Inst.Block.base_tag, | 4051 | .data = undefined, |
| 4094 | .ty = undefined, // Set after analysis. | 4052 | }); |
| 4095 | .src = src, | | |
| 4096 | }, | | |
| 4097 | .body = undefined, | | |
| 4098 | }; | | |
| 4099 | | | |
| 4100 | var label: Scope.Block.Label = .{ | 4053 | var label: Scope.Block.Label = .{ |
| 4101 | .zir_block = switch_inst, | 4054 | .zir_block = switch_inst, |
| 4102 | .merges = .{ | 4055 | .merges = .{ |
| ... | @@ -4634,7 +4587,7 @@ fn zirBitwise( | ... | @@ -4634,7 +4587,7 @@ fn zirBitwise( |
| 4634 | const lhs_ty = sema.getTypeOf(lhs); | 4587 | const lhs_ty = sema.getTypeOf(lhs); |
| 4635 | const rhs_ty = sema.getTypeOf(rhs); | 4588 | const rhs_ty = sema.getTypeOf(rhs); |
| 4636 | | 4589 | |
| 4637 | const instructions = &[_]Air.Inst.Index{ lhs, rhs }; | 4590 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| 4638 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); | 4591 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| 4639 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | 4592 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 4640 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); | 4593 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| ... | @@ -4763,18 +4716,8 @@ fn analyzeArithmetic( | ... | @@ -4763,18 +4716,8 @@ fn analyzeArithmetic( |
| 4763 | lhs_src: LazySrcLoc, | 4716 | lhs_src: LazySrcLoc, |
| 4764 | rhs_src: LazySrcLoc, | 4717 | rhs_src: LazySrcLoc, |
| 4765 | ) CompileError!Air.Inst.Ref { | 4718 | ) CompileError!Air.Inst.Ref { |
| 4766 | const instructions = &[_]Air.Inst.Index{ lhs, rhs }; | 4719 | const lhs_ty = sema.getTypeOf(lhs); |
| 4767 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); | 4720 | const rhs_ty = sema.getTypeOf(rhs); |
| 4768 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | | |
| 4769 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); | | |
| 4770 | | | |
| 4771 | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) | | |
| 4772 | resolved_type.elemType() | | |
| 4773 | else | | |
| 4774 | resolved_type; | | |
| 4775 | | | |
| 4776 | const scalar_tag = scalar_type.zigTypeTag(); | | |
| 4777 | | | |
| 4778 | if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { | 4721 | if (lhs_ty.zigTypeTag() == .Vector and rhs_ty.zigTypeTag() == .Vector) { |
| 4779 | if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { | 4722 | if (lhs_ty.arrayLen() != rhs_ty.arrayLen()) { |
| 4780 | return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{ | 4723 | return sema.mod.fail(&block.base, src, "vector length mismatch: {d} and {d}", .{ |
| ... | @@ -4790,6 +4733,18 @@ fn analyzeArithmetic( | ... | @@ -4790,6 +4733,18 @@ fn analyzeArithmetic( |
| 4790 | }); | 4733 | }); |
| 4791 | } | 4734 | } |
| 4792 | | 4735 | |
| | 4736 | const instructions = &[_]Air.Inst.Ref{ lhs, rhs }; |
| | 4737 | const resolved_type = try sema.resolvePeerTypes(block, src, instructions); |
| | 4738 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| | 4739 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| | 4740 | |
| | 4741 | const scalar_type = if (resolved_type.zigTypeTag() == .Vector) |
| | 4742 | resolved_type.elemType() |
| | 4743 | else |
| | 4744 | resolved_type; |
| | 4745 | |
| | 4746 | const scalar_tag = scalar_type.zigTypeTag(); |
| | 4747 | |
| 4793 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; | 4748 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 4794 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; | 4749 | const is_float = scalar_tag == .Float or scalar_tag == .ComptimeFloat; |
| 4795 | | 4750 | |
| ... | @@ -4807,10 +4762,7 @@ fn analyzeArithmetic( | ... | @@ -4807,10 +4762,7 @@ fn analyzeArithmetic( |
| 4807 | if (rhs_val.compareWithZero(.eq)) { | 4762 | if (rhs_val.compareWithZero(.eq)) { |
| 4808 | switch (zir_tag) { | 4763 | switch (zir_tag) { |
| 4809 | .add, .addwrap, .sub, .subwrap => { | 4764 | .add, .addwrap, .sub, .subwrap => { |
| 4810 | return sema.mod.constInst(sema.arena, src, .{ | 4765 | return sema.addConstant(scalar_type, lhs_val); |
| 4811 | .ty = scalar_type, | | |
| 4812 | .val = lhs_val, | | |
| 4813 | }); | | |
| 4814 | }, | 4766 | }, |
| 4815 | else => {}, | 4767 | else => {}, |
| 4816 | } | 4768 | } |
| ... | @@ -4850,10 +4802,7 @@ fn analyzeArithmetic( | ... | @@ -4850,10 +4802,7 @@ fn analyzeArithmetic( |
| 4850 | | 4802 | |
| 4851 | log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tag), lhs_val, rhs_val, value }); | 4803 | log.debug("{s}({}, {}) result: {}", .{ @tagName(zir_tag), lhs_val, rhs_val, value }); |
| 4852 | | 4804 | |
| 4853 | return sema.mod.constInst(sema.arena, src, .{ | 4805 | return sema.addConstant(scalar_type, value); |
| 4854 | .ty = scalar_type, | | |
| 4855 | .val = value, | | |
| 4856 | }); | | |
| 4857 | } | 4806 | } |
| 4858 | } | 4807 | } |
| 4859 | | 4808 | |
| ... | @@ -5167,16 +5116,16 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -5167,16 +5116,16 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 5167 | // args: []const FnArg, | 5116 | // args: []const FnArg, |
| 5168 | field_values[5] = Value.initTag(.null_value); // TODO | 5117 | field_values[5] = Value.initTag(.null_value); // TODO |
| 5169 | | 5118 | |
| 5170 | return sema.mod.constInst(sema.arena, src, .{ | 5119 | return sema.addConstant( |
| 5171 | .ty = type_info_ty, | 5120 | type_info_ty, |
| 5172 | .val = try Value.Tag.@"union".create(sema.arena, .{ | 5121 | try Value.Tag.@"union".create(sema.arena, .{ |
| 5173 | .tag = try Value.Tag.enum_field_index.create( | 5122 | .tag = try Value.Tag.enum_field_index.create( |
| 5174 | sema.arena, | 5123 | sema.arena, |
| 5175 | @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn), | 5124 | @enumToInt(@typeInfo(std.builtin.TypeInfo).Union.tag_type.?.Fn), |
| 5176 | ), | 5125 | ), |
| 5177 | .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr), | 5126 | .val = try Value.Tag.@"struct".create(sema.arena, field_values.ptr), |
| 5178 | }), | 5127 | }), |
| 5179 | }); | 5128 | ); |
| 5180 | }, | 5129 | }, |
| 5181 | else => |t| return sema.mod.fail(&block.base, src, "TODO: implement zirTypeInfo for {s}", .{ | 5130 | else => |t| return sema.mod.fail(&block.base, src, "TODO: implement zirTypeInfo for {s}", .{ |
| 5182 | @tagName(t), | 5131 | @tagName(t), |
| ... | @@ -5189,7 +5138,8 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro | ... | @@ -5189,7 +5138,8 @@ fn zirTypeof(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro |
| 5189 | const zir_datas = sema.code.instructions.items(.data); | 5138 | const zir_datas = sema.code.instructions.items(.data); |
| 5190 | const inst_data = zir_datas[inst].un_node; | 5139 | const inst_data = zir_datas[inst].un_node; |
| 5191 | const operand = sema.resolveInst(inst_data.operand); | 5140 | const operand = sema.resolveInst(inst_data.operand); |
| 5192 | return sema.addType(operand.ty); | 5141 | const operand_ty = sema.getTypeOf(operand); |
| | 5142 | return sema.addType(operand_ty); |
| 5193 | } | 5143 | } |
| 5194 | | 5144 | |
| 5195 | fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5145 | fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -5241,11 +5191,12 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -5241,11 +5191,12 @@ fn zirBoolNot(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 5241 | | 5191 | |
| 5242 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; | 5192 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 5243 | const src = inst_data.src(); | 5193 | const src = inst_data.src(); |
| | 5194 | const operand_src = src; // TODO put this on the operand, not the `!` |
| 5244 | const uncasted_operand = sema.resolveInst(inst_data.operand); | 5195 | const uncasted_operand = sema.resolveInst(inst_data.operand); |
| 5245 | | 5196 | |
| 5246 | const bool_type = Type.initTag(.bool); | 5197 | const bool_type = Type.initTag(.bool); |
| 5247 | const operand = try sema.coerce(block, bool_type, uncasted_operand, uncasted_operand.src); | 5198 | const operand = try sema.coerce(block, bool_type, uncasted_operand, operand_src); |
| 5248 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { | 5199 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| { |
| 5249 | if (val.toBool()) { | 5200 | if (val.toBool()) { |
| 5250 | return Air.Inst.Ref.bool_false; | 5201 | return Air.Inst.Ref.bool_false; |
| 5251 | } else { | 5202 | } else { |
| ... | @@ -5267,12 +5218,13 @@ fn zirBoolBr( | ... | @@ -5267,12 +5218,13 @@ fn zirBoolBr( |
| 5267 | | 5218 | |
| 5268 | const datas = sema.code.instructions.items(.data); | 5219 | const datas = sema.code.instructions.items(.data); |
| 5269 | const inst_data = datas[inst].bool_br; | 5220 | const inst_data = datas[inst].bool_br; |
| 5270 | const src: LazySrcLoc = .unneeded; | | |
| 5271 | const lhs = sema.resolveInst(inst_data.lhs); | 5221 | const lhs = sema.resolveInst(inst_data.lhs); |
| | 5222 | const lhs_src = sema.src; |
| 5272 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); | 5223 | const extra = sema.code.extraData(Zir.Inst.Block, inst_data.payload_index); |
| 5273 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; | 5224 | const body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| | 5225 | const gpa = sema.gpa; |
| 5274 | | 5226 | |
| 5275 | if (try sema.resolveDefinedValue(parent_block, src, lhs)) |lhs_val| { | 5227 | if (try sema.resolveDefinedValue(parent_block, lhs_src, lhs)) |lhs_val| { |
| 5276 | if (lhs_val.toBool() == is_bool_or) { | 5228 | if (lhs_val.toBool() == is_bool_or) { |
| 5277 | if (is_bool_or) { | 5229 | if (is_bool_or) { |
| 5278 | return Air.Inst.Ref.bool_true; | 5230 | return Air.Inst.Ref.bool_true; |
| ... | @@ -5286,49 +5238,59 @@ fn zirBoolBr( | ... | @@ -5286,49 +5238,59 @@ fn zirBoolBr( |
| 5286 | return sema.resolveBody(parent_block, body); | 5238 | return sema.resolveBody(parent_block, body); |
| 5287 | } | 5239 | } |
| 5288 | | 5240 | |
| 5289 | const block_inst = try sema.arena.create(Inst.Block); | 5241 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| 5290 | block_inst.* = .{ | 5242 | try sema.air_instructions.append(gpa, .{ |
| 5291 | .base = .{ | 5243 | .tag = .block, |
| 5292 | .tag = Inst.Block.base_tag, | 5244 | .data = .{ .ty_pl = .{ |
| 5293 | .ty = Type.initTag(.bool), | 5245 | .ty = .bool_type, |
| 5294 | .src = src, | 5246 | .payload = undefined, |
| 5295 | }, | 5247 | } }, |
| 5296 | .body = undefined, | 5248 | }); |
| 5297 | }; | | |
| 5298 | | 5249 | |
| 5299 | var child_block = parent_block.makeSubBlock(); | 5250 | var child_block = parent_block.makeSubBlock(); |
| 5300 | child_block.runtime_loop = null; | 5251 | child_block.runtime_loop = null; |
| 5301 | child_block.runtime_cond = lhs.src; | 5252 | child_block.runtime_cond = lhs_src; |
| 5302 | child_block.runtime_index += 1; | 5253 | child_block.runtime_index += 1; |
| 5303 | defer child_block.instructions.deinit(sema.gpa); | 5254 | defer child_block.instructions.deinit(gpa); |
| 5304 | | 5255 | |
| 5305 | var then_block = child_block.makeSubBlock(); | 5256 | var then_block = child_block.makeSubBlock(); |
| 5306 | defer then_block.instructions.deinit(sema.gpa); | 5257 | defer then_block.instructions.deinit(gpa); |
| 5307 | | 5258 | |
| 5308 | var else_block = child_block.makeSubBlock(); | 5259 | var else_block = child_block.makeSubBlock(); |
| 5309 | defer else_block.instructions.deinit(sema.gpa); | 5260 | defer else_block.instructions.deinit(gpa); |
| 5310 | | 5261 | |
| 5311 | const lhs_block = if (is_bool_or) &then_block else &else_block; | 5262 | const lhs_block = if (is_bool_or) &then_block else &else_block; |
| 5312 | const rhs_block = if (is_bool_or) &else_block else &then_block; | 5263 | const rhs_block = if (is_bool_or) &else_block else &then_block; |
| 5313 | | 5264 | |
| 5314 | const lhs_result = try sema.mod.constInst(sema.arena, src, .{ | 5265 | const lhs_result: Air.Inst.Ref = if (is_bool_or) .bool_true else .bool_false; |
| 5315 | .ty = Type.initTag(.bool), | 5266 | _ = try lhs_block.addBr(block_inst, lhs_result); |
| 5316 | .val = if (is_bool_or) Value.initTag(.bool_true) else Value.initTag(.bool_false), | | |
| 5317 | }); | | |
| 5318 | _ = try lhs_block.addBr(src, block_inst, lhs_result); | | |
| 5319 | | 5267 | |
| 5320 | const rhs_result = try sema.resolveBody(rhs_block, body); | 5268 | const rhs_result = try sema.resolveBody(rhs_block, body); |
| 5321 | _ = try rhs_block.addBr(src, block_inst, rhs_result); | 5269 | _ = try rhs_block.addBr(block_inst, rhs_result); |
| 5322 | | 5270 | |
| 5323 | const air_then_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, then_block.instructions.items) }; | 5271 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).Struct.fields.len + |
| 5324 | const air_else_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, else_block.instructions.items) }; | 5272 | then_block.instructions.items.len + else_block.instructions.items.len + |
| 5325 | _ = try child_block.addCondBr(src, lhs, air_then_body, air_else_body); | 5273 | @typeInfo(Air.Block).Struct.fields.len + child_block.instructions.items.len); |
| 5326 | | 5274 | |
| 5327 | block_inst.body = .{ | 5275 | sema.air_instructions.items(.data)[block_inst].ty_pl.payload = sema.addExtraAssumeCapacity( |
| 5328 | .instructions = try sema.arena.dupe(Air.Inst.Index, child_block.instructions.items), | 5276 | Air.Block{ .body_len = @intCast(u32, child_block.instructions.items.len) }, |
| 5329 | }; | 5277 | ); |
| 5330 | try parent_block.instructions.append(sema.gpa, &block_inst.base); | 5278 | sema.air_extra.appendSliceAssumeCapacity(child_block.instructions.items); |
| 5331 | return &block_inst.base; | 5279 | |
| | 5280 | const cond_br_payload = sema.addExtraAssumeCapacity(Air.CondBr{ |
| | 5281 | .then_body_len = @intCast(u32, then_block.instructions.items.len), |
| | 5282 | .else_body_len = @intCast(u32, else_block.instructions.items.len), |
| | 5283 | }); |
| | 5284 | sema.air_extra.appendSliceAssumeCapacity(then_block.instructions.items); |
| | 5285 | sema.air_extra.appendSliceAssumeCapacity(else_block.instructions.items); |
| | 5286 | |
| | 5287 | _ = try child_block.addInst(.{ .tag = .cond_br, .data = .{ .pl_op = .{ |
| | 5288 | .operand = lhs, |
| | 5289 | .payload = cond_br_payload, |
| | 5290 | } } }); |
| | 5291 | |
| | 5292 | try parent_block.instructions.append(gpa, block_inst); |
| | 5293 | return indexToRef(block_inst); |
| 5332 | } | 5294 | } |
| 5333 | | 5295 | |
| 5334 | fn zirIsNonNull( | 5296 | fn zirIsNonNull( |
| ... | @@ -5439,7 +5401,7 @@ fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil | ... | @@ -5439,7 +5401,7 @@ fn zirUnreachable(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil |
| 5439 | if (safety_check and block.wantSafety()) { | 5401 | if (safety_check and block.wantSafety()) { |
| 5440 | return sema.safetyPanic(block, src, .unreach); | 5402 | return sema.safetyPanic(block, src, .unreach); |
| 5441 | } else { | 5403 | } else { |
| 5442 | _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach); | 5404 | _ = try block.addNoOp(.unreach); |
| 5443 | return always_noreturn; | 5405 | return always_noreturn; |
| 5444 | } | 5406 | } |
| 5445 | } | 5407 | } |
| ... | @@ -5461,10 +5423,10 @@ fn zirRetErrValue( | ... | @@ -5461,10 +5423,10 @@ fn zirRetErrValue( |
| 5461 | } | 5423 | } |
| 5462 | // Return the error code from the function. | 5424 | // Return the error code from the function. |
| 5463 | const kv = try sema.mod.getErrorValue(err_name); | 5425 | const kv = try sema.mod.getErrorValue(err_name); |
| 5464 | const result_inst = try sema.mod.constInst(sema.arena, src, .{ | 5426 | const result_inst = try sema.addConstant( |
| 5465 | .ty = try Type.Tag.error_set_single.create(sema.arena, kv.key), | 5427 | try Type.Tag.error_set_single.create(sema.arena, kv.key), |
| 5466 | .val = try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }), | 5428 | try Value.Tag.@"error".create(sema.arena, .{ .name = kv.key }), |
| 5467 | }); | 5429 | ); |
| 5468 | return sema.analyzeRet(block, result_inst, src, true); | 5430 | return sema.analyzeRet(block, result_inst, src, true); |
| 5469 | } | 5431 | } |
| 5470 | | 5432 | |
| ... | @@ -5505,7 +5467,7 @@ fn analyzeRet( | ... | @@ -5505,7 +5467,7 @@ fn analyzeRet( |
| 5505 | if (block.inlining) |inlining| { | 5467 | if (block.inlining) |inlining| { |
| 5506 | // We are inlining a function call; rewrite the `ret` as a `break`. | 5468 | // We are inlining a function call; rewrite the `ret` as a `break`. |
| 5507 | try inlining.merges.results.append(sema.gpa, operand); | 5469 | try inlining.merges.results.append(sema.gpa, operand); |
| 5508 | _ = try block.addBr(src, inlining.merges.block_inst, operand); | 5470 | _ = try block.addBr(inlining.merges.block_inst, operand); |
| 5509 | return always_noreturn; | 5471 | return always_noreturn; |
| 5510 | } | 5472 | } |
| 5511 | | 5473 | |
| ... | @@ -5613,10 +5575,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co | ... | @@ -5613,10 +5575,7 @@ fn zirStructInitEmpty(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co |
| 5613 | const src = inst_data.src(); | 5575 | const src = inst_data.src(); |
| 5614 | const struct_type = try sema.resolveType(block, src, inst_data.operand); | 5576 | const struct_type = try sema.resolveType(block, src, inst_data.operand); |
| 5615 | | 5577 | |
| 5616 | return sema.mod.constInst(sema.arena, src, .{ | 5578 | return sema.addConstant(struct_type, Value.initTag(.empty_struct_value)); |
| 5617 | .ty = struct_type, | | |
| 5618 | .val = Value.initTag(.empty_struct_value), | | |
| 5619 | }); | | |
| 5620 | } | 5579 | } |
| 5621 | | 5580 | |
| 5622 | fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5581 | fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -5696,10 +5655,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: | ... | @@ -5696,10 +5655,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: |
| 5696 | root_msg = try mod.errMsg(&block.base, src, template, args); | 5655 | root_msg = try mod.errMsg(&block.base, src, template, args); |
| 5697 | } | 5656 | } |
| 5698 | } else { | 5657 | } else { |
| 5699 | field_inits[i] = try mod.constInst(sema.arena, src, .{ | 5658 | field_inits[i] = try sema.addConstant(field.ty, field.default_val); |
| 5700 | .ty = field.ty, | | |
| 5701 | .val = field.default_val, | | |
| 5702 | }); | | |
| 5703 | } | 5659 | } |
| 5704 | } | 5660 | } |
| 5705 | if (root_msg) |msg| { | 5661 | if (root_msg) |msg| { |
| ... | @@ -5729,10 +5685,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: | ... | @@ -5729,10 +5685,7 @@ fn zirStructInit(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index, is_ref: |
| 5729 | for (field_inits) |field_init, i| { | 5685 | for (field_inits) |field_init, i| { |
| 5730 | values[i] = field_init.value().?; | 5686 | values[i] = field_init.value().?; |
| 5731 | } | 5687 | } |
| 5732 | return mod.constInst(sema.arena, src, .{ | 5688 | return sema.addConstant(struct_ty, try Value.Tag.@"struct".create(sema.arena, values.ptr)); |
| 5733 | .ty = struct_ty, | | |
| 5734 | .val = try Value.Tag.@"struct".create(sema.arena, values.ptr), | | |
| 5735 | }); | | |
| 5736 | } | 5689 | } |
| 5737 | | 5690 | |
| 5738 | return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); | 5691 | return mod.fail(&block.base, src, "TODO: Sema.zirStructInit for runtime-known struct values", .{}); |
| ... | @@ -5913,20 +5866,13 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -5913,20 +5866,13 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 5913 | .base = .{ .tag = .int_u64 }, | 5866 | .base = .{ .tag = .int_u64 }, |
| 5914 | .data = addr, | 5867 | .data = addr, |
| 5915 | }; | 5868 | }; |
| 5916 | return sema.mod.constInst(sema.arena, src, .{ | 5869 | return sema.addConstant(type_res, Value.initPayload(&val_payload.base)); |
| 5917 | .ty = type_res, | | |
| 5918 | .val = Value.initPayload(&val_payload.base), | | |
| 5919 | }); | | |
| 5920 | } | 5870 | } |
| 5921 | | 5871 | |
| 5922 | try sema.requireRuntimeBlock(block, src); | 5872 | try sema.requireRuntimeBlock(block, src); |
| 5923 | if (block.wantSafety()) { | 5873 | if (block.wantSafety()) { |
| 5924 | const zero = try sema.mod.constInst(sema.arena, src, .{ | | |
| 5925 | .ty = Type.initTag(.u64), | | |
| 5926 | .val = Value.initTag(.zero), | | |
| 5927 | }); | | |
| 5928 | if (!type_res.isAllowzeroPtr()) { | 5874 | if (!type_res.isAllowzeroPtr()) { |
| 5929 | const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, zero); | 5875 | const is_non_zero = try block.addBinOp(.cmp_neq, operand_coerced, .zero_usize); |
| 5930 | try sema.addSafetyCheck(block, is_non_zero, .cast_to_null); | 5876 | try sema.addSafetyCheck(block, is_non_zero, .cast_to_null); |
| 5931 | } | 5877 | } |
| 5932 | | 5878 | |
| ... | @@ -5936,12 +5882,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -5936,12 +5882,12 @@ fn zirIntToPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 5936 | .base = .{ .tag = .int_u64 }, | 5882 | .base = .{ .tag = .int_u64 }, |
| 5937 | .data = ptr_align - 1, | 5883 | .data = ptr_align - 1, |
| 5938 | }; | 5884 | }; |
| 5939 | const align_minus_1 = try sema.mod.constInst(sema.arena, src, .{ | 5885 | const align_minus_1 = try sema.addConstant( |
| 5940 | .ty = Type.initTag(.u64), | 5886 | Type.initTag(.usize), |
| 5941 | .val = Value.initPayload(&val_payload.base), | 5887 | Value.initPayload(&val_payload.base), |
| 5942 | }); | 5888 | ); |
| 5943 | const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1); | 5889 | const remainder = try block.addBinOp(.bit_and, operand_coerced, align_minus_1); |
| 5944 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, zero); | 5890 | const is_aligned = try block.addBinOp(.cmp_eq, remainder, .zero_usize); |
| 5945 | try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment); | 5891 | try sema.addSafetyCheck(block, is_aligned, .incorrect_alignment); |
| 5946 | } | 5892 | } |
| 5947 | } | 5893 | } |
| ... | @@ -6217,10 +6163,10 @@ fn zirVarExtended( | ... | @@ -6217,10 +6163,10 @@ fn zirVarExtended( |
| 6217 | .is_mutable = true, // TODO get rid of this unused field | 6163 | .is_mutable = true, // TODO get rid of this unused field |
| 6218 | .is_threadlocal = small.is_threadlocal, | 6164 | .is_threadlocal = small.is_threadlocal, |
| 6219 | }; | 6165 | }; |
| 6220 | const result = try sema.mod.constInst(sema.arena, src, .{ | 6166 | const result = try sema.addConstant( |
| 6221 | .ty = var_ty, | 6167 | var_ty, |
| 6222 | .val = try Value.Tag.variable.create(sema.arena, new_var), | 6168 | try Value.Tag.variable.create(sema.arena, new_var), |
| 6223 | }); | 6169 | ); |
| 6224 | return result; | 6170 | return result; |
| 6225 | } | 6171 | } |
| 6226 | | 6172 | |
| ... | @@ -6380,32 +6326,13 @@ pub const PanicId = enum { | ... | @@ -6380,32 +6326,13 @@ pub const PanicId = enum { |
| 6380 | invalid_error_code, | 6326 | invalid_error_code, |
| 6381 | }; | 6327 | }; |
| 6382 | | 6328 | |
| 6383 | fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, panic_id: PanicId) !void { | 6329 | fn addSafetyCheck( |
| 6384 | const block_inst = try sema.arena.create(Inst.Block); | 6330 | sema: *Sema, |
| 6385 | block_inst.* = .{ | 6331 | parent_block: *Scope.Block, |
| 6386 | .base = .{ | 6332 | ok: Air.Inst.Ref, |
| 6387 | .tag = Inst.Block.base_tag, | 6333 | panic_id: PanicId, |
| 6388 | .ty = Type.initTag(.void), | 6334 | ) !void { |
| 6389 | .src = ok.src, | 6335 | const gpa = sema.gpa; |
| 6390 | }, | | |
| 6391 | .body = .{ | | |
| 6392 | .instructions = try sema.arena.alloc(Air.Inst.Index, 1), // Only need space for the condbr. | | |
| 6393 | }, | | |
| 6394 | }; | | |
| 6395 | | | |
| 6396 | const ok_body: ir.Body = .{ | | |
| 6397 | .instructions = try sema.arena.alloc(Air.Inst.Index, 1), // Only need space for the br_void. | | |
| 6398 | }; | | |
| 6399 | const br_void = try sema.arena.create(Inst.BrVoid); | | |
| 6400 | br_void.* = .{ | | |
| 6401 | .base = .{ | | |
| 6402 | .tag = .br_void, | | |
| 6403 | .ty = Type.initTag(.noreturn), | | |
| 6404 | .src = ok.src, | | |
| 6405 | }, | | |
| 6406 | .block = block_inst, | | |
| 6407 | }; | | |
| 6408 | ok_body.instructions[0] = &br_void.base; | | |
| 6409 | | 6336 | |
| 6410 | var fail_block: Scope.Block = .{ | 6337 | var fail_block: Scope.Block = .{ |
| 6411 | .parent = parent_block, | 6338 | .parent = parent_block, |
| ... | @@ -6416,26 +6343,55 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, pan | ... | @@ -6416,26 +6343,55 @@ fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, pan |
| 6416 | .is_comptime = parent_block.is_comptime, | 6343 | .is_comptime = parent_block.is_comptime, |
| 6417 | }; | 6344 | }; |
| 6418 | | 6345 | |
| 6419 | defer fail_block.instructions.deinit(sema.gpa); | 6346 | defer fail_block.instructions.deinit(gpa); |
| 6420 | | 6347 | |
| 6421 | _ = try sema.safetyPanic(&fail_block, ok.src, panic_id); | 6348 | _ = try sema.safetyPanic(&fail_block, .unneeded, panic_id); |
| 6422 | | 6349 | |
| 6423 | const fail_body: ir.Body = .{ .instructions = try sema.arena.dupe(Air.Inst.Index, fail_block.instructions.items) }; | 6350 | try parent_block.instructions.ensureUnusedCapacity(gpa, 1); |
| 6424 | | 6351 | |
| 6425 | const condbr = try sema.arena.create(Inst.CondBr); | 6352 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 6426 | condbr.* = .{ | 6353 | 1 + // The main block only needs space for the cond_br. |
| 6427 | .base = .{ | 6354 | @typeInfo(Air.CondBr).Struct.fields.len + |
| 6428 | .tag = .condbr, | 6355 | 1 + // The ok branch of the cond_br only needs space for the br. |
| 6429 | .ty = Type.initTag(.noreturn), | 6356 | fail_block.instructions.items.len); |
| 6430 | .src = ok.src, | | |
| 6431 | }, | | |
| 6432 | .condition = ok, | | |
| 6433 | .then_body = ok_body, | | |
| 6434 | .else_body = fail_body, | | |
| 6435 | }; | | |
| 6436 | block_inst.body.instructions[0] = &condbr.base; | | |
| 6437 | | 6357 | |
| 6438 | try parent_block.instructions.append(sema.gpa, &block_inst.base); | 6358 | try sema.air_instructions.ensureUnusedCapacity(gpa, 3); |
| | 6359 | const block_inst = @intCast(Air.Inst.Index, sema.air_instructions.len); |
| | 6360 | const cond_br_inst = block_inst + 1; |
| | 6361 | const br_inst = cond_br_inst + 1; |
| | 6362 | sema.air_instructions.appendAssumeCapacity(gpa, .{ |
| | 6363 | .tag = .block, |
| | 6364 | .data = .{ .ty_pl = .{ |
| | 6365 | .ty = .void_type, |
| | 6366 | .payload = sema.addExtraAssumeCapacity(Air.Block{ |
| | 6367 | .body_len = 1, |
| | 6368 | }), |
| | 6369 | } }, |
| | 6370 | }); |
| | 6371 | sema.air_extra.appendAssumeCapacity(cond_br_inst); |
| | 6372 | |
| | 6373 | sema.air_instructions.appendAssumeCapacity(gpa, .{ |
| | 6374 | .tag = .cond_br, |
| | 6375 | .data = .{ .pl_op = .{ |
| | 6376 | .operand = ok, |
| | 6377 | .payload = sema.addExtraAssumeCapacity(Air.CondBr{ |
| | 6378 | .then_body_len = 1, |
| | 6379 | .else_body_len = @intCast(u32, fail_block.instructions.items.len), |
| | 6380 | }), |
| | 6381 | } }, |
| | 6382 | }); |
| | 6383 | sema.air_extra.appendAssumeCapacity(br_inst); |
| | 6384 | sema.air_extra.appendSliceAssumeCapacity(fail_block.instructions.items); |
| | 6385 | |
| | 6386 | sema.air_instructions.appendAssumeCapacity(gpa, .{ |
| | 6387 | .tag = .br, |
| | 6388 | .data = .{ .br = .{ |
| | 6389 | .block_inst = block_inst, |
| | 6390 | .operand = .void_value, |
| | 6391 | } }, |
| | 6392 | }); |
| | 6393 | |
| | 6394 | parent_block.instructions.appendAssumeCapacity(block_inst); |
| 6439 | } | 6395 | } |
| 6440 | | 6396 | |
| 6441 | fn panicWithMsg( | 6397 | fn panicWithMsg( |
| ... | @@ -6451,18 +6407,18 @@ fn panicWithMsg( | ... | @@ -6451,18 +6407,18 @@ fn panicWithMsg( |
| 6451 | mod.comp.bin_file.options.object_format == .c; | 6407 | mod.comp.bin_file.options.object_format == .c; |
| 6452 | if (!this_feature_is_implemented_in_the_backend) { | 6408 | if (!this_feature_is_implemented_in_the_backend) { |
| 6453 | // TODO implement this feature in all the backends and then delete this branch | 6409 | // TODO implement this feature in all the backends and then delete this branch |
| 6454 | _ = try block.addNoOp(src, Type.initTag(.void), .breakpoint); | 6410 | _ = try block.addNoOp(.breakpoint); |
| 6455 | _ = try block.addNoOp(src, Type.initTag(.noreturn), .unreach); | 6411 | _ = try block.addNoOp(.unreach); |
| 6456 | return always_noreturn; | 6412 | return always_noreturn; |
| 6457 | } | 6413 | } |
| 6458 | const panic_fn = try sema.getBuiltin(block, src, "panic"); | 6414 | const panic_fn = try sema.getBuiltin(block, src, "panic"); |
| 6459 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); | 6415 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace"); |
| 6460 | const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); | 6416 | const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty); |
| 6461 | const ptr_stack_trace_ty = try Module.simplePtrType(arena, stack_trace_ty, true, .One); | 6417 | const ptr_stack_trace_ty = try Module.simplePtrType(arena, stack_trace_ty, true, .One); |
| 6462 | const null_stack_trace = try mod.constInst(arena, src, .{ | 6418 | const null_stack_trace = try sema.addConstant( |
| 6463 | .ty = try mod.optionalType(arena, ptr_stack_trace_ty), | 6419 | try mod.optionalType(arena, ptr_stack_trace_ty), |
| 6464 | .val = Value.initTag(.null_value), | 6420 | Value.initTag(.null_value), |
| 6465 | }); | 6421 | ); |
| 6466 | const args = try arena.create([2]Air.Inst.Index); | 6422 | const args = try arena.create([2]Air.Inst.Index); |
| 6467 | args.* = .{ msg_inst, null_stack_trace }; | 6423 | args.* = .{ msg_inst, null_stack_trace }; |
| 6468 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, args); | 6424 | _ = try sema.analyzeCall(block, panic_fn, src, src, .auto, false, args); |
| ... | @@ -6503,7 +6459,6 @@ fn safetyPanic( | ... | @@ -6503,7 +6459,6 @@ fn safetyPanic( |
| 6503 | }; | 6459 | }; |
| 6504 | | 6460 | |
| 6505 | const casted_msg_inst = try sema.coerce(block, Type.initTag(.const_slice_u8), msg_inst, src); | 6461 | const casted_msg_inst = try sema.coerce(block, Type.initTag(.const_slice_u8), msg_inst, src); |
| 6506 | | | |
| 6507 | return sema.panicWithMsg(block, src, casted_msg_inst); | 6462 | return sema.panicWithMsg(block, src, casted_msg_inst); |
| 6508 | } | 6463 | } |
| 6509 | | 6464 | |
| ... | @@ -6533,13 +6488,13 @@ fn namedFieldPtr( | ... | @@ -6533,13 +6488,13 @@ fn namedFieldPtr( |
| 6533 | switch (elem_ty.zigTypeTag()) { | 6488 | switch (elem_ty.zigTypeTag()) { |
| 6534 | .Array => { | 6489 | .Array => { |
| 6535 | if (mem.eql(u8, field_name, "len")) { | 6490 | if (mem.eql(u8, field_name, "len")) { |
| 6536 | return mod.constInst(arena, src, .{ | 6491 | return sema.addConstant( |
| 6537 | .ty = Type.initTag(.single_const_pointer_to_comptime_int), | 6492 | Type.initTag(.single_const_pointer_to_comptime_int), |
| 6538 | .val = try Value.Tag.ref_val.create( | 6493 | try Value.Tag.ref_val.create( |
| 6539 | arena, | 6494 | arena, |
| 6540 | try Value.Tag.int_u64.create(arena, elem_ty.arrayLen()), | 6495 | try Value.Tag.int_u64.create(arena, elem_ty.arrayLen()), |
| 6541 | ), | 6496 | ), |
| 6542 | }); | 6497 | ); |
| 6543 | } else { | 6498 | } else { |
| 6544 | return mod.fail( | 6499 | return mod.fail( |
| 6545 | &block.base, | 6500 | &block.base, |
| ... | @@ -6554,13 +6509,13 @@ fn namedFieldPtr( | ... | @@ -6554,13 +6509,13 @@ fn namedFieldPtr( |
| 6554 | switch (ptr_child.zigTypeTag()) { | 6509 | switch (ptr_child.zigTypeTag()) { |
| 6555 | .Array => { | 6510 | .Array => { |
| 6556 | if (mem.eql(u8, field_name, "len")) { | 6511 | if (mem.eql(u8, field_name, "len")) { |
| 6557 | return mod.constInst(arena, src, .{ | 6512 | return sema.addConstant( |
| 6558 | .ty = Type.initTag(.single_const_pointer_to_comptime_int), | 6513 | Type.initTag(.single_const_pointer_to_comptime_int), |
| 6559 | .val = try Value.Tag.ref_val.create( | 6514 | try Value.Tag.ref_val.create( |
| 6560 | arena, | 6515 | arena, |
| 6561 | try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()), | 6516 | try Value.Tag.int_u64.create(arena, ptr_child.arrayLen()), |
| 6562 | ), | 6517 | ), |
| 6563 | }); | 6518 | ); |
| 6564 | } else { | 6519 | } else { |
| 6565 | return mod.fail( | 6520 | return mod.fail( |
| 6566 | &block.base, | 6521 | &block.base, |
| ... | @@ -6597,15 +6552,15 @@ fn namedFieldPtr( | ... | @@ -6597,15 +6552,15 @@ fn namedFieldPtr( |
| 6597 | }); | 6552 | }); |
| 6598 | } else (try mod.getErrorValue(field_name)).key; | 6553 | } else (try mod.getErrorValue(field_name)).key; |
| 6599 | | 6554 | |
| 6600 | return mod.constInst(arena, src, .{ | 6555 | return sema.addConstant( |
| 6601 | .ty = try Module.simplePtrType(arena, child_type, false, .One), | 6556 | try Module.simplePtrType(arena, child_type, false, .One), |
| 6602 | .val = try Value.Tag.ref_val.create( | 6557 | try Value.Tag.ref_val.create( |
| 6603 | arena, | 6558 | arena, |
| 6604 | try Value.Tag.@"error".create(arena, .{ | 6559 | try Value.Tag.@"error".create(arena, .{ |
| 6605 | .name = name, | 6560 | .name = name, |
| 6606 | }), | 6561 | }), |
| 6607 | ), | 6562 | ), |
| 6608 | }); | 6563 | ); |
| 6609 | }, | 6564 | }, |
| 6610 | .Struct, .Opaque, .Union => { | 6565 | .Struct, .Opaque, .Union => { |
| 6611 | if (child_type.getNamespace()) |namespace| { | 6566 | if (child_type.getNamespace()) |namespace| { |
| ... | @@ -6651,10 +6606,10 @@ fn namedFieldPtr( | ... | @@ -6651,10 +6606,10 @@ fn namedFieldPtr( |
| 6651 | }; | 6606 | }; |
| 6652 | const field_index_u32 = @intCast(u32, field_index); | 6607 | const field_index_u32 = @intCast(u32, field_index); |
| 6653 | const enum_val = try Value.Tag.enum_field_index.create(arena, field_index_u32); | 6608 | const enum_val = try Value.Tag.enum_field_index.create(arena, field_index_u32); |
| 6654 | return mod.constInst(arena, src, .{ | 6609 | return sema.addConstant( |
| 6655 | .ty = try Module.simplePtrType(arena, child_type, false, .One), | 6610 | try Module.simplePtrType(arena, child_type, false, .One), |
| 6656 | .val = try Value.Tag.ref_val.create(arena, enum_val), | 6611 | try Value.Tag.ref_val.create(arena, enum_val), |
| 6657 | }); | 6612 | ); |
| 6658 | }, | 6613 | }, |
| 6659 | else => return mod.fail(&block.base, src, "type '{}' has no members", .{child_type}), | 6614 | else => return mod.fail(&block.base, src, "type '{}' has no members", .{child_type}), |
| 6660 | } | 6615 | } |
| ... | @@ -6701,7 +6656,6 @@ fn analyzeStructFieldPtr( | ... | @@ -6701,7 +6656,6 @@ fn analyzeStructFieldPtr( |
| 6701 | field_name_src: LazySrcLoc, | 6656 | field_name_src: LazySrcLoc, |
| 6702 | unresolved_struct_ty: Type, | 6657 | unresolved_struct_ty: Type, |
| 6703 | ) CompileError!Air.Inst.Ref { | 6658 | ) CompileError!Air.Inst.Ref { |
| 6704 | const mod = sema.mod; | | |
| 6705 | const arena = sema.arena; | 6659 | const arena = sema.arena; |
| 6706 | assert(unresolved_struct_ty.zigTypeTag() == .Struct); | 6660 | assert(unresolved_struct_ty.zigTypeTag() == .Struct); |
| 6707 | | 6661 | |
| ... | @@ -6714,13 +6668,13 @@ fn analyzeStructFieldPtr( | ... | @@ -6714,13 +6668,13 @@ fn analyzeStructFieldPtr( |
| 6714 | const ptr_field_ty = try Module.simplePtrType(arena, field.ty, true, .One); | 6668 | const ptr_field_ty = try Module.simplePtrType(arena, field.ty, true, .One); |
| 6715 | | 6669 | |
| 6716 | if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { | 6670 | if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| { |
| 6717 | return mod.constInst(arena, src, .{ | 6671 | return sema.addConstant( |
| 6718 | .ty = ptr_field_ty, | 6672 | ptr_field_ty, |
| 6719 | .val = try Value.Tag.field_ptr.create(arena, .{ | 6673 | try Value.Tag.field_ptr.create(arena, .{ |
| 6720 | .container_ptr = struct_ptr_val, | 6674 | .container_ptr = struct_ptr_val, |
| 6721 | .field_index = field_index, | 6675 | .field_index = field_index, |
| 6722 | }), | 6676 | }), |
| 6723 | }); | 6677 | ); |
| 6724 | } | 6678 | } |
| 6725 | | 6679 | |
| 6726 | try sema.requireRuntimeBlock(block, src); | 6680 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -6751,13 +6705,13 @@ fn analyzeUnionFieldPtr( | ... | @@ -6751,13 +6705,13 @@ fn analyzeUnionFieldPtr( |
| 6751 | | 6705 | |
| 6752 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| { | 6706 | if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| { |
| 6753 | // TODO detect inactive union field and emit compile error | 6707 | // TODO detect inactive union field and emit compile error |
| 6754 | return mod.constInst(arena, src, .{ | 6708 | return sema.addConstant( |
| 6755 | .ty = ptr_field_ty, | 6709 | ptr_field_ty, |
| 6756 | .val = try Value.Tag.field_ptr.create(arena, .{ | 6710 | try Value.Tag.field_ptr.create(arena, .{ |
| 6757 | .container_ptr = union_ptr_val, | 6711 | .container_ptr = union_ptr_val, |
| 6758 | .field_index = field_index, | 6712 | .field_index = field_index, |
| 6759 | }), | 6713 | }), |
| 6760 | }); | 6714 | ); |
| 6761 | } | 6715 | } |
| 6762 | | 6716 | |
| 6763 | try sema.requireRuntimeBlock(block, src); | 6717 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -6808,10 +6762,10 @@ fn elemPtrArray( | ... | @@ -6808,10 +6762,10 @@ fn elemPtrArray( |
| 6808 | const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64)); | 6762 | const elem_ptr = try array_ptr_val.elemPtr(sema.arena, @intCast(usize, index_u64)); |
| 6809 | const pointee_type = array_ptr.ty.elemType().elemType(); | 6763 | const pointee_type = array_ptr.ty.elemType().elemType(); |
| 6810 | | 6764 | |
| 6811 | return sema.mod.constInst(sema.arena, src, .{ | 6765 | return sema.addConstant( |
| 6812 | .ty = try Type.Tag.single_const_pointer.create(sema.arena, pointee_type), | 6766 | try Type.Tag.single_const_pointer.create(sema.arena, pointee_type), |
| 6813 | .val = elem_ptr, | 6767 | elem_ptr, |
| 6814 | }); | 6768 | ); |
| 6815 | } | 6769 | } |
| 6816 | } | 6770 | } |
| 6817 | _ = elem_index; | 6771 | _ = elem_index; |
| ... | @@ -6870,7 +6824,7 @@ fn coerce( | ... | @@ -6870,7 +6824,7 @@ fn coerce( |
| 6870 | .Optional => { | 6824 | .Optional => { |
| 6871 | // null to ?T | 6825 | // null to ?T |
| 6872 | if (inst_ty.zigTypeTag() == .Null) { | 6826 | if (inst_ty.zigTypeTag() == .Null) { |
| 6873 | return mod.constInst(arena, inst_src, .{ .ty = dest_type, .val = Value.initTag(.null_value) }); | 6827 | return sema.addConstant(dest_type, Value.initTag(.null_value)); |
| 6874 | } | 6828 | } |
| 6875 | | 6829 | |
| 6876 | // T to ?T | 6830 | // T to ?T |
| ... | @@ -6981,10 +6935,10 @@ fn coerce( | ... | @@ -6981,10 +6935,10 @@ fn coerce( |
| 6981 | }; | 6935 | }; |
| 6982 | return mod.failWithOwnedErrorMsg(&block.base, msg); | 6936 | return mod.failWithOwnedErrorMsg(&block.base, msg); |
| 6983 | }; | 6937 | }; |
| 6984 | return mod.constInst(arena, inst_src, .{ | 6938 | return sema.addConstant( |
| 6985 | .ty = resolved_dest_type, | 6939 | resolved_dest_type, |
| 6986 | .val = try Value.Tag.enum_field_index.create(arena, @intCast(u32, field_index)), | 6940 | try Value.Tag.enum_field_index.create(arena, @intCast(u32, field_index)), |
| 6987 | }); | 6941 | ); |
| 6988 | } | 6942 | } |
| 6989 | }, | 6943 | }, |
| 6990 | else => {}, | 6944 | else => {}, |
| ... | @@ -7024,7 +6978,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R | ... | @@ -7024,7 +6978,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R |
| 7024 | if (!val.intFitsInType(dest_type, target)) { | 6978 | if (!val.intFitsInType(dest_type, target)) { |
| 7025 | return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val }); | 6979 | return sema.mod.fail(&block.base, inst.src, "type {} cannot represent integer value {}", .{ inst.ty, val }); |
| 7026 | } | 6980 | } |
| 7027 | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val }); | 6981 | return sema.addConstant(dest_type, val); |
| 7028 | } | 6982 | } |
| 7029 | } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) { | 6983 | } else if (dst_zig_tag == .ComptimeFloat or dst_zig_tag == .Float) { |
| 7030 | if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) { | 6984 | if (src_zig_tag == .Float or src_zig_tag == .ComptimeFloat) { |
| ... | @@ -7037,7 +6991,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R | ... | @@ -7037,7 +6991,7 @@ fn coerceNum(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.R |
| 7037 | ), | 6991 | ), |
| 7038 | error.OutOfMemory => return error.OutOfMemory, | 6992 | error.OutOfMemory => return error.OutOfMemory, |
| 7039 | }; | 6993 | }; |
| 7040 | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = res }); | 6994 | return sema.addConstant(dest_type, res); |
| 7041 | } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) { | 6995 | } else if (src_zig_tag == .Int or src_zig_tag == .ComptimeInt) { |
| 7042 | return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{}); | 6996 | return sema.mod.fail(&block.base, inst.src, "TODO int to float", .{}); |
| 7043 | } | 6997 | } |
| ... | @@ -7132,7 +7086,7 @@ fn bitcast( | ... | @@ -7132,7 +7086,7 @@ fn bitcast( |
| 7132 | fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) CompileError!Air.Inst.Ref { | 7086 | fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) CompileError!Air.Inst.Ref { |
| 7133 | if (inst.value()) |val| { | 7087 | if (inst.value()) |val| { |
| 7134 | // The comptime Value representation is compatible with both types. | 7088 | // The comptime Value representation is compatible with both types. |
| 7135 | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val }); | 7089 | return sema.addConstant(dest_type, val); |
| 7136 | } | 7090 | } |
| 7137 | return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{}); | 7091 | return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToSlice runtime instruction", .{}); |
| 7138 | } | 7092 | } |
| ... | @@ -7140,7 +7094,7 @@ fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst | ... | @@ -7140,7 +7094,7 @@ fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst |
| 7140 | fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Ref { | 7094 | fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Ref { |
| 7141 | if (inst.value()) |val| { | 7095 | if (inst.value()) |val| { |
| 7142 | // The comptime Value representation is compatible with both types. | 7096 | // The comptime Value representation is compatible with both types. |
| 7143 | return sema.mod.constInst(sema.arena, inst.src, .{ .ty = dest_type, .val = val }); | 7097 | return sema.addConstant(dest_type, val); |
| 7144 | } | 7098 | } |
| 7145 | return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{}); | 7099 | return sema.mod.fail(&block.base, inst.src, "TODO implement coerceArrayPtrToMany runtime instruction", .{}); |
| 7146 | } | 7100 | } |
| ... | @@ -7200,13 +7154,11 @@ fn analyzeRef( | ... | @@ -7200,13 +7154,11 @@ fn analyzeRef( |
| 7200 | src: LazySrcLoc, | 7154 | src: LazySrcLoc, |
| 7201 | operand: Air.Inst.Ref, | 7155 | operand: Air.Inst.Ref, |
| 7202 | ) CompileError!Air.Inst.Ref { | 7156 | ) CompileError!Air.Inst.Ref { |
| 7203 | const ptr_type = try sema.mod.simplePtrType(sema.arena, operand.ty, false, .One); | 7157 | const operand_ty = sema.getTypeOf(operand); |
| | 7158 | const ptr_type = try sema.mod.simplePtrType(sema.arena, operand_ty, false, .One); |
| 7204 | | 7159 | |
| 7205 | if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |val| { | 7160 | if (try sema.resolvePossiblyUndefinedValue(block, src, operand)) |val| { |
| 7206 | return sema.mod.constInst(sema.arena, src, .{ | 7161 | return sema.addConstant(ptr_type, try Value.Tag.ref_val.create(sema.arena, val)); |
| 7207 | .ty = ptr_type, | | |
| 7208 | .val = try Value.Tag.ref_val.create(sema.arena, val), | | |
| 7209 | }); | | |
| 7210 | } | 7162 | } |
| 7211 | | 7163 | |
| 7212 | try sema.requireRuntimeBlock(block, src); | 7164 | try sema.requireRuntimeBlock(block, src); |
| ... | @@ -7267,7 +7219,8 @@ fn analyzeIsNonErr( | ... | @@ -7267,7 +7219,8 @@ fn analyzeIsNonErr( |
| 7267 | src: LazySrcLoc, | 7219 | src: LazySrcLoc, |
| 7268 | operand: Air.Inst.Ref, | 7220 | operand: Air.Inst.Ref, |
| 7269 | ) CompileError!Air.Inst.Ref { | 7221 | ) CompileError!Air.Inst.Ref { |
| 7270 | const ot = operand.ty.zigTypeTag(); | 7222 | const operand_ty = sema.getTypeOf(operand); |
| | 7223 | const ot = operand_ty.zigTypeTag(); |
| 7271 | if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true; | 7224 | if (ot != .ErrorSet and ot != .ErrorUnion) return Air.Inst.Ref.bool_true; |
| 7272 | if (ot == .ErrorSet) return Air.Inst.Ref.bool_false; | 7225 | if (ot == .ErrorSet) return Air.Inst.Ref.bool_false; |
| 7273 | assert(ot == .ErrorUnion); | 7226 | assert(ot == .ErrorUnion); |
| ... | @@ -7549,7 +7502,7 @@ fn cmpNumeric( | ... | @@ -7549,7 +7502,7 @@ fn cmpNumeric( |
| 7549 | | 7502 | |
| 7550 | fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index { | 7503 | fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index { |
| 7551 | if (try sema.resolvePossiblyUndefinedValue(block, inst_src, inst)) |val| { | 7504 | if (try sema.resolvePossiblyUndefinedValue(block, inst_src, inst)) |val| { |
| 7552 | return sema.mod.constInst(sema.arena, inst_src, .{ .ty = dest_type, .val = val }); | 7505 | return sema.addConstant(dest_type, val); |
| 7553 | } | 7506 | } |
| 7554 | | 7507 | |
| 7555 | try sema.requireRuntimeBlock(block, inst.src); | 7508 | try sema.requireRuntimeBlock(block, inst.src); |
| ... | @@ -7614,11 +7567,8 @@ fn wrapErrorUnion( | ... | @@ -7614,11 +7567,8 @@ fn wrapErrorUnion( |
| 7614 | else => unreachable, | 7567 | else => unreachable, |
| 7615 | } | 7568 | } |
| 7616 | | 7569 | |
| 7617 | return sema.mod.constInst(sema.arena, inst.src, .{ | 7570 | // Create a SubValue for the error_union payload. |
| 7618 | .ty = dest_type, | 7571 | return sema.addConstant(dest_type, try Value.Tag.error_union.create(sema.arena, val)); |
| 7619 | // creating a SubValue for the error_union payload | | |
| 7620 | .val = try Value.Tag.error_union.create(sema.arena, val), | | |
| 7621 | }); | | |
| 7622 | } | 7572 | } |
| 7623 | | 7573 | |
| 7624 | try sema.requireRuntimeBlock(block, inst.src); | 7574 | try sema.requireRuntimeBlock(block, inst.src); |