diff --git a/src/AstGen.zig b/src/AstGen.zig index 49861cd145..5dc890f96f 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1125,7 +1125,7 @@ pub fn structInitExpr( } return init_inst; }, - .ref => unreachable, // struct literal not valid as l-value + .ref => return astgen.failNode(node, "cannot take address of struct literal", .{}), .ty => |ty_inst| { if (struct_init.ast.type_expr == 0) { return structInitExprRlTy(gz, scope, rl, node, struct_init, ty_inst); @@ -5819,7 +5819,7 @@ fn bitCast( const astgen = gz.astgen; const dest_type = try typeExpr(gz, scope, lhs); switch (rl) { - .none, .discard, .ty => { + .none, .none_or_ref, .discard, .ty => { const operand = try expr(gz, scope, .none, rhs); const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{ .lhs = dest_type, @@ -5827,21 +5827,34 @@ fn bitCast( }); return rvalue(gz, scope, rl, result, node); }, - .ref, .none_or_ref => unreachable, // `@bitCast` is not allowed as an r-value. - .ptr => |result_ptr| { - const casted_result_ptr = try gz.addUnNode(.bitcast_result_ptr, result_ptr, node); - return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs); + .ref => { + return astgen.failNode(node, "cannot take address of `@bitCast` result", .{}); }, - .block_ptr => |block_ptr| { - return astgen.failNode(node, "TODO implement @bitCast with result location inferred peer types", .{}); + .ptr, .inferred_ptr => |result_ptr| { + return bitCastRlPtr(gz, scope, rl, node, dest_type, result_ptr, rhs); }, - .inferred_ptr => |result_alloc| { - // TODO here we should be able to resolve the inference; we now have a type for the result. - return astgen.failNode(node, "TODO implement @bitCast with inferred-type result location pointer", .{}); + .block_ptr => |block| { + return bitCastRlPtr(gz, scope, rl, node, dest_type, block.rl_ptr, rhs); }, } } +fn bitCastRlPtr( + gz: *GenZir, + scope: *Scope, + rl: ResultLoc, + node: ast.Node.Index, + dest_type: Zir.Inst.Ref, + result_ptr: Zir.Inst.Ref, + rhs: ast.Node.Index, +) InnerError!Zir.Inst.Ref { + const casted_result_ptr = try gz.addPlNode(.bitcast_result_ptr, node, Zir.Inst.Bin{ + .lhs = dest_type, + .rhs = result_ptr, + }); + return expr(gz, scope, .{ .ptr = casted_result_ptr }, rhs); +} + fn typeOf( gz: *GenZir, scope: *Scope, diff --git a/src/Sema.zig b/src/Sema.zig index 81bb33e771..ab912f5fbe 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -641,9 +641,9 @@ fn resolveInstConst( } fn zirBitcastResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { - const tracy = trace(@src()); - defer tracy.end(); - return sema.mod.fail(&block.base, sema.src, "TODO implement zir_sema.zirBitcastResultPtr", .{}); + const inst_data = sema.code.instructions.items(.data)[inst].pl_node; + const src = inst_data.src(); + return sema.mod.fail(&block.base, src, "TODO implement zir_sema.zirBitcastResultPtr", .{}); } fn zirCoerceResultPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst { diff --git a/src/Zir.zig b/src/Zir.zig index c51ca04760..803ef898b8 100644 --- a/src/Zir.zig +++ b/src/Zir.zig @@ -196,7 +196,7 @@ pub const Inst = struct { bitcast, /// A typed result location pointer is bitcasted to a new result location pointer. /// The new result location pointer has an inferred type. - /// Uses the un_node field. + /// Uses the pl_node field with payload `Bin`. bitcast_result_ptr, /// Bitwise NOT. `~` /// Uses `un_node`. @@ -2329,7 +2329,6 @@ const Writer = struct { .byte_swap, .bit_reverse, .elem_type, - .bitcast_result_ptr, => try self.writeUnNode(stream, inst), .ref, @@ -2450,6 +2449,7 @@ const Writer = struct { .reduce, .atomic_load, .bitcast, + .bitcast_result_ptr, => try self.writePlNodeBin(stream, inst), .call,