diff --git a/src/Sema.zig b/src/Sema.zig index e2f2022716..543e3528cf 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2913,7 +2913,7 @@ fn zirIsNull( const tracy = trace(@src()); defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].un_tok; + const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const operand = try sema.resolveInst(inst_data.operand); return sema.analyzeIsNull(block, src, operand, invert_logic); @@ -2928,7 +2928,7 @@ fn zirIsNullPtr( const tracy = trace(@src()); defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].un_tok; + const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const ptr = try sema.resolveInst(inst_data.operand); const loaded = try sema.analyzeDeref(block, src, ptr, src); @@ -2939,7 +2939,7 @@ fn zirIsErr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!* const tracy = trace(@src()); defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].un_tok; + const inst_data = sema.code.instructions.items(.data)[inst].un_node; const operand = try sema.resolveInst(inst_data.operand); return sema.analyzeIsErr(block, inst_data.src(), operand); } @@ -2948,7 +2948,7 @@ fn zirIsErrPtr(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerErro const tracy = trace(@src()); defer tracy.end(); - const inst_data = sema.code.instructions.items(.data)[inst].un_tok; + const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); const ptr = try sema.resolveInst(inst_data.operand); const loaded = try sema.analyzeDeref(block, src, ptr, src); diff --git a/src/astgen.zig b/src/astgen.zig index c54d6b2d99..ab97e000c6 100644 --- a/src/astgen.zig +++ b/src/astgen.zig @@ -526,8 +526,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In mod, scope, rl, + node, node_datas[node].lhs, - main_tokens[node], .is_err_ptr, .err_union_payload_unsafe_ptr, .err_union_code_ptr, @@ -538,8 +538,8 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In mod, scope, rl, + node, node_datas[node].lhs, - main_tokens[node], .is_err, .err_union_payload_unsafe, .err_union_code, @@ -555,7 +555,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In rl, node, node_datas[node].lhs, - main_tokens[node], .is_null_ptr, .optional_payload_unsafe_ptr, undefined, @@ -568,7 +567,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In rl, node, node_datas[node].lhs, - main_tokens[node], .is_null, .optional_payload_unsafe, undefined, @@ -1637,7 +1635,6 @@ fn orelseCatchExpr( rl: ResultLoc, node: ast.Node.Index, lhs: ast.Node.Index, - op_token: ast.TokenIndex, cond_op: zir.Inst.Tag, unwrap_op: zir.Inst.Tag, unwrap_code_op: zir.Inst.Tag, @@ -1645,6 +1642,8 @@ fn orelseCatchExpr( payload_token: ?ast.TokenIndex, ) InnerError!zir.Inst.Ref { const parent_gz = scope.getGenZir(); + const tree = parent_gz.tree(); + var block_scope: Scope.GenZir = .{ .parent = scope, .zir_code = parent_gz.zir_code, @@ -1674,8 +1673,7 @@ fn orelseCatchExpr( }, }; const operand = try expr(mod, &block_scope.base, operand_rl, lhs); - const cond = try block_scope.addUnTok(cond_op, operand, op_token); - + const cond = try block_scope.addUnNode(cond_op, operand, node); const condbr = try block_scope.addCondBr(node); const block = try parent_gz.addBlock(.block, node); @@ -1690,25 +1688,25 @@ fn orelseCatchExpr( }; defer then_scope.instructions.deinit(mod.gpa); - if (payload_token != null) @panic("TODO handle catch"); - // var err_val_scope: Scope.LocalVal = undefined; - // const then_sub_scope = blk: { - // const payload = payload_token orelse break :blk &then_scope.base; - // if (mem.eql(u8, tree.tokenSlice(payload), "_")) { - // return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{}); - // } - // const err_name = try mod.identifierTokenString(scope, payload); - // err_val_scope = .{ - // .parent = &then_scope.base, - // .gen_zir = &then_scope, - // .name = err_name, - // .inst = try addZIRUnOp(mod, &then_scope.base, src, unwrap_code_op, operand), - // }; - // break :blk &err_val_scope.base; - // }; + var err_val_scope: Scope.LocalVal = undefined; + const then_sub_scope = blk: { + const payload = payload_token orelse break :blk &then_scope.base; + if (mem.eql(u8, tree.tokenSlice(payload), "_")) { + return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{}); + } + const err_name = try mod.identifierTokenString(scope, payload); + err_val_scope = .{ + .parent = &then_scope.base, + .gen_zir = &then_scope, + .name = err_name, + .inst = try then_scope.addUnNode(unwrap_code_op, operand, node), + .src = parent_gz.tokSrcLoc(payload), + }; + break :blk &err_val_scope.base; + }; block_scope.break_count += 1; - const then_result = try expr(mod, &then_scope.base, block_scope.break_result_loc, rhs); + const then_result = try expr(mod, then_sub_scope, block_scope.break_result_loc, rhs); // We hold off on the break instructions as well as copying the then/else // instructions into place until we know whether to keep store_to_block_ptr // instructions or not. @@ -3861,25 +3859,6 @@ fn rlStrategy(rl: ResultLoc, block_scope: *Scope.GenZir) ResultLoc.Strategy { } } -/// If the input ResultLoc is ref, returns ResultLoc.ref. Otherwise: -/// Returns ResultLoc.ty, where the type is determined by the input -/// ResultLoc type, wrapped in an optional type. If the input ResultLoc -/// has no type, .none is returned. -fn makeOptionalTypeResultLoc(mod: *Module, scope: *Scope, src: usize, rl: ResultLoc) !ResultLoc { - switch (rl) { - .ref => return ResultLoc.ref, - .discard, .none, .block_ptr, .inferred_ptr, .bitcasted_ptr => return ResultLoc.none, - .ty => |elem_ty| { - const wrapped_ty = try addZIRUnOp(mod, scope, src, .optional_type, elem_ty); - return ResultLoc{ .ty = wrapped_ty }; - }, - .ptr => |ptr_ty| { - const wrapped_ty = try addZIRUnOp(mod, scope, src, .optional_type_from_ptr_elem, ptr_ty); - return ResultLoc{ .ty = wrapped_ty }; - }, - } -} - fn setBlockResultLoc(block_scope: *Scope.GenZir, parent_rl: ResultLoc) void { // Depending on whether the result location is a pointer or value, different // ZIR needs to be generated. In the former case we rely on storing to the diff --git a/src/zir.zig b/src/zir.zig index df62d3051a..8a64ce19c5 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -362,22 +362,22 @@ pub const Inst = struct { /// Payload is `int_type` int_type, /// Return a boolean false if an optional is null. `x != null` - /// Uses the `un_tok` field. + /// Uses the `un_node` field. is_non_null, /// Return a boolean true if an optional is null. `x == null` - /// Uses the `un_tok` field. + /// Uses the `un_node` field. is_null, /// Return a boolean false if an optional is null. `x.* != null` - /// Uses the `un_tok` field. + /// Uses the `un_node` field. is_non_null_ptr, /// Return a boolean true if an optional is null. `x.* == null` - /// Uses the `un_tok` field. + /// Uses the `un_node` field. is_null_ptr, /// Return a boolean true if value is an error - /// Uses the `un_tok` field. + /// Uses the `un_node` field. is_err, /// Return a boolean true if dereferenced pointer is an error - /// Uses the `un_tok` field. + /// Uses the `un_node` field. is_err_ptr, /// A labeled block of code that loops forever. At the end of the body will have either /// a `repeat` instruction or a `repeat_inline` instruction. @@ -1411,14 +1411,14 @@ const Writer = struct { .err_union_code, .err_union_code_ptr, .break_flat, - => try self.writeUnNode(stream, inst), - .is_non_null, .is_null, .is_non_null_ptr, .is_null_ptr, .is_err, .is_err_ptr, + => try self.writeUnNode(stream, inst), + .ref, .ret_tok, .ret_coerce,