authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-14 19:04:02-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-20 12:19:16-07:00
log27be4f31402557972ae28d552f4ec4617357d454
treee8c88a0307752dcc00946e261e4e18b4f25a0f89
parent7bb2d13a090f700b3806127a639e164726af8e03

Sema: more AIR memory layout reworking progress

Additionally: ZIR encoding for floats now supports float literals up to f64, not only f32. This is because we no longer need a source location for this instruction.

5 files changed, 486 insertions(+), 517 deletions(-)

src/Air.zig+6-5
...@@ -94,6 +94,11 @@ pub const Inst = struct {...@@ -94,6 +94,11 @@ pub const Inst = struct {
94 bitcast,94 bitcast,
95 /// Uses the `ty_pl` field with payload `Block`.95 /// Uses the `ty_pl` field with payload `Block`.
96 block,96 block,
97 /// A labeled block of code that loops forever. At the end of the body it is implied
98 /// to repeat; no explicit "repeat" instruction terminates loop bodies.
99 /// Result type is always noreturn; no instructions in a block follow this one.
100 /// Uses the `ty_pl` field. Payload is `Block`.
101 loop,
97 /// Return from a block with a result.102 /// Return from a block with a result.
98 /// Result type is always noreturn; no instructions in a block follow this one.103 /// Result type is always noreturn; no instructions in a block follow this one.
99 /// Uses the `br` field.104 /// Uses the `br` field.
...@@ -181,11 +186,6 @@ pub const Inst = struct {...@@ -181,11 +186,6 @@ pub const Inst = struct {
181 /// Read a value from a pointer.186 /// Read a value from a pointer.
182 /// Uses the `ty_op` field.187 /// Uses the `ty_op` field.
183 load,188 load,
184 /// A labeled block of code that loops forever. At the end of the body it is implied
185 /// to repeat; no explicit "repeat" instruction terminates loop bodies.
186 /// Result type is always noreturn; no instructions in a block follow this one.
187 /// Uses the `ty_pl` field. Payload is `Block`.
188 loop,
189 /// Converts a pointer to its address. Result type is always `usize`.189 /// Converts a pointer to its address. Result type is always `usize`.
190 /// Uses the `un_op` field.190 /// Uses the `un_op` field.
191 ptrtoint,191 ptrtoint,
...@@ -279,6 +279,7 @@ pub const Inst = struct {...@@ -279,6 +279,7 @@ pub const Inst = struct {
279 /// this union. `Tag` determines which union field is active, as well as279 /// this union. `Tag` determines which union field is active, as well as
280 /// how to interpret the data within.280 /// how to interpret the data within.
281 pub const Data = union {281 pub const Data = union {
282 no_op: void,
282 un_op: Ref,283 un_op: Ref,
283 bin_op: struct {284 bin_op: struct {
284 lhs: Ref,285 lhs: Ref,
src/AstGen.zig+5-8
...@@ -6589,12 +6589,12 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir...@@ -6589,12 +6589,12 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir
6589 } else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) {6589 } else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) {
6590 error.InvalidCharacter => unreachable, // validated by tokenizer6590 error.InvalidCharacter => unreachable, // validated by tokenizer
6591 };6591 };
6592 // If the value fits into a f32 without losing any precision, store it that way.6592 // If the value fits into a f64 without losing any precision, store it that way.
6593 @setFloatMode(.Strict);6593 @setFloatMode(.Strict);
6594 const smaller_float = @floatCast(f32, float_number);6594 const smaller_float = @floatCast(f64, float_number);
6595 const bigger_again: f128 = smaller_float;6595 const bigger_again: f128 = smaller_float;
6596 if (bigger_again == float_number) {6596 if (bigger_again == float_number) {
6597 const result = try gz.addFloat(smaller_float, node);6597 const result = try gz.addFloat(smaller_float);
6598 return rvalue(gz, rl, result, node);6598 return rvalue(gz, rl, result, node);
6599 }6599 }
6600 // We need to use 128 bits. Break the float into 4 u32 values so we can6600 // We need to use 128 bits. Break the float into 4 u32 values so we can
...@@ -9145,13 +9145,10 @@ const GenZir = struct {...@@ -9145,13 +9145,10 @@ const GenZir = struct {
9145 return indexToRef(new_index);9145 return indexToRef(new_index);
9146 }9146 }
91479147
9148 fn addFloat(gz: *GenZir, number: f32, src_node: ast.Node.Index) !Zir.Inst.Ref {9148 fn addFloat(gz: *GenZir, number: f64) !Zir.Inst.Ref {
9149 return gz.add(.{9149 return gz.add(.{
9150 .tag = .float,9150 .tag = .float,
9151 .data = .{ .float = .{9151 .data = .{ .float = number },
9152 .src_node = gz.nodeIndexToRelative(src_node),
9153 .number = number,
9154 } },
9155 });9152 });
9156 }9153 }
91579154
src/Module.zig+32
...@@ -1226,6 +1226,17 @@ pub const Scope = struct {...@@ -1226,6 +1226,17 @@ pub const Scope = struct {
1226 return block.src_decl.namespace.file_scope;1226 return block.src_decl.namespace.file_scope;
1227 }1227 }
12281228
1229 pub fn addTy(
1230 block: *Block,
1231 tag: Air.Inst.Tag,
1232 ty: Type,
1233 ) error{OutOfMemory}!Air.Inst.Ref {
1234 return block.addInst(.{
1235 .tag = tag,
1236 .data = .{ .ty = ty },
1237 });
1238 }
1239
1229 pub fn addTyOp(1240 pub fn addTyOp(
1230 block: *Block,1241 block: *Block,
1231 tag: Air.Inst.Tag,1242 tag: Air.Inst.Tag,
...@@ -1241,6 +1252,13 @@ pub const Scope = struct {...@@ -1241,6 +1252,13 @@ pub const Scope = struct {
1241 });1252 });
1242 }1253 }
12431254
1255 pub fn addNoOp(block: *Block, tag: Air.Inst.Tag) error{OutOfMemory}!Air.Inst.Ref {
1256 return block.addInst(.{
1257 .tag = tag,
1258 .data = .no_op,
1259 });
1260 }
1261
1244 pub fn addUnOp(1262 pub fn addUnOp(
1245 block: *Block,1263 block: *Block,
1246 tag: Air.Inst.Tag,1264 tag: Air.Inst.Tag,
...@@ -1252,6 +1270,20 @@ pub const Scope = struct {...@@ -1252,6 +1270,20 @@ pub const Scope = struct {
1252 });1270 });
1253 }1271 }
12541272
1273 pub fn addBr(
1274 block: *Block,
1275 target_block: Air.Inst.Index,
1276 operand: Air.Inst.Ref,
1277 ) error{OutOfMemory}!Air.Inst.Ref {
1278 return block.addInst(.{
1279 .tag = .br,
1280 .data = .{ .br = .{
1281 .block_inst = target_block,
1282 .operand = operand,
1283 } },
1284 });
1285 }
1286
1255 pub fn addBinOp(1287 pub fn addBinOp(
1256 block: *Block,1288 block: *Block,
1257 tag: Air.Inst.Tag,1289 tag: Air.Inst.Tag,
src/Sema.zig+439-489
...@@ -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),
374374
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),
383383
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 can385 //// 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}
11911191
1192fn zirRef(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {1192fn 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);
12591261
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();
13181320
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 load1330 .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}
13371335
1338fn zirAllocInferredComptime(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {1336fn 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}
13561354
1357fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {1355fn 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}
13701368
1371fn zirAllocInferred(1369fn 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 append1387 // 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}
13991394
...@@ -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();
16321627
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;
16371635
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 };
16471645
...@@ -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);
17131711
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}
17191717
1720fn zirFloat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {1718fn 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),
17261724 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}
17321727
1733fn zirFloat128(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {1728fn 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();
17401734 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}
17461739
1747fn zirCompileError(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {1740fn 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}
17931783
1794fn zirRepeat(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Zir.Inst.Index {1784fn 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;
18201811
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,
18311822 });
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;
18461844
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 };
18631848
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);
18661851
1867 _ = try sema.analyzeBody(&loop_block, body);1852 _ = try sema.analyzeBody(&loop_block, body);
18681853
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);
18701856
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);
18731859 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}
18761865
...@@ -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}
18921881
1893fn zirBlock(sema: *Sema, parent_block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {1882fn 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();
18961889
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;
19011895
1902 // Reserve space for a Block instruction so that generated Break instructions can1896 // 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 being1897 // 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 };
19141904
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;
19341924
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);
19381928
1939 _ = try sema.analyzeBody(&child_block, body);1929 _ = try sema.analyzeBody(&child_block, body);
19401930
...@@ -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();
19651955
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 instructions1963 // 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 directly1974 // 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(
19921984
1993 // Need to set the type and emit the Block instruction. This allows machine code generation1985 // 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 break1998 // 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 a2008 // 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}
20372034
2038fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {2035fn 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}
21092106
2110fn zirFence(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {2107fn 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 }
23132310
2311 const gpa = sema.gpa;
2312
2314 const ret_type = func.ty.fnReturnType();2313 const ret_type = func.ty.fnReturnType();
23152314
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 the2331 // 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 not2338 // 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 }
23642359
...@@ -2390,9 +2385,9 @@ fn analyzeCall(...@@ -2390,9 +2385,9 @@ fn analyzeCall(
23902385
2391 const merges = &child_block.inlining.?.merges;2386 const merges = &child_block.inlining.?.merges;
23922387
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);
23962391
2397 try sema.emitBackwardBranch(&child_block, call_src);2392 try sema.emitBackwardBranch(&child_block, call_src);
23982393
...@@ -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();
25262521
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();
25292523
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}
25402534
2541fn zirErrorToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {2535fn 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 }
25662557
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
26302618
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 can2623 // 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 then2624 // 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}
26932675
2694fn zirEnumLiteral(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {2676fn 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();
26982680
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}
27072688
2708fn zirEnumToInt(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {2689fn 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);
27152697
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);
27352718
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);
27382721
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 }
27452725
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 }
27852753
...@@ -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
2790fn zirIntToEnum(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {2758fn 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
28052772
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 }
28402801
2841 try sema.requireRuntimeBlock(block, src);2802 try sema.requireRuntimeBlock(block, src);
...@@ -2854,16 +2815,17 @@ fn zirOptionalPayloadPtr(...@@ -2854,16 +2815,17 @@ fn zirOptionalPayloadPtr(
28542815
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();
28592821
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 }
28642826
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);
28672829
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 }
28792838
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 }
29172874
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});
29412900
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}
29602919
...@@ -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);
29752935
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()});
29782938
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);
29802940
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 }
29962956
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});
30152976
3016 const result_ty = operand.ty.castTag(.error_union).?.data.error_set;2977 const result_ty = operand_ty.castTag(.error_union).?.data.error_set;
30172978
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 }
30262984
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);
30402999
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()});
30433002
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;
30453004
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 }
30553011
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 }
32343191
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 }
32413198
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}
32703223
3271fn zirAs(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {3224fn 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 object3281 object
3329 else3282 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 };
33993352
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 }
34093363
...@@ -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 };
34563410
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 }
34663421
...@@ -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
34793434
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 array3439 array
3484 else3440 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 array3458 array
3502 else3459 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);
37083666
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 }
37303688
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);
37363694
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 }
37793737
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;
38003758
3801 const field_name = operand.ty.enumFieldName(i);3759 const field_name = operand_ty.enumFieldName(i);
38023760
3803 // TODO have this point to the tag decl instead of here3761 // 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 }
39093867
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();
39143872
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 }
39853943
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 }
40213979
...@@ -4063,7 +4021,7 @@ fn analyzeSwitch(...@@ -4063,7 +4021,7 @@ fn analyzeSwitch(
4063 );4021 );
4064 }4022 }
40654023
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 }
40894047
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);
46364589
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 }
47924735
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;
47954750
...@@ -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(
48504802
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 });
48524804
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 }
48594808
...@@ -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); // TODO5117 field_values[5] = Value.initTag(.null_value); // TODO
51695118
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}
51945144
5195fn zirTypeofElem(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5145fn 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
52415191
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);
52455196
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(
52675218
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;
52745226
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 }
52885240
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 };
52985249
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);
53045255
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);
53075258
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);
53105261
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;
53135264
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);
53195267
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);
53225270
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);
53265274
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}
53335295
5334fn zirIsNonNull(5296fn 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}
54705432
...@@ -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 }
55115473
...@@ -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);
56155577
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}
56215580
5622fn zirUnionInitPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5581fn 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 }
57375690
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 }
59215871
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 }
59325878
...@@ -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 field6163 .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}
62266172
...@@ -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};
63826328
6383fn addSafetyCheck(sema: *Sema, parent_block: *Scope.Block, ok: Air.Inst.Ref, panic_id: PanicId) !void {6329fn 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;
64096336
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 };
64186345
6419 defer fail_block.instructions.deinit(sema.gpa);6346 defer fail_block.instructions.deinit(gpa);
64206347
6421 _ = try sema.safetyPanic(&fail_block, ok.src, panic_id);6348 _ = try sema.safetyPanic(&fail_block, .unneeded, panic_id);
64226349
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);
64246351
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;
64376357
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}
64406396
6441fn panicWithMsg(6397fn 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 branch6409 // 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 };
65046460
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}
65096464
...@@ -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;
65996554
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);
67076661
...@@ -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);
67156669
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 }
67256679
6726 try sema.requireRuntimeBlock(block, src);6680 try sema.requireRuntimeBlock(block, src);
...@@ -6751,13 +6705,13 @@ fn analyzeUnionFieldPtr(...@@ -6751,13 +6705,13 @@ fn analyzeUnionFieldPtr(
67516705
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 error6707 // 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 }
67626716
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();
68106764
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 ?T6825 // 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 }
68756829
6876 // T to ?T6830 // 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(
7132fn coerceArrayPtrToSlice(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) CompileError!Air.Inst.Ref {7086fn 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
7140fn coerceArrayPtrToMany(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Ref {7094fn 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);
72047159
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 }
72117163
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(
75497502
7550fn wrapOptional(sema: *Sema, block: *Scope.Block, dest_type: Type, inst: Air.Inst.Ref) !Air.Inst.Index {7503fn 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 }
75547507
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 }
76167569
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 }
76237573
7624 try sema.requireRuntimeBlock(block, inst.src);7574 try sema.requireRuntimeBlock(block, inst.src);
src/Zir.zig+4-15
...@@ -386,7 +386,7 @@ pub const Inst = struct {...@@ -386,7 +386,7 @@ pub const Inst = struct {
386 int,386 int,
387 /// Arbitrary sized integer literal. Uses the `str` union field.387 /// Arbitrary sized integer literal. Uses the `str` union field.
388 int_big,388 int_big,
389 /// A float literal that fits in a f32. Uses the float union value.389 /// A float literal that fits in a f64. Uses the float union value.
390 float,390 float,
391 /// A float literal that fits in a f128. Uses the `pl_node` union value.391 /// A float literal that fits in a f128. Uses the `pl_node` union value.
392 /// Payload is `Float128`.392 /// Payload is `Float128`.
...@@ -2058,16 +2058,7 @@ pub const Inst = struct {...@@ -2058,16 +2058,7 @@ pub const Inst = struct {
2058 /// Offset from Decl AST node index.2058 /// Offset from Decl AST node index.
2059 node: i32,2059 node: i32,
2060 int: u64,2060 int: u64,
2061 float: struct {2061 float: f64,
2062 /// Offset from Decl AST node index.
2063 /// `Tag` determines which kind of AST node this points to.
2064 src_node: i32,
2065 number: f32,
2066
2067 pub fn src(self: @This()) LazySrcLoc {
2068 return .{ .node_offset = self.src_node };
2069 }
2070 },
2071 array_type_sentinel: struct {2062 array_type_sentinel: struct {
2072 len: Ref,2063 len: Ref,
2073 /// index into extra, points to an `ArrayTypeSentinel`2064 /// index into extra, points to an `ArrayTypeSentinel`
...@@ -3256,10 +3247,8 @@ const Writer = struct {...@@ -3256,10 +3247,8 @@ const Writer = struct {
3256 }3247 }
32573248
3258 fn writeFloat(self: *Writer, stream: anytype, inst: Inst.Index) !void {3249 fn writeFloat(self: *Writer, stream: anytype, inst: Inst.Index) !void {
3259 const inst_data = self.code.instructions.items(.data)[inst].float;3250 const number = self.code.instructions.items(.data)[inst].float;
3260 const src = inst_data.src();3251 try stream.print("{d})", .{number});
3261 try stream.print("{d}) ", .{inst_data.number});
3262 try self.writeSrc(stream, src);
3263 }3252 }
32643253
3265 fn writeFloat128(self: *Writer, stream: anytype, inst: Inst.Index) !void {3254 fn writeFloat128(self: *Writer, stream: anytype, inst: Inst.Index) !void {