| ... | ... | @@ -213,127 +213,145 @@ pub fn deinit(astgen: *AstGen, gpa: Allocator) void { |
| 213 | 213 | astgen.ref_table.deinit(gpa); |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | | pub const ResultLoc = union(enum) { |
| 217 | | /// The expression is the right-hand side of assignment to `_`. Only the side-effects of the |
| 218 | | /// expression should be generated. The result instruction from the expression must |
| 219 | | /// be ignored. |
| 220 | | discard, |
| 221 | | /// The expression has an inferred type, and it will be evaluated as an rvalue. |
| 222 | | none, |
| 223 | | /// The expression must generate a pointer rather than a value. For example, the left hand side |
| 224 | | /// of an assignment uses this kind of result location. |
| 225 | | ref, |
| 226 | | /// Exactly like `none`, except also indicates this is an error-handling expr (try/catch/return etc.) |
| 227 | | catch_none, |
| 228 | | /// Exactly like `ref`, except also indicates this is an error-handling expr (try/catch/return etc.) |
| 229 | | catch_ref, |
| 230 | | /// The expression will be coerced into this type, but it will be evaluated as an rvalue. |
| 231 | | ty: Zir.Inst.Ref, |
| 232 | | /// Same as `ty` but for shift operands. |
| 233 | | ty_shift_operand: Zir.Inst.Ref, |
| 234 | | /// Same as `ty` but it is guaranteed that Sema will additionally perform the coercion, |
| 235 | | /// so no `as` instruction needs to be emitted. |
| 236 | | coerced_ty: Zir.Inst.Ref, |
| 237 | | /// The expression must store its result into this typed pointer. The result instruction |
| 238 | | /// from the expression must be ignored. |
| 239 | | ptr: PtrResultLoc, |
| 240 | | /// The expression must store its result into this allocation, which has an inferred type. |
| 241 | | /// The result instruction from the expression must be ignored. |
| 242 | | /// Always an instruction with tag `alloc_inferred`. |
| 243 | | inferred_ptr: Zir.Inst.Ref, |
| 244 | | /// There is a pointer for the expression to store its result into, however, its type |
| 245 | | /// is inferred based on peer type resolution for a `Zir.Inst.Block`. |
| 246 | | /// The result instruction from the expression must be ignored. |
| 247 | | block_ptr: *GenZir, |
| 248 | | |
| 249 | | const PtrResultLoc = struct { |
| 250 | | inst: Zir.Inst.Ref, |
| 251 | | src_node: ?Ast.Node.Index = null, |
| 252 | | }; |
| 216 | pub const ResultInfo = struct { |
| 217 | /// The semantics requested for the result location |
| 218 | rl: Loc, |
| 253 | 219 | |
| 254 | | pub const Strategy = struct { |
| 255 | | elide_store_to_block_ptr_instructions: bool, |
| 256 | | tag: Tag, |
| 257 | | |
| 258 | | pub const Tag = enum { |
| 259 | | /// Both branches will use break_void; result location is used to communicate the |
| 260 | | /// result instruction. |
| 261 | | break_void, |
| 262 | | /// Use break statements to pass the block result value, and call rvalue() at |
| 263 | | /// the end depending on rl. Also elide the store_to_block_ptr instructions |
| 264 | | /// depending on rl. |
| 265 | | break_operand, |
| 266 | | }; |
| 267 | | }; |
| 220 | /// The "operator" consuming the result location |
| 221 | ctx: Context = .none, |
| 268 | 222 | |
| 269 | | fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy { |
| 270 | | switch (rl) { |
| 271 | | // In this branch there will not be any store_to_block_ptr instructions. |
| 272 | | .none, .catch_none, .ty, .ty_shift_operand, .coerced_ty, .ref, .catch_ref => return .{ |
| 273 | | .tag = .break_operand, |
| 274 | | .elide_store_to_block_ptr_instructions = false, |
| 275 | | }, |
| 276 | | .discard => return .{ |
| 277 | | .tag = .break_void, |
| 278 | | .elide_store_to_block_ptr_instructions = false, |
| 279 | | }, |
| 280 | | // The pointer got passed through to the sub-expressions, so we will use |
| 281 | | // break_void here. |
| 282 | | // In this branch there will not be any store_to_block_ptr instructions. |
| 283 | | .ptr => return .{ |
| 284 | | .tag = .break_void, |
| 285 | | .elide_store_to_block_ptr_instructions = false, |
| 223 | /// Turns a `coerced_ty` back into a `ty`. Should be called at branch points |
| 224 | /// such as if and switch expressions. |
| 225 | fn br(ri: ResultInfo) ResultInfo { |
| 226 | return switch (ri.rl) { |
| 227 | .coerced_ty => |ty| .{ |
| 228 | .rl = .{ .ty = ty }, |
| 229 | .ctx = ri.ctx, |
| 286 | 230 | }, |
| 287 | | .inferred_ptr, .block_ptr => { |
| 288 | | if (block_scope.rvalue_rl_count == block_scope.break_count) { |
| 289 | | // Neither prong of the if consumed the result location, so we can |
| 290 | | // use break instructions to create an rvalue. |
| 291 | | return .{ |
| 292 | | .tag = .break_operand, |
| 293 | | .elide_store_to_block_ptr_instructions = true, |
| 294 | | }; |
| 295 | | } else { |
| 296 | | // Allow the store_to_block_ptr instructions to remain so that |
| 297 | | // semantic analysis can turn them into bitcasts. |
| 298 | | return .{ |
| 299 | | .tag = .break_void, |
| 300 | | .elide_store_to_block_ptr_instructions = false, |
| 301 | | }; |
| 302 | | } |
| 231 | else => ri, |
| 232 | }; |
| 233 | } |
| 234 | |
| 235 | fn zirTag(ri: ResultInfo) Zir.Inst.Tag { |
| 236 | switch (ri.rl) { |
| 237 | .ty => return switch (ri.ctx) { |
| 238 | .shift_op => .as_shift_operand, |
| 239 | else => .as_node, |
| 303 | 240 | }, |
| 241 | else => unreachable, |
| 304 | 242 | } |
| 305 | 243 | } |
| 306 | 244 | |
| 307 | | /// Turns a `coerced_ty` back into a `ty`. Should be called at branch points |
| 308 | | /// such as if and switch expressions. |
| 309 | | fn br(rl: ResultLoc) ResultLoc { |
| 310 | | return switch (rl) { |
| 311 | | .coerced_ty => |ty| .{ .ty = ty }, |
| 312 | | else => rl, |
| 245 | pub const Loc = union(enum) { |
| 246 | /// The expression is the right-hand side of assignment to `_`. Only the side-effects of the |
| 247 | /// expression should be generated. The result instruction from the expression must |
| 248 | /// be ignored. |
| 249 | discard, |
| 250 | /// The expression has an inferred type, and it will be evaluated as an rvalue. |
| 251 | none, |
| 252 | /// The expression must generate a pointer rather than a value. For example, the left hand side |
| 253 | /// of an assignment uses this kind of result location. |
| 254 | ref, |
| 255 | /// The expression will be coerced into this type, but it will be evaluated as an rvalue. |
| 256 | ty: Zir.Inst.Ref, |
| 257 | /// Same as `ty` but it is guaranteed that Sema will additionally perform the coercion, |
| 258 | /// so no `as` instruction needs to be emitted. |
| 259 | coerced_ty: Zir.Inst.Ref, |
| 260 | /// The expression must store its result into this typed pointer. The result instruction |
| 261 | /// from the expression must be ignored. |
| 262 | ptr: PtrResultLoc, |
| 263 | /// The expression must store its result into this allocation, which has an inferred type. |
| 264 | /// The result instruction from the expression must be ignored. |
| 265 | /// Always an instruction with tag `alloc_inferred`. |
| 266 | inferred_ptr: Zir.Inst.Ref, |
| 267 | /// There is a pointer for the expression to store its result into, however, its type |
| 268 | /// is inferred based on peer type resolution for a `Zir.Inst.Block`. |
| 269 | /// The result instruction from the expression must be ignored. |
| 270 | block_ptr: *GenZir, |
| 271 | |
| 272 | const PtrResultLoc = struct { |
| 273 | inst: Zir.Inst.Ref, |
| 274 | src_node: ?Ast.Node.Index = null, |
| 313 | 275 | }; |
| 314 | | } |
| 315 | 276 | |
| 316 | | fn zirTag(rl: ResultLoc) Zir.Inst.Tag { |
| 317 | | return switch (rl) { |
| 318 | | .ty => .as_node, |
| 319 | | .ty_shift_operand => .as_shift_operand, |
| 320 | | else => unreachable, |
| 277 | pub const Strategy = struct { |
| 278 | elide_store_to_block_ptr_instructions: bool, |
| 279 | tag: Tag, |
| 280 | |
| 281 | pub const Tag = enum { |
| 282 | /// Both branches will use break_void; result location is used to communicate the |
| 283 | /// result instruction. |
| 284 | break_void, |
| 285 | /// Use break statements to pass the block result value, and call rvalue() at |
| 286 | /// the end depending on rl. Also elide the store_to_block_ptr instructions |
| 287 | /// depending on rl. |
| 288 | break_operand, |
| 289 | }; |
| 321 | 290 | }; |
| 322 | | } |
| 291 | |
| 292 | fn strategy(rl: Loc, block_scope: *GenZir) Strategy { |
| 293 | switch (rl) { |
| 294 | // In this branch there will not be any store_to_block_ptr instructions. |
| 295 | .none, .ty, .coerced_ty, .ref => return .{ |
| 296 | .tag = .break_operand, |
| 297 | .elide_store_to_block_ptr_instructions = false, |
| 298 | }, |
| 299 | .discard => return .{ |
| 300 | .tag = .break_void, |
| 301 | .elide_store_to_block_ptr_instructions = false, |
| 302 | }, |
| 303 | // The pointer got passed through to the sub-expressions, so we will use |
| 304 | // break_void here. |
| 305 | // In this branch there will not be any store_to_block_ptr instructions. |
| 306 | .ptr => return .{ |
| 307 | .tag = .break_void, |
| 308 | .elide_store_to_block_ptr_instructions = false, |
| 309 | }, |
| 310 | .inferred_ptr, .block_ptr => { |
| 311 | if (block_scope.rvalue_rl_count == block_scope.break_count) { |
| 312 | // Neither prong of the if consumed the result location, so we can |
| 313 | // use break instructions to create an rvalue. |
| 314 | return .{ |
| 315 | .tag = .break_operand, |
| 316 | .elide_store_to_block_ptr_instructions = true, |
| 317 | }; |
| 318 | } else { |
| 319 | // Allow the store_to_block_ptr instructions to remain so that |
| 320 | // semantic analysis can turn them into bitcasts. |
| 321 | return .{ |
| 322 | .tag = .break_void, |
| 323 | .elide_store_to_block_ptr_instructions = false, |
| 324 | }; |
| 325 | } |
| 326 | }, |
| 327 | } |
| 328 | } |
| 329 | }; |
| 330 | |
| 331 | pub const Context = enum { |
| 332 | /// The expression is the operand to a return expression. |
| 333 | @"return", |
| 334 | /// The expression is the input to an error-handling operator (if-else, try, or catch). |
| 335 | error_handling_expr, |
| 336 | /// The expression is the right-hand side of a shift operation. |
| 337 | shift_op, |
| 338 | /// No specific operator in particular. |
| 339 | none, |
| 340 | }; |
| 323 | 341 | }; |
| 324 | 342 | |
| 325 | | pub const align_rl: ResultLoc = .{ .ty = .u29_type }; |
| 326 | | pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u29_type }; |
| 327 | | pub const bool_rl: ResultLoc = .{ .ty = .bool_type }; |
| 328 | | pub const type_rl: ResultLoc = .{ .ty = .type_type }; |
| 329 | | pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type }; |
| 343 | pub const align_ri: ResultInfo = .{ .rl = .{ .ty = .u29_type } }; |
| 344 | pub const coerced_align_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .u29_type } }; |
| 345 | pub const bool_ri: ResultInfo = .{ .rl = .{ .ty = .bool_type } }; |
| 346 | pub const type_ri: ResultInfo = .{ .rl = .{ .ty = .type_type } }; |
| 347 | pub const coerced_type_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .type_type } }; |
| 330 | 348 | |
| 331 | 349 | fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 332 | 350 | const prev_force_comptime = gz.force_comptime; |
| 333 | 351 | gz.force_comptime = true; |
| 334 | 352 | defer gz.force_comptime = prev_force_comptime; |
| 335 | 353 | |
| 336 | | return expr(gz, scope, coerced_type_rl, type_node); |
| 354 | return expr(gz, scope, coerced_type_ri, type_node); |
| 337 | 355 | } |
| 338 | 356 | |
| 339 | 357 | fn reachableTypeExpr( |
| ... | ... | @@ -346,24 +364,24 @@ fn reachableTypeExpr( |
| 346 | 364 | gz.force_comptime = true; |
| 347 | 365 | defer gz.force_comptime = prev_force_comptime; |
| 348 | 366 | |
| 349 | | return reachableExpr(gz, scope, coerced_type_rl, type_node, reachable_node); |
| 367 | return reachableExpr(gz, scope, coerced_type_ri, type_node, reachable_node); |
| 350 | 368 | } |
| 351 | 369 | |
| 352 | 370 | /// Same as `expr` but fails with a compile error if the result type is `noreturn`. |
| 353 | 371 | fn reachableExpr( |
| 354 | 372 | gz: *GenZir, |
| 355 | 373 | scope: *Scope, |
| 356 | | rl: ResultLoc, |
| 374 | ri: ResultInfo, |
| 357 | 375 | node: Ast.Node.Index, |
| 358 | 376 | reachable_node: Ast.Node.Index, |
| 359 | 377 | ) InnerError!Zir.Inst.Ref { |
| 360 | | return reachableExprComptime(gz, scope, rl, node, reachable_node, false); |
| 378 | return reachableExprComptime(gz, scope, ri, node, reachable_node, false); |
| 361 | 379 | } |
| 362 | 380 | |
| 363 | 381 | fn reachableExprComptime( |
| 364 | 382 | gz: *GenZir, |
| 365 | 383 | scope: *Scope, |
| 366 | | rl: ResultLoc, |
| 384 | ri: ResultInfo, |
| 367 | 385 | node: Ast.Node.Index, |
| 368 | 386 | reachable_node: Ast.Node.Index, |
| 369 | 387 | force_comptime: bool, |
| ... | ... | @@ -372,7 +390,7 @@ fn reachableExprComptime( |
| 372 | 390 | gz.force_comptime = prev_force_comptime or force_comptime; |
| 373 | 391 | defer gz.force_comptime = prev_force_comptime; |
| 374 | 392 | |
| 375 | | const result_inst = try expr(gz, scope, rl, node); |
| 393 | const result_inst = try expr(gz, scope, ri, node); |
| 376 | 394 | if (gz.refIsNoReturn(result_inst)) { |
| 377 | 395 | try gz.astgen.appendErrorNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{ |
| 378 | 396 | try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}), |
| ... | ... | @@ -573,14 +591,14 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins |
| 573 | 591 | .@"orelse", |
| 574 | 592 | => {}, |
| 575 | 593 | } |
| 576 | | return expr(gz, scope, .ref, node); |
| 594 | return expr(gz, scope, .{ .rl = .ref }, node); |
| 577 | 595 | } |
| 578 | 596 | |
| 579 | 597 | /// Turn Zig AST into untyped ZIR instructions. |
| 580 | 598 | /// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the |
| 581 | 599 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, |
| 582 | 600 | /// it must otherwise not be used. |
| 583 | | fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 601 | fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 584 | 602 | const astgen = gz.astgen; |
| 585 | 603 | const tree = astgen.tree; |
| 586 | 604 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -621,161 +639,161 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 621 | 639 | |
| 622 | 640 | .assign => { |
| 623 | 641 | try assign(gz, scope, node); |
| 624 | | return rvalue(gz, rl, .void_value, node); |
| 642 | return rvalue(gz, ri, .void_value, node); |
| 625 | 643 | }, |
| 626 | 644 | |
| 627 | 645 | .assign_shl => { |
| 628 | 646 | try assignShift(gz, scope, node, .shl); |
| 629 | | return rvalue(gz, rl, .void_value, node); |
| 647 | return rvalue(gz, ri, .void_value, node); |
| 630 | 648 | }, |
| 631 | 649 | .assign_shl_sat => { |
| 632 | 650 | try assignShiftSat(gz, scope, node); |
| 633 | | return rvalue(gz, rl, .void_value, node); |
| 651 | return rvalue(gz, ri, .void_value, node); |
| 634 | 652 | }, |
| 635 | 653 | .assign_shr => { |
| 636 | 654 | try assignShift(gz, scope, node, .shr); |
| 637 | | return rvalue(gz, rl, .void_value, node); |
| 655 | return rvalue(gz, ri, .void_value, node); |
| 638 | 656 | }, |
| 639 | 657 | |
| 640 | 658 | .assign_bit_and => { |
| 641 | 659 | try assignOp(gz, scope, node, .bit_and); |
| 642 | | return rvalue(gz, rl, .void_value, node); |
| 660 | return rvalue(gz, ri, .void_value, node); |
| 643 | 661 | }, |
| 644 | 662 | .assign_bit_or => { |
| 645 | 663 | try assignOp(gz, scope, node, .bit_or); |
| 646 | | return rvalue(gz, rl, .void_value, node); |
| 664 | return rvalue(gz, ri, .void_value, node); |
| 647 | 665 | }, |
| 648 | 666 | .assign_bit_xor => { |
| 649 | 667 | try assignOp(gz, scope, node, .xor); |
| 650 | | return rvalue(gz, rl, .void_value, node); |
| 668 | return rvalue(gz, ri, .void_value, node); |
| 651 | 669 | }, |
| 652 | 670 | .assign_div => { |
| 653 | 671 | try assignOp(gz, scope, node, .div); |
| 654 | | return rvalue(gz, rl, .void_value, node); |
| 672 | return rvalue(gz, ri, .void_value, node); |
| 655 | 673 | }, |
| 656 | 674 | .assign_sub => { |
| 657 | 675 | try assignOp(gz, scope, node, .sub); |
| 658 | | return rvalue(gz, rl, .void_value, node); |
| 676 | return rvalue(gz, ri, .void_value, node); |
| 659 | 677 | }, |
| 660 | 678 | .assign_sub_wrap => { |
| 661 | 679 | try assignOp(gz, scope, node, .subwrap); |
| 662 | | return rvalue(gz, rl, .void_value, node); |
| 680 | return rvalue(gz, ri, .void_value, node); |
| 663 | 681 | }, |
| 664 | 682 | .assign_sub_sat => { |
| 665 | 683 | try assignOp(gz, scope, node, .sub_sat); |
| 666 | | return rvalue(gz, rl, .void_value, node); |
| 684 | return rvalue(gz, ri, .void_value, node); |
| 667 | 685 | }, |
| 668 | 686 | .assign_mod => { |
| 669 | 687 | try assignOp(gz, scope, node, .mod_rem); |
| 670 | | return rvalue(gz, rl, .void_value, node); |
| 688 | return rvalue(gz, ri, .void_value, node); |
| 671 | 689 | }, |
| 672 | 690 | .assign_add => { |
| 673 | 691 | try assignOp(gz, scope, node, .add); |
| 674 | | return rvalue(gz, rl, .void_value, node); |
| 692 | return rvalue(gz, ri, .void_value, node); |
| 675 | 693 | }, |
| 676 | 694 | .assign_add_wrap => { |
| 677 | 695 | try assignOp(gz, scope, node, .addwrap); |
| 678 | | return rvalue(gz, rl, .void_value, node); |
| 696 | return rvalue(gz, ri, .void_value, node); |
| 679 | 697 | }, |
| 680 | 698 | .assign_add_sat => { |
| 681 | 699 | try assignOp(gz, scope, node, .add_sat); |
| 682 | | return rvalue(gz, rl, .void_value, node); |
| 700 | return rvalue(gz, ri, .void_value, node); |
| 683 | 701 | }, |
| 684 | 702 | .assign_mul => { |
| 685 | 703 | try assignOp(gz, scope, node, .mul); |
| 686 | | return rvalue(gz, rl, .void_value, node); |
| 704 | return rvalue(gz, ri, .void_value, node); |
| 687 | 705 | }, |
| 688 | 706 | .assign_mul_wrap => { |
| 689 | 707 | try assignOp(gz, scope, node, .mulwrap); |
| 690 | | return rvalue(gz, rl, .void_value, node); |
| 708 | return rvalue(gz, ri, .void_value, node); |
| 691 | 709 | }, |
| 692 | 710 | .assign_mul_sat => { |
| 693 | 711 | try assignOp(gz, scope, node, .mul_sat); |
| 694 | | return rvalue(gz, rl, .void_value, node); |
| 712 | return rvalue(gz, ri, .void_value, node); |
| 695 | 713 | }, |
| 696 | 714 | |
| 697 | 715 | // zig fmt: off |
| 698 | | .shl => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl), |
| 699 | | .shr => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shr), |
| 700 | | |
| 701 | | .add => return simpleBinOp(gz, scope, rl, node, .add), |
| 702 | | .add_wrap => return simpleBinOp(gz, scope, rl, node, .addwrap), |
| 703 | | .add_sat => return simpleBinOp(gz, scope, rl, node, .add_sat), |
| 704 | | .sub => return simpleBinOp(gz, scope, rl, node, .sub), |
| 705 | | .sub_wrap => return simpleBinOp(gz, scope, rl, node, .subwrap), |
| 706 | | .sub_sat => return simpleBinOp(gz, scope, rl, node, .sub_sat), |
| 707 | | .mul => return simpleBinOp(gz, scope, rl, node, .mul), |
| 708 | | .mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap), |
| 709 | | .mul_sat => return simpleBinOp(gz, scope, rl, node, .mul_sat), |
| 710 | | .div => return simpleBinOp(gz, scope, rl, node, .div), |
| 711 | | .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem), |
| 712 | | .shl_sat => return simpleBinOp(gz, scope, rl, node, .shl_sat), |
| 713 | | |
| 714 | | .bit_and => return simpleBinOp(gz, scope, rl, node, .bit_and), |
| 715 | | .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or), |
| 716 | | .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor), |
| 717 | | .bang_equal => return simpleBinOp(gz, scope, rl, node, .cmp_neq), |
| 718 | | .equal_equal => return simpleBinOp(gz, scope, rl, node, .cmp_eq), |
| 719 | | .greater_than => return simpleBinOp(gz, scope, rl, node, .cmp_gt), |
| 720 | | .greater_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_gte), |
| 721 | | .less_than => return simpleBinOp(gz, scope, rl, node, .cmp_lt), |
| 722 | | .less_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_lte), |
| 723 | | .array_cat => return simpleBinOp(gz, scope, rl, node, .array_cat), |
| 716 | .shl => return shiftOp(gz, scope, ri, node, node_datas[node].lhs, node_datas[node].rhs, .shl), |
| 717 | .shr => return shiftOp(gz, scope, ri, node, node_datas[node].lhs, node_datas[node].rhs, .shr), |
| 718 | |
| 719 | .add => return simpleBinOp(gz, scope, ri, node, .add), |
| 720 | .add_wrap => return simpleBinOp(gz, scope, ri, node, .addwrap), |
| 721 | .add_sat => return simpleBinOp(gz, scope, ri, node, .add_sat), |
| 722 | .sub => return simpleBinOp(gz, scope, ri, node, .sub), |
| 723 | .sub_wrap => return simpleBinOp(gz, scope, ri, node, .subwrap), |
| 724 | .sub_sat => return simpleBinOp(gz, scope, ri, node, .sub_sat), |
| 725 | .mul => return simpleBinOp(gz, scope, ri, node, .mul), |
| 726 | .mul_wrap => return simpleBinOp(gz, scope, ri, node, .mulwrap), |
| 727 | .mul_sat => return simpleBinOp(gz, scope, ri, node, .mul_sat), |
| 728 | .div => return simpleBinOp(gz, scope, ri, node, .div), |
| 729 | .mod => return simpleBinOp(gz, scope, ri, node, .mod_rem), |
| 730 | .shl_sat => return simpleBinOp(gz, scope, ri, node, .shl_sat), |
| 731 | |
| 732 | .bit_and => return simpleBinOp(gz, scope, ri, node, .bit_and), |
| 733 | .bit_or => return simpleBinOp(gz, scope, ri, node, .bit_or), |
| 734 | .bit_xor => return simpleBinOp(gz, scope, ri, node, .xor), |
| 735 | .bang_equal => return simpleBinOp(gz, scope, ri, node, .cmp_neq), |
| 736 | .equal_equal => return simpleBinOp(gz, scope, ri, node, .cmp_eq), |
| 737 | .greater_than => return simpleBinOp(gz, scope, ri, node, .cmp_gt), |
| 738 | .greater_or_equal => return simpleBinOp(gz, scope, ri, node, .cmp_gte), |
| 739 | .less_than => return simpleBinOp(gz, scope, ri, node, .cmp_lt), |
| 740 | .less_or_equal => return simpleBinOp(gz, scope, ri, node, .cmp_lte), |
| 741 | .array_cat => return simpleBinOp(gz, scope, ri, node, .array_cat), |
| 724 | 742 | |
| 725 | 743 | .array_mult => { |
| 726 | 744 | const result = try gz.addPlNode(.array_mul, node, Zir.Inst.Bin{ |
| 727 | | .lhs = try expr(gz, scope, .none, node_datas[node].lhs), |
| 728 | | .rhs = try comptimeExpr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs), |
| 745 | .lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs), |
| 746 | .rhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs), |
| 729 | 747 | }); |
| 730 | | return rvalue(gz, rl, result, node); |
| 748 | return rvalue(gz, ri, result, node); |
| 731 | 749 | }, |
| 732 | 750 | |
| 733 | | .error_union => return simpleBinOp(gz, scope, rl, node, .error_union_type), |
| 734 | | .merge_error_sets => return simpleBinOp(gz, scope, rl, node, .merge_error_sets), |
| 751 | .error_union => return simpleBinOp(gz, scope, ri, node, .error_union_type), |
| 752 | .merge_error_sets => return simpleBinOp(gz, scope, ri, node, .merge_error_sets), |
| 735 | 753 | |
| 736 | | .bool_and => return boolBinOp(gz, scope, rl, node, .bool_br_and), |
| 737 | | .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or), |
| 754 | .bool_and => return boolBinOp(gz, scope, ri, node, .bool_br_and), |
| 755 | .bool_or => return boolBinOp(gz, scope, ri, node, .bool_br_or), |
| 738 | 756 | |
| 739 | | .bool_not => return simpleUnOp(gz, scope, rl, node, bool_rl, node_datas[node].lhs, .bool_not), |
| 740 | | .bit_not => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .bit_not), |
| 757 | .bool_not => return simpleUnOp(gz, scope, ri, node, bool_ri, node_datas[node].lhs, .bool_not), |
| 758 | .bit_not => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, node_datas[node].lhs, .bit_not), |
| 741 | 759 | |
| 742 | | .negation => return negation(gz, scope, rl, node), |
| 743 | | .negation_wrap => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .negate_wrap), |
| 760 | .negation => return negation(gz, scope, ri, node), |
| 761 | .negation_wrap => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, node_datas[node].lhs, .negate_wrap), |
| 744 | 762 | |
| 745 | | .identifier => return identifier(gz, scope, rl, node), |
| 763 | .identifier => return identifier(gz, scope, ri, node), |
| 746 | 764 | |
| 747 | | .asm_simple => return asmExpr(gz, scope, rl, node, tree.asmSimple(node)), |
| 748 | | .@"asm" => return asmExpr(gz, scope, rl, node, tree.asmFull(node)), |
| 765 | .asm_simple => return asmExpr(gz, scope, ri, node, tree.asmSimple(node)), |
| 766 | .@"asm" => return asmExpr(gz, scope, ri, node, tree.asmFull(node)), |
| 749 | 767 | |
| 750 | | .string_literal => return stringLiteral(gz, rl, node), |
| 751 | | .multiline_string_literal => return multilineStringLiteral(gz, rl, node), |
| 768 | .string_literal => return stringLiteral(gz, ri, node), |
| 769 | .multiline_string_literal => return multilineStringLiteral(gz, ri, node), |
| 752 | 770 | |
| 753 | | .number_literal => return numberLiteral(gz, rl, node, node, .positive), |
| 771 | .number_literal => return numberLiteral(gz, ri, node, node, .positive), |
| 754 | 772 | // zig fmt: on |
| 755 | 773 | |
| 756 | 774 | .builtin_call_two, .builtin_call_two_comma => { |
| 757 | 775 | if (node_datas[node].lhs == 0) { |
| 758 | 776 | const params = [_]Ast.Node.Index{}; |
| 759 | | return builtinCall(gz, scope, rl, node, &params); |
| 777 | return builtinCall(gz, scope, ri, node, &params); |
| 760 | 778 | } else if (node_datas[node].rhs == 0) { |
| 761 | 779 | const params = [_]Ast.Node.Index{node_datas[node].lhs}; |
| 762 | | return builtinCall(gz, scope, rl, node, &params); |
| 780 | return builtinCall(gz, scope, ri, node, &params); |
| 763 | 781 | } else { |
| 764 | 782 | const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; |
| 765 | | return builtinCall(gz, scope, rl, node, &params); |
| 783 | return builtinCall(gz, scope, ri, node, &params); |
| 766 | 784 | } |
| 767 | 785 | }, |
| 768 | 786 | .builtin_call, .builtin_call_comma => { |
| 769 | 787 | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; |
| 770 | | return builtinCall(gz, scope, rl, node, params); |
| 788 | return builtinCall(gz, scope, ri, node, params); |
| 771 | 789 | }, |
| 772 | 790 | |
| 773 | 791 | .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => { |
| 774 | 792 | var params: [1]Ast.Node.Index = undefined; |
| 775 | | return callExpr(gz, scope, rl, node, tree.callOne(&params, node)); |
| 793 | return callExpr(gz, scope, ri, node, tree.callOne(&params, node)); |
| 776 | 794 | }, |
| 777 | 795 | .call, .call_comma, .async_call, .async_call_comma => { |
| 778 | | return callExpr(gz, scope, rl, node, tree.callFull(node)); |
| 796 | return callExpr(gz, scope, ri, node, tree.callFull(node)); |
| 779 | 797 | }, |
| 780 | 798 | |
| 781 | 799 | .unreachable_literal => { |
| ... | ... | @@ -790,112 +808,112 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 790 | 808 | return Zir.Inst.Ref.unreachable_value; |
| 791 | 809 | }, |
| 792 | 810 | .@"return" => return ret(gz, scope, node), |
| 793 | | .field_access => return fieldAccess(gz, scope, rl, node), |
| 811 | .field_access => return fieldAccess(gz, scope, ri, node), |
| 794 | 812 | |
| 795 | | .if_simple => return ifExpr(gz, scope, rl.br(), node, tree.ifSimple(node)), |
| 796 | | .@"if" => return ifExpr(gz, scope, rl.br(), node, tree.ifFull(node)), |
| 813 | .if_simple => return ifExpr(gz, scope, ri.br(), node, tree.ifSimple(node)), |
| 814 | .@"if" => return ifExpr(gz, scope, ri.br(), node, tree.ifFull(node)), |
| 797 | 815 | |
| 798 | | .while_simple => return whileExpr(gz, scope, rl.br(), node, tree.whileSimple(node), false), |
| 799 | | .while_cont => return whileExpr(gz, scope, rl.br(), node, tree.whileCont(node), false), |
| 800 | | .@"while" => return whileExpr(gz, scope, rl.br(), node, tree.whileFull(node), false), |
| 816 | .while_simple => return whileExpr(gz, scope, ri.br(), node, tree.whileSimple(node), false), |
| 817 | .while_cont => return whileExpr(gz, scope, ri.br(), node, tree.whileCont(node), false), |
| 818 | .@"while" => return whileExpr(gz, scope, ri.br(), node, tree.whileFull(node), false), |
| 801 | 819 | |
| 802 | | .for_simple => return forExpr(gz, scope, rl.br(), node, tree.forSimple(node), false), |
| 803 | | .@"for" => return forExpr(gz, scope, rl.br(), node, tree.forFull(node), false), |
| 820 | .for_simple => return forExpr(gz, scope, ri.br(), node, tree.forSimple(node), false), |
| 821 | .@"for" => return forExpr(gz, scope, ri.br(), node, tree.forFull(node), false), |
| 804 | 822 | |
| 805 | 823 | .slice_open => { |
| 806 | | const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); |
| 807 | | const start = try expr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs); |
| 824 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 825 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs); |
| 808 | 826 | const result = try gz.addPlNode(.slice_start, node, Zir.Inst.SliceStart{ |
| 809 | 827 | .lhs = lhs, |
| 810 | 828 | .start = start, |
| 811 | 829 | }); |
| 812 | | return rvalue(gz, rl, result, node); |
| 830 | return rvalue(gz, ri, result, node); |
| 813 | 831 | }, |
| 814 | 832 | .slice => { |
| 815 | | const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); |
| 833 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 816 | 834 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); |
| 817 | | const start = try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.start); |
| 818 | | const end = try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.end); |
| 835 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start); |
| 836 | const end = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end); |
| 819 | 837 | const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{ |
| 820 | 838 | .lhs = lhs, |
| 821 | 839 | .start = start, |
| 822 | 840 | .end = end, |
| 823 | 841 | }); |
| 824 | | return rvalue(gz, rl, result, node); |
| 842 | return rvalue(gz, ri, result, node); |
| 825 | 843 | }, |
| 826 | 844 | .slice_sentinel => { |
| 827 | | const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); |
| 845 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 828 | 846 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); |
| 829 | | const start = try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.start); |
| 830 | | const end = if (extra.end != 0) try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.end) else .none; |
| 831 | | const sentinel = try expr(gz, scope, .none, extra.sentinel); |
| 847 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start); |
| 848 | const end = if (extra.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end) else .none; |
| 849 | const sentinel = try expr(gz, scope, .{ .rl = .none }, extra.sentinel); |
| 832 | 850 | const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{ |
| 833 | 851 | .lhs = lhs, |
| 834 | 852 | .start = start, |
| 835 | 853 | .end = end, |
| 836 | 854 | .sentinel = sentinel, |
| 837 | 855 | }); |
| 838 | | return rvalue(gz, rl, result, node); |
| 856 | return rvalue(gz, ri, result, node); |
| 839 | 857 | }, |
| 840 | 858 | |
| 841 | 859 | .deref => { |
| 842 | | const lhs = try expr(gz, scope, .none, node_datas[node].lhs); |
| 860 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); |
| 843 | 861 | _ = try gz.addUnNode(.validate_deref, lhs, node); |
| 844 | | switch (rl) { |
| 845 | | .ref, .catch_ref => return lhs, |
| 862 | switch (ri.rl) { |
| 863 | .ref => return lhs, |
| 846 | 864 | else => { |
| 847 | 865 | const result = try gz.addUnNode(.load, lhs, node); |
| 848 | | return rvalue(gz, rl, result, node); |
| 866 | return rvalue(gz, ri, result, node); |
| 849 | 867 | }, |
| 850 | 868 | } |
| 851 | 869 | }, |
| 852 | 870 | .address_of => { |
| 853 | | const result = try expr(gz, scope, .ref, node_datas[node].lhs); |
| 854 | | return rvalue(gz, rl, result, node); |
| 871 | const result = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 872 | return rvalue(gz, ri, result, node); |
| 855 | 873 | }, |
| 856 | 874 | .optional_type => { |
| 857 | 875 | const operand = try typeExpr(gz, scope, node_datas[node].lhs); |
| 858 | 876 | const result = try gz.addUnNode(.optional_type, operand, node); |
| 859 | | return rvalue(gz, rl, result, node); |
| 877 | return rvalue(gz, ri, result, node); |
| 860 | 878 | }, |
| 861 | | .unwrap_optional => switch (rl) { |
| 862 | | .ref, .catch_ref => return gz.addUnNode( |
| 879 | .unwrap_optional => switch (ri.rl) { |
| 880 | .ref => return gz.addUnNode( |
| 863 | 881 | .optional_payload_safe_ptr, |
| 864 | | try expr(gz, scope, .ref, node_datas[node].lhs), |
| 882 | try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs), |
| 865 | 883 | node, |
| 866 | 884 | ), |
| 867 | | else => return rvalue(gz, rl, try gz.addUnNode( |
| 885 | else => return rvalue(gz, ri, try gz.addUnNode( |
| 868 | 886 | .optional_payload_safe, |
| 869 | | try expr(gz, scope, .none, node_datas[node].lhs), |
| 887 | try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs), |
| 870 | 888 | node, |
| 871 | 889 | ), node), |
| 872 | 890 | }, |
| 873 | 891 | .block_two, .block_two_semicolon => { |
| 874 | 892 | const statements = [2]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; |
| 875 | 893 | if (node_datas[node].lhs == 0) { |
| 876 | | return blockExpr(gz, scope, rl, node, statements[0..0]); |
| 894 | return blockExpr(gz, scope, ri, node, statements[0..0]); |
| 877 | 895 | } else if (node_datas[node].rhs == 0) { |
| 878 | | return blockExpr(gz, scope, rl, node, statements[0..1]); |
| 896 | return blockExpr(gz, scope, ri, node, statements[0..1]); |
| 879 | 897 | } else { |
| 880 | | return blockExpr(gz, scope, rl, node, statements[0..2]); |
| 898 | return blockExpr(gz, scope, ri, node, statements[0..2]); |
| 881 | 899 | } |
| 882 | 900 | }, |
| 883 | 901 | .block, .block_semicolon => { |
| 884 | 902 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; |
| 885 | | return blockExpr(gz, scope, rl, node, statements); |
| 903 | return blockExpr(gz, scope, ri, node, statements); |
| 886 | 904 | }, |
| 887 | | .enum_literal => return simpleStrTok(gz, rl, main_tokens[node], node, .enum_literal), |
| 888 | | .error_value => return simpleStrTok(gz, rl, node_datas[node].rhs, node, .error_value), |
| 905 | .enum_literal => return simpleStrTok(gz, ri, main_tokens[node], node, .enum_literal), |
| 906 | .error_value => return simpleStrTok(gz, ri, node_datas[node].rhs, node, .error_value), |
| 889 | 907 | // TODO restore this when implementing https://github.com/ziglang/zig/issues/6025 |
| 890 | | // .anyframe_literal => return rvalue(gz, rl, .anyframe_type, node), |
| 908 | // .anyframe_literal => return rvalue(gz, ri, .anyframe_type, node), |
| 891 | 909 | .anyframe_literal => { |
| 892 | 910 | const result = try gz.addUnNode(.anyframe_type, .void_type, node); |
| 893 | | return rvalue(gz, rl, result, node); |
| 911 | return rvalue(gz, ri, result, node); |
| 894 | 912 | }, |
| 895 | 913 | .anyframe_type => { |
| 896 | 914 | const return_type = try typeExpr(gz, scope, node_datas[node].rhs); |
| 897 | 915 | const result = try gz.addUnNode(.anyframe_type, return_type, node); |
| 898 | | return rvalue(gz, rl, result, node); |
| 916 | return rvalue(gz, ri, result, node); |
| 899 | 917 | }, |
| 900 | 918 | .@"catch" => { |
| 901 | 919 | const catch_token = main_tokens[node]; |
| ... | ... | @@ -903,11 +921,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 903 | 921 | catch_token + 2 |
| 904 | 922 | else |
| 905 | 923 | null; |
| 906 | | switch (rl) { |
| 907 | | .ref, .catch_ref => return orelseCatchExpr( |
| 924 | switch (ri.rl) { |
| 925 | .ref => return orelseCatchExpr( |
| 908 | 926 | gz, |
| 909 | 927 | scope, |
| 910 | | rl, |
| 928 | ri, |
| 911 | 929 | node, |
| 912 | 930 | node_datas[node].lhs, |
| 913 | 931 | .is_non_err_ptr, |
| ... | ... | @@ -919,7 +937,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 919 | 937 | else => return orelseCatchExpr( |
| 920 | 938 | gz, |
| 921 | 939 | scope, |
| 922 | | rl, |
| 940 | ri, |
| 923 | 941 | node, |
| 924 | 942 | node_datas[node].lhs, |
| 925 | 943 | .is_non_err, |
| ... | ... | @@ -930,11 +948,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 930 | 948 | ), |
| 931 | 949 | } |
| 932 | 950 | }, |
| 933 | | .@"orelse" => switch (rl) { |
| 934 | | .ref, .catch_ref => return orelseCatchExpr( |
| 951 | .@"orelse" => switch (ri.rl) { |
| 952 | .ref => return orelseCatchExpr( |
| 935 | 953 | gz, |
| 936 | 954 | scope, |
| 937 | | rl, |
| 955 | ri, |
| 938 | 956 | node, |
| 939 | 957 | node_datas[node].lhs, |
| 940 | 958 | .is_non_null_ptr, |
| ... | ... | @@ -946,7 +964,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 946 | 964 | else => return orelseCatchExpr( |
| 947 | 965 | gz, |
| 948 | 966 | scope, |
| 949 | | rl, |
| 967 | ri, |
| 950 | 968 | node, |
| 951 | 969 | node_datas[node].lhs, |
| 952 | 970 | .is_non_null, |
| ... | ... | @@ -957,94 +975,94 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 957 | 975 | ), |
| 958 | 976 | }, |
| 959 | 977 | |
| 960 | | .ptr_type_aligned => return ptrType(gz, scope, rl, node, tree.ptrTypeAligned(node)), |
| 961 | | .ptr_type_sentinel => return ptrType(gz, scope, rl, node, tree.ptrTypeSentinel(node)), |
| 962 | | .ptr_type => return ptrType(gz, scope, rl, node, tree.ptrType(node)), |
| 963 | | .ptr_type_bit_range => return ptrType(gz, scope, rl, node, tree.ptrTypeBitRange(node)), |
| 978 | .ptr_type_aligned => return ptrType(gz, scope, ri, node, tree.ptrTypeAligned(node)), |
| 979 | .ptr_type_sentinel => return ptrType(gz, scope, ri, node, tree.ptrTypeSentinel(node)), |
| 980 | .ptr_type => return ptrType(gz, scope, ri, node, tree.ptrType(node)), |
| 981 | .ptr_type_bit_range => return ptrType(gz, scope, ri, node, tree.ptrTypeBitRange(node)), |
| 964 | 982 | |
| 965 | 983 | .container_decl, |
| 966 | 984 | .container_decl_trailing, |
| 967 | | => return containerDecl(gz, scope, rl, node, tree.containerDecl(node)), |
| 985 | => return containerDecl(gz, scope, ri, node, tree.containerDecl(node)), |
| 968 | 986 | .container_decl_two, .container_decl_two_trailing => { |
| 969 | 987 | var buffer: [2]Ast.Node.Index = undefined; |
| 970 | | return containerDecl(gz, scope, rl, node, tree.containerDeclTwo(&buffer, node)); |
| 988 | return containerDecl(gz, scope, ri, node, tree.containerDeclTwo(&buffer, node)); |
| 971 | 989 | }, |
| 972 | 990 | .container_decl_arg, |
| 973 | 991 | .container_decl_arg_trailing, |
| 974 | | => return containerDecl(gz, scope, rl, node, tree.containerDeclArg(node)), |
| 992 | => return containerDecl(gz, scope, ri, node, tree.containerDeclArg(node)), |
| 975 | 993 | |
| 976 | 994 | .tagged_union, |
| 977 | 995 | .tagged_union_trailing, |
| 978 | | => return containerDecl(gz, scope, rl, node, tree.taggedUnion(node)), |
| 996 | => return containerDecl(gz, scope, ri, node, tree.taggedUnion(node)), |
| 979 | 997 | .tagged_union_two, .tagged_union_two_trailing => { |
| 980 | 998 | var buffer: [2]Ast.Node.Index = undefined; |
| 981 | | return containerDecl(gz, scope, rl, node, tree.taggedUnionTwo(&buffer, node)); |
| 999 | return containerDecl(gz, scope, ri, node, tree.taggedUnionTwo(&buffer, node)); |
| 982 | 1000 | }, |
| 983 | 1001 | .tagged_union_enum_tag, |
| 984 | 1002 | .tagged_union_enum_tag_trailing, |
| 985 | | => return containerDecl(gz, scope, rl, node, tree.taggedUnionEnumTag(node)), |
| 1003 | => return containerDecl(gz, scope, ri, node, tree.taggedUnionEnumTag(node)), |
| 986 | 1004 | |
| 987 | 1005 | .@"break" => return breakExpr(gz, scope, node), |
| 988 | 1006 | .@"continue" => return continueExpr(gz, scope, node), |
| 989 | | .grouped_expression => return expr(gz, scope, rl, node_datas[node].lhs), |
| 990 | | .array_type => return arrayType(gz, scope, rl, node), |
| 991 | | .array_type_sentinel => return arrayTypeSentinel(gz, scope, rl, node), |
| 992 | | .char_literal => return charLiteral(gz, rl, node), |
| 993 | | .error_set_decl => return errorSetDecl(gz, rl, node), |
| 994 | | .array_access => return arrayAccess(gz, scope, rl, node), |
| 995 | | .@"comptime" => return comptimeExprAst(gz, scope, rl, node), |
| 996 | | .@"switch", .switch_comma => return switchExpr(gz, scope, rl.br(), node), |
| 997 | | |
| 998 | | .@"nosuspend" => return nosuspendExpr(gz, scope, rl, node), |
| 1007 | .grouped_expression => return expr(gz, scope, ri, node_datas[node].lhs), |
| 1008 | .array_type => return arrayType(gz, scope, ri, node), |
| 1009 | .array_type_sentinel => return arrayTypeSentinel(gz, scope, ri, node), |
| 1010 | .char_literal => return charLiteral(gz, ri, node), |
| 1011 | .error_set_decl => return errorSetDecl(gz, ri, node), |
| 1012 | .array_access => return arrayAccess(gz, scope, ri, node), |
| 1013 | .@"comptime" => return comptimeExprAst(gz, scope, ri, node), |
| 1014 | .@"switch", .switch_comma => return switchExpr(gz, scope, ri.br(), node), |
| 1015 | |
| 1016 | .@"nosuspend" => return nosuspendExpr(gz, scope, ri, node), |
| 999 | 1017 | .@"suspend" => return suspendExpr(gz, scope, node), |
| 1000 | | .@"await" => return awaitExpr(gz, scope, rl, node), |
| 1001 | | .@"resume" => return resumeExpr(gz, scope, rl, node), |
| 1018 | .@"await" => return awaitExpr(gz, scope, ri, node), |
| 1019 | .@"resume" => return resumeExpr(gz, scope, ri, node), |
| 1002 | 1020 | |
| 1003 | | .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs), |
| 1021 | .@"try" => return tryExpr(gz, scope, ri, node, node_datas[node].lhs), |
| 1004 | 1022 | |
| 1005 | 1023 | .array_init_one, .array_init_one_comma => { |
| 1006 | 1024 | var elements: [1]Ast.Node.Index = undefined; |
| 1007 | | return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node)); |
| 1025 | return arrayInitExpr(gz, scope, ri, node, tree.arrayInitOne(&elements, node)); |
| 1008 | 1026 | }, |
| 1009 | 1027 | .array_init_dot_two, .array_init_dot_two_comma => { |
| 1010 | 1028 | var elements: [2]Ast.Node.Index = undefined; |
| 1011 | | return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node)); |
| 1029 | return arrayInitExpr(gz, scope, ri, node, tree.arrayInitDotTwo(&elements, node)); |
| 1012 | 1030 | }, |
| 1013 | 1031 | .array_init_dot, |
| 1014 | 1032 | .array_init_dot_comma, |
| 1015 | | => return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDot(node)), |
| 1033 | => return arrayInitExpr(gz, scope, ri, node, tree.arrayInitDot(node)), |
| 1016 | 1034 | .array_init, |
| 1017 | 1035 | .array_init_comma, |
| 1018 | | => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)), |
| 1036 | => return arrayInitExpr(gz, scope, ri, node, tree.arrayInit(node)), |
| 1019 | 1037 | |
| 1020 | 1038 | .struct_init_one, .struct_init_one_comma => { |
| 1021 | 1039 | var fields: [1]Ast.Node.Index = undefined; |
| 1022 | | return structInitExpr(gz, scope, rl, node, tree.structInitOne(&fields, node)); |
| 1040 | return structInitExpr(gz, scope, ri, node, tree.structInitOne(&fields, node)); |
| 1023 | 1041 | }, |
| 1024 | 1042 | .struct_init_dot_two, .struct_init_dot_two_comma => { |
| 1025 | 1043 | var fields: [2]Ast.Node.Index = undefined; |
| 1026 | | return structInitExpr(gz, scope, rl, node, tree.structInitDotTwo(&fields, node)); |
| 1044 | return structInitExpr(gz, scope, ri, node, tree.structInitDotTwo(&fields, node)); |
| 1027 | 1045 | }, |
| 1028 | 1046 | .struct_init_dot, |
| 1029 | 1047 | .struct_init_dot_comma, |
| 1030 | | => return structInitExpr(gz, scope, rl, node, tree.structInitDot(node)), |
| 1048 | => return structInitExpr(gz, scope, ri, node, tree.structInitDot(node)), |
| 1031 | 1049 | .struct_init, |
| 1032 | 1050 | .struct_init_comma, |
| 1033 | | => return structInitExpr(gz, scope, rl, node, tree.structInit(node)), |
| 1051 | => return structInitExpr(gz, scope, ri, node, tree.structInit(node)), |
| 1034 | 1052 | |
| 1035 | 1053 | .fn_proto_simple => { |
| 1036 | 1054 | var params: [1]Ast.Node.Index = undefined; |
| 1037 | | return fnProtoExpr(gz, scope, rl, node, tree.fnProtoSimple(&params, node)); |
| 1055 | return fnProtoExpr(gz, scope, ri, node, tree.fnProtoSimple(&params, node)); |
| 1038 | 1056 | }, |
| 1039 | 1057 | .fn_proto_multi => { |
| 1040 | | return fnProtoExpr(gz, scope, rl, node, tree.fnProtoMulti(node)); |
| 1058 | return fnProtoExpr(gz, scope, ri, node, tree.fnProtoMulti(node)); |
| 1041 | 1059 | }, |
| 1042 | 1060 | .fn_proto_one => { |
| 1043 | 1061 | var params: [1]Ast.Node.Index = undefined; |
| 1044 | | return fnProtoExpr(gz, scope, rl, node, tree.fnProtoOne(&params, node)); |
| 1062 | return fnProtoExpr(gz, scope, ri, node, tree.fnProtoOne(&params, node)); |
| 1045 | 1063 | }, |
| 1046 | 1064 | .fn_proto => { |
| 1047 | | return fnProtoExpr(gz, scope, rl, node, tree.fnProto(node)); |
| 1065 | return fnProtoExpr(gz, scope, ri, node, tree.fnProto(node)); |
| 1048 | 1066 | }, |
| 1049 | 1067 | } |
| 1050 | 1068 | } |
| ... | ... | @@ -1052,7 +1070,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 1052 | 1070 | fn nosuspendExpr( |
| 1053 | 1071 | gz: *GenZir, |
| 1054 | 1072 | scope: *Scope, |
| 1055 | | rl: ResultLoc, |
| 1073 | ri: ResultInfo, |
| 1056 | 1074 | node: Ast.Node.Index, |
| 1057 | 1075 | ) InnerError!Zir.Inst.Ref { |
| 1058 | 1076 | const astgen = gz.astgen; |
| ... | ... | @@ -1067,7 +1085,7 @@ fn nosuspendExpr( |
| 1067 | 1085 | } |
| 1068 | 1086 | gz.nosuspend_node = node; |
| 1069 | 1087 | defer gz.nosuspend_node = 0; |
| 1070 | | return expr(gz, scope, rl, body_node); |
| 1088 | return expr(gz, scope, ri, body_node); |
| 1071 | 1089 | } |
| 1072 | 1090 | |
| 1073 | 1091 | fn suspendExpr( |
| ... | ... | @@ -1100,7 +1118,7 @@ fn suspendExpr( |
| 1100 | 1118 | suspend_scope.suspend_node = node; |
| 1101 | 1119 | defer suspend_scope.unstack(); |
| 1102 | 1120 | |
| 1103 | | const body_result = try expr(&suspend_scope, &suspend_scope.base, .none, body_node); |
| 1121 | const body_result = try expr(&suspend_scope, &suspend_scope.base, .{ .rl = .none }, body_node); |
| 1104 | 1122 | if (!gz.refIsNoReturn(body_result)) { |
| 1105 | 1123 | _ = try suspend_scope.addBreak(.break_inline, suspend_inst, .void_value); |
| 1106 | 1124 | } |
| ... | ... | @@ -1112,7 +1130,7 @@ fn suspendExpr( |
| 1112 | 1130 | fn awaitExpr( |
| 1113 | 1131 | gz: *GenZir, |
| 1114 | 1132 | scope: *Scope, |
| 1115 | | rl: ResultLoc, |
| 1133 | ri: ResultInfo, |
| 1116 | 1134 | node: Ast.Node.Index, |
| 1117 | 1135 | ) InnerError!Zir.Inst.Ref { |
| 1118 | 1136 | const astgen = gz.astgen; |
| ... | ... | @@ -1125,7 +1143,7 @@ fn awaitExpr( |
| 1125 | 1143 | try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), |
| 1126 | 1144 | }); |
| 1127 | 1145 | } |
| 1128 | | const operand = try expr(gz, scope, .none, rhs_node); |
| 1146 | const operand = try expr(gz, scope, .{ .rl = .none }, rhs_node); |
| 1129 | 1147 | const result = if (gz.nosuspend_node != 0) |
| 1130 | 1148 | try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ |
| 1131 | 1149 | .node = gz.nodeIndexToRelative(node), |
| ... | ... | @@ -1134,28 +1152,28 @@ fn awaitExpr( |
| 1134 | 1152 | else |
| 1135 | 1153 | try gz.addUnNode(.@"await", operand, node); |
| 1136 | 1154 | |
| 1137 | | return rvalue(gz, rl, result, node); |
| 1155 | return rvalue(gz, ri, result, node); |
| 1138 | 1156 | } |
| 1139 | 1157 | |
| 1140 | 1158 | fn resumeExpr( |
| 1141 | 1159 | gz: *GenZir, |
| 1142 | 1160 | scope: *Scope, |
| 1143 | | rl: ResultLoc, |
| 1161 | ri: ResultInfo, |
| 1144 | 1162 | node: Ast.Node.Index, |
| 1145 | 1163 | ) InnerError!Zir.Inst.Ref { |
| 1146 | 1164 | const astgen = gz.astgen; |
| 1147 | 1165 | const tree = astgen.tree; |
| 1148 | 1166 | const node_datas = tree.nodes.items(.data); |
| 1149 | 1167 | const rhs_node = node_datas[node].lhs; |
| 1150 | | const operand = try expr(gz, scope, .none, rhs_node); |
| 1168 | const operand = try expr(gz, scope, .{ .rl = .none }, rhs_node); |
| 1151 | 1169 | const result = try gz.addUnNode(.@"resume", operand, node); |
| 1152 | | return rvalue(gz, rl, result, node); |
| 1170 | return rvalue(gz, ri, result, node); |
| 1153 | 1171 | } |
| 1154 | 1172 | |
| 1155 | 1173 | fn fnProtoExpr( |
| 1156 | 1174 | gz: *GenZir, |
| 1157 | 1175 | scope: *Scope, |
| 1158 | | rl: ResultLoc, |
| 1176 | ri: ResultInfo, |
| 1159 | 1177 | node: Ast.Node.Index, |
| 1160 | 1178 | fn_proto: Ast.full.FnProto, |
| 1161 | 1179 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -1221,7 +1239,7 @@ fn fnProtoExpr( |
| 1221 | 1239 | assert(param_type_node != 0); |
| 1222 | 1240 | var param_gz = block_scope.makeSubBlock(scope); |
| 1223 | 1241 | defer param_gz.unstack(); |
| 1224 | | const param_type = try expr(&param_gz, scope, coerced_type_rl, param_type_node); |
| 1242 | const param_type = try expr(&param_gz, scope, coerced_type_ri, param_type_node); |
| 1225 | 1243 | const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); |
| 1226 | 1244 | _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); |
| 1227 | 1245 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -1235,7 +1253,7 @@ fn fnProtoExpr( |
| 1235 | 1253 | }; |
| 1236 | 1254 | |
| 1237 | 1255 | const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { |
| 1238 | | break :inst try expr(&block_scope, scope, align_rl, fn_proto.ast.align_expr); |
| 1256 | break :inst try expr(&block_scope, scope, align_ri, fn_proto.ast.align_expr); |
| 1239 | 1257 | }; |
| 1240 | 1258 | |
| 1241 | 1259 | if (fn_proto.ast.addrspace_expr != 0) { |
| ... | ... | @@ -1250,7 +1268,7 @@ fn fnProtoExpr( |
| 1250 | 1268 | try expr( |
| 1251 | 1269 | &block_scope, |
| 1252 | 1270 | scope, |
| 1253 | | .{ .ty = .calling_convention_type }, |
| 1271 | .{ .rl = .{ .ty = .calling_convention_type } }, |
| 1254 | 1272 | fn_proto.ast.callconv_expr, |
| 1255 | 1273 | ) |
| 1256 | 1274 | else |
| ... | ... | @@ -1261,7 +1279,7 @@ fn fnProtoExpr( |
| 1261 | 1279 | if (is_inferred_error) { |
| 1262 | 1280 | return astgen.failTok(maybe_bang, "function prototype may not have inferred error set", .{}); |
| 1263 | 1281 | } |
| 1264 | | const ret_ty = try expr(&block_scope, scope, coerced_type_rl, fn_proto.ast.return_type); |
| 1282 | const ret_ty = try expr(&block_scope, scope, coerced_type_ri, fn_proto.ast.return_type); |
| 1265 | 1283 | |
| 1266 | 1284 | const result = try block_scope.addFunc(.{ |
| 1267 | 1285 | .src_node = fn_proto.ast.proto_node, |
| ... | ... | @@ -1292,13 +1310,13 @@ fn fnProtoExpr( |
| 1292 | 1310 | try block_scope.setBlockBody(block_inst); |
| 1293 | 1311 | try gz.instructions.append(astgen.gpa, block_inst); |
| 1294 | 1312 | |
| 1295 | | return rvalue(gz, rl, indexToRef(block_inst), fn_proto.ast.proto_node); |
| 1313 | return rvalue(gz, ri, indexToRef(block_inst), fn_proto.ast.proto_node); |
| 1296 | 1314 | } |
| 1297 | 1315 | |
| 1298 | 1316 | fn arrayInitExpr( |
| 1299 | 1317 | gz: *GenZir, |
| 1300 | 1318 | scope: *Scope, |
| 1301 | | rl: ResultLoc, |
| 1319 | ri: ResultInfo, |
| 1302 | 1320 | node: Ast.Node.Index, |
| 1303 | 1321 | array_init: Ast.full.ArrayInit, |
| 1304 | 1322 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -1340,7 +1358,7 @@ fn arrayInitExpr( |
| 1340 | 1358 | .elem = elem_type, |
| 1341 | 1359 | }; |
| 1342 | 1360 | } else { |
| 1343 | | const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); |
| 1361 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, array_type.ast.sentinel); |
| 1344 | 1362 | const array_type_inst = try gz.addPlNode( |
| 1345 | 1363 | .array_type_sentinel, |
| 1346 | 1364 | array_init.ast.type_expr, |
| ... | ... | @@ -1368,29 +1386,29 @@ fn arrayInitExpr( |
| 1368 | 1386 | }; |
| 1369 | 1387 | }; |
| 1370 | 1388 | |
| 1371 | | switch (rl) { |
| 1389 | switch (ri.rl) { |
| 1372 | 1390 | .discard => { |
| 1373 | 1391 | // TODO elements should still be coerced if type is provided |
| 1374 | 1392 | for (array_init.ast.elements) |elem_init| { |
| 1375 | | _ = try expr(gz, scope, .discard, elem_init); |
| 1393 | _ = try expr(gz, scope, .{ .rl = .discard }, elem_init); |
| 1376 | 1394 | } |
| 1377 | 1395 | return Zir.Inst.Ref.void_value; |
| 1378 | 1396 | }, |
| 1379 | | .ref, .catch_ref => { |
| 1397 | .ref => { |
| 1380 | 1398 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init_ref else .array_init_anon_ref; |
| 1381 | 1399 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1382 | 1400 | }, |
| 1383 | | .none, .catch_none => { |
| 1401 | .none => { |
| 1384 | 1402 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; |
| 1385 | 1403 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1386 | 1404 | }, |
| 1387 | | .ty, .ty_shift_operand, .coerced_ty => { |
| 1405 | .ty, .coerced_ty => { |
| 1388 | 1406 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; |
| 1389 | 1407 | const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1390 | | return rvalue(gz, rl, result, node); |
| 1408 | return rvalue(gz, ri, result, node); |
| 1391 | 1409 | }, |
| 1392 | 1410 | .ptr => |ptr_res| { |
| 1393 | | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_res.inst, array_init.ast.elements, types.array); |
| 1411 | return arrayInitExprRlPtr(gz, scope, ri, node, ptr_res.inst, array_init.ast.elements, types.array); |
| 1394 | 1412 | }, |
| 1395 | 1413 | .inferred_ptr => |ptr_inst| { |
| 1396 | 1414 | if (types.array == .none) { |
| ... | ... | @@ -1398,9 +1416,9 @@ fn arrayInitExpr( |
| 1398 | 1416 | // analyzing array_base_ptr against an alloc_inferred_mut. |
| 1399 | 1417 | // See corresponding logic in structInitExpr. |
| 1400 | 1418 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); |
| 1401 | | return rvalue(gz, rl, result, node); |
| 1419 | return rvalue(gz, ri, result, node); |
| 1402 | 1420 | } else { |
| 1403 | | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, types.array); |
| 1421 | return arrayInitExprRlPtr(gz, scope, ri, node, ptr_inst, array_init.ast.elements, types.array); |
| 1404 | 1422 | } |
| 1405 | 1423 | }, |
| 1406 | 1424 | .block_ptr => |block_gz| { |
| ... | ... | @@ -1408,9 +1426,9 @@ fn arrayInitExpr( |
| 1408 | 1426 | // See corresponding logic in structInitExpr. |
| 1409 | 1427 | if (types.array == .none and astgen.isInferred(block_gz.rl_ptr)) { |
| 1410 | 1428 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); |
| 1411 | | return rvalue(gz, rl, result, node); |
| 1429 | return rvalue(gz, ri, result, node); |
| 1412 | 1430 | } |
| 1413 | | return arrayInitExprRlPtr(gz, scope, rl, node, block_gz.rl_ptr, array_init.ast.elements, types.array); |
| 1431 | return arrayInitExprRlPtr(gz, scope, ri, node, block_gz.rl_ptr, array_init.ast.elements, types.array); |
| 1414 | 1432 | }, |
| 1415 | 1433 | } |
| 1416 | 1434 | } |
| ... | ... | @@ -1430,7 +1448,7 @@ fn arrayInitExprRlNone( |
| 1430 | 1448 | var extra_index = try reserveExtra(astgen, elements.len); |
| 1431 | 1449 | |
| 1432 | 1450 | for (elements) |elem_init| { |
| 1433 | | const elem_ref = try expr(gz, scope, .none, elem_init); |
| 1451 | const elem_ref = try expr(gz, scope, .{ .rl = .none }, elem_init); |
| 1434 | 1452 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); |
| 1435 | 1453 | extra_index += 1; |
| 1436 | 1454 | } |
| ... | ... | @@ -1459,9 +1477,9 @@ fn arrayInitExprInner( |
| 1459 | 1477 | } |
| 1460 | 1478 | |
| 1461 | 1479 | for (elements) |elem_init, i| { |
| 1462 | | const rl = if (elem_ty != .none) |
| 1463 | | ResultLoc{ .coerced_ty = elem_ty } |
| 1464 | | else if (array_ty_inst != .none and nodeMayNeedMemoryLocation(astgen.tree, elem_init, true)) rl: { |
| 1480 | const ri = if (elem_ty != .none) |
| 1481 | ResultInfo{ .rl = .{ .coerced_ty = elem_ty } } |
| 1482 | else if (array_ty_inst != .none and nodeMayNeedMemoryLocation(astgen.tree, elem_init, true)) ri: { |
| 1465 | 1483 | const ty_expr = try gz.add(.{ |
| 1466 | 1484 | .tag = .elem_type_index, |
| 1467 | 1485 | .data = .{ .bin = .{ |
| ... | ... | @@ -1469,10 +1487,10 @@ fn arrayInitExprInner( |
| 1469 | 1487 | .rhs = @intToEnum(Zir.Inst.Ref, i), |
| 1470 | 1488 | } }, |
| 1471 | 1489 | }); |
| 1472 | | break :rl ResultLoc{ .coerced_ty = ty_expr }; |
| 1473 | | } else ResultLoc{ .none = {} }; |
| 1490 | break :ri ResultInfo{ .rl = .{ .coerced_ty = ty_expr } }; |
| 1491 | } else ResultInfo{ .rl = .{ .none = {} } }; |
| 1474 | 1492 | |
| 1475 | | const elem_ref = try expr(gz, scope, rl, elem_init); |
| 1493 | const elem_ref = try expr(gz, scope, ri, elem_init); |
| 1476 | 1494 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); |
| 1477 | 1495 | extra_index += 1; |
| 1478 | 1496 | } |
| ... | ... | @@ -1483,7 +1501,7 @@ fn arrayInitExprInner( |
| 1483 | 1501 | fn arrayInitExprRlPtr( |
| 1484 | 1502 | gz: *GenZir, |
| 1485 | 1503 | scope: *Scope, |
| 1486 | | rl: ResultLoc, |
| 1504 | ri: ResultInfo, |
| 1487 | 1505 | node: Ast.Node.Index, |
| 1488 | 1506 | result_ptr: Zir.Inst.Ref, |
| 1489 | 1507 | elements: []const Ast.Node.Index, |
| ... | ... | @@ -1498,7 +1516,7 @@ fn arrayInitExprRlPtr( |
| 1498 | 1516 | defer as_scope.unstack(); |
| 1499 | 1517 | |
| 1500 | 1518 | const result = try arrayInitExprRlPtrInner(&as_scope, scope, node, as_scope.rl_ptr, elements); |
| 1501 | | return as_scope.finishCoercion(gz, rl, node, result, array_ty); |
| 1519 | return as_scope.finishCoercion(gz, ri, node, result, array_ty); |
| 1502 | 1520 | } |
| 1503 | 1521 | |
| 1504 | 1522 | fn arrayInitExprRlPtrInner( |
| ... | ... | @@ -1522,7 +1540,7 @@ fn arrayInitExprRlPtrInner( |
| 1522 | 1540 | }); |
| 1523 | 1541 | astgen.extra.items[extra_index] = refToIndex(elem_ptr).?; |
| 1524 | 1542 | extra_index += 1; |
| 1525 | | _ = try expr(gz, scope, .{ .ptr = .{ .inst = elem_ptr } }, elem_init); |
| 1543 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = elem_ptr } } }, elem_init); |
| 1526 | 1544 | } |
| 1527 | 1545 | |
| 1528 | 1546 | const tag: Zir.Inst.Tag = if (gz.force_comptime) |
| ... | ... | @@ -1537,7 +1555,7 @@ fn arrayInitExprRlPtrInner( |
| 1537 | 1555 | fn structInitExpr( |
| 1538 | 1556 | gz: *GenZir, |
| 1539 | 1557 | scope: *Scope, |
| 1540 | | rl: ResultLoc, |
| 1558 | ri: ResultInfo, |
| 1541 | 1559 | node: Ast.Node.Index, |
| 1542 | 1560 | struct_init: Ast.full.StructInit, |
| 1543 | 1561 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -1546,7 +1564,7 @@ fn structInitExpr( |
| 1546 | 1564 | |
| 1547 | 1565 | if (struct_init.ast.type_expr == 0) { |
| 1548 | 1566 | if (struct_init.ast.fields.len == 0) { |
| 1549 | | return rvalue(gz, rl, .empty_struct, node); |
| 1567 | return rvalue(gz, ri, .empty_struct, node); |
| 1550 | 1568 | } |
| 1551 | 1569 | } else array: { |
| 1552 | 1570 | const node_tags = tree.nodes.items(.tag); |
| ... | ... | @@ -1558,7 +1576,7 @@ fn structInitExpr( |
| 1558 | 1576 | if (struct_init.ast.fields.len == 0) { |
| 1559 | 1577 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1560 | 1578 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1561 | | return rvalue(gz, rl, result, node); |
| 1579 | return rvalue(gz, ri, result, node); |
| 1562 | 1580 | } |
| 1563 | 1581 | break :array; |
| 1564 | 1582 | }, |
| ... | ... | @@ -1575,7 +1593,7 @@ fn structInitExpr( |
| 1575 | 1593 | .rhs = elem_type, |
| 1576 | 1594 | }); |
| 1577 | 1595 | } else blk: { |
| 1578 | | const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); |
| 1596 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, array_type.ast.sentinel); |
| 1579 | 1597 | break :blk try gz.addPlNode( |
| 1580 | 1598 | .array_type_sentinel, |
| 1581 | 1599 | struct_init.ast.type_expr, |
| ... | ... | @@ -1587,11 +1605,11 @@ fn structInitExpr( |
| 1587 | 1605 | ); |
| 1588 | 1606 | }; |
| 1589 | 1607 | const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node); |
| 1590 | | return rvalue(gz, rl, result, node); |
| 1608 | return rvalue(gz, ri, result, node); |
| 1591 | 1609 | } |
| 1592 | 1610 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1593 | 1611 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1594 | | return rvalue(gz, rl, result, node); |
| 1612 | return rvalue(gz, ri, result, node); |
| 1595 | 1613 | } else { |
| 1596 | 1614 | return astgen.failNode( |
| 1597 | 1615 | struct_init.ast.type_expr, |
| ... | ... | @@ -1601,7 +1619,7 @@ fn structInitExpr( |
| 1601 | 1619 | } |
| 1602 | 1620 | } |
| 1603 | 1621 | |
| 1604 | | switch (rl) { |
| 1622 | switch (ri.rl) { |
| 1605 | 1623 | .discard => { |
| 1606 | 1624 | if (struct_init.ast.type_expr != 0) { |
| 1607 | 1625 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| ... | ... | @@ -1612,7 +1630,7 @@ fn structInitExpr( |
| 1612 | 1630 | } |
| 1613 | 1631 | return Zir.Inst.Ref.void_value; |
| 1614 | 1632 | }, |
| 1615 | | .ref, .catch_ref => { |
| 1633 | .ref => { |
| 1616 | 1634 | if (struct_init.ast.type_expr != 0) { |
| 1617 | 1635 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1618 | 1636 | _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node); |
| ... | ... | @@ -1621,7 +1639,7 @@ fn structInitExpr( |
| 1621 | 1639 | return structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon_ref); |
| 1622 | 1640 | } |
| 1623 | 1641 | }, |
| 1624 | | .none, .catch_none => { |
| 1642 | .none => { |
| 1625 | 1643 | if (struct_init.ast.type_expr != 0) { |
| 1626 | 1644 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1627 | 1645 | _ = try gz.addUnNode(.validate_struct_init_ty, ty_inst, node); |
| ... | ... | @@ -1630,26 +1648,26 @@ fn structInitExpr( |
| 1630 | 1648 | return structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); |
| 1631 | 1649 | } |
| 1632 | 1650 | }, |
| 1633 | | .ty, .ty_shift_operand, .coerced_ty => |ty_inst| { |
| 1651 | .ty, .coerced_ty => |ty_inst| { |
| 1634 | 1652 | if (struct_init.ast.type_expr == 0) { |
| 1635 | 1653 | const result = try structInitExprRlNone(gz, scope, node, struct_init, ty_inst, .struct_init_anon); |
| 1636 | | return rvalue(gz, rl, result, node); |
| 1654 | return rvalue(gz, ri, result, node); |
| 1637 | 1655 | } |
| 1638 | 1656 | const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1639 | 1657 | _ = try gz.addUnNode(.validate_struct_init_ty, inner_ty_inst, node); |
| 1640 | 1658 | const result = try structInitExprRlTy(gz, scope, node, struct_init, inner_ty_inst, .struct_init); |
| 1641 | | return rvalue(gz, rl, result, node); |
| 1659 | return rvalue(gz, ri, result, node); |
| 1642 | 1660 | }, |
| 1643 | | .ptr => |ptr_res| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_res.inst), |
| 1661 | .ptr => |ptr_res| return structInitExprRlPtr(gz, scope, ri, node, struct_init, ptr_res.inst), |
| 1644 | 1662 | .inferred_ptr => |ptr_inst| { |
| 1645 | 1663 | if (struct_init.ast.type_expr == 0) { |
| 1646 | 1664 | // We treat this case differently so that we don't get a crash when |
| 1647 | 1665 | // analyzing field_base_ptr against an alloc_inferred_mut. |
| 1648 | 1666 | // See corresponding logic in arrayInitExpr. |
| 1649 | 1667 | const result = try structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); |
| 1650 | | return rvalue(gz, rl, result, node); |
| 1668 | return rvalue(gz, ri, result, node); |
| 1651 | 1669 | } else { |
| 1652 | | return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst); |
| 1670 | return structInitExprRlPtr(gz, scope, ri, node, struct_init, ptr_inst); |
| 1653 | 1671 | } |
| 1654 | 1672 | }, |
| 1655 | 1673 | .block_ptr => |block_gz| { |
| ... | ... | @@ -1657,10 +1675,10 @@ fn structInitExpr( |
| 1657 | 1675 | // See corresponding logic in arrayInitExpr. |
| 1658 | 1676 | if (struct_init.ast.type_expr == 0 and astgen.isInferred(block_gz.rl_ptr)) { |
| 1659 | 1677 | const result = try structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); |
| 1660 | | return rvalue(gz, rl, result, node); |
| 1678 | return rvalue(gz, ri, result, node); |
| 1661 | 1679 | } |
| 1662 | 1680 | |
| 1663 | | return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr); |
| 1681 | return structInitExprRlPtr(gz, scope, ri, node, struct_init, block_gz.rl_ptr); |
| 1664 | 1682 | }, |
| 1665 | 1683 | } |
| 1666 | 1684 | } |
| ... | ... | @@ -1685,16 +1703,15 @@ fn structInitExprRlNone( |
| 1685 | 1703 | for (struct_init.ast.fields) |field_init| { |
| 1686 | 1704 | const name_token = tree.firstToken(field_init) - 2; |
| 1687 | 1705 | const str_index = try astgen.identAsString(name_token); |
| 1688 | | const sub_rl: ResultLoc = if (ty_inst != .none) |
| 1689 | | ResultLoc{ .ty = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ |
| 1706 | const sub_ri: ResultInfo = if (ty_inst != .none) |
| 1707 | ResultInfo{ .rl = .{ .ty = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ |
| 1690 | 1708 | .container_type = ty_inst, |
| 1691 | 1709 | .name_start = str_index, |
| 1692 | | }) } |
| 1693 | | else |
| 1694 | | .none; |
| 1710 | }) } } |
| 1711 | else .{ .rl = .none }; |
| 1695 | 1712 | setExtra(astgen, extra_index, Zir.Inst.StructInitAnon.Item{ |
| 1696 | 1713 | .field_name = str_index, |
| 1697 | | .init = try expr(gz, scope, sub_rl, field_init), |
| 1714 | .init = try expr(gz, scope, sub_ri, field_init), |
| 1698 | 1715 | }); |
| 1699 | 1716 | extra_index += field_size; |
| 1700 | 1717 | } |
| ... | ... | @@ -1705,7 +1722,7 @@ fn structInitExprRlNone( |
| 1705 | 1722 | fn structInitExprRlPtr( |
| 1706 | 1723 | gz: *GenZir, |
| 1707 | 1724 | scope: *Scope, |
| 1708 | | rl: ResultLoc, |
| 1725 | ri: ResultInfo, |
| 1709 | 1726 | node: Ast.Node.Index, |
| 1710 | 1727 | struct_init: Ast.full.StructInit, |
| 1711 | 1728 | result_ptr: Zir.Inst.Ref, |
| ... | ... | @@ -1721,7 +1738,7 @@ fn structInitExprRlPtr( |
| 1721 | 1738 | defer as_scope.unstack(); |
| 1722 | 1739 | |
| 1723 | 1740 | const result = try structInitExprRlPtrInner(&as_scope, scope, node, struct_init, as_scope.rl_ptr); |
| 1724 | | return as_scope.finishCoercion(gz, rl, node, result, ty_inst); |
| 1741 | return as_scope.finishCoercion(gz, ri, node, result, ty_inst); |
| 1725 | 1742 | } |
| 1726 | 1743 | |
| 1727 | 1744 | fn structInitExprRlPtrInner( |
| ... | ... | @@ -1748,7 +1765,7 @@ fn structInitExprRlPtrInner( |
| 1748 | 1765 | }); |
| 1749 | 1766 | astgen.extra.items[extra_index] = refToIndex(field_ptr).?; |
| 1750 | 1767 | extra_index += 1; |
| 1751 | | _ = try expr(gz, scope, .{ .ptr = .{ .inst = field_ptr } }, field_init); |
| 1768 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = field_ptr } } }, field_init); |
| 1752 | 1769 | } |
| 1753 | 1770 | |
| 1754 | 1771 | const tag: Zir.Inst.Tag = if (gz.force_comptime) |
| ... | ... | @@ -1786,7 +1803,7 @@ fn structInitExprRlTy( |
| 1786 | 1803 | }); |
| 1787 | 1804 | setExtra(astgen, extra_index, Zir.Inst.StructInit.Item{ |
| 1788 | 1805 | .field_type = refToIndex(field_ty_inst).?, |
| 1789 | | .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init), |
| 1806 | .init = try expr(gz, scope, .{ .rl = .{ .ty = field_ty_inst } }, field_init), |
| 1790 | 1807 | }); |
| 1791 | 1808 | extra_index += field_size; |
| 1792 | 1809 | } |
| ... | ... | @@ -1799,14 +1816,14 @@ fn structInitExprRlTy( |
| 1799 | 1816 | fn comptimeExpr( |
| 1800 | 1817 | gz: *GenZir, |
| 1801 | 1818 | scope: *Scope, |
| 1802 | | rl: ResultLoc, |
| 1819 | ri: ResultInfo, |
| 1803 | 1820 | node: Ast.Node.Index, |
| 1804 | 1821 | ) InnerError!Zir.Inst.Ref { |
| 1805 | 1822 | const prev_force_comptime = gz.force_comptime; |
| 1806 | 1823 | gz.force_comptime = true; |
| 1807 | 1824 | defer gz.force_comptime = prev_force_comptime; |
| 1808 | 1825 | |
| 1809 | | return expr(gz, scope, rl, node); |
| 1826 | return expr(gz, scope, ri, node); |
| 1810 | 1827 | } |
| 1811 | 1828 | |
| 1812 | 1829 | /// This one is for an actual `comptime` syntax, and will emit a compile error if |
| ... | ... | @@ -1815,7 +1832,7 @@ fn comptimeExpr( |
| 1815 | 1832 | fn comptimeExprAst( |
| 1816 | 1833 | gz: *GenZir, |
| 1817 | 1834 | scope: *Scope, |
| 1818 | | rl: ResultLoc, |
| 1835 | ri: ResultInfo, |
| 1819 | 1836 | node: Ast.Node.Index, |
| 1820 | 1837 | ) InnerError!Zir.Inst.Ref { |
| 1821 | 1838 | const astgen = gz.astgen; |
| ... | ... | @@ -1826,7 +1843,7 @@ fn comptimeExprAst( |
| 1826 | 1843 | const node_datas = tree.nodes.items(.data); |
| 1827 | 1844 | const body_node = node_datas[node].lhs; |
| 1828 | 1845 | gz.force_comptime = true; |
| 1829 | | const result = try expr(gz, scope, rl, body_node); |
| 1846 | const result = try expr(gz, scope, ri, body_node); |
| 1830 | 1847 | gz.force_comptime = false; |
| 1831 | 1848 | return result; |
| 1832 | 1849 | } |
| ... | ... | @@ -1904,7 +1921,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1904 | 1921 | } |
| 1905 | 1922 | block_gz.break_count += 1; |
| 1906 | 1923 | |
| 1907 | | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_loc, rhs, node); |
| 1924 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_info, rhs, node); |
| 1908 | 1925 | const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| 1909 | 1926 | |
| 1910 | 1927 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| ... | ... | @@ -1915,14 +1932,14 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1915 | 1932 | try popErrorReturnTrace( |
| 1916 | 1933 | parent_gz, |
| 1917 | 1934 | scope, |
| 1918 | | block_gz.break_result_loc, |
| 1935 | block_gz.break_result_info, |
| 1919 | 1936 | rhs, |
| 1920 | 1937 | operand, |
| 1921 | 1938 | err_trace_index_to_restore, |
| 1922 | 1939 | ); |
| 1923 | 1940 | } |
| 1924 | 1941 | |
| 1925 | | switch (block_gz.break_result_loc) { |
| 1942 | switch (block_gz.break_result_info.rl) { |
| 1926 | 1943 | .block_ptr => { |
| 1927 | 1944 | const br = try parent_gz.addBreak(break_tag, block_inst, operand); |
| 1928 | 1945 | try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index }); |
| ... | ... | @@ -2028,7 +2045,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 2028 | 2045 | fn blockExpr( |
| 2029 | 2046 | gz: *GenZir, |
| 2030 | 2047 | scope: *Scope, |
| 2031 | | rl: ResultLoc, |
| 2048 | ri: ResultInfo, |
| 2032 | 2049 | block_node: Ast.Node.Index, |
| 2033 | 2050 | statements: []const Ast.Node.Index, |
| 2034 | 2051 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -2044,12 +2061,12 @@ fn blockExpr( |
| 2044 | 2061 | if (token_tags[lbrace - 1] == .colon and |
| 2045 | 2062 | token_tags[lbrace - 2] == .identifier) |
| 2046 | 2063 | { |
| 2047 | | return labeledBlockExpr(gz, scope, rl, block_node, statements); |
| 2064 | return labeledBlockExpr(gz, scope, ri, block_node, statements); |
| 2048 | 2065 | } |
| 2049 | 2066 | |
| 2050 | 2067 | var sub_gz = gz.makeSubBlock(scope); |
| 2051 | 2068 | try blockExprStmts(&sub_gz, &sub_gz.base, statements); |
| 2052 | | return rvalue(gz, rl, .void_value, block_node); |
| 2069 | return rvalue(gz, ri, .void_value, block_node); |
| 2053 | 2070 | } |
| 2054 | 2071 | |
| 2055 | 2072 | fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void { |
| ... | ... | @@ -2087,7 +2104,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.Toke |
| 2087 | 2104 | fn labeledBlockExpr( |
| 2088 | 2105 | gz: *GenZir, |
| 2089 | 2106 | parent_scope: *Scope, |
| 2090 | | rl: ResultLoc, |
| 2107 | ri: ResultInfo, |
| 2091 | 2108 | block_node: Ast.Node.Index, |
| 2092 | 2109 | statements: []const Ast.Node.Index, |
| 2093 | 2110 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -2116,7 +2133,7 @@ fn labeledBlockExpr( |
| 2116 | 2133 | .token = label_token, |
| 2117 | 2134 | .block_inst = block_inst, |
| 2118 | 2135 | }; |
| 2119 | | block_scope.setBreakResultLoc(rl); |
| 2136 | block_scope.setBreakResultInfo(ri); |
| 2120 | 2137 | defer block_scope.unstack(); |
| 2121 | 2138 | defer block_scope.labeled_breaks.deinit(astgen.gpa); |
| 2122 | 2139 | |
| ... | ... | @@ -2132,7 +2149,7 @@ fn labeledBlockExpr( |
| 2132 | 2149 | |
| 2133 | 2150 | const zir_datas = gz.astgen.instructions.items(.data); |
| 2134 | 2151 | const zir_tags = gz.astgen.instructions.items(.tag); |
| 2135 | | const strat = rl.strategy(&block_scope); |
| 2152 | const strat = ri.rl.strategy(&block_scope); |
| 2136 | 2153 | switch (strat.tag) { |
| 2137 | 2154 | .break_void => { |
| 2138 | 2155 | // The code took advantage of the result location as a pointer. |
| ... | ... | @@ -2173,9 +2190,9 @@ fn labeledBlockExpr( |
| 2173 | 2190 | } |
| 2174 | 2191 | try block_scope.setBlockBody(block_inst); |
| 2175 | 2192 | const block_ref = indexToRef(block_inst); |
| 2176 | | switch (rl) { |
| 2177 | | .ref, .catch_ref => return block_ref, |
| 2178 | | else => return rvalue(gz, rl, block_ref, block_node), |
| 2193 | switch (ri.rl) { |
| 2194 | .ref => return block_ref, |
| 2195 | else => return rvalue(gz, ri, block_ref, block_node), |
| 2179 | 2196 | } |
| 2180 | 2197 | }, |
| 2181 | 2198 | } |
| ... | ... | @@ -2246,12 +2263,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2246 | 2263 | continue; |
| 2247 | 2264 | }, |
| 2248 | 2265 | |
| 2249 | | .while_simple => _ = try whileExpr(gz, scope, .discard, inner_node, tree.whileSimple(inner_node), true), |
| 2250 | | .while_cont => _ = try whileExpr(gz, scope, .discard, inner_node, tree.whileCont(inner_node), true), |
| 2251 | | .@"while" => _ = try whileExpr(gz, scope, .discard, inner_node, tree.whileFull(inner_node), true), |
| 2266 | .while_simple => _ = try whileExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.whileSimple(inner_node), true), |
| 2267 | .while_cont => _ = try whileExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.whileCont(inner_node), true), |
| 2268 | .@"while" => _ = try whileExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.whileFull(inner_node), true), |
| 2252 | 2269 | |
| 2253 | | .for_simple => _ = try forExpr(gz, scope, .discard, inner_node, tree.forSimple(inner_node), true), |
| 2254 | | .@"for" => _ = try forExpr(gz, scope, .discard, inner_node, tree.forFull(inner_node), true), |
| 2270 | .for_simple => _ = try forExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.forSimple(inner_node), true), |
| 2271 | .@"for" => _ = try forExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.forFull(inner_node), true), |
| 2255 | 2272 | |
| 2256 | 2273 | else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node), |
| 2257 | 2274 | // zig fmt: on |
| ... | ... | @@ -2272,7 +2289,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2272 | 2289 | try emitDbgNode(gz, statement); |
| 2273 | 2290 | // We need to emit an error if the result is not `noreturn` or `void`, but |
| 2274 | 2291 | // we want to avoid adding the ZIR instruction if possible for performance. |
| 2275 | | const maybe_unused_result = try expr(gz, scope, .none, statement); |
| 2292 | const maybe_unused_result = try expr(gz, scope, .{ .rl = .none }, statement); |
| 2276 | 2293 | return addEnsureResult(gz, maybe_unused_result, statement); |
| 2277 | 2294 | } |
| 2278 | 2295 | |
| ... | ... | @@ -2839,7 +2856,7 @@ fn varDecl( |
| 2839 | 2856 | } |
| 2840 | 2857 | |
| 2841 | 2858 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node != 0) |
| 2842 | | try expr(gz, scope, align_rl, var_decl.ast.align_node) |
| 2859 | try expr(gz, scope, align_ri, var_decl.ast.align_node) |
| 2843 | 2860 | else |
| 2844 | 2861 | .none; |
| 2845 | 2862 | |
| ... | ... | @@ -2856,12 +2873,12 @@ fn varDecl( |
| 2856 | 2873 | if (align_inst == .none and |
| 2857 | 2874 | !nodeMayNeedMemoryLocation(tree, var_decl.ast.init_node, type_node != 0)) |
| 2858 | 2875 | { |
| 2859 | | const result_loc: ResultLoc = if (type_node != 0) .{ |
| 2860 | | .ty = try typeExpr(gz, scope, type_node), |
| 2861 | | } else .none; |
| 2876 | const result_info: ResultInfo = if (type_node != 0) .{ |
| 2877 | .rl = .{ .ty = try typeExpr(gz, scope, type_node) }, |
| 2878 | } else .{ .rl = .none }; |
| 2862 | 2879 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 2863 | 2880 | gz.anon_name_strategy = .dbg_var; |
| 2864 | | const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node); |
| 2881 | const init_inst = try reachableExpr(gz, scope, result_info, var_decl.ast.init_node, node); |
| 2865 | 2882 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 2866 | 2883 | |
| 2867 | 2884 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); |
| ... | ... | @@ -2931,8 +2948,8 @@ fn varDecl( |
| 2931 | 2948 | init_scope.rl_ptr = alloc; |
| 2932 | 2949 | init_scope.rl_ty_inst = .none; |
| 2933 | 2950 | } |
| 2934 | | const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope }; |
| 2935 | | const init_inst = try reachableExpr(&init_scope, &init_scope.base, init_result_loc, var_decl.ast.init_node, node); |
| 2951 | const init_result_info: ResultInfo = .{ .rl = .{ .block_ptr = &init_scope } }; |
| 2952 | const init_inst = try reachableExpr(&init_scope, &init_scope.base, init_result_info, var_decl.ast.init_node, node); |
| 2936 | 2953 | |
| 2937 | 2954 | const zir_tags = astgen.instructions.items(.tag); |
| 2938 | 2955 | const zir_datas = astgen.instructions.items(.data); |
| ... | ... | @@ -3021,7 +3038,7 @@ fn varDecl( |
| 3021 | 3038 | const is_comptime = var_decl.comptime_token != null or gz.force_comptime; |
| 3022 | 3039 | var resolve_inferred_alloc: Zir.Inst.Ref = .none; |
| 3023 | 3040 | const var_data: struct { |
| 3024 | | result_loc: ResultLoc, |
| 3041 | result_info: ResultInfo, |
| 3025 | 3042 | alloc: Zir.Inst.Ref, |
| 3026 | 3043 | } = if (var_decl.ast.type_node != 0) a: { |
| 3027 | 3044 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); |
| ... | ... | @@ -3043,7 +3060,7 @@ fn varDecl( |
| 3043 | 3060 | } |
| 3044 | 3061 | }; |
| 3045 | 3062 | gz.rl_ty_inst = type_inst; |
| 3046 | | break :a .{ .alloc = alloc, .result_loc = .{ .ptr = .{ .inst = alloc } } }; |
| 3063 | break :a .{ .alloc = alloc, .result_info = .{ .rl = .{ .ptr = .{ .inst = alloc } } } }; |
| 3047 | 3064 | } else a: { |
| 3048 | 3065 | const alloc = alloc: { |
| 3049 | 3066 | if (align_inst == .none) { |
| ... | ... | @@ -3064,11 +3081,11 @@ fn varDecl( |
| 3064 | 3081 | }; |
| 3065 | 3082 | gz.rl_ty_inst = .none; |
| 3066 | 3083 | resolve_inferred_alloc = alloc; |
| 3067 | | break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } }; |
| 3084 | break :a .{ .alloc = alloc, .result_info = .{ .rl = .{ .inferred_ptr = alloc } } }; |
| 3068 | 3085 | }; |
| 3069 | 3086 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3070 | 3087 | gz.anon_name_strategy = .dbg_var; |
| 3071 | | _ = try reachableExprComptime(gz, scope, var_data.result_loc, var_decl.ast.init_node, node, is_comptime); |
| 3088 | _ = try reachableExprComptime(gz, scope, var_data.result_info, var_decl.ast.init_node, node, is_comptime); |
| 3072 | 3089 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 3073 | 3090 | if (resolve_inferred_alloc != .none) { |
| 3074 | 3091 | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); |
| ... | ... | @@ -3138,15 +3155,15 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi |
| 3138 | 3155 | // This intentionally does not support `@"_"` syntax. |
| 3139 | 3156 | const ident_name = tree.tokenSlice(main_tokens[lhs]); |
| 3140 | 3157 | if (mem.eql(u8, ident_name, "_")) { |
| 3141 | | _ = try expr(gz, scope, .discard, rhs); |
| 3158 | _ = try expr(gz, scope, .{ .rl = .discard }, rhs); |
| 3142 | 3159 | return; |
| 3143 | 3160 | } |
| 3144 | 3161 | } |
| 3145 | 3162 | const lvalue = try lvalExpr(gz, scope, lhs); |
| 3146 | | _ = try expr(gz, scope, .{ .ptr = .{ |
| 3163 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ |
| 3147 | 3164 | .inst = lvalue, |
| 3148 | 3165 | .src_node = infix_node, |
| 3149 | | } }, rhs); |
| 3166 | } } }, rhs); |
| 3150 | 3167 | } |
| 3151 | 3168 | |
| 3152 | 3169 | fn assignOp( |
| ... | ... | @@ -3163,7 +3180,7 @@ fn assignOp( |
| 3163 | 3180 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| 3164 | 3181 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3165 | 3182 | const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node); |
| 3166 | | const rhs = try expr(gz, scope, .{ .coerced_ty = lhs_type }, node_datas[infix_node].rhs); |
| 3183 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = lhs_type } }, node_datas[infix_node].rhs); |
| 3167 | 3184 | |
| 3168 | 3185 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ |
| 3169 | 3186 | .lhs = lhs, |
| ... | ... | @@ -3186,7 +3203,7 @@ fn assignShift( |
| 3186 | 3203 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| 3187 | 3204 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3188 | 3205 | const rhs_type = try gz.addUnNode(.typeof_log2_int_type, lhs, infix_node); |
| 3189 | | const rhs = try expr(gz, scope, .{ .ty = rhs_type }, node_datas[infix_node].rhs); |
| 3206 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = rhs_type } }, node_datas[infix_node].rhs); |
| 3190 | 3207 | |
| 3191 | 3208 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ |
| 3192 | 3209 | .lhs = lhs, |
| ... | ... | @@ -3204,7 +3221,7 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE |
| 3204 | 3221 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| 3205 | 3222 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3206 | 3223 | // Saturating shift-left allows any integer type for both the LHS and RHS. |
| 3207 | | const rhs = try expr(gz, scope, .none, node_datas[infix_node].rhs); |
| 3224 | const rhs = try expr(gz, scope, .{ .rl = .none }, node_datas[infix_node].rhs); |
| 3208 | 3225 | |
| 3209 | 3226 | const result = try gz.addPlNode(.shl_sat, infix_node, Zir.Inst.Bin{ |
| 3210 | 3227 | .lhs = lhs, |
| ... | ... | @@ -3216,7 +3233,7 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE |
| 3216 | 3233 | fn ptrType( |
| 3217 | 3234 | gz: *GenZir, |
| 3218 | 3235 | scope: *Scope, |
| 3219 | | rl: ResultLoc, |
| 3236 | ri: ResultInfo, |
| 3220 | 3237 | node: Ast.Node.Index, |
| 3221 | 3238 | ptr_info: Ast.full.PtrType, |
| 3222 | 3239 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -3234,21 +3251,21 @@ fn ptrType( |
| 3234 | 3251 | var trailing_count: u32 = 0; |
| 3235 | 3252 | |
| 3236 | 3253 | if (ptr_info.ast.sentinel != 0) { |
| 3237 | | sentinel_ref = try expr(gz, scope, .{ .ty = elem_type }, ptr_info.ast.sentinel); |
| 3254 | sentinel_ref = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, ptr_info.ast.sentinel); |
| 3238 | 3255 | trailing_count += 1; |
| 3239 | 3256 | } |
| 3240 | 3257 | if (ptr_info.ast.align_node != 0) { |
| 3241 | | align_ref = try expr(gz, scope, coerced_align_rl, ptr_info.ast.align_node); |
| 3258 | align_ref = try expr(gz, scope, coerced_align_ri, ptr_info.ast.align_node); |
| 3242 | 3259 | trailing_count += 1; |
| 3243 | 3260 | } |
| 3244 | 3261 | if (ptr_info.ast.addrspace_node != 0) { |
| 3245 | | addrspace_ref = try expr(gz, scope, .{ .ty = .address_space_type }, ptr_info.ast.addrspace_node); |
| 3262 | addrspace_ref = try expr(gz, scope, .{ .rl = .{ .ty = .address_space_type } }, ptr_info.ast.addrspace_node); |
| 3246 | 3263 | trailing_count += 1; |
| 3247 | 3264 | } |
| 3248 | 3265 | if (ptr_info.ast.bit_range_start != 0) { |
| 3249 | 3266 | assert(ptr_info.ast.bit_range_end != 0); |
| 3250 | | bit_start_ref = try expr(gz, scope, .{ .coerced_ty = .u16_type }, ptr_info.ast.bit_range_start); |
| 3251 | | bit_end_ref = try expr(gz, scope, .{ .coerced_ty = .u16_type }, ptr_info.ast.bit_range_end); |
| 3267 | bit_start_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_start); |
| 3268 | bit_end_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_end); |
| 3252 | 3269 | trailing_count += 2; |
| 3253 | 3270 | } |
| 3254 | 3271 | |
| ... | ... | @@ -3295,10 +3312,10 @@ fn ptrType( |
| 3295 | 3312 | } }); |
| 3296 | 3313 | gz.instructions.appendAssumeCapacity(new_index); |
| 3297 | 3314 | |
| 3298 | | return rvalue(gz, rl, result, node); |
| 3315 | return rvalue(gz, ri, result, node); |
| 3299 | 3316 | } |
| 3300 | 3317 | |
| 3301 | | fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 3318 | fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 3302 | 3319 | const astgen = gz.astgen; |
| 3303 | 3320 | const tree = astgen.tree; |
| 3304 | 3321 | const node_datas = tree.nodes.items(.data); |
| ... | ... | @@ -3311,17 +3328,17 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Z |
| 3311 | 3328 | { |
| 3312 | 3329 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 3313 | 3330 | } |
| 3314 | | const len = try expr(gz, scope, .{ .coerced_ty = .usize_type }, len_node); |
| 3331 | const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node); |
| 3315 | 3332 | const elem_type = try typeExpr(gz, scope, node_datas[node].rhs); |
| 3316 | 3333 | |
| 3317 | 3334 | const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ |
| 3318 | 3335 | .lhs = len, |
| 3319 | 3336 | .rhs = elem_type, |
| 3320 | 3337 | }); |
| 3321 | | return rvalue(gz, rl, result, node); |
| 3338 | return rvalue(gz, ri, result, node); |
| 3322 | 3339 | } |
| 3323 | 3340 | |
| 3324 | | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 3341 | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 3325 | 3342 | const astgen = gz.astgen; |
| 3326 | 3343 | const tree = astgen.tree; |
| 3327 | 3344 | const node_datas = tree.nodes.items(.data); |
| ... | ... | @@ -3335,16 +3352,16 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.I |
| 3335 | 3352 | { |
| 3336 | 3353 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 3337 | 3354 | } |
| 3338 | | const len = try reachableExpr(gz, scope, .{ .coerced_ty = .usize_type }, len_node, node); |
| 3355 | const len = try reachableExpr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node, node); |
| 3339 | 3356 | const elem_type = try typeExpr(gz, scope, extra.elem_type); |
| 3340 | | const sentinel = try reachableExpr(gz, scope, .{ .coerced_ty = elem_type }, extra.sentinel, node); |
| 3357 | const sentinel = try reachableExpr(gz, scope, .{ .rl = .{ .coerced_ty = elem_type } }, extra.sentinel, node); |
| 3341 | 3358 | |
| 3342 | 3359 | const result = try gz.addPlNode(.array_type_sentinel, node, Zir.Inst.ArrayTypeSentinel{ |
| 3343 | 3360 | .len = len, |
| 3344 | 3361 | .elem_type = elem_type, |
| 3345 | 3362 | .sentinel = sentinel, |
| 3346 | 3363 | }); |
| 3347 | | return rvalue(gz, rl, result, node); |
| 3364 | return rvalue(gz, ri, result, node); |
| 3348 | 3365 | } |
| 3349 | 3366 | |
| 3350 | 3367 | const WipMembers = struct { |
| ... | ... | @@ -3580,7 +3597,7 @@ fn fnDecl( |
| 3580 | 3597 | assert(param_type_node != 0); |
| 3581 | 3598 | var param_gz = decl_gz.makeSubBlock(scope); |
| 3582 | 3599 | defer param_gz.unstack(); |
| 3583 | | const param_type = try expr(&param_gz, params_scope, coerced_type_rl, param_type_node); |
| 3600 | const param_type = try expr(&param_gz, params_scope, coerced_type_ri, param_type_node); |
| 3584 | 3601 | const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); |
| 3585 | 3602 | _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); |
| 3586 | 3603 | |
| ... | ... | @@ -3629,7 +3646,7 @@ fn fnDecl( |
| 3629 | 3646 | var align_gz = decl_gz.makeSubBlock(params_scope); |
| 3630 | 3647 | defer align_gz.unstack(); |
| 3631 | 3648 | const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { |
| 3632 | | const inst = try expr(&decl_gz, params_scope, coerced_align_rl, fn_proto.ast.align_expr); |
| 3649 | const inst = try expr(&decl_gz, params_scope, coerced_align_ri, fn_proto.ast.align_expr); |
| 3633 | 3650 | if (align_gz.instructionsSlice().len == 0) { |
| 3634 | 3651 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3635 | 3652 | break :inst inst; |
| ... | ... | @@ -3641,7 +3658,7 @@ fn fnDecl( |
| 3641 | 3658 | var addrspace_gz = decl_gz.makeSubBlock(params_scope); |
| 3642 | 3659 | defer addrspace_gz.unstack(); |
| 3643 | 3660 | const addrspace_ref: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: { |
| 3644 | | const inst = try expr(&decl_gz, params_scope, .{ .coerced_ty = .address_space_type }, fn_proto.ast.addrspace_expr); |
| 3661 | const inst = try expr(&decl_gz, params_scope, .{ .rl = .{ .coerced_ty = .address_space_type } }, fn_proto.ast.addrspace_expr); |
| 3645 | 3662 | if (addrspace_gz.instructionsSlice().len == 0) { |
| 3646 | 3663 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3647 | 3664 | break :inst inst; |
| ... | ... | @@ -3653,7 +3670,7 @@ fn fnDecl( |
| 3653 | 3670 | var section_gz = decl_gz.makeSubBlock(params_scope); |
| 3654 | 3671 | defer section_gz.unstack(); |
| 3655 | 3672 | const section_ref: Zir.Inst.Ref = if (fn_proto.ast.section_expr == 0) .none else inst: { |
| 3656 | | const inst = try expr(&decl_gz, params_scope, .{ .coerced_ty = .const_slice_u8_type }, fn_proto.ast.section_expr); |
| 3673 | const inst = try expr(&decl_gz, params_scope, .{ .rl = .{ .coerced_ty = .const_slice_u8_type } }, fn_proto.ast.section_expr); |
| 3657 | 3674 | if (section_gz.instructionsSlice().len == 0) { |
| 3658 | 3675 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3659 | 3676 | break :inst inst; |
| ... | ... | @@ -3676,7 +3693,7 @@ fn fnDecl( |
| 3676 | 3693 | const inst = try expr( |
| 3677 | 3694 | &decl_gz, |
| 3678 | 3695 | params_scope, |
| 3679 | | .{ .coerced_ty = .calling_convention_type }, |
| 3696 | .{ .rl = .{ .coerced_ty = .calling_convention_type } }, |
| 3680 | 3697 | fn_proto.ast.callconv_expr, |
| 3681 | 3698 | ); |
| 3682 | 3699 | if (cc_gz.instructionsSlice().len == 0) { |
| ... | ... | @@ -3698,7 +3715,7 @@ fn fnDecl( |
| 3698 | 3715 | var ret_gz = decl_gz.makeSubBlock(params_scope); |
| 3699 | 3716 | defer ret_gz.unstack(); |
| 3700 | 3717 | const ret_ref: Zir.Inst.Ref = inst: { |
| 3701 | | const inst = try expr(&ret_gz, params_scope, coerced_type_rl, fn_proto.ast.return_type); |
| 3718 | const inst = try expr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type); |
| 3702 | 3719 | if (ret_gz.instructionsSlice().len == 0) { |
| 3703 | 3720 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3704 | 3721 | break :inst inst; |
| ... | ... | @@ -3752,7 +3769,7 @@ fn fnDecl( |
| 3752 | 3769 | const lbrace_line = astgen.source_line - decl_gz.decl_line; |
| 3753 | 3770 | const lbrace_column = astgen.source_column; |
| 3754 | 3771 | |
| 3755 | | _ = try expr(&fn_gz, params_scope, .none, body_node); |
| 3772 | _ = try expr(&fn_gz, params_scope, .{ .rl = .none }, body_node); |
| 3756 | 3773 | try checkUsed(gz, &fn_gz.base, params_scope); |
| 3757 | 3774 | |
| 3758 | 3775 | if (!fn_gz.endsWithNoReturn()) { |
| ... | ... | @@ -3848,13 +3865,13 @@ fn globalVarDecl( |
| 3848 | 3865 | break :blk token_tags[maybe_extern_token] == .keyword_extern; |
| 3849 | 3866 | }; |
| 3850 | 3867 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node == 0) .none else inst: { |
| 3851 | | break :inst try expr(&block_scope, &block_scope.base, align_rl, var_decl.ast.align_node); |
| 3868 | break :inst try expr(&block_scope, &block_scope.base, align_ri, var_decl.ast.align_node); |
| 3852 | 3869 | }; |
| 3853 | 3870 | const addrspace_inst: Zir.Inst.Ref = if (var_decl.ast.addrspace_node == 0) .none else inst: { |
| 3854 | | break :inst try expr(&block_scope, &block_scope.base, .{ .ty = .address_space_type }, var_decl.ast.addrspace_node); |
| 3871 | break :inst try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = .address_space_type } }, var_decl.ast.addrspace_node); |
| 3855 | 3872 | }; |
| 3856 | 3873 | const section_inst: Zir.Inst.Ref = if (var_decl.ast.section_node == 0) .none else inst: { |
| 3857 | | break :inst try comptimeExpr(&block_scope, &block_scope.base, .{ .ty = .const_slice_u8_type }, var_decl.ast.section_node); |
| 3874 | break :inst try comptimeExpr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = .const_slice_u8_type } }, var_decl.ast.section_node); |
| 3858 | 3875 | }; |
| 3859 | 3876 | const has_section_or_addrspace = section_inst != .none or addrspace_inst != .none; |
| 3860 | 3877 | wip_members.nextDecl(is_pub, is_export, align_inst != .none, has_section_or_addrspace); |
| ... | ... | @@ -3894,7 +3911,7 @@ fn globalVarDecl( |
| 3894 | 3911 | try expr( |
| 3895 | 3912 | &block_scope, |
| 3896 | 3913 | &block_scope.base, |
| 3897 | | .{ .ty = .type_type }, |
| 3914 | .{ .rl = .{ .ty = .type_type } }, |
| 3898 | 3915 | var_decl.ast.type_node, |
| 3899 | 3916 | ) |
| 3900 | 3917 | else |
| ... | ... | @@ -3903,7 +3920,7 @@ fn globalVarDecl( |
| 3903 | 3920 | const init_inst = try expr( |
| 3904 | 3921 | &block_scope, |
| 3905 | 3922 | &block_scope.base, |
| 3906 | | if (type_inst != .none) .{ .ty = type_inst } else .none, |
| 3923 | if (type_inst != .none) .{ .rl = .{ .ty = type_inst } } else .{ .rl = .none }, |
| 3907 | 3924 | var_decl.ast.init_node, |
| 3908 | 3925 | ); |
| 3909 | 3926 | |
| ... | ... | @@ -3992,7 +4009,7 @@ fn comptimeDecl( |
| 3992 | 4009 | }; |
| 3993 | 4010 | defer decl_block.unstack(); |
| 3994 | 4011 | |
| 3995 | | const block_result = try expr(&decl_block, &decl_block.base, .none, body_node); |
| 4012 | const block_result = try expr(&decl_block, &decl_block.base, .{ .rl = .none }, body_node); |
| 3996 | 4013 | if (decl_block.isEmpty() or !decl_block.refIsNoReturn(block_result)) { |
| 3997 | 4014 | _ = try decl_block.addBreak(.break_inline, block_inst, .void_value); |
| 3998 | 4015 | } |
| ... | ... | @@ -4196,7 +4213,7 @@ fn testDecl( |
| 4196 | 4213 | const lbrace_line = astgen.source_line - decl_block.decl_line; |
| 4197 | 4214 | const lbrace_column = astgen.source_column; |
| 4198 | 4215 | |
| 4199 | | const block_result = try expr(&fn_block, &fn_block.base, .none, body_node); |
| 4216 | const block_result = try expr(&fn_block, &fn_block.base, .{ .rl = .none }, body_node); |
| 4200 | 4217 | if (fn_block.isEmpty() or !fn_block.refIsNoReturn(block_result)) { |
| 4201 | 4218 | // Since we are adding the return instruction here, we must handle the coercion. |
| 4202 | 4219 | // We do this by using the `ret_tok` instruction. |
| ... | ... | @@ -4410,7 +4427,7 @@ fn structDeclInner( |
| 4410 | 4427 | if (layout == .Packed) { |
| 4411 | 4428 | try astgen.appendErrorNode(member.ast.align_expr, "unable to override alignment of packed struct fields", .{}); |
| 4412 | 4429 | } |
| 4413 | | const align_ref = try expr(&block_scope, &namespace.base, coerced_align_rl, member.ast.align_expr); |
| 4430 | const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, member.ast.align_expr); |
| 4414 | 4431 | if (!block_scope.endsWithNoReturn()) { |
| 4415 | 4432 | _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref); |
| 4416 | 4433 | } |
| ... | ... | @@ -4423,9 +4440,9 @@ fn structDeclInner( |
| 4423 | 4440 | } |
| 4424 | 4441 | |
| 4425 | 4442 | if (have_value) { |
| 4426 | | const rl: ResultLoc = if (field_type == .none) .none else .{ .coerced_ty = field_type }; |
| 4443 | const ri: ResultInfo = .{ .rl = if (field_type == .none) .none else .{ .coerced_ty = field_type } }; |
| 4427 | 4444 | |
| 4428 | | const default_inst = try expr(&block_scope, &namespace.base, rl, member.ast.value_expr); |
| 4445 | const default_inst = try expr(&block_scope, &namespace.base, ri, member.ast.value_expr); |
| 4429 | 4446 | if (!block_scope.endsWithNoReturn()) { |
| 4430 | 4447 | _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst); |
| 4431 | 4448 | } |
| ... | ... | @@ -4554,7 +4571,7 @@ fn unionDeclInner( |
| 4554 | 4571 | return astgen.failNode(member_node, "union field missing type", .{}); |
| 4555 | 4572 | } |
| 4556 | 4573 | if (have_align) { |
| 4557 | | const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr); |
| 4574 | const align_inst = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = .u32_type } }, member.ast.align_expr); |
| 4558 | 4575 | wip_members.appendToField(@enumToInt(align_inst)); |
| 4559 | 4576 | } |
| 4560 | 4577 | if (have_value) { |
| ... | ... | @@ -4586,7 +4603,7 @@ fn unionDeclInner( |
| 4586 | 4603 | }, |
| 4587 | 4604 | ); |
| 4588 | 4605 | } |
| 4589 | | const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr); |
| 4606 | const tag_value = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = arg_inst } }, member.ast.value_expr); |
| 4590 | 4607 | wip_members.appendToField(@enumToInt(tag_value)); |
| 4591 | 4608 | } |
| 4592 | 4609 | } |
| ... | ... | @@ -4624,7 +4641,7 @@ fn unionDeclInner( |
| 4624 | 4641 | fn containerDecl( |
| 4625 | 4642 | gz: *GenZir, |
| 4626 | 4643 | scope: *Scope, |
| 4627 | | rl: ResultLoc, |
| 4644 | ri: ResultInfo, |
| 4628 | 4645 | node: Ast.Node.Index, |
| 4629 | 4646 | container_decl: Ast.full.ContainerDecl, |
| 4630 | 4647 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -4650,7 +4667,7 @@ fn containerDecl( |
| 4650 | 4667 | } else std.builtin.Type.ContainerLayout.Auto; |
| 4651 | 4668 | |
| 4652 | 4669 | const result = try structDeclInner(gz, scope, node, container_decl, layout, container_decl.ast.arg); |
| 4653 | | return rvalue(gz, rl, result, node); |
| 4670 | return rvalue(gz, ri, result, node); |
| 4654 | 4671 | }, |
| 4655 | 4672 | .keyword_union => { |
| 4656 | 4673 | const layout = if (container_decl.layout_token) |t| switch (token_tags[t]) { |
| ... | ... | @@ -4660,7 +4677,7 @@ fn containerDecl( |
| 4660 | 4677 | } else std.builtin.Type.ContainerLayout.Auto; |
| 4661 | 4678 | |
| 4662 | 4679 | const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, container_decl.ast.enum_token); |
| 4663 | | return rvalue(gz, rl, result, node); |
| 4680 | return rvalue(gz, ri, result, node); |
| 4664 | 4681 | }, |
| 4665 | 4682 | .keyword_enum => { |
| 4666 | 4683 | if (container_decl.layout_token) |t| { |
| ... | ... | @@ -4790,7 +4807,7 @@ fn containerDecl( |
| 4790 | 4807 | _ = try astgen.scanDecls(&namespace, container_decl.ast.members); |
| 4791 | 4808 | |
| 4792 | 4809 | const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0) |
| 4793 | | try comptimeExpr(&block_scope, &namespace.base, .{ .ty = .type_type }, container_decl.ast.arg) |
| 4810 | try comptimeExpr(&block_scope, &namespace.base, .{ .rl = .{ .ty = .type_type } }, container_decl.ast.arg) |
| 4794 | 4811 | else |
| 4795 | 4812 | .none; |
| 4796 | 4813 | |
| ... | ... | @@ -4834,7 +4851,7 @@ fn containerDecl( |
| 4834 | 4851 | }, |
| 4835 | 4852 | ); |
| 4836 | 4853 | } |
| 4837 | | const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .ty = arg_inst }, member.ast.value_expr); |
| 4854 | const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .rl = .{ .ty = arg_inst } }, member.ast.value_expr); |
| 4838 | 4855 | wip_members.appendToField(@enumToInt(tag_value_inst)); |
| 4839 | 4856 | } |
| 4840 | 4857 | } |
| ... | ... | @@ -4865,7 +4882,7 @@ fn containerDecl( |
| 4865 | 4882 | |
| 4866 | 4883 | block_scope.unstack(); |
| 4867 | 4884 | try gz.addNamespaceCaptures(&namespace); |
| 4868 | | return rvalue(gz, rl, indexToRef(decl_inst), node); |
| 4885 | return rvalue(gz, ri, indexToRef(decl_inst), node); |
| 4869 | 4886 | }, |
| 4870 | 4887 | .keyword_opaque => { |
| 4871 | 4888 | assert(container_decl.ast.arg == 0); |
| ... | ... | @@ -4915,7 +4932,7 @@ fn containerDecl( |
| 4915 | 4932 | astgen.extra.appendSliceAssumeCapacity(decls_slice); |
| 4916 | 4933 | |
| 4917 | 4934 | try gz.addNamespaceCaptures(&namespace); |
| 4918 | | return rvalue(gz, rl, indexToRef(decl_inst), node); |
| 4935 | return rvalue(gz, ri, indexToRef(decl_inst), node); |
| 4919 | 4936 | }, |
| 4920 | 4937 | else => unreachable, |
| 4921 | 4938 | } |
| ... | ... | @@ -5046,7 +5063,7 @@ fn containerMember( |
| 5046 | 5063 | return .decl; |
| 5047 | 5064 | } |
| 5048 | 5065 | |
| 5049 | | fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 5066 | fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 5050 | 5067 | const astgen = gz.astgen; |
| 5051 | 5068 | const gpa = astgen.gpa; |
| 5052 | 5069 | const tree = astgen.tree; |
| ... | ... | @@ -5101,13 +5118,13 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir |
| 5101 | 5118 | .fields_len = @intCast(u32, fields_len), |
| 5102 | 5119 | }); |
| 5103 | 5120 | const result = try gz.addPlNodePayloadIndex(.error_set_decl, node, payload_index); |
| 5104 | | return rvalue(gz, rl, result, node); |
| 5121 | return rvalue(gz, ri, result, node); |
| 5105 | 5122 | } |
| 5106 | 5123 | |
| 5107 | 5124 | fn tryExpr( |
| 5108 | 5125 | parent_gz: *GenZir, |
| 5109 | 5126 | scope: *Scope, |
| 5110 | | rl: ResultLoc, |
| 5127 | ri: ResultInfo, |
| 5111 | 5128 | node: Ast.Node.Index, |
| 5112 | 5129 | operand_node: Ast.Node.Index, |
| 5113 | 5130 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -5137,15 +5154,15 @@ fn tryExpr( |
| 5137 | 5154 | const try_line = astgen.source_line - parent_gz.decl_line; |
| 5138 | 5155 | const try_column = astgen.source_column; |
| 5139 | 5156 | |
| 5140 | | const operand_rl: ResultLoc = switch (rl) { |
| 5141 | | .ref, .catch_ref => .catch_ref, |
| 5142 | | else => .catch_none, |
| 5157 | const operand_ri: ResultInfo = switch (ri.rl) { |
| 5158 | .ref => .{ .rl = .ref, .ctx = .error_handling_expr }, |
| 5159 | else => .{ .rl = .none, .ctx = .error_handling_expr }, |
| 5143 | 5160 | }; |
| 5144 | | // This could be a pointer or value depending on the `rl` parameter. |
| 5145 | | const operand = try reachableExpr(parent_gz, scope, operand_rl, operand_node, node); |
| 5161 | // This could be a pointer or value depending on the `ri` parameter. |
| 5162 | const operand = try reachableExpr(parent_gz, scope, operand_ri, operand_node, node); |
| 5146 | 5163 | const is_inline = parent_gz.force_comptime; |
| 5147 | 5164 | const is_inline_bit = @as(u2, @boolToInt(is_inline)); |
| 5148 | | const is_ptr_bit = @as(u2, @boolToInt(operand_rl == .ref or operand_rl == .catch_ref)) << 1; |
| 5165 | const is_ptr_bit = @as(u2, @boolToInt(operand_ri.rl == .ref)) << 1; |
| 5149 | 5166 | const block_tag: Zir.Inst.Tag = switch (is_inline_bit | is_ptr_bit) { |
| 5150 | 5167 | 0b00 => .@"try", |
| 5151 | 5168 | 0b01 => .@"try", |
| ... | ... | @@ -5160,8 +5177,8 @@ fn tryExpr( |
| 5160 | 5177 | var else_scope = parent_gz.makeSubBlock(scope); |
| 5161 | 5178 | defer else_scope.unstack(); |
| 5162 | 5179 | |
| 5163 | | const err_tag = switch (rl) { |
| 5164 | | .ref, .catch_ref => Zir.Inst.Tag.err_union_code_ptr, |
| 5180 | const err_tag = switch (ri.rl) { |
| 5181 | .ref => Zir.Inst.Tag.err_union_code_ptr, |
| 5165 | 5182 | else => Zir.Inst.Tag.err_union_code, |
| 5166 | 5183 | }; |
| 5167 | 5184 | const err_code = try else_scope.addUnNode(err_tag, operand, node); |
| ... | ... | @@ -5171,9 +5188,9 @@ fn tryExpr( |
| 5171 | 5188 | |
| 5172 | 5189 | try else_scope.setTryBody(try_inst, operand); |
| 5173 | 5190 | const result = indexToRef(try_inst); |
| 5174 | | switch (rl) { |
| 5175 | | .ref, .catch_ref => return result, |
| 5176 | | else => return rvalue(parent_gz, rl, result, node), |
| 5191 | switch (ri.rl) { |
| 5192 | .ref => return result, |
| 5193 | else => return rvalue(parent_gz, ri, result, node), |
| 5177 | 5194 | } |
| 5178 | 5195 | } |
| 5179 | 5196 | |
| ... | ... | @@ -5190,7 +5207,7 @@ fn tryExpr( |
| 5190 | 5207 | fn popErrorReturnTrace( |
| 5191 | 5208 | gz: *GenZir, |
| 5192 | 5209 | scope: *Scope, |
| 5193 | | rl: ResultLoc, |
| 5210 | ri: ResultInfo, |
| 5194 | 5211 | node: Ast.Node.Index, |
| 5195 | 5212 | result_inst: Zir.Inst.Ref, |
| 5196 | 5213 | error_trace_index: Zir.Inst.Ref, |
| ... | ... | @@ -5201,13 +5218,8 @@ fn popErrorReturnTrace( |
| 5201 | 5218 | const result_is_err = nodeMayEvalToError(tree, node); |
| 5202 | 5219 | |
| 5203 | 5220 | // If we are breaking to a try/catch/error-union-if/return, the error trace propagates. |
| 5204 | | const propagate_error_trace = switch (rl) { |
| 5205 | | .catch_none, .catch_ref => true, // Propagate to try/catch/error-union-if |
| 5206 | | .ptr, .ty => |ref| b: { // Otherwise, propagate if result loc is a return |
| 5207 | | const inst = refToIndex(ref) orelse break :b false; |
| 5208 | | const zir_tags = astgen.instructions.items(.tag); |
| 5209 | | break :b zir_tags[inst] == .ret_ptr or zir_tags[inst] == .ret_type; |
| 5210 | | }, |
| 5221 | const propagate_error_trace = switch (ri.ctx) { |
| 5222 | .error_handling_expr, .@"return" => true, |
| 5211 | 5223 | else => false, |
| 5212 | 5224 | }; |
| 5213 | 5225 | |
| ... | ... | @@ -5219,14 +5231,14 @@ fn popErrorReturnTrace( |
| 5219 | 5231 | // We are returning to an error-handling operator with a maybe-error. |
| 5220 | 5232 | // Restore only if it's a non-error, implying the catch was successfully handled. |
| 5221 | 5233 | var block_scope = gz.makeSubBlock(scope); |
| 5222 | | block_scope.setBreakResultLoc(.discard); |
| 5234 | block_scope.setBreakResultInfo(.{ .rl = .discard }); |
| 5223 | 5235 | defer block_scope.unstack(); |
| 5224 | 5236 | |
| 5225 | 5237 | // Emit conditional branch for restoring error trace index |
| 5226 | | const is_non_err = switch (rl) { |
| 5227 | | .catch_ref => try block_scope.addUnNode(.is_non_err_ptr, result_inst, node), |
| 5228 | | .ptr => |ptr| try block_scope.addUnNode(.is_non_err_ptr, ptr, node), |
| 5229 | | .ty, .catch_none => try block_scope.addUnNode(.is_non_err, result_inst, node), |
| 5238 | const is_non_err = switch (ri.rl) { |
| 5239 | .ref => try block_scope.addUnNode(.is_non_err_ptr, result_inst, node), |
| 5240 | .ptr => |ptr| try block_scope.addUnNode(.is_non_err_ptr, ptr.inst, node), |
| 5241 | .ty, .none => try block_scope.addUnNode(.is_non_err, result_inst, node), |
| 5230 | 5242 | else => unreachable, // Error-handling operators only generate the above result locations |
| 5231 | 5243 | }; |
| 5232 | 5244 | const condbr = try block_scope.addCondBr(.condbr, node); |
| ... | ... | @@ -5255,7 +5267,7 @@ fn popErrorReturnTrace( |
| 5255 | 5267 | fn orelseCatchExpr( |
| 5256 | 5268 | parent_gz: *GenZir, |
| 5257 | 5269 | scope: *Scope, |
| 5258 | | rl: ResultLoc, |
| 5270 | ri: ResultInfo, |
| 5259 | 5271 | node: Ast.Node.Index, |
| 5260 | 5272 | lhs: Ast.Node.Index, |
| 5261 | 5273 | cond_op: Zir.Inst.Tag, |
| ... | ... | @@ -5270,21 +5282,21 @@ fn orelseCatchExpr( |
| 5270 | 5282 | const do_err_trace = astgen.fn_block != null and (cond_op == .is_non_err or cond_op == .is_non_err_ptr); |
| 5271 | 5283 | |
| 5272 | 5284 | var block_scope = parent_gz.makeSubBlock(scope); |
| 5273 | | block_scope.setBreakResultLoc(rl); |
| 5285 | block_scope.setBreakResultInfo(ri); |
| 5274 | 5286 | defer block_scope.unstack(); |
| 5275 | 5287 | |
| 5276 | 5288 | const saved_err_trace_index = if (do_err_trace) try parent_gz.addNode(.save_err_ret_index, node) else .none; |
| 5277 | 5289 | |
| 5278 | | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { |
| 5279 | | .ref, .catch_ref => if (do_err_trace) ResultLoc{ .catch_ref = {} } else .ref, |
| 5280 | | else => if (do_err_trace) ResultLoc{ .catch_none = {} } else .none, |
| 5290 | const operand_ri: ResultInfo = switch (block_scope.break_result_info.rl) { |
| 5291 | .ref => .{ .rl = .ref, .ctx = if (do_err_trace) .error_handling_expr else .none }, |
| 5292 | else => .{ .rl = .none, .ctx = if (do_err_trace) .error_handling_expr else .none }, |
| 5281 | 5293 | }; |
| 5282 | 5294 | block_scope.break_count += 1; |
| 5283 | | // This could be a pointer or value depending on the `operand_rl` parameter. |
| 5284 | | // We cannot use `block_scope.break_result_loc` because that has the bare |
| 5295 | // This could be a pointer or value depending on the `operand_ri` parameter. |
| 5296 | // We cannot use `block_scope.break_result_info` because that has the bare |
| 5285 | 5297 | // type, whereas this expression has the optional type. Later we make |
| 5286 | 5298 | // up for this fact by calling rvalue on the else branch. |
| 5287 | | const operand = try reachableExpr(&block_scope, &block_scope.base, operand_rl, lhs, rhs); |
| 5299 | const operand = try reachableExpr(&block_scope, &block_scope.base, operand_ri, lhs, rhs); |
| 5288 | 5300 | const cond = try block_scope.addUnNode(cond_op, operand, node); |
| 5289 | 5301 | const condbr = try block_scope.addCondBr(.condbr, node); |
| 5290 | 5302 | |
| ... | ... | @@ -5298,9 +5310,9 @@ fn orelseCatchExpr( |
| 5298 | 5310 | |
| 5299 | 5311 | // This could be a pointer or value depending on `unwrap_op`. |
| 5300 | 5312 | const unwrapped_payload = try then_scope.addUnNode(unwrap_op, operand, node); |
| 5301 | | const then_result = switch (rl) { |
| 5302 | | .ref, .catch_ref => unwrapped_payload, |
| 5303 | | else => try rvalue(&then_scope, block_scope.break_result_loc, unwrapped_payload, node), |
| 5313 | const then_result = switch (ri.rl) { |
| 5314 | .ref => unwrapped_payload, |
| 5315 | else => try rvalue(&then_scope, block_scope.break_result_info, unwrapped_payload, node), |
| 5304 | 5316 | }; |
| 5305 | 5317 | |
| 5306 | 5318 | var else_scope = block_scope.makeSubBlock(scope); |
| ... | ... | @@ -5334,7 +5346,7 @@ fn orelseCatchExpr( |
| 5334 | 5346 | break :blk &err_val_scope.base; |
| 5335 | 5347 | }; |
| 5336 | 5348 | |
| 5337 | | const else_result = try expr(&else_scope, else_sub_scope, block_scope.break_result_loc, rhs); |
| 5349 | const else_result = try expr(&else_scope, else_sub_scope, block_scope.break_result_info, rhs); |
| 5338 | 5350 | if (!else_scope.endsWithNoReturn()) { |
| 5339 | 5351 | block_scope.break_count += 1; |
| 5340 | 5352 | |
| ... | ... | @@ -5342,7 +5354,7 @@ fn orelseCatchExpr( |
| 5342 | 5354 | try popErrorReturnTrace( |
| 5343 | 5355 | &else_scope, |
| 5344 | 5356 | else_sub_scope, |
| 5345 | | block_scope.break_result_loc, |
| 5357 | block_scope.break_result_info, |
| 5346 | 5358 | rhs, |
| 5347 | 5359 | else_result, |
| 5348 | 5360 | saved_err_trace_index, |
| ... | ... | @@ -5358,7 +5370,7 @@ fn orelseCatchExpr( |
| 5358 | 5370 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; |
| 5359 | 5371 | const result = try finishThenElseBlock( |
| 5360 | 5372 | parent_gz, |
| 5361 | | rl, |
| 5373 | ri, |
| 5362 | 5374 | node, |
| 5363 | 5375 | &block_scope, |
| 5364 | 5376 | &then_scope, |
| ... | ... | @@ -5377,7 +5389,7 @@ fn orelseCatchExpr( |
| 5377 | 5389 | /// Supports `else_scope` stacked on `then_scope` stacked on `block_scope`. Unstacks `else_scope` then `then_scope`. |
| 5378 | 5390 | fn finishThenElseBlock( |
| 5379 | 5391 | parent_gz: *GenZir, |
| 5380 | | rl: ResultLoc, |
| 5392 | ri: ResultInfo, |
| 5381 | 5393 | node: Ast.Node.Index, |
| 5382 | 5394 | block_scope: *GenZir, |
| 5383 | 5395 | then_scope: *GenZir, |
| ... | ... | @@ -5392,7 +5404,7 @@ fn finishThenElseBlock( |
| 5392 | 5404 | ) InnerError!Zir.Inst.Ref { |
| 5393 | 5405 | // We now have enough information to decide whether the result instruction should |
| 5394 | 5406 | // be communicated via result location pointer or break instructions. |
| 5395 | | const strat = rl.strategy(block_scope); |
| 5407 | const strat = ri.rl.strategy(block_scope); |
| 5396 | 5408 | // else_scope may be stacked on then_scope, so check for no-return on then_scope manually |
| 5397 | 5409 | const tags = parent_gz.astgen.instructions.items(.tag); |
| 5398 | 5410 | const then_slice = then_scope.instructionsSliceUpto(else_scope); |
| ... | ... | @@ -5422,9 +5434,9 @@ fn finishThenElseBlock( |
| 5422 | 5434 | try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break); |
| 5423 | 5435 | } |
| 5424 | 5436 | const block_ref = indexToRef(main_block); |
| 5425 | | switch (rl) { |
| 5426 | | .ref, .catch_ref => return block_ref, |
| 5427 | | else => return rvalue(parent_gz, rl, block_ref, node), |
| 5437 | switch (ri.rl) { |
| 5438 | .ref => return block_ref, |
| 5439 | else => return rvalue(parent_gz, ri, block_ref, node), |
| 5428 | 5440 | } |
| 5429 | 5441 | }, |
| 5430 | 5442 | } |
| ... | ... | @@ -5443,14 +5455,14 @@ fn tokenIdentEql(astgen: *AstGen, token1: Ast.TokenIndex, token2: Ast.TokenIndex |
| 5443 | 5455 | fn fieldAccess( |
| 5444 | 5456 | gz: *GenZir, |
| 5445 | 5457 | scope: *Scope, |
| 5446 | | rl: ResultLoc, |
| 5458 | ri: ResultInfo, |
| 5447 | 5459 | node: Ast.Node.Index, |
| 5448 | 5460 | ) InnerError!Zir.Inst.Ref { |
| 5449 | | switch (rl) { |
| 5450 | | .ref, .catch_ref => return addFieldAccess(.field_ptr, gz, scope, .ref, node), |
| 5461 | switch (ri.rl) { |
| 5462 | .ref => return addFieldAccess(.field_ptr, gz, scope, .{ .rl = .ref }, node), |
| 5451 | 5463 | else => { |
| 5452 | | const access = try addFieldAccess(.field_val, gz, scope, .none, node); |
| 5453 | | return rvalue(gz, rl, access, node); |
| 5464 | const access = try addFieldAccess(.field_val, gz, scope, .{ .rl = .none }, node); |
| 5465 | return rvalue(gz, ri, access, node); |
| 5454 | 5466 | }, |
| 5455 | 5467 | } |
| 5456 | 5468 | } |
| ... | ... | @@ -5459,7 +5471,7 @@ fn addFieldAccess( |
| 5459 | 5471 | tag: Zir.Inst.Tag, |
| 5460 | 5472 | gz: *GenZir, |
| 5461 | 5473 | scope: *Scope, |
| 5462 | | lhs_rl: ResultLoc, |
| 5474 | lhs_ri: ResultInfo, |
| 5463 | 5475 | node: Ast.Node.Index, |
| 5464 | 5476 | ) InnerError!Zir.Inst.Ref { |
| 5465 | 5477 | const astgen = gz.astgen; |
| ... | ... | @@ -5473,7 +5485,7 @@ fn addFieldAccess( |
| 5473 | 5485 | const str_index = try astgen.identAsString(field_ident); |
| 5474 | 5486 | |
| 5475 | 5487 | return gz.addPlNode(tag, node, Zir.Inst.Field{ |
| 5476 | | .lhs = try expr(gz, scope, lhs_rl, object_node), |
| 5488 | .lhs = try expr(gz, scope, lhs_ri, object_node), |
| 5477 | 5489 | .field_name_start = str_index, |
| 5478 | 5490 | }); |
| 5479 | 5491 | } |
| ... | ... | @@ -5481,20 +5493,20 @@ fn addFieldAccess( |
| 5481 | 5493 | fn arrayAccess( |
| 5482 | 5494 | gz: *GenZir, |
| 5483 | 5495 | scope: *Scope, |
| 5484 | | rl: ResultLoc, |
| 5496 | ri: ResultInfo, |
| 5485 | 5497 | node: Ast.Node.Index, |
| 5486 | 5498 | ) InnerError!Zir.Inst.Ref { |
| 5487 | 5499 | const astgen = gz.astgen; |
| 5488 | 5500 | const tree = astgen.tree; |
| 5489 | 5501 | const node_datas = tree.nodes.items(.data); |
| 5490 | | switch (rl) { |
| 5491 | | .ref, .catch_ref => return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ |
| 5492 | | .lhs = try expr(gz, scope, .ref, node_datas[node].lhs), |
| 5493 | | .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), |
| 5502 | switch (ri.rl) { |
| 5503 | .ref => return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ |
| 5504 | .lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs), |
| 5505 | .rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs), |
| 5494 | 5506 | }), |
| 5495 | | else => return rvalue(gz, rl, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ |
| 5496 | | .lhs = try expr(gz, scope, .none, node_datas[node].lhs), |
| 5497 | | .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), |
| 5507 | else => return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ |
| 5508 | .lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs), |
| 5509 | .rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs), |
| 5498 | 5510 | }), node), |
| 5499 | 5511 | } |
| 5500 | 5512 | } |
| ... | ... | @@ -5502,7 +5514,7 @@ fn arrayAccess( |
| 5502 | 5514 | fn simpleBinOp( |
| 5503 | 5515 | gz: *GenZir, |
| 5504 | 5516 | scope: *Scope, |
| 5505 | | rl: ResultLoc, |
| 5517 | ri: ResultInfo, |
| 5506 | 5518 | node: Ast.Node.Index, |
| 5507 | 5519 | op_inst_tag: Zir.Inst.Tag, |
| 5508 | 5520 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -5511,15 +5523,15 @@ fn simpleBinOp( |
| 5511 | 5523 | const node_datas = tree.nodes.items(.data); |
| 5512 | 5524 | |
| 5513 | 5525 | const result = try gz.addPlNode(op_inst_tag, node, Zir.Inst.Bin{ |
| 5514 | | .lhs = try reachableExpr(gz, scope, .none, node_datas[node].lhs, node), |
| 5515 | | .rhs = try reachableExpr(gz, scope, .none, node_datas[node].rhs, node), |
| 5526 | .lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node), |
| 5527 | .rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node), |
| 5516 | 5528 | }); |
| 5517 | | return rvalue(gz, rl, result, node); |
| 5529 | return rvalue(gz, ri, result, node); |
| 5518 | 5530 | } |
| 5519 | 5531 | |
| 5520 | 5532 | fn simpleStrTok( |
| 5521 | 5533 | gz: *GenZir, |
| 5522 | | rl: ResultLoc, |
| 5534 | ri: ResultInfo, |
| 5523 | 5535 | ident_token: Ast.TokenIndex, |
| 5524 | 5536 | node: Ast.Node.Index, |
| 5525 | 5537 | op_inst_tag: Zir.Inst.Tag, |
| ... | ... | @@ -5527,13 +5539,13 @@ fn simpleStrTok( |
| 5527 | 5539 | const astgen = gz.astgen; |
| 5528 | 5540 | const str_index = try astgen.identAsString(ident_token); |
| 5529 | 5541 | const result = try gz.addStrTok(op_inst_tag, str_index, ident_token); |
| 5530 | | return rvalue(gz, rl, result, node); |
| 5542 | return rvalue(gz, ri, result, node); |
| 5531 | 5543 | } |
| 5532 | 5544 | |
| 5533 | 5545 | fn boolBinOp( |
| 5534 | 5546 | gz: *GenZir, |
| 5535 | 5547 | scope: *Scope, |
| 5536 | | rl: ResultLoc, |
| 5548 | ri: ResultInfo, |
| 5537 | 5549 | node: Ast.Node.Index, |
| 5538 | 5550 | zir_tag: Zir.Inst.Tag, |
| 5539 | 5551 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -5541,25 +5553,25 @@ fn boolBinOp( |
| 5541 | 5553 | const tree = astgen.tree; |
| 5542 | 5554 | const node_datas = tree.nodes.items(.data); |
| 5543 | 5555 | |
| 5544 | | const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs); |
| 5556 | const lhs = try expr(gz, scope, bool_ri, node_datas[node].lhs); |
| 5545 | 5557 | const bool_br = try gz.addBoolBr(zir_tag, lhs); |
| 5546 | 5558 | |
| 5547 | 5559 | var rhs_scope = gz.makeSubBlock(scope); |
| 5548 | 5560 | defer rhs_scope.unstack(); |
| 5549 | | const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_rl, node_datas[node].rhs); |
| 5561 | const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs); |
| 5550 | 5562 | if (!gz.refIsNoReturn(rhs)) { |
| 5551 | 5563 | _ = try rhs_scope.addBreak(.break_inline, bool_br, rhs); |
| 5552 | 5564 | } |
| 5553 | 5565 | try rhs_scope.setBoolBrBody(bool_br); |
| 5554 | 5566 | |
| 5555 | 5567 | const block_ref = indexToRef(bool_br); |
| 5556 | | return rvalue(gz, rl, block_ref, node); |
| 5568 | return rvalue(gz, ri, block_ref, node); |
| 5557 | 5569 | } |
| 5558 | 5570 | |
| 5559 | 5571 | fn ifExpr( |
| 5560 | 5572 | parent_gz: *GenZir, |
| 5561 | 5573 | scope: *Scope, |
| 5562 | | rl: ResultLoc, |
| 5574 | ri: ResultInfo, |
| 5563 | 5575 | node: Ast.Node.Index, |
| 5564 | 5576 | if_full: Ast.full.If, |
| 5565 | 5577 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -5570,7 +5582,7 @@ fn ifExpr( |
| 5570 | 5582 | const do_err_trace = astgen.fn_block != null and if_full.error_token != null; |
| 5571 | 5583 | |
| 5572 | 5584 | var block_scope = parent_gz.makeSubBlock(scope); |
| 5573 | | block_scope.setBreakResultLoc(rl); |
| 5585 | block_scope.setBreakResultInfo(ri); |
| 5574 | 5586 | defer block_scope.unstack(); |
| 5575 | 5587 | |
| 5576 | 5588 | const saved_err_trace_index = if (do_err_trace) try parent_gz.addNode(.save_err_ret_index, node) else .none; |
| ... | ... | @@ -5586,23 +5598,23 @@ fn ifExpr( |
| 5586 | 5598 | bool_bit: Zir.Inst.Ref, |
| 5587 | 5599 | } = c: { |
| 5588 | 5600 | if (if_full.error_token) |_| { |
| 5589 | | const cond_rl: ResultLoc = if (payload_is_ref) .catch_ref else .catch_none; |
| 5590 | | const err_union = try expr(&block_scope, &block_scope.base, cond_rl, if_full.ast.cond_expr); |
| 5601 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none, .ctx = .error_handling_expr }; |
| 5602 | const err_union = try expr(&block_scope, &block_scope.base, cond_ri, if_full.ast.cond_expr); |
| 5591 | 5603 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err; |
| 5592 | 5604 | break :c .{ |
| 5593 | 5605 | .inst = err_union, |
| 5594 | 5606 | .bool_bit = try block_scope.addUnNode(tag, err_union, if_full.ast.cond_expr), |
| 5595 | 5607 | }; |
| 5596 | 5608 | } else if (if_full.payload_token) |_| { |
| 5597 | | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; |
| 5598 | | const optional = try expr(&block_scope, &block_scope.base, cond_rl, if_full.ast.cond_expr); |
| 5609 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 5610 | const optional = try expr(&block_scope, &block_scope.base, cond_ri, if_full.ast.cond_expr); |
| 5599 | 5611 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null; |
| 5600 | 5612 | break :c .{ |
| 5601 | 5613 | .inst = optional, |
| 5602 | 5614 | .bool_bit = try block_scope.addUnNode(tag, optional, if_full.ast.cond_expr), |
| 5603 | 5615 | }; |
| 5604 | 5616 | } else { |
| 5605 | | const cond = try expr(&block_scope, &block_scope.base, bool_rl, if_full.ast.cond_expr); |
| 5617 | const cond = try expr(&block_scope, &block_scope.base, bool_ri, if_full.ast.cond_expr); |
| 5606 | 5618 | break :c .{ |
| 5607 | 5619 | .inst = cond, |
| 5608 | 5620 | .bool_bit = cond, |
| ... | ... | @@ -5678,7 +5690,7 @@ fn ifExpr( |
| 5678 | 5690 | } |
| 5679 | 5691 | }; |
| 5680 | 5692 | |
| 5681 | | const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_loc, if_full.ast.then_expr); |
| 5693 | const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, if_full.ast.then_expr); |
| 5682 | 5694 | if (!then_scope.endsWithNoReturn()) { |
| 5683 | 5695 | block_scope.break_count += 1; |
| 5684 | 5696 | } |
| ... | ... | @@ -5729,7 +5741,7 @@ fn ifExpr( |
| 5729 | 5741 | break :s &else_scope.base; |
| 5730 | 5742 | } |
| 5731 | 5743 | }; |
| 5732 | | const e = try expr(&else_scope, sub_scope, block_scope.break_result_loc, else_node); |
| 5744 | const e = try expr(&else_scope, sub_scope, block_scope.break_result_info, else_node); |
| 5733 | 5745 | if (!else_scope.endsWithNoReturn()) { |
| 5734 | 5746 | block_scope.break_count += 1; |
| 5735 | 5747 | |
| ... | ... | @@ -5737,7 +5749,7 @@ fn ifExpr( |
| 5737 | 5749 | try popErrorReturnTrace( |
| 5738 | 5750 | &else_scope, |
| 5739 | 5751 | sub_scope, |
| 5740 | | block_scope.break_result_loc, |
| 5752 | block_scope.break_result_info, |
| 5741 | 5753 | else_node, |
| 5742 | 5754 | e, |
| 5743 | 5755 | saved_err_trace_index, |
| ... | ... | @@ -5752,9 +5764,9 @@ fn ifExpr( |
| 5752 | 5764 | }; |
| 5753 | 5765 | } else .{ |
| 5754 | 5766 | .src = if_full.ast.then_expr, |
| 5755 | | .result = switch (rl) { |
| 5767 | .result = switch (ri.rl) { |
| 5756 | 5768 | // Explicitly store void to ptr result loc if there is no else branch |
| 5757 | | .ptr, .block_ptr => try rvalue(&else_scope, rl, .void_value, node), |
| 5769 | .ptr, .block_ptr => try rvalue(&else_scope, ri, .void_value, node), |
| 5758 | 5770 | else => .none, |
| 5759 | 5771 | }, |
| 5760 | 5772 | }; |
| ... | ... | @@ -5762,7 +5774,7 @@ fn ifExpr( |
| 5762 | 5774 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; |
| 5763 | 5775 | const result = try finishThenElseBlock( |
| 5764 | 5776 | parent_gz, |
| 5765 | | rl, |
| 5777 | ri, |
| 5766 | 5778 | node, |
| 5767 | 5779 | &block_scope, |
| 5768 | 5780 | &then_scope, |
| ... | ... | @@ -5896,7 +5908,7 @@ fn setCondBrPayloadElideBlockStorePtr( |
| 5896 | 5908 | fn whileExpr( |
| 5897 | 5909 | parent_gz: *GenZir, |
| 5898 | 5910 | scope: *Scope, |
| 5899 | | rl: ResultLoc, |
| 5911 | ri: ResultInfo, |
| 5900 | 5912 | node: Ast.Node.Index, |
| 5901 | 5913 | while_full: Ast.full.While, |
| 5902 | 5914 | is_statement: bool, |
| ... | ... | @@ -5916,7 +5928,7 @@ fn whileExpr( |
| 5916 | 5928 | |
| 5917 | 5929 | var loop_scope = parent_gz.makeSubBlock(scope); |
| 5918 | 5930 | loop_scope.is_inline = is_inline; |
| 5919 | | loop_scope.setBreakResultLoc(rl); |
| 5931 | loop_scope.setBreakResultInfo(ri); |
| 5920 | 5932 | defer loop_scope.unstack(); |
| 5921 | 5933 | defer loop_scope.labeled_breaks.deinit(astgen.gpa); |
| 5922 | 5934 | |
| ... | ... | @@ -5934,23 +5946,23 @@ fn whileExpr( |
| 5934 | 5946 | bool_bit: Zir.Inst.Ref, |
| 5935 | 5947 | } = c: { |
| 5936 | 5948 | if (while_full.error_token) |_| { |
| 5937 | | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; |
| 5938 | | const err_union = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr); |
| 5949 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 5950 | const err_union = try expr(&continue_scope, &continue_scope.base, cond_ri, while_full.ast.cond_expr); |
| 5939 | 5951 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err; |
| 5940 | 5952 | break :c .{ |
| 5941 | 5953 | .inst = err_union, |
| 5942 | 5954 | .bool_bit = try continue_scope.addUnNode(tag, err_union, while_full.ast.then_expr), |
| 5943 | 5955 | }; |
| 5944 | 5956 | } else if (while_full.payload_token) |_| { |
| 5945 | | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; |
| 5946 | | const optional = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr); |
| 5957 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 5958 | const optional = try expr(&continue_scope, &continue_scope.base, cond_ri, while_full.ast.cond_expr); |
| 5947 | 5959 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null; |
| 5948 | 5960 | break :c .{ |
| 5949 | 5961 | .inst = optional, |
| 5950 | 5962 | .bool_bit = try continue_scope.addUnNode(tag, optional, while_full.ast.then_expr), |
| 5951 | 5963 | }; |
| 5952 | 5964 | } else { |
| 5953 | | const cond = try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr); |
| 5965 | const cond = try expr(&continue_scope, &continue_scope.base, bool_ri, while_full.ast.cond_expr); |
| 5954 | 5966 | break :c .{ |
| 5955 | 5967 | .inst = cond, |
| 5956 | 5968 | .bool_bit = cond, |
| ... | ... | @@ -6069,7 +6081,7 @@ fn whileExpr( |
| 6069 | 6081 | if (dbg_var_name) |some| { |
| 6070 | 6082 | try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst); |
| 6071 | 6083 | } |
| 6072 | | const then_result = try expr(&then_scope, then_sub_scope, .none, while_full.ast.then_expr); |
| 6084 | const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, while_full.ast.then_expr); |
| 6073 | 6085 | _ = try addEnsureResult(&then_scope, then_result, while_full.ast.then_expr); |
| 6074 | 6086 | |
| 6075 | 6087 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| ... | ... | @@ -6114,7 +6126,7 @@ fn whileExpr( |
| 6114 | 6126 | // control flow apply to outer loops; not this one. |
| 6115 | 6127 | loop_scope.continue_block = 0; |
| 6116 | 6128 | loop_scope.break_block = 0; |
| 6117 | | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node); |
| 6129 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); |
| 6118 | 6130 | if (is_statement) { |
| 6119 | 6131 | _ = try addEnsureResult(&else_scope, else_result, else_node); |
| 6120 | 6132 | } |
| ... | ... | @@ -6141,7 +6153,7 @@ fn whileExpr( |
| 6141 | 6153 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6142 | 6154 | const result = try finishThenElseBlock( |
| 6143 | 6155 | parent_gz, |
| 6144 | | rl, |
| 6156 | ri, |
| 6145 | 6157 | node, |
| 6146 | 6158 | &loop_scope, |
| 6147 | 6159 | &then_scope, |
| ... | ... | @@ -6163,7 +6175,7 @@ fn whileExpr( |
| 6163 | 6175 | fn forExpr( |
| 6164 | 6176 | parent_gz: *GenZir, |
| 6165 | 6177 | scope: *Scope, |
| 6166 | | rl: ResultLoc, |
| 6178 | ri: ResultInfo, |
| 6167 | 6179 | node: Ast.Node.Index, |
| 6168 | 6180 | for_full: Ast.full.While, |
| 6169 | 6181 | is_statement: bool, |
| ... | ... | @@ -6186,8 +6198,8 @@ fn forExpr( |
| 6186 | 6198 | |
| 6187 | 6199 | try emitDbgNode(parent_gz, for_full.ast.cond_expr); |
| 6188 | 6200 | |
| 6189 | | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; |
| 6190 | | const array_ptr = try expr(parent_gz, scope, cond_rl, for_full.ast.cond_expr); |
| 6201 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 6202 | const array_ptr = try expr(parent_gz, scope, cond_ri, for_full.ast.cond_expr); |
| 6191 | 6203 | const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr); |
| 6192 | 6204 | |
| 6193 | 6205 | const index_ptr = blk: { |
| ... | ... | @@ -6204,7 +6216,7 @@ fn forExpr( |
| 6204 | 6216 | |
| 6205 | 6217 | var loop_scope = parent_gz.makeSubBlock(scope); |
| 6206 | 6218 | loop_scope.is_inline = is_inline; |
| 6207 | | loop_scope.setBreakResultLoc(rl); |
| 6219 | loop_scope.setBreakResultInfo(ri); |
| 6208 | 6220 | defer loop_scope.unstack(); |
| 6209 | 6221 | defer loop_scope.labeled_breaks.deinit(astgen.gpa); |
| 6210 | 6222 | |
| ... | ... | @@ -6308,7 +6320,7 @@ fn forExpr( |
| 6308 | 6320 | break :blk &index_scope.base; |
| 6309 | 6321 | }; |
| 6310 | 6322 | |
| 6311 | | const then_result = try expr(&then_scope, then_sub_scope, .none, for_full.ast.then_expr); |
| 6323 | const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, for_full.ast.then_expr); |
| 6312 | 6324 | _ = try addEnsureResult(&then_scope, then_result, for_full.ast.then_expr); |
| 6313 | 6325 | |
| 6314 | 6326 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| ... | ... | @@ -6327,7 +6339,7 @@ fn forExpr( |
| 6327 | 6339 | // control flow apply to outer loops; not this one. |
| 6328 | 6340 | loop_scope.continue_block = 0; |
| 6329 | 6341 | loop_scope.break_block = 0; |
| 6330 | | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node); |
| 6342 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); |
| 6331 | 6343 | if (is_statement) { |
| 6332 | 6344 | _ = try addEnsureResult(&else_scope, else_result, else_node); |
| 6333 | 6345 | } |
| ... | ... | @@ -6352,7 +6364,7 @@ fn forExpr( |
| 6352 | 6364 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6353 | 6365 | const result = try finishThenElseBlock( |
| 6354 | 6366 | parent_gz, |
| 6355 | | rl, |
| 6367 | ri, |
| 6356 | 6368 | node, |
| 6357 | 6369 | &loop_scope, |
| 6358 | 6370 | &then_scope, |
| ... | ... | @@ -6374,7 +6386,7 @@ fn forExpr( |
| 6374 | 6386 | fn switchExpr( |
| 6375 | 6387 | parent_gz: *GenZir, |
| 6376 | 6388 | scope: *Scope, |
| 6377 | | rl: ResultLoc, |
| 6389 | ri: ResultInfo, |
| 6378 | 6390 | switch_node: Ast.Node.Index, |
| 6379 | 6391 | ) InnerError!Zir.Inst.Ref { |
| 6380 | 6392 | const astgen = parent_gz.astgen; |
| ... | ... | @@ -6505,13 +6517,13 @@ fn switchExpr( |
| 6505 | 6517 | } |
| 6506 | 6518 | } |
| 6507 | 6519 | |
| 6508 | | const operand_rl: ResultLoc = if (any_payload_is_ref) .ref else .none; |
| 6509 | | const raw_operand = try expr(parent_gz, scope, operand_rl, operand_node); |
| 6520 | const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none }; |
| 6521 | const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node); |
| 6510 | 6522 | const cond_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_cond_ref else .switch_cond; |
| 6511 | 6523 | const cond = try parent_gz.addUnNode(cond_tag, raw_operand, operand_node); |
| 6512 | 6524 | // We need the type of the operand to use as the result location for all the prong items. |
| 6513 | 6525 | const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node); |
| 6514 | | const item_rl: ResultLoc = .{ .ty = cond_ty_inst }; |
| 6526 | const item_ri: ResultInfo = .{ .rl = .{ .ty = cond_ty_inst } }; |
| 6515 | 6527 | |
| 6516 | 6528 | // This contains the data that goes into the `extra` array for the SwitchBlock/SwitchBlockMulti, |
| 6517 | 6529 | // except the first cases_nodes.len slots are a table that indexes payloads later in the array, with |
| ... | ... | @@ -6528,7 +6540,7 @@ fn switchExpr( |
| 6528 | 6540 | var block_scope = parent_gz.makeSubBlock(scope); |
| 6529 | 6541 | // block_scope not used for collecting instructions |
| 6530 | 6542 | block_scope.instructions_top = GenZir.unstacked_top; |
| 6531 | | block_scope.setBreakResultLoc(rl); |
| 6543 | block_scope.setBreakResultInfo(ri); |
| 6532 | 6544 | |
| 6533 | 6545 | // This gets added to the parent block later, after the item expressions. |
| 6534 | 6546 | const switch_block = try parent_gz.makeBlockInst(.switch_block, switch_node); |
| ... | ... | @@ -6669,7 +6681,7 @@ fn switchExpr( |
| 6669 | 6681 | if (node_tags[item_node] == .switch_range) continue; |
| 6670 | 6682 | items_len += 1; |
| 6671 | 6683 | |
| 6672 | | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); |
| 6684 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node); |
| 6673 | 6685 | try payloads.append(gpa, @enumToInt(item_inst)); |
| 6674 | 6686 | } |
| 6675 | 6687 | |
| ... | ... | @@ -6679,8 +6691,8 @@ fn switchExpr( |
| 6679 | 6691 | if (node_tags[range] != .switch_range) continue; |
| 6680 | 6692 | ranges_len += 1; |
| 6681 | 6693 | |
| 6682 | | const first = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].lhs); |
| 6683 | | const last = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].rhs); |
| 6694 | const first = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].lhs); |
| 6695 | const last = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].rhs); |
| 6684 | 6696 | try payloads.appendSlice(gpa, &[_]u32{ |
| 6685 | 6697 | @enumToInt(first), @enumToInt(last), |
| 6686 | 6698 | }); |
| ... | ... | @@ -6698,7 +6710,7 @@ fn switchExpr( |
| 6698 | 6710 | scalar_case_index += 1; |
| 6699 | 6711 | try payloads.resize(gpa, header_index + 2); // item, body_len |
| 6700 | 6712 | const item_node = case.ast.values[0]; |
| 6701 | | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); |
| 6713 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node); |
| 6702 | 6714 | payloads.items[header_index] = @enumToInt(item_inst); |
| 6703 | 6715 | break :blk header_index + 1; |
| 6704 | 6716 | }; |
| ... | ... | @@ -6717,7 +6729,7 @@ fn switchExpr( |
| 6717 | 6729 | if (dbg_var_tag_name) |some| { |
| 6718 | 6730 | try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst); |
| 6719 | 6731 | } |
| 6720 | | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); |
| 6732 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, case.ast.target_expr); |
| 6721 | 6733 | try checkUsed(parent_gz, &case_scope.base, sub_scope); |
| 6722 | 6734 | try case_scope.addDbgBlockEnd(); |
| 6723 | 6735 | if (!parent_gz.refIsNoReturn(case_result)) { |
| ... | ... | @@ -6759,7 +6771,7 @@ fn switchExpr( |
| 6759 | 6771 | |
| 6760 | 6772 | zir_datas[switch_block].pl_node.payload_index = payload_index; |
| 6761 | 6773 | |
| 6762 | | const strat = rl.strategy(&block_scope); |
| 6774 | const strat = ri.rl.strategy(&block_scope); |
| 6763 | 6775 | for (payloads.items[case_table_start..case_table_end]) |start_index, i| { |
| 6764 | 6776 | var body_len_index = start_index; |
| 6765 | 6777 | var end_index = start_index; |
| ... | ... | @@ -6831,8 +6843,8 @@ fn switchExpr( |
| 6831 | 6843 | } |
| 6832 | 6844 | |
| 6833 | 6845 | const block_ref = indexToRef(switch_block); |
| 6834 | | if (strat.tag == .break_operand and strat.elide_store_to_block_ptr_instructions and rl != .ref and rl != .catch_ref) |
| 6835 | | return rvalue(parent_gz, rl, block_ref, switch_node); |
| 6846 | if (strat.tag == .break_operand and strat.elide_store_to_block_ptr_instructions and ri.rl != .ref) |
| 6847 | return rvalue(parent_gz, ri, block_ref, switch_node); |
| 6836 | 6848 | return block_ref; |
| 6837 | 6849 | } |
| 6838 | 6850 | |
| ... | ... | @@ -6895,14 +6907,16 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6895 | 6907 | return Zir.Inst.Ref.unreachable_value; |
| 6896 | 6908 | } |
| 6897 | 6909 | |
| 6898 | | const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{ |
| 6899 | | .ptr = .{ .inst = try gz.addNode(.ret_ptr, node) }, |
| 6910 | const ri: ResultInfo = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{ |
| 6911 | .rl = .{ .ptr = .{ .inst = try gz.addNode(.ret_ptr, node) } }, |
| 6912 | .ctx = .@"return", |
| 6900 | 6913 | } else .{ |
| 6901 | | .ty = try gz.addNode(.ret_type, node), |
| 6914 | .rl = .{ .ty = try gz.addNode(.ret_type, node) }, |
| 6915 | .ctx = .@"return", |
| 6902 | 6916 | }; |
| 6903 | 6917 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 6904 | 6918 | gz.anon_name_strategy = .func; |
| 6905 | | const operand = try reachableExpr(gz, scope, rl, operand_node, node); |
| 6919 | const operand = try reachableExpr(gz, scope, ri, operand_node, node); |
| 6906 | 6920 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 6907 | 6921 | |
| 6908 | 6922 | // TODO: This should be almost identical for every break/ret |
| ... | ... | @@ -6916,15 +6930,15 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6916 | 6930 | _ = try gz.addUnNode(.restore_err_ret_index, gz.outermost_err_trace_index, node); |
| 6917 | 6931 | |
| 6918 | 6932 | try emitDbgStmt(gz, ret_line, ret_column); |
| 6919 | | try gz.addRet(rl, operand, node); |
| 6933 | try gz.addRet(ri, operand, node); |
| 6920 | 6934 | return Zir.Inst.Ref.unreachable_value; |
| 6921 | 6935 | }, |
| 6922 | 6936 | .always => { |
| 6923 | 6937 | // Value is always an error. Emit both error defers and regular defers. |
| 6924 | | const err_code = if (rl == .ptr) try gz.addUnNode(.load, rl.ptr.inst, node) else operand; |
| 6938 | const err_code = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; |
| 6925 | 6939 | try genDefers(gz, defer_outer, scope, .{ .both = err_code }); |
| 6926 | 6940 | try emitDbgStmt(gz, ret_line, ret_column); |
| 6927 | | try gz.addRet(rl, operand, node); |
| 6941 | try gz.addRet(ri, operand, node); |
| 6928 | 6942 | return Zir.Inst.Ref.unreachable_value; |
| 6929 | 6943 | }, |
| 6930 | 6944 | .maybe => { |
| ... | ... | @@ -6933,12 +6947,12 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6933 | 6947 | // Only regular defers; no branch needed. |
| 6934 | 6948 | try genDefers(gz, defer_outer, scope, .normal_only); |
| 6935 | 6949 | try emitDbgStmt(gz, ret_line, ret_column); |
| 6936 | | try gz.addRet(rl, operand, node); |
| 6950 | try gz.addRet(ri, operand, node); |
| 6937 | 6951 | return Zir.Inst.Ref.unreachable_value; |
| 6938 | 6952 | } |
| 6939 | 6953 | |
| 6940 | 6954 | // Emit conditional branch for generating errdefers. |
| 6941 | | const result = if (rl == .ptr) try gz.addUnNode(.load, rl.ptr.inst, node) else operand; |
| 6955 | const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; |
| 6942 | 6956 | const is_non_err = try gz.addUnNode(.is_non_err, result, node); |
| 6943 | 6957 | const condbr = try gz.addCondBr(.condbr, node); |
| 6944 | 6958 | |
| ... | ... | @@ -6952,7 +6966,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6952 | 6966 | _ = try then_scope.addUnNode(.restore_err_ret_index, then_scope.outermost_err_trace_index, node); |
| 6953 | 6967 | |
| 6954 | 6968 | try emitDbgStmt(&then_scope, ret_line, ret_column); |
| 6955 | | try then_scope.addRet(rl, operand, node); |
| 6969 | try then_scope.addRet(ri, operand, node); |
| 6956 | 6970 | |
| 6957 | 6971 | var else_scope = gz.makeSubBlock(scope); |
| 6958 | 6972 | defer else_scope.unstack(); |
| ... | ... | @@ -6962,7 +6976,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6962 | 6976 | }; |
| 6963 | 6977 | try genDefers(&else_scope, defer_outer, scope, which_ones); |
| 6964 | 6978 | try emitDbgStmt(&else_scope, ret_line, ret_column); |
| 6965 | | try else_scope.addRet(rl, operand, node); |
| 6979 | try else_scope.addRet(ri, operand, node); |
| 6966 | 6980 | |
| 6967 | 6981 | try setCondBrPayload(condbr, is_non_err, &then_scope, 0, &else_scope, 0); |
| 6968 | 6982 | |
| ... | ... | @@ -6995,7 +7009,7 @@ fn parseBitCount(buf: []const u8) std.fmt.ParseIntError!u16 { |
| 6995 | 7009 | fn identifier( |
| 6996 | 7010 | gz: *GenZir, |
| 6997 | 7011 | scope: *Scope, |
| 6998 | | rl: ResultLoc, |
| 7012 | ri: ResultInfo, |
| 6999 | 7013 | ident: Ast.Node.Index, |
| 7000 | 7014 | ) InnerError!Zir.Inst.Ref { |
| 7001 | 7015 | const tracy = trace(@src()); |
| ... | ... | @@ -7014,7 +7028,7 @@ fn identifier( |
| 7014 | 7028 | // if not @"" syntax, just use raw token slice |
| 7015 | 7029 | if (ident_name_raw[0] != '@') { |
| 7016 | 7030 | if (primitives.get(ident_name_raw)) |zir_const_ref| { |
| 7017 | | return rvalue(gz, rl, zir_const_ref, ident); |
| 7031 | return rvalue(gz, ri, zir_const_ref, ident); |
| 7018 | 7032 | } |
| 7019 | 7033 | |
| 7020 | 7034 | if (ident_name_raw.len >= 2) integer: { |
| ... | ... | @@ -7047,19 +7061,19 @@ fn identifier( |
| 7047 | 7061 | .bit_count = bit_count, |
| 7048 | 7062 | } }, |
| 7049 | 7063 | }); |
| 7050 | | return rvalue(gz, rl, result, ident); |
| 7064 | return rvalue(gz, ri, result, ident); |
| 7051 | 7065 | } |
| 7052 | 7066 | } |
| 7053 | 7067 | } |
| 7054 | 7068 | |
| 7055 | 7069 | // Local variables, including function parameters. |
| 7056 | | return localVarRef(gz, scope, rl, ident, ident_token); |
| 7070 | return localVarRef(gz, scope, ri, ident, ident_token); |
| 7057 | 7071 | } |
| 7058 | 7072 | |
| 7059 | 7073 | fn localVarRef( |
| 7060 | 7074 | gz: *GenZir, |
| 7061 | 7075 | scope: *Scope, |
| 7062 | | rl: ResultLoc, |
| 7076 | ri: ResultInfo, |
| 7063 | 7077 | ident: Ast.Node.Index, |
| 7064 | 7078 | ident_token: Ast.TokenIndex, |
| 7065 | 7079 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -7077,7 +7091,7 @@ fn localVarRef( |
| 7077 | 7091 | if (local_val.name == name_str_index) { |
| 7078 | 7092 | // Locals cannot shadow anything, so we do not need to look for ambiguous |
| 7079 | 7093 | // references in this case. |
| 7080 | | if (rl == .discard) { |
| 7094 | if (ri.rl == .discard) { |
| 7081 | 7095 | local_val.discarded = ident_token; |
| 7082 | 7096 | } else { |
| 7083 | 7097 | local_val.used = ident_token; |
| ... | ... | @@ -7093,14 +7107,14 @@ fn localVarRef( |
| 7093 | 7107 | gpa, |
| 7094 | 7108 | ); |
| 7095 | 7109 | |
| 7096 | | return rvalue(gz, rl, value_inst, ident); |
| 7110 | return rvalue(gz, ri, value_inst, ident); |
| 7097 | 7111 | } |
| 7098 | 7112 | s = local_val.parent; |
| 7099 | 7113 | }, |
| 7100 | 7114 | .local_ptr => { |
| 7101 | 7115 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 7102 | 7116 | if (local_ptr.name == name_str_index) { |
| 7103 | | if (rl == .discard) { |
| 7117 | if (ri.rl == .discard) { |
| 7104 | 7118 | local_ptr.discarded = ident_token; |
| 7105 | 7119 | } else { |
| 7106 | 7120 | local_ptr.used = ident_token; |
| ... | ... | @@ -7125,11 +7139,11 @@ fn localVarRef( |
| 7125 | 7139 | gpa, |
| 7126 | 7140 | ); |
| 7127 | 7141 | |
| 7128 | | switch (rl) { |
| 7129 | | .ref, .catch_ref => return ptr_inst, |
| 7142 | switch (ri.rl) { |
| 7143 | .ref => return ptr_inst, |
| 7130 | 7144 | else => { |
| 7131 | 7145 | const loaded = try gz.addUnNode(.load, ptr_inst, ident); |
| 7132 | | return rvalue(gz, rl, loaded, ident); |
| 7146 | return rvalue(gz, ri, loaded, ident); |
| 7133 | 7147 | }, |
| 7134 | 7148 | } |
| 7135 | 7149 | } |
| ... | ... | @@ -7162,11 +7176,11 @@ fn localVarRef( |
| 7162 | 7176 | |
| 7163 | 7177 | // Decl references happen by name rather than ZIR index so that when unrelated |
| 7164 | 7178 | // decls are modified, ZIR code containing references to them can be unmodified. |
| 7165 | | switch (rl) { |
| 7166 | | .ref, .catch_ref => return gz.addStrTok(.decl_ref, name_str_index, ident_token), |
| 7179 | switch (ri.rl) { |
| 7180 | .ref => return gz.addStrTok(.decl_ref, name_str_index, ident_token), |
| 7167 | 7181 | else => { |
| 7168 | 7182 | const result = try gz.addStrTok(.decl_val, name_str_index, ident_token); |
| 7169 | | return rvalue(gz, rl, result, ident); |
| 7183 | return rvalue(gz, ri, result, ident); |
| 7170 | 7184 | }, |
| 7171 | 7185 | } |
| 7172 | 7186 | } |
| ... | ... | @@ -7210,7 +7224,7 @@ fn tunnelThroughClosure( |
| 7210 | 7224 | |
| 7211 | 7225 | fn stringLiteral( |
| 7212 | 7226 | gz: *GenZir, |
| 7213 | | rl: ResultLoc, |
| 7227 | ri: ResultInfo, |
| 7214 | 7228 | node: Ast.Node.Index, |
| 7215 | 7229 | ) InnerError!Zir.Inst.Ref { |
| 7216 | 7230 | const astgen = gz.astgen; |
| ... | ... | @@ -7225,12 +7239,12 @@ fn stringLiteral( |
| 7225 | 7239 | .len = str.len, |
| 7226 | 7240 | } }, |
| 7227 | 7241 | }); |
| 7228 | | return rvalue(gz, rl, result, node); |
| 7242 | return rvalue(gz, ri, result, node); |
| 7229 | 7243 | } |
| 7230 | 7244 | |
| 7231 | 7245 | fn multilineStringLiteral( |
| 7232 | 7246 | gz: *GenZir, |
| 7233 | | rl: ResultLoc, |
| 7247 | ri: ResultInfo, |
| 7234 | 7248 | node: Ast.Node.Index, |
| 7235 | 7249 | ) InnerError!Zir.Inst.Ref { |
| 7236 | 7250 | const astgen = gz.astgen; |
| ... | ... | @@ -7242,10 +7256,10 @@ fn multilineStringLiteral( |
| 7242 | 7256 | .len = str.len, |
| 7243 | 7257 | } }, |
| 7244 | 7258 | }); |
| 7245 | | return rvalue(gz, rl, result, node); |
| 7259 | return rvalue(gz, ri, result, node); |
| 7246 | 7260 | } |
| 7247 | 7261 | |
| 7248 | | fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 7262 | fn charLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 7249 | 7263 | const astgen = gz.astgen; |
| 7250 | 7264 | const tree = astgen.tree; |
| 7251 | 7265 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -7255,7 +7269,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir. |
| 7255 | 7269 | switch (std.zig.parseCharLiteral(slice)) { |
| 7256 | 7270 | .success => |codepoint| { |
| 7257 | 7271 | const result = try gz.addInt(codepoint); |
| 7258 | | return rvalue(gz, rl, result, node); |
| 7272 | return rvalue(gz, ri, result, node); |
| 7259 | 7273 | }, |
| 7260 | 7274 | .failure => |err| return astgen.failWithStrLitError(err, main_token, slice, 0), |
| 7261 | 7275 | } |
| ... | ... | @@ -7263,7 +7277,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir. |
| 7263 | 7277 | |
| 7264 | 7278 | const Sign = enum { negative, positive }; |
| 7265 | 7279 | |
| 7266 | | fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { |
| 7280 | fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { |
| 7267 | 7281 | const astgen = gz.astgen; |
| 7268 | 7282 | const tree = astgen.tree; |
| 7269 | 7283 | const main_tokens = tree.nodes.items(.main_token); |
| ... | ... | @@ -7305,7 +7319,7 @@ fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: |
| 7305 | 7319 | const bigger_again: f128 = smaller_float; |
| 7306 | 7320 | if (bigger_again == float_number) { |
| 7307 | 7321 | const result = try gz.addFloat(smaller_float); |
| 7308 | | return rvalue(gz, rl, result, source_node); |
| 7322 | return rvalue(gz, ri, result, source_node); |
| 7309 | 7323 | } |
| 7310 | 7324 | // We need to use 128 bits. Break the float into 4 u32 values so we can |
| 7311 | 7325 | // put it into the `extra` array. |
| ... | ... | @@ -7316,16 +7330,16 @@ fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: |
| 7316 | 7330 | .piece2 = @truncate(u32, int_bits >> 64), |
| 7317 | 7331 | .piece3 = @truncate(u32, int_bits >> 96), |
| 7318 | 7332 | }); |
| 7319 | | return rvalue(gz, rl, result, source_node); |
| 7333 | return rvalue(gz, ri, result, source_node); |
| 7320 | 7334 | }, |
| 7321 | 7335 | .failure => |err| return astgen.failWithNumberError(err, num_token, bytes), |
| 7322 | 7336 | }; |
| 7323 | 7337 | |
| 7324 | 7338 | if (sign == .positive) { |
| 7325 | | return rvalue(gz, rl, result, source_node); |
| 7339 | return rvalue(gz, ri, result, source_node); |
| 7326 | 7340 | } else { |
| 7327 | 7341 | const negated = try gz.addUnNode(.negate, result, source_node); |
| 7328 | | return rvalue(gz, rl, negated, source_node); |
| 7342 | return rvalue(gz, ri, negated, source_node); |
| 7329 | 7343 | } |
| 7330 | 7344 | } |
| 7331 | 7345 | |
| ... | ... | @@ -7361,7 +7375,7 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token |
| 7361 | 7375 | fn asmExpr( |
| 7362 | 7376 | gz: *GenZir, |
| 7363 | 7377 | scope: *Scope, |
| 7364 | | rl: ResultLoc, |
| 7378 | ri: ResultInfo, |
| 7365 | 7379 | node: Ast.Node.Index, |
| 7366 | 7380 | full: Ast.full.Asm, |
| 7367 | 7381 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -7384,7 +7398,7 @@ fn asmExpr( |
| 7384 | 7398 | }, |
| 7385 | 7399 | else => .{ |
| 7386 | 7400 | .tag = .asm_expr, |
| 7387 | | .tmpl = @enumToInt(try comptimeExpr(gz, scope, .none, full.ast.template)), |
| 7401 | .tmpl = @enumToInt(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template)), |
| 7388 | 7402 | }, |
| 7389 | 7403 | }; |
| 7390 | 7404 | |
| ... | ... | @@ -7436,7 +7450,7 @@ fn asmExpr( |
| 7436 | 7450 | outputs[i] = .{ |
| 7437 | 7451 | .name = name, |
| 7438 | 7452 | .constraint = constraint, |
| 7439 | | .operand = try localVarRef(gz, scope, .ref, node, ident_token), |
| 7453 | .operand = try localVarRef(gz, scope, .{ .rl = .ref }, node, ident_token), |
| 7440 | 7454 | }; |
| 7441 | 7455 | } |
| 7442 | 7456 | } |
| ... | ... | @@ -7452,7 +7466,7 @@ fn asmExpr( |
| 7452 | 7466 | const name = try astgen.identAsString(symbolic_name); |
| 7453 | 7467 | const constraint_token = symbolic_name + 2; |
| 7454 | 7468 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 7455 | | const operand = try expr(gz, scope, .none, node_datas[input_node].lhs); |
| 7469 | const operand = try expr(gz, scope, .{ .rl = .none }, node_datas[input_node].lhs); |
| 7456 | 7470 | inputs[i] = .{ |
| 7457 | 7471 | .name = name, |
| 7458 | 7472 | .constraint = constraint, |
| ... | ... | @@ -7497,31 +7511,31 @@ fn asmExpr( |
| 7497 | 7511 | .inputs = inputs, |
| 7498 | 7512 | .clobbers = clobbers_buffer[0..clobber_i], |
| 7499 | 7513 | }); |
| 7500 | | return rvalue(gz, rl, result, node); |
| 7514 | return rvalue(gz, ri, result, node); |
| 7501 | 7515 | } |
| 7502 | 7516 | |
| 7503 | 7517 | fn as( |
| 7504 | 7518 | gz: *GenZir, |
| 7505 | 7519 | scope: *Scope, |
| 7506 | | rl: ResultLoc, |
| 7520 | ri: ResultInfo, |
| 7507 | 7521 | node: Ast.Node.Index, |
| 7508 | 7522 | lhs: Ast.Node.Index, |
| 7509 | 7523 | rhs: Ast.Node.Index, |
| 7510 | 7524 | ) InnerError!Zir.Inst.Ref { |
| 7511 | 7525 | const dest_type = try typeExpr(gz, scope, lhs); |
| 7512 | | switch (rl) { |
| 7513 | | .none, .catch_none, .discard, .ref, .catch_ref, .ty, .ty_shift_operand, .coerced_ty => { |
| 7514 | | const result = try reachableExpr(gz, scope, .{ .ty = dest_type }, rhs, node); |
| 7515 | | return rvalue(gz, rl, result, node); |
| 7526 | switch (ri.rl) { |
| 7527 | .none, .discard, .ref, .ty, .coerced_ty => { |
| 7528 | const result = try reachableExpr(gz, scope, .{ .rl = .{ .ty = dest_type } }, rhs, node); |
| 7529 | return rvalue(gz, ri, result, node); |
| 7516 | 7530 | }, |
| 7517 | 7531 | .ptr => |result_ptr| { |
| 7518 | | return asRlPtr(gz, scope, rl, node, result_ptr.inst, rhs, dest_type); |
| 7532 | return asRlPtr(gz, scope, ri, node, result_ptr.inst, rhs, dest_type); |
| 7519 | 7533 | }, |
| 7520 | 7534 | .inferred_ptr => |result_ptr| { |
| 7521 | | return asRlPtr(gz, scope, rl, node, result_ptr, rhs, dest_type); |
| 7535 | return asRlPtr(gz, scope, ri, node, result_ptr, rhs, dest_type); |
| 7522 | 7536 | }, |
| 7523 | 7537 | .block_ptr => |block_scope| { |
| 7524 | | return asRlPtr(gz, scope, rl, node, block_scope.rl_ptr, rhs, dest_type); |
| 7538 | return asRlPtr(gz, scope, ri, node, block_scope.rl_ptr, rhs, dest_type); |
| 7525 | 7539 | }, |
| 7526 | 7540 | } |
| 7527 | 7541 | } |
| ... | ... | @@ -7529,29 +7543,29 @@ fn as( |
| 7529 | 7543 | fn unionInit( |
| 7530 | 7544 | gz: *GenZir, |
| 7531 | 7545 | scope: *Scope, |
| 7532 | | rl: ResultLoc, |
| 7546 | ri: ResultInfo, |
| 7533 | 7547 | node: Ast.Node.Index, |
| 7534 | 7548 | params: []const Ast.Node.Index, |
| 7535 | 7549 | ) InnerError!Zir.Inst.Ref { |
| 7536 | 7550 | const union_type = try typeExpr(gz, scope, params[0]); |
| 7537 | | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); |
| 7551 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]); |
| 7538 | 7552 | const field_type = try gz.addPlNode(.field_type_ref, params[1], Zir.Inst.FieldTypeRef{ |
| 7539 | 7553 | .container_type = union_type, |
| 7540 | 7554 | .field_name = field_name, |
| 7541 | 7555 | }); |
| 7542 | | const init = try reachableExpr(gz, scope, .{ .ty = field_type }, params[2], node); |
| 7556 | const init = try reachableExpr(gz, scope, .{ .rl = .{ .ty = field_type } }, params[2], node); |
| 7543 | 7557 | const result = try gz.addPlNode(.union_init, node, Zir.Inst.UnionInit{ |
| 7544 | 7558 | .union_type = union_type, |
| 7545 | 7559 | .init = init, |
| 7546 | 7560 | .field_name = field_name, |
| 7547 | 7561 | }); |
| 7548 | | return rvalue(gz, rl, result, node); |
| 7562 | return rvalue(gz, ri, result, node); |
| 7549 | 7563 | } |
| 7550 | 7564 | |
| 7551 | 7565 | fn asRlPtr( |
| 7552 | 7566 | parent_gz: *GenZir, |
| 7553 | 7567 | scope: *Scope, |
| 7554 | | rl: ResultLoc, |
| 7568 | ri: ResultInfo, |
| 7555 | 7569 | src_node: Ast.Node.Index, |
| 7556 | 7570 | result_ptr: Zir.Inst.Ref, |
| 7557 | 7571 | operand_node: Ast.Node.Index, |
| ... | ... | @@ -7560,31 +7574,31 @@ fn asRlPtr( |
| 7560 | 7574 | var as_scope = try parent_gz.makeCoercionScope(scope, dest_type, result_ptr, src_node); |
| 7561 | 7575 | defer as_scope.unstack(); |
| 7562 | 7576 | |
| 7563 | | const result = try reachableExpr(&as_scope, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node, src_node); |
| 7564 | | return as_scope.finishCoercion(parent_gz, rl, operand_node, result, dest_type); |
| 7577 | const result = try reachableExpr(&as_scope, &as_scope.base, .{ .rl = .{ .block_ptr = &as_scope } }, operand_node, src_node); |
| 7578 | return as_scope.finishCoercion(parent_gz, ri, operand_node, result, dest_type); |
| 7565 | 7579 | } |
| 7566 | 7580 | |
| 7567 | 7581 | fn bitCast( |
| 7568 | 7582 | gz: *GenZir, |
| 7569 | 7583 | scope: *Scope, |
| 7570 | | rl: ResultLoc, |
| 7584 | ri: ResultInfo, |
| 7571 | 7585 | node: Ast.Node.Index, |
| 7572 | 7586 | lhs: Ast.Node.Index, |
| 7573 | 7587 | rhs: Ast.Node.Index, |
| 7574 | 7588 | ) InnerError!Zir.Inst.Ref { |
| 7575 | 7589 | const dest_type = try reachableTypeExpr(gz, scope, lhs, node); |
| 7576 | | const operand = try reachableExpr(gz, scope, .none, rhs, node); |
| 7590 | const operand = try reachableExpr(gz, scope, .{ .rl = .none }, rhs, node); |
| 7577 | 7591 | const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{ |
| 7578 | 7592 | .lhs = dest_type, |
| 7579 | 7593 | .rhs = operand, |
| 7580 | 7594 | }); |
| 7581 | | return rvalue(gz, rl, result, node); |
| 7595 | return rvalue(gz, ri, result, node); |
| 7582 | 7596 | } |
| 7583 | 7597 | |
| 7584 | 7598 | fn typeOf( |
| 7585 | 7599 | gz: *GenZir, |
| 7586 | 7600 | scope: *Scope, |
| 7587 | | rl: ResultLoc, |
| 7601 | ri: ResultInfo, |
| 7588 | 7602 | node: Ast.Node.Index, |
| 7589 | 7603 | args: []const Ast.Node.Index, |
| 7590 | 7604 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -7600,7 +7614,7 @@ fn typeOf( |
| 7600 | 7614 | typeof_scope.force_comptime = false; |
| 7601 | 7615 | defer typeof_scope.unstack(); |
| 7602 | 7616 | |
| 7603 | | const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .none, args[0], node); |
| 7617 | const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node); |
| 7604 | 7618 | if (!gz.refIsNoReturn(ty_expr)) { |
| 7605 | 7619 | _ = try typeof_scope.addBreak(.break_inline, typeof_inst, ty_expr); |
| 7606 | 7620 | } |
| ... | ... | @@ -7608,7 +7622,7 @@ fn typeOf( |
| 7608 | 7622 | |
| 7609 | 7623 | // typeof_scope unstacked now, can add new instructions to gz |
| 7610 | 7624 | try gz.instructions.append(gpa, typeof_inst); |
| 7611 | | return rvalue(gz, rl, indexToRef(typeof_inst), node); |
| 7625 | return rvalue(gz, ri, indexToRef(typeof_inst), node); |
| 7612 | 7626 | } |
| 7613 | 7627 | const payload_size: u32 = std.meta.fields(Zir.Inst.TypeOfPeer).len; |
| 7614 | 7628 | const payload_index = try reserveExtra(astgen, payload_size + args.len); |
| ... | ... | @@ -7620,7 +7634,7 @@ fn typeOf( |
| 7620 | 7634 | typeof_scope.force_comptime = false; |
| 7621 | 7635 | |
| 7622 | 7636 | for (args) |arg, i| { |
| 7623 | | const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .none, arg, node); |
| 7637 | const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, arg, node); |
| 7624 | 7638 | astgen.extra.items[args_index + i] = @enumToInt(param_ref); |
| 7625 | 7639 | } |
| 7626 | 7640 | _ = try typeof_scope.addBreak(.break_inline, refToIndex(typeof_inst).?, .void_value); |
| ... | ... | @@ -7636,13 +7650,13 @@ fn typeOf( |
| 7636 | 7650 | astgen.appendBodyWithFixups(body); |
| 7637 | 7651 | typeof_scope.unstack(); |
| 7638 | 7652 | |
| 7639 | | return rvalue(gz, rl, typeof_inst, node); |
| 7653 | return rvalue(gz, ri, typeof_inst, node); |
| 7640 | 7654 | } |
| 7641 | 7655 | |
| 7642 | 7656 | fn builtinCall( |
| 7643 | 7657 | gz: *GenZir, |
| 7644 | 7658 | scope: *Scope, |
| 7645 | | rl: ResultLoc, |
| 7659 | ri: ResultInfo, |
| 7646 | 7660 | node: Ast.Node.Index, |
| 7647 | 7661 | params: []const Ast.Node.Index, |
| 7648 | 7662 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -7694,7 +7708,7 @@ fn builtinCall( |
| 7694 | 7708 | if (!gop.found_existing) { |
| 7695 | 7709 | gop.value_ptr.* = str_lit_token; |
| 7696 | 7710 | } |
| 7697 | | return rvalue(gz, rl, result, node); |
| 7711 | return rvalue(gz, ri, result, node); |
| 7698 | 7712 | }, |
| 7699 | 7713 | .compile_log => { |
| 7700 | 7714 | const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{ |
| ... | ... | @@ -7702,32 +7716,32 @@ fn builtinCall( |
| 7702 | 7716 | }); |
| 7703 | 7717 | var extra_index = try reserveExtra(gz.astgen, params.len); |
| 7704 | 7718 | for (params) |param| { |
| 7705 | | const param_ref = try expr(gz, scope, .none, param); |
| 7719 | const param_ref = try expr(gz, scope, .{ .rl = .none }, param); |
| 7706 | 7720 | astgen.extra.items[extra_index] = @enumToInt(param_ref); |
| 7707 | 7721 | extra_index += 1; |
| 7708 | 7722 | } |
| 7709 | 7723 | const result = try gz.addExtendedMultiOpPayloadIndex(.compile_log, payload_index, params.len); |
| 7710 | | return rvalue(gz, rl, result, node); |
| 7724 | return rvalue(gz, ri, result, node); |
| 7711 | 7725 | }, |
| 7712 | 7726 | .field => { |
| 7713 | | if (rl == .ref or rl == .catch_ref) { |
| 7727 | if (ri.rl == .ref) { |
| 7714 | 7728 | return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{ |
| 7715 | | .lhs = try expr(gz, scope, .ref, params[0]), |
| 7716 | | .field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]), |
| 7729 | .lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]), |
| 7730 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]), |
| 7717 | 7731 | }); |
| 7718 | 7732 | } |
| 7719 | 7733 | const result = try gz.addPlNode(.field_val_named, node, Zir.Inst.FieldNamed{ |
| 7720 | | .lhs = try expr(gz, scope, .none, params[0]), |
| 7721 | | .field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]), |
| 7734 | .lhs = try expr(gz, scope, .{ .rl = .none }, params[0]), |
| 7735 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]), |
| 7722 | 7736 | }); |
| 7723 | | return rvalue(gz, rl, result, node); |
| 7737 | return rvalue(gz, ri, result, node); |
| 7724 | 7738 | }, |
| 7725 | 7739 | |
| 7726 | 7740 | // zig fmt: off |
| 7727 | | .as => return as( gz, scope, rl, node, params[0], params[1]), |
| 7728 | | .bit_cast => return bitCast( gz, scope, rl, node, params[0], params[1]), |
| 7729 | | .TypeOf => return typeOf( gz, scope, rl, node, params), |
| 7730 | | .union_init => return unionInit(gz, scope, rl, node, params), |
| 7741 | .as => return as( gz, scope, ri, node, params[0], params[1]), |
| 7742 | .bit_cast => return bitCast( gz, scope, ri, node, params[0], params[1]), |
| 7743 | .TypeOf => return typeOf( gz, scope, ri, node, params), |
| 7744 | .union_init => return unionInit(gz, scope, ri, node, params), |
| 7731 | 7745 | .c_import => return cImport( gz, scope, node, params[0]), |
| 7732 | 7746 | // zig fmt: on |
| 7733 | 7747 | |
| ... | ... | @@ -7752,9 +7766,9 @@ fn builtinCall( |
| 7752 | 7766 | local_val.used = ident_token; |
| 7753 | 7767 | _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ |
| 7754 | 7768 | .operand = local_val.inst, |
| 7755 | | .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]), |
| 7769 | .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]), |
| 7756 | 7770 | }); |
| 7757 | | return rvalue(gz, rl, .void_value, node); |
| 7771 | return rvalue(gz, ri, .void_value, node); |
| 7758 | 7772 | } |
| 7759 | 7773 | s = local_val.parent; |
| 7760 | 7774 | }, |
| ... | ... | @@ -7767,9 +7781,9 @@ fn builtinCall( |
| 7767 | 7781 | const loaded = try gz.addUnNode(.load, local_ptr.ptr, node); |
| 7768 | 7782 | _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ |
| 7769 | 7783 | .operand = loaded, |
| 7770 | | .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]), |
| 7784 | .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]), |
| 7771 | 7785 | }); |
| 7772 | | return rvalue(gz, rl, .void_value, node); |
| 7786 | return rvalue(gz, ri, .void_value, node); |
| 7773 | 7787 | } |
| 7774 | 7788 | s = local_ptr.parent; |
| 7775 | 7789 | }, |
| ... | ... | @@ -7801,47 +7815,47 @@ fn builtinCall( |
| 7801 | 7815 | }, |
| 7802 | 7816 | else => return astgen.failNode(params[0], "symbol to export must identify a declaration", .{}), |
| 7803 | 7817 | } |
| 7804 | | const options = try comptimeExpr(gz, scope, .{ .ty = .export_options_type }, params[1]); |
| 7818 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .export_options_type } }, params[1]); |
| 7805 | 7819 | _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{ |
| 7806 | 7820 | .namespace = namespace, |
| 7807 | 7821 | .decl_name = decl_name, |
| 7808 | 7822 | .options = options, |
| 7809 | 7823 | }); |
| 7810 | | return rvalue(gz, rl, .void_value, node); |
| 7824 | return rvalue(gz, ri, .void_value, node); |
| 7811 | 7825 | }, |
| 7812 | 7826 | .@"extern" => { |
| 7813 | 7827 | const type_inst = try typeExpr(gz, scope, params[0]); |
| 7814 | | const options = try comptimeExpr(gz, scope, .{ .ty = .extern_options_type }, params[1]); |
| 7828 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .extern_options_type } }, params[1]); |
| 7815 | 7829 | const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{ |
| 7816 | 7830 | .node = gz.nodeIndexToRelative(node), |
| 7817 | 7831 | .lhs = type_inst, |
| 7818 | 7832 | .rhs = options, |
| 7819 | 7833 | }); |
| 7820 | | return rvalue(gz, rl, result, node); |
| 7834 | return rvalue(gz, ri, result, node); |
| 7821 | 7835 | }, |
| 7822 | 7836 | .fence => { |
| 7823 | | const order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[0]); |
| 7837 | const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[0]); |
| 7824 | 7838 | const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{ |
| 7825 | 7839 | .node = gz.nodeIndexToRelative(node), |
| 7826 | 7840 | .operand = order, |
| 7827 | 7841 | }); |
| 7828 | | return rvalue(gz, rl, result, node); |
| 7842 | return rvalue(gz, ri, result, node); |
| 7829 | 7843 | }, |
| 7830 | 7844 | .set_float_mode => { |
| 7831 | | const order = try expr(gz, scope, .{ .coerced_ty = .float_mode_type }, params[0]); |
| 7845 | const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .float_mode_type } }, params[0]); |
| 7832 | 7846 | const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{ |
| 7833 | 7847 | .node = gz.nodeIndexToRelative(node), |
| 7834 | 7848 | .operand = order, |
| 7835 | 7849 | }); |
| 7836 | | return rvalue(gz, rl, result, node); |
| 7850 | return rvalue(gz, ri, result, node); |
| 7837 | 7851 | }, |
| 7838 | 7852 | .set_align_stack => { |
| 7839 | | const order = try expr(gz, scope, align_rl, params[0]); |
| 7853 | const order = try expr(gz, scope, align_ri, params[0]); |
| 7840 | 7854 | const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{ |
| 7841 | 7855 | .node = gz.nodeIndexToRelative(node), |
| 7842 | 7856 | .operand = order, |
| 7843 | 7857 | }); |
| 7844 | | return rvalue(gz, rl, result, node); |
| 7858 | return rvalue(gz, ri, result, node); |
| 7845 | 7859 | }, |
| 7846 | 7860 | |
| 7847 | 7861 | .src => { |
| ... | ... | @@ -7853,62 +7867,62 @@ fn builtinCall( |
| 7853 | 7867 | .line = astgen.source_line, |
| 7854 | 7868 | .column = astgen.source_column, |
| 7855 | 7869 | }); |
| 7856 | | return rvalue(gz, rl, result, node); |
| 7870 | return rvalue(gz, ri, result, node); |
| 7857 | 7871 | }, |
| 7858 | 7872 | |
| 7859 | 7873 | // zig fmt: off |
| 7860 | | .This => return rvalue(gz, rl, try gz.addNodeExtended(.this, node), node), |
| 7861 | | .return_address => return rvalue(gz, rl, try gz.addNodeExtended(.ret_addr, node), node), |
| 7862 | | .error_return_trace => return rvalue(gz, rl, try gz.addNodeExtended(.error_return_trace, node), node), |
| 7863 | | .frame => return rvalue(gz, rl, try gz.addNodeExtended(.frame, node), node), |
| 7864 | | .frame_address => return rvalue(gz, rl, try gz.addNodeExtended(.frame_address, node), node), |
| 7865 | | .breakpoint => return rvalue(gz, rl, try gz.addNodeExtended(.breakpoint, node), node), |
| 7866 | | |
| 7867 | | .type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info), |
| 7868 | | .size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of), |
| 7869 | | .bit_size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .bit_size_of), |
| 7870 | | .align_of => return simpleUnOpType(gz, scope, rl, node, params[0], .align_of), |
| 7871 | | |
| 7872 | | .ptr_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .ptr_to_int), |
| 7873 | | .compile_error => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .compile_error), |
| 7874 | | .set_eval_branch_quota => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .u32_type }, params[0], .set_eval_branch_quota), |
| 7875 | | .enum_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .enum_to_int), |
| 7876 | | .bool_to_int => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .bool_to_int), |
| 7877 | | .embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file), |
| 7878 | | .error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name), |
| 7879 | | .set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold), |
| 7880 | | .set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety), |
| 7881 | | .sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt), |
| 7882 | | .sin => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sin), |
| 7883 | | .cos => return simpleUnOp(gz, scope, rl, node, .none, params[0], .cos), |
| 7884 | | .tan => return simpleUnOp(gz, scope, rl, node, .none, params[0], .tan), |
| 7885 | | .exp => return simpleUnOp(gz, scope, rl, node, .none, params[0], .exp), |
| 7886 | | .exp2 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .exp2), |
| 7887 | | .log => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log), |
| 7888 | | .log2 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log2), |
| 7889 | | .log10 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log10), |
| 7890 | | .fabs => return simpleUnOp(gz, scope, rl, node, .none, params[0], .fabs), |
| 7891 | | .floor => return simpleUnOp(gz, scope, rl, node, .none, params[0], .floor), |
| 7892 | | .ceil => return simpleUnOp(gz, scope, rl, node, .none, params[0], .ceil), |
| 7893 | | .trunc => return simpleUnOp(gz, scope, rl, node, .none, params[0], .trunc), |
| 7894 | | .round => return simpleUnOp(gz, scope, rl, node, .none, params[0], .round), |
| 7895 | | .tag_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .tag_name), |
| 7896 | | .type_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .type_name), |
| 7897 | | .Frame => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_type), |
| 7898 | | .frame_size => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_size), |
| 7899 | | |
| 7900 | | .float_to_int => return typeCast(gz, scope, rl, node, params[0], params[1], .float_to_int), |
| 7901 | | .int_to_float => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_float), |
| 7902 | | .int_to_ptr => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_ptr), |
| 7903 | | .int_to_enum => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_enum), |
| 7904 | | .float_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .float_cast), |
| 7905 | | .int_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .int_cast), |
| 7906 | | .ptr_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .ptr_cast), |
| 7907 | | .truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate), |
| 7874 | .This => return rvalue(gz, ri, try gz.addNodeExtended(.this, node), node), |
| 7875 | .return_address => return rvalue(gz, ri, try gz.addNodeExtended(.ret_addr, node), node), |
| 7876 | .error_return_trace => return rvalue(gz, ri, try gz.addNodeExtended(.error_return_trace, node), node), |
| 7877 | .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node), |
| 7878 | .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node), |
| 7879 | .breakpoint => return rvalue(gz, ri, try gz.addNodeExtended(.breakpoint, node), node), |
| 7880 | |
| 7881 | .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info), |
| 7882 | .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of), |
| 7883 | .bit_size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .bit_size_of), |
| 7884 | .align_of => return simpleUnOpType(gz, scope, ri, node, params[0], .align_of), |
| 7885 | |
| 7886 | .ptr_to_int => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .ptr_to_int), |
| 7887 | .compile_error => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], .compile_error), |
| 7888 | .set_eval_branch_quota => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0], .set_eval_branch_quota), |
| 7889 | .enum_to_int => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .enum_to_int), |
| 7890 | .bool_to_int => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .bool_to_int), |
| 7891 | .embed_file => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], .embed_file), |
| 7892 | .error_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .anyerror_type } }, params[0], .error_name), |
| 7893 | .set_cold => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_cold), |
| 7894 | .set_runtime_safety => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_runtime_safety), |
| 7895 | .sqrt => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sqrt), |
| 7896 | .sin => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sin), |
| 7897 | .cos => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .cos), |
| 7898 | .tan => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tan), |
| 7899 | .exp => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp), |
| 7900 | .exp2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp2), |
| 7901 | .log => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log), |
| 7902 | .log2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log2), |
| 7903 | .log10 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log10), |
| 7904 | .fabs => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .fabs), |
| 7905 | .floor => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .floor), |
| 7906 | .ceil => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .ceil), |
| 7907 | .trunc => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .trunc), |
| 7908 | .round => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .round), |
| 7909 | .tag_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tag_name), |
| 7910 | .type_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .type_name), |
| 7911 | .Frame => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_type), |
| 7912 | .frame_size => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_size), |
| 7913 | |
| 7914 | .float_to_int => return typeCast(gz, scope, ri, node, params[0], params[1], .float_to_int), |
| 7915 | .int_to_float => return typeCast(gz, scope, ri, node, params[0], params[1], .int_to_float), |
| 7916 | .int_to_ptr => return typeCast(gz, scope, ri, node, params[0], params[1], .int_to_ptr), |
| 7917 | .int_to_enum => return typeCast(gz, scope, ri, node, params[0], params[1], .int_to_enum), |
| 7918 | .float_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast), |
| 7919 | .int_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast), |
| 7920 | .ptr_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast), |
| 7921 | .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate), |
| 7908 | 7922 | // zig fmt: on |
| 7909 | 7923 | |
| 7910 | 7924 | .Type => { |
| 7911 | | const operand = try expr(gz, scope, .{ .coerced_ty = .type_info_type }, params[0]); |
| 7925 | const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .type_info_type } }, params[0]); |
| 7912 | 7926 | |
| 7913 | 7927 | const gpa = gz.astgen.gpa; |
| 7914 | 7928 | |
| ... | ... | @@ -7930,219 +7944,219 @@ fn builtinCall( |
| 7930 | 7944 | }); |
| 7931 | 7945 | gz.instructions.appendAssumeCapacity(new_index); |
| 7932 | 7946 | const result = indexToRef(new_index); |
| 7933 | | return rvalue(gz, rl, result, node); |
| 7947 | return rvalue(gz, ri, result, node); |
| 7934 | 7948 | }, |
| 7935 | 7949 | .panic => { |
| 7936 | 7950 | try emitDbgNode(gz, node); |
| 7937 | | return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], if (gz.force_comptime) .panic_comptime else .panic); |
| 7951 | return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], if (gz.force_comptime) .panic_comptime else .panic); |
| 7938 | 7952 | }, |
| 7939 | 7953 | .error_to_int => { |
| 7940 | | const operand = try expr(gz, scope, .none, params[0]); |
| 7954 | const operand = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 7941 | 7955 | const result = try gz.addExtendedPayload(.error_to_int, Zir.Inst.UnNode{ |
| 7942 | 7956 | .node = gz.nodeIndexToRelative(node), |
| 7943 | 7957 | .operand = operand, |
| 7944 | 7958 | }); |
| 7945 | | return rvalue(gz, rl, result, node); |
| 7959 | return rvalue(gz, ri, result, node); |
| 7946 | 7960 | }, |
| 7947 | 7961 | .int_to_error => { |
| 7948 | | const operand = try expr(gz, scope, .{ .coerced_ty = .u16_type }, params[0]); |
| 7962 | const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, params[0]); |
| 7949 | 7963 | const result = try gz.addExtendedPayload(.int_to_error, Zir.Inst.UnNode{ |
| 7950 | 7964 | .node = gz.nodeIndexToRelative(node), |
| 7951 | 7965 | .operand = operand, |
| 7952 | 7966 | }); |
| 7953 | | return rvalue(gz, rl, result, node); |
| 7967 | return rvalue(gz, ri, result, node); |
| 7954 | 7968 | }, |
| 7955 | 7969 | .align_cast => { |
| 7956 | | const dest_align = try comptimeExpr(gz, scope, align_rl, params[0]); |
| 7957 | | const rhs = try expr(gz, scope, .none, params[1]); |
| 7970 | const dest_align = try comptimeExpr(gz, scope, align_ri, params[0]); |
| 7971 | const rhs = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 7958 | 7972 | const result = try gz.addPlNode(.align_cast, node, Zir.Inst.Bin{ |
| 7959 | 7973 | .lhs = dest_align, |
| 7960 | 7974 | .rhs = rhs, |
| 7961 | 7975 | }); |
| 7962 | | return rvalue(gz, rl, result, node); |
| 7976 | return rvalue(gz, ri, result, node); |
| 7963 | 7977 | }, |
| 7964 | 7978 | .err_set_cast => { |
| 7965 | 7979 | const result = try gz.addExtendedPayload(.err_set_cast, Zir.Inst.BinNode{ |
| 7966 | 7980 | .lhs = try typeExpr(gz, scope, params[0]), |
| 7967 | | .rhs = try expr(gz, scope, .none, params[1]), |
| 7981 | .rhs = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 7968 | 7982 | .node = gz.nodeIndexToRelative(node), |
| 7969 | 7983 | }); |
| 7970 | | return rvalue(gz, rl, result, node); |
| 7984 | return rvalue(gz, ri, result, node); |
| 7971 | 7985 | }, |
| 7972 | 7986 | .addrspace_cast => { |
| 7973 | 7987 | const result = try gz.addExtendedPayload(.addrspace_cast, Zir.Inst.BinNode{ |
| 7974 | | .lhs = try comptimeExpr(gz, scope, .{ .ty = .address_space_type }, params[0]), |
| 7975 | | .rhs = try expr(gz, scope, .none, params[1]), |
| 7988 | .lhs = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .address_space_type } }, params[0]), |
| 7989 | .rhs = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 7976 | 7990 | .node = gz.nodeIndexToRelative(node), |
| 7977 | 7991 | }); |
| 7978 | | return rvalue(gz, rl, result, node); |
| 7992 | return rvalue(gz, ri, result, node); |
| 7979 | 7993 | }, |
| 7980 | 7994 | |
| 7981 | 7995 | // zig fmt: off |
| 7982 | | .has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl), |
| 7983 | | .has_field => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_field), |
| 7996 | .has_decl => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_decl), |
| 7997 | .has_field => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_field), |
| 7984 | 7998 | |
| 7985 | | .clz => return bitBuiltin(gz, scope, rl, node, params[0], .clz), |
| 7986 | | .ctz => return bitBuiltin(gz, scope, rl, node, params[0], .ctz), |
| 7987 | | .pop_count => return bitBuiltin(gz, scope, rl, node, params[0], .pop_count), |
| 7988 | | .byte_swap => return bitBuiltin(gz, scope, rl, node, params[0], .byte_swap), |
| 7989 | | .bit_reverse => return bitBuiltin(gz, scope, rl, node, params[0], .bit_reverse), |
| 7999 | .clz => return bitBuiltin(gz, scope, ri, node, params[0], .clz), |
| 8000 | .ctz => return bitBuiltin(gz, scope, ri, node, params[0], .ctz), |
| 8001 | .pop_count => return bitBuiltin(gz, scope, ri, node, params[0], .pop_count), |
| 8002 | .byte_swap => return bitBuiltin(gz, scope, ri, node, params[0], .byte_swap), |
| 8003 | .bit_reverse => return bitBuiltin(gz, scope, ri, node, params[0], .bit_reverse), |
| 7990 | 8004 | |
| 7991 | | .div_exact => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_exact), |
| 7992 | | .div_floor => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_floor), |
| 7993 | | .div_trunc => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_trunc), |
| 7994 | | .mod => return divBuiltin(gz, scope, rl, node, params[0], params[1], .mod), |
| 7995 | | .rem => return divBuiltin(gz, scope, rl, node, params[0], params[1], .rem), |
| 8005 | .div_exact => return divBuiltin(gz, scope, ri, node, params[0], params[1], .div_exact), |
| 8006 | .div_floor => return divBuiltin(gz, scope, ri, node, params[0], params[1], .div_floor), |
| 8007 | .div_trunc => return divBuiltin(gz, scope, ri, node, params[0], params[1], .div_trunc), |
| 8008 | .mod => return divBuiltin(gz, scope, ri, node, params[0], params[1], .mod), |
| 8009 | .rem => return divBuiltin(gz, scope, ri, node, params[0], params[1], .rem), |
| 7996 | 8010 | |
| 7997 | | .shl_exact => return shiftOp(gz, scope, rl, node, params[0], params[1], .shl_exact), |
| 7998 | | .shr_exact => return shiftOp(gz, scope, rl, node, params[0], params[1], .shr_exact), |
| 8011 | .shl_exact => return shiftOp(gz, scope, ri, node, params[0], params[1], .shl_exact), |
| 8012 | .shr_exact => return shiftOp(gz, scope, ri, node, params[0], params[1], .shr_exact), |
| 7999 | 8013 | |
| 8000 | | .bit_offset_of => return offsetOf(gz, scope, rl, node, params[0], params[1], .bit_offset_of), |
| 8001 | | .offset_of => return offsetOf(gz, scope, rl, node, params[0], params[1], .offset_of), |
| 8014 | .bit_offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .bit_offset_of), |
| 8015 | .offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .offset_of), |
| 8002 | 8016 | |
| 8003 | | .c_undef => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_undef), |
| 8004 | | .c_include => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_include), |
| 8017 | .c_undef => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_undef), |
| 8018 | .c_include => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_include), |
| 8005 | 8019 | |
| 8006 | | .cmpxchg_strong => return cmpxchg(gz, scope, rl, node, params, 1), |
| 8007 | | .cmpxchg_weak => return cmpxchg(gz, scope, rl, node, params, 0), |
| 8020 | .cmpxchg_strong => return cmpxchg(gz, scope, ri, node, params, 1), |
| 8021 | .cmpxchg_weak => return cmpxchg(gz, scope, ri, node, params, 0), |
| 8008 | 8022 | // zig fmt: on |
| 8009 | 8023 | |
| 8010 | 8024 | .wasm_memory_size => { |
| 8011 | | const operand = try comptimeExpr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]); |
| 8025 | const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); |
| 8012 | 8026 | const result = try gz.addExtendedPayload(.wasm_memory_size, Zir.Inst.UnNode{ |
| 8013 | 8027 | .node = gz.nodeIndexToRelative(node), |
| 8014 | 8028 | .operand = operand, |
| 8015 | 8029 | }); |
| 8016 | | return rvalue(gz, rl, result, node); |
| 8030 | return rvalue(gz, ri, result, node); |
| 8017 | 8031 | }, |
| 8018 | 8032 | .wasm_memory_grow => { |
| 8019 | | const index_arg = try comptimeExpr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]); |
| 8020 | | const delta_arg = try expr(gz, scope, .{ .coerced_ty = .u32_type }, params[1]); |
| 8033 | const index_arg = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); |
| 8034 | const delta_arg = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[1]); |
| 8021 | 8035 | const result = try gz.addExtendedPayload(.wasm_memory_grow, Zir.Inst.BinNode{ |
| 8022 | 8036 | .node = gz.nodeIndexToRelative(node), |
| 8023 | 8037 | .lhs = index_arg, |
| 8024 | 8038 | .rhs = delta_arg, |
| 8025 | 8039 | }); |
| 8026 | | return rvalue(gz, rl, result, node); |
| 8040 | return rvalue(gz, ri, result, node); |
| 8027 | 8041 | }, |
| 8028 | 8042 | .c_define => { |
| 8029 | 8043 | if (!gz.c_import) return gz.astgen.failNode(node, "C define valid only inside C import block", .{}); |
| 8030 | | const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[0]); |
| 8031 | | const value = try comptimeExpr(gz, scope, .none, params[1]); |
| 8044 | const name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0]); |
| 8045 | const value = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]); |
| 8032 | 8046 | const result = try gz.addExtendedPayload(.c_define, Zir.Inst.BinNode{ |
| 8033 | 8047 | .node = gz.nodeIndexToRelative(node), |
| 8034 | 8048 | .lhs = name, |
| 8035 | 8049 | .rhs = value, |
| 8036 | 8050 | }); |
| 8037 | | return rvalue(gz, rl, result, node); |
| 8051 | return rvalue(gz, ri, result, node); |
| 8038 | 8052 | }, |
| 8039 | 8053 | |
| 8040 | 8054 | .splat => { |
| 8041 | | const len = try expr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]); |
| 8042 | | const scalar = try expr(gz, scope, .none, params[1]); |
| 8055 | const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); |
| 8056 | const scalar = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 8043 | 8057 | const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{ |
| 8044 | 8058 | .lhs = len, |
| 8045 | 8059 | .rhs = scalar, |
| 8046 | 8060 | }); |
| 8047 | | return rvalue(gz, rl, result, node); |
| 8061 | return rvalue(gz, ri, result, node); |
| 8048 | 8062 | }, |
| 8049 | 8063 | .reduce => { |
| 8050 | | const op = try expr(gz, scope, .{ .ty = .reduce_op_type }, params[0]); |
| 8051 | | const scalar = try expr(gz, scope, .none, params[1]); |
| 8064 | const op = try expr(gz, scope, .{ .rl = .{ .ty = .reduce_op_type } }, params[0]); |
| 8065 | const scalar = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 8052 | 8066 | const result = try gz.addPlNode(.reduce, node, Zir.Inst.Bin{ |
| 8053 | 8067 | .lhs = op, |
| 8054 | 8068 | .rhs = scalar, |
| 8055 | 8069 | }); |
| 8056 | | return rvalue(gz, rl, result, node); |
| 8070 | return rvalue(gz, ri, result, node); |
| 8057 | 8071 | }, |
| 8058 | 8072 | |
| 8059 | 8073 | .max => { |
| 8060 | | const a = try expr(gz, scope, .none, params[0]); |
| 8061 | | const b = try expr(gz, scope, .none, params[1]); |
| 8074 | const a = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 8075 | const b = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 8062 | 8076 | const result = try gz.addPlNode(.max, node, Zir.Inst.Bin{ |
| 8063 | 8077 | .lhs = a, |
| 8064 | 8078 | .rhs = b, |
| 8065 | 8079 | }); |
| 8066 | | return rvalue(gz, rl, result, node); |
| 8080 | return rvalue(gz, ri, result, node); |
| 8067 | 8081 | }, |
| 8068 | 8082 | .min => { |
| 8069 | | const a = try expr(gz, scope, .none, params[0]); |
| 8070 | | const b = try expr(gz, scope, .none, params[1]); |
| 8083 | const a = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 8084 | const b = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 8071 | 8085 | const result = try gz.addPlNode(.min, node, Zir.Inst.Bin{ |
| 8072 | 8086 | .lhs = a, |
| 8073 | 8087 | .rhs = b, |
| 8074 | 8088 | }); |
| 8075 | | return rvalue(gz, rl, result, node); |
| 8089 | return rvalue(gz, ri, result, node); |
| 8076 | 8090 | }, |
| 8077 | 8091 | |
| 8078 | | .add_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .add_with_overflow), |
| 8079 | | .sub_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .sub_with_overflow), |
| 8080 | | .mul_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .mul_with_overflow), |
| 8092 | .add_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .add_with_overflow), |
| 8093 | .sub_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .sub_with_overflow), |
| 8094 | .mul_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .mul_with_overflow), |
| 8081 | 8095 | .shl_with_overflow => { |
| 8082 | 8096 | const int_type = try typeExpr(gz, scope, params[0]); |
| 8083 | 8097 | const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]); |
| 8084 | 8098 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); |
| 8085 | | const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]); |
| 8086 | | const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]); |
| 8087 | | const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]); |
| 8099 | const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]); |
| 8100 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type } }, params[2]); |
| 8101 | const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]); |
| 8088 | 8102 | const result = try gz.addExtendedPayload(.shl_with_overflow, Zir.Inst.OverflowArithmetic{ |
| 8089 | 8103 | .node = gz.nodeIndexToRelative(node), |
| 8090 | 8104 | .lhs = lhs, |
| 8091 | 8105 | .rhs = rhs, |
| 8092 | 8106 | .ptr = ptr, |
| 8093 | 8107 | }); |
| 8094 | | return rvalue(gz, rl, result, node); |
| 8108 | return rvalue(gz, ri, result, node); |
| 8095 | 8109 | }, |
| 8096 | 8110 | |
| 8097 | 8111 | .atomic_load => { |
| 8098 | 8112 | const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.AtomicLoad{ |
| 8099 | 8113 | // zig fmt: off |
| 8100 | | .elem_type = try typeExpr(gz, scope, params[0]), |
| 8101 | | .ptr = try expr (gz, scope, .none, params[1]), |
| 8102 | | .ordering = try expr (gz, scope, .{ .coerced_ty = .atomic_order_type }, params[2]), |
| 8114 | .elem_type = try typeExpr(gz, scope, params[0]), |
| 8115 | .ptr = try expr (gz, scope, .{ .rl = .none }, params[1]), |
| 8116 | .ordering = try expr (gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[2]), |
| 8103 | 8117 | // zig fmt: on |
| 8104 | 8118 | }); |
| 8105 | | return rvalue(gz, rl, result, node); |
| 8119 | return rvalue(gz, ri, result, node); |
| 8106 | 8120 | }, |
| 8107 | 8121 | .atomic_rmw => { |
| 8108 | 8122 | const int_type = try typeExpr(gz, scope, params[0]); |
| 8109 | 8123 | const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{ |
| 8110 | 8124 | // zig fmt: off |
| 8111 | | .ptr = try expr(gz, scope, .none, params[1]), |
| 8112 | | .operation = try expr(gz, scope, .{ .coerced_ty = .atomic_rmw_op_type }, params[2]), |
| 8113 | | .operand = try expr(gz, scope, .{ .ty = int_type }, params[3]), |
| 8114 | | .ordering = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[4]), |
| 8125 | .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8126 | .operation = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_rmw_op_type } }, params[2]), |
| 8127 | .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[3]), |
| 8128 | .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[4]), |
| 8115 | 8129 | // zig fmt: on |
| 8116 | 8130 | }); |
| 8117 | | return rvalue(gz, rl, result, node); |
| 8131 | return rvalue(gz, ri, result, node); |
| 8118 | 8132 | }, |
| 8119 | 8133 | .atomic_store => { |
| 8120 | 8134 | const int_type = try typeExpr(gz, scope, params[0]); |
| 8121 | 8135 | const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{ |
| 8122 | 8136 | // zig fmt: off |
| 8123 | | .ptr = try expr(gz, scope, .none, params[1]), |
| 8124 | | .operand = try expr(gz, scope, .{ .ty = int_type }, params[2]), |
| 8125 | | .ordering = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[3]), |
| 8137 | .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8138 | .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), |
| 8139 | .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[3]), |
| 8126 | 8140 | // zig fmt: on |
| 8127 | 8141 | }); |
| 8128 | | return rvalue(gz, rl, result, node); |
| 8142 | return rvalue(gz, ri, result, node); |
| 8129 | 8143 | }, |
| 8130 | 8144 | .mul_add => { |
| 8131 | 8145 | const float_type = try typeExpr(gz, scope, params[0]); |
| 8132 | | const mulend1 = try expr(gz, scope, .{ .coerced_ty = float_type }, params[1]); |
| 8133 | | const mulend2 = try expr(gz, scope, .{ .coerced_ty = float_type }, params[2]); |
| 8134 | | const addend = try expr(gz, scope, .{ .ty = float_type }, params[3]); |
| 8146 | const mulend1 = try expr(gz, scope, .{ .rl = .{ .coerced_ty = float_type } }, params[1]); |
| 8147 | const mulend2 = try expr(gz, scope, .{ .rl = .{ .coerced_ty = float_type } }, params[2]); |
| 8148 | const addend = try expr(gz, scope, .{ .rl = .{ .ty = float_type } }, params[3]); |
| 8135 | 8149 | const result = try gz.addPlNode(.mul_add, node, Zir.Inst.MulAdd{ |
| 8136 | 8150 | .mulend1 = mulend1, |
| 8137 | 8151 | .mulend2 = mulend2, |
| 8138 | 8152 | .addend = addend, |
| 8139 | 8153 | }); |
| 8140 | | return rvalue(gz, rl, result, node); |
| 8154 | return rvalue(gz, ri, result, node); |
| 8141 | 8155 | }, |
| 8142 | 8156 | .call => { |
| 8143 | | const options = try comptimeExpr(gz, scope, .{ .ty = .call_options_type }, params[0]); |
| 8157 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .call_options_type } }, params[0]); |
| 8144 | 8158 | const callee = try calleeExpr(gz, scope, params[1]); |
| 8145 | | const args = try expr(gz, scope, .none, params[2]); |
| 8159 | const args = try expr(gz, scope, .{ .rl = .none }, params[2]); |
| 8146 | 8160 | const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{ |
| 8147 | 8161 | .options = options, |
| 8148 | 8162 | .callee = callee, |
| ... | ... | @@ -8153,115 +8167,115 @@ fn builtinCall( |
| 8153 | 8167 | .ensure_result_used = false, |
| 8154 | 8168 | }, |
| 8155 | 8169 | }); |
| 8156 | | return rvalue(gz, rl, result, node); |
| 8170 | return rvalue(gz, ri, result, node); |
| 8157 | 8171 | }, |
| 8158 | 8172 | .field_parent_ptr => { |
| 8159 | 8173 | const parent_type = try typeExpr(gz, scope, params[0]); |
| 8160 | | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); |
| 8174 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]); |
| 8161 | 8175 | const result = try gz.addPlNode(.field_parent_ptr, node, Zir.Inst.FieldParentPtr{ |
| 8162 | 8176 | .parent_type = parent_type, |
| 8163 | 8177 | .field_name = field_name, |
| 8164 | | .field_ptr = try expr(gz, scope, .none, params[2]), |
| 8178 | .field_ptr = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 8165 | 8179 | }); |
| 8166 | | return rvalue(gz, rl, result, node); |
| 8180 | return rvalue(gz, ri, result, node); |
| 8167 | 8181 | }, |
| 8168 | 8182 | .memcpy => { |
| 8169 | 8183 | const result = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{ |
| 8170 | | .dest = try expr(gz, scope, .{ .coerced_ty = .manyptr_u8_type }, params[0]), |
| 8171 | | .source = try expr(gz, scope, .{ .coerced_ty = .manyptr_const_u8_type }, params[1]), |
| 8172 | | .byte_count = try expr(gz, scope, .{ .coerced_ty = .usize_type }, params[2]), |
| 8184 | .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), |
| 8185 | .source = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_const_u8_type } }, params[1]), |
| 8186 | .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), |
| 8173 | 8187 | }); |
| 8174 | | return rvalue(gz, rl, result, node); |
| 8188 | return rvalue(gz, ri, result, node); |
| 8175 | 8189 | }, |
| 8176 | 8190 | .memset => { |
| 8177 | 8191 | const result = try gz.addPlNode(.memset, node, Zir.Inst.Memset{ |
| 8178 | | .dest = try expr(gz, scope, .{ .coerced_ty = .manyptr_u8_type }, params[0]), |
| 8179 | | .byte = try expr(gz, scope, .{ .coerced_ty = .u8_type }, params[1]), |
| 8180 | | .byte_count = try expr(gz, scope, .{ .coerced_ty = .usize_type }, params[2]), |
| 8192 | .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), |
| 8193 | .byte = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u8_type } }, params[1]), |
| 8194 | .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), |
| 8181 | 8195 | }); |
| 8182 | | return rvalue(gz, rl, result, node); |
| 8196 | return rvalue(gz, ri, result, node); |
| 8183 | 8197 | }, |
| 8184 | 8198 | .shuffle => { |
| 8185 | 8199 | const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{ |
| 8186 | 8200 | .elem_type = try typeExpr(gz, scope, params[0]), |
| 8187 | | .a = try expr(gz, scope, .none, params[1]), |
| 8188 | | .b = try expr(gz, scope, .none, params[2]), |
| 8189 | | .mask = try comptimeExpr(gz, scope, .none, params[3]), |
| 8201 | .a = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8202 | .b = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 8203 | .mask = try comptimeExpr(gz, scope, .{ .rl = .none }, params[3]), |
| 8190 | 8204 | }); |
| 8191 | | return rvalue(gz, rl, result, node); |
| 8205 | return rvalue(gz, ri, result, node); |
| 8192 | 8206 | }, |
| 8193 | 8207 | .select => { |
| 8194 | 8208 | const result = try gz.addExtendedPayload(.select, Zir.Inst.Select{ |
| 8195 | 8209 | .node = gz.nodeIndexToRelative(node), |
| 8196 | 8210 | .elem_type = try typeExpr(gz, scope, params[0]), |
| 8197 | | .pred = try expr(gz, scope, .none, params[1]), |
| 8198 | | .a = try expr(gz, scope, .none, params[2]), |
| 8199 | | .b = try expr(gz, scope, .none, params[3]), |
| 8211 | .pred = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8212 | .a = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 8213 | .b = try expr(gz, scope, .{ .rl = .none }, params[3]), |
| 8200 | 8214 | }); |
| 8201 | | return rvalue(gz, rl, result, node); |
| 8215 | return rvalue(gz, ri, result, node); |
| 8202 | 8216 | }, |
| 8203 | 8217 | .async_call => { |
| 8204 | 8218 | const result = try gz.addExtendedPayload(.builtin_async_call, Zir.Inst.AsyncCall{ |
| 8205 | 8219 | .node = gz.nodeIndexToRelative(node), |
| 8206 | | .frame_buffer = try expr(gz, scope, .none, params[0]), |
| 8207 | | .result_ptr = try expr(gz, scope, .none, params[1]), |
| 8208 | | .fn_ptr = try expr(gz, scope, .none, params[2]), |
| 8209 | | .args = try expr(gz, scope, .none, params[3]), |
| 8220 | .frame_buffer = try expr(gz, scope, .{ .rl = .none }, params[0]), |
| 8221 | .result_ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8222 | .fn_ptr = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 8223 | .args = try expr(gz, scope, .{ .rl = .none }, params[3]), |
| 8210 | 8224 | }); |
| 8211 | | return rvalue(gz, rl, result, node); |
| 8225 | return rvalue(gz, ri, result, node); |
| 8212 | 8226 | }, |
| 8213 | 8227 | .Vector => { |
| 8214 | 8228 | const result = try gz.addPlNode(.vector_type, node, Zir.Inst.Bin{ |
| 8215 | | .lhs = try comptimeExpr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]), |
| 8229 | .lhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]), |
| 8216 | 8230 | .rhs = try typeExpr(gz, scope, params[1]), |
| 8217 | 8231 | }); |
| 8218 | | return rvalue(gz, rl, result, node); |
| 8232 | return rvalue(gz, ri, result, node); |
| 8219 | 8233 | }, |
| 8220 | 8234 | .prefetch => { |
| 8221 | | const ptr = try expr(gz, scope, .none, params[0]); |
| 8222 | | const options = try comptimeExpr(gz, scope, .{ .ty = .prefetch_options_type }, params[1]); |
| 8235 | const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 8236 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .prefetch_options_type } }, params[1]); |
| 8223 | 8237 | const result = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{ |
| 8224 | 8238 | .node = gz.nodeIndexToRelative(node), |
| 8225 | 8239 | .lhs = ptr, |
| 8226 | 8240 | .rhs = options, |
| 8227 | 8241 | }); |
| 8228 | | return rvalue(gz, rl, result, node); |
| 8242 | return rvalue(gz, ri, result, node); |
| 8229 | 8243 | }, |
| 8230 | 8244 | } |
| 8231 | 8245 | } |
| 8232 | 8246 | |
| 8233 | 8247 | fn simpleNoOpVoid( |
| 8234 | 8248 | gz: *GenZir, |
| 8235 | | rl: ResultLoc, |
| 8249 | ri: ResultInfo, |
| 8236 | 8250 | node: Ast.Node.Index, |
| 8237 | 8251 | tag: Zir.Inst.Tag, |
| 8238 | 8252 | ) InnerError!Zir.Inst.Ref { |
| 8239 | 8253 | _ = try gz.addNode(tag, node); |
| 8240 | | return rvalue(gz, rl, .void_value, node); |
| 8254 | return rvalue(gz, ri, .void_value, node); |
| 8241 | 8255 | } |
| 8242 | 8256 | |
| 8243 | 8257 | fn hasDeclOrField( |
| 8244 | 8258 | gz: *GenZir, |
| 8245 | 8259 | scope: *Scope, |
| 8246 | | rl: ResultLoc, |
| 8260 | ri: ResultInfo, |
| 8247 | 8261 | node: Ast.Node.Index, |
| 8248 | 8262 | lhs_node: Ast.Node.Index, |
| 8249 | 8263 | rhs_node: Ast.Node.Index, |
| 8250 | 8264 | tag: Zir.Inst.Tag, |
| 8251 | 8265 | ) InnerError!Zir.Inst.Ref { |
| 8252 | 8266 | const container_type = try typeExpr(gz, scope, lhs_node); |
| 8253 | | const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, rhs_node); |
| 8267 | const name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, rhs_node); |
| 8254 | 8268 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8255 | 8269 | .lhs = container_type, |
| 8256 | 8270 | .rhs = name, |
| 8257 | 8271 | }); |
| 8258 | | return rvalue(gz, rl, result, node); |
| 8272 | return rvalue(gz, ri, result, node); |
| 8259 | 8273 | } |
| 8260 | 8274 | |
| 8261 | 8275 | fn typeCast( |
| 8262 | 8276 | gz: *GenZir, |
| 8263 | 8277 | scope: *Scope, |
| 8264 | | rl: ResultLoc, |
| 8278 | ri: ResultInfo, |
| 8265 | 8279 | node: Ast.Node.Index, |
| 8266 | 8280 | lhs_node: Ast.Node.Index, |
| 8267 | 8281 | rhs_node: Ast.Node.Index, |
| ... | ... | @@ -8269,42 +8283,42 @@ fn typeCast( |
| 8269 | 8283 | ) InnerError!Zir.Inst.Ref { |
| 8270 | 8284 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8271 | 8285 | .lhs = try typeExpr(gz, scope, lhs_node), |
| 8272 | | .rhs = try expr(gz, scope, .none, rhs_node), |
| 8286 | .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node), |
| 8273 | 8287 | }); |
| 8274 | | return rvalue(gz, rl, result, node); |
| 8288 | return rvalue(gz, ri, result, node); |
| 8275 | 8289 | } |
| 8276 | 8290 | |
| 8277 | 8291 | fn simpleUnOpType( |
| 8278 | 8292 | gz: *GenZir, |
| 8279 | 8293 | scope: *Scope, |
| 8280 | | rl: ResultLoc, |
| 8294 | ri: ResultInfo, |
| 8281 | 8295 | node: Ast.Node.Index, |
| 8282 | 8296 | operand_node: Ast.Node.Index, |
| 8283 | 8297 | tag: Zir.Inst.Tag, |
| 8284 | 8298 | ) InnerError!Zir.Inst.Ref { |
| 8285 | 8299 | const operand = try typeExpr(gz, scope, operand_node); |
| 8286 | 8300 | const result = try gz.addUnNode(tag, operand, node); |
| 8287 | | return rvalue(gz, rl, result, node); |
| 8301 | return rvalue(gz, ri, result, node); |
| 8288 | 8302 | } |
| 8289 | 8303 | |
| 8290 | 8304 | fn simpleUnOp( |
| 8291 | 8305 | gz: *GenZir, |
| 8292 | 8306 | scope: *Scope, |
| 8293 | | rl: ResultLoc, |
| 8307 | ri: ResultInfo, |
| 8294 | 8308 | node: Ast.Node.Index, |
| 8295 | | operand_rl: ResultLoc, |
| 8309 | operand_ri: ResultInfo, |
| 8296 | 8310 | operand_node: Ast.Node.Index, |
| 8297 | 8311 | tag: Zir.Inst.Tag, |
| 8298 | 8312 | ) InnerError!Zir.Inst.Ref { |
| 8299 | | const operand = try expr(gz, scope, operand_rl, operand_node); |
| 8313 | const operand = try expr(gz, scope, operand_ri, operand_node); |
| 8300 | 8314 | const result = try gz.addUnNode(tag, operand, node); |
| 8301 | | return rvalue(gz, rl, result, node); |
| 8315 | return rvalue(gz, ri, result, node); |
| 8302 | 8316 | } |
| 8303 | 8317 | |
| 8304 | 8318 | fn negation( |
| 8305 | 8319 | gz: *GenZir, |
| 8306 | 8320 | scope: *Scope, |
| 8307 | | rl: ResultLoc, |
| 8321 | ri: ResultInfo, |
| 8308 | 8322 | node: Ast.Node.Index, |
| 8309 | 8323 | ) InnerError!Zir.Inst.Ref { |
| 8310 | 8324 | const astgen = gz.astgen; |
| ... | ... | @@ -8316,18 +8330,18 @@ fn negation( |
| 8316 | 8330 | // its negativity rather than having it go through comptime subtraction. |
| 8317 | 8331 | const operand_node = node_datas[node].lhs; |
| 8318 | 8332 | if (node_tags[operand_node] == .number_literal) { |
| 8319 | | return numberLiteral(gz, rl, operand_node, node, .negative); |
| 8333 | return numberLiteral(gz, ri, operand_node, node, .negative); |
| 8320 | 8334 | } |
| 8321 | 8335 | |
| 8322 | | const operand = try expr(gz, scope, .none, operand_node); |
| 8336 | const operand = try expr(gz, scope, .{ .rl = .none }, operand_node); |
| 8323 | 8337 | const result = try gz.addUnNode(.negate, operand, node); |
| 8324 | | return rvalue(gz, rl, result, node); |
| 8338 | return rvalue(gz, ri, result, node); |
| 8325 | 8339 | } |
| 8326 | 8340 | |
| 8327 | 8341 | fn cmpxchg( |
| 8328 | 8342 | gz: *GenZir, |
| 8329 | 8343 | scope: *Scope, |
| 8330 | | rl: ResultLoc, |
| 8344 | ri: ResultInfo, |
| 8331 | 8345 | node: Ast.Node.Index, |
| 8332 | 8346 | params: []const Ast.Node.Index, |
| 8333 | 8347 | small: u16, |
| ... | ... | @@ -8336,98 +8350,98 @@ fn cmpxchg( |
| 8336 | 8350 | const result = try gz.addExtendedPayloadSmall(.cmpxchg, small, Zir.Inst.Cmpxchg{ |
| 8337 | 8351 | // zig fmt: off |
| 8338 | 8352 | .node = gz.nodeIndexToRelative(node), |
| 8339 | | .ptr = try expr(gz, scope, .none, params[1]), |
| 8340 | | .expected_value = try expr(gz, scope, .{ .ty = int_type }, params[2]), |
| 8341 | | .new_value = try expr(gz, scope, .{ .coerced_ty = int_type }, params[3]), |
| 8342 | | .success_order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[4]), |
| 8343 | | .failure_order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[5]), |
| 8353 | .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8354 | .expected_value = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), |
| 8355 | .new_value = try expr(gz, scope, .{ .rl = .{ .coerced_ty = int_type } }, params[3]), |
| 8356 | .success_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[4]), |
| 8357 | .failure_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[5]), |
| 8344 | 8358 | // zig fmt: on |
| 8345 | 8359 | }); |
| 8346 | | return rvalue(gz, rl, result, node); |
| 8360 | return rvalue(gz, ri, result, node); |
| 8347 | 8361 | } |
| 8348 | 8362 | |
| 8349 | 8363 | fn bitBuiltin( |
| 8350 | 8364 | gz: *GenZir, |
| 8351 | 8365 | scope: *Scope, |
| 8352 | | rl: ResultLoc, |
| 8366 | ri: ResultInfo, |
| 8353 | 8367 | node: Ast.Node.Index, |
| 8354 | 8368 | operand_node: Ast.Node.Index, |
| 8355 | 8369 | tag: Zir.Inst.Tag, |
| 8356 | 8370 | ) InnerError!Zir.Inst.Ref { |
| 8357 | | const operand = try expr(gz, scope, .none, operand_node); |
| 8371 | const operand = try expr(gz, scope, .{ .rl = .none }, operand_node); |
| 8358 | 8372 | const result = try gz.addUnNode(tag, operand, node); |
| 8359 | | return rvalue(gz, rl, result, node); |
| 8373 | return rvalue(gz, ri, result, node); |
| 8360 | 8374 | } |
| 8361 | 8375 | |
| 8362 | 8376 | fn divBuiltin( |
| 8363 | 8377 | gz: *GenZir, |
| 8364 | 8378 | scope: *Scope, |
| 8365 | | rl: ResultLoc, |
| 8379 | ri: ResultInfo, |
| 8366 | 8380 | node: Ast.Node.Index, |
| 8367 | 8381 | lhs_node: Ast.Node.Index, |
| 8368 | 8382 | rhs_node: Ast.Node.Index, |
| 8369 | 8383 | tag: Zir.Inst.Tag, |
| 8370 | 8384 | ) InnerError!Zir.Inst.Ref { |
| 8371 | 8385 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8372 | | .lhs = try expr(gz, scope, .none, lhs_node), |
| 8373 | | .rhs = try expr(gz, scope, .none, rhs_node), |
| 8386 | .lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node), |
| 8387 | .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node), |
| 8374 | 8388 | }); |
| 8375 | | return rvalue(gz, rl, result, node); |
| 8389 | return rvalue(gz, ri, result, node); |
| 8376 | 8390 | } |
| 8377 | 8391 | |
| 8378 | 8392 | fn simpleCBuiltin( |
| 8379 | 8393 | gz: *GenZir, |
| 8380 | 8394 | scope: *Scope, |
| 8381 | | rl: ResultLoc, |
| 8395 | ri: ResultInfo, |
| 8382 | 8396 | node: Ast.Node.Index, |
| 8383 | 8397 | operand_node: Ast.Node.Index, |
| 8384 | 8398 | tag: Zir.Inst.Extended, |
| 8385 | 8399 | ) InnerError!Zir.Inst.Ref { |
| 8386 | 8400 | const name: []const u8 = if (tag == .c_undef) "C undef" else "C include"; |
| 8387 | 8401 | if (!gz.c_import) return gz.astgen.failNode(node, "{s} valid only inside C import block", .{name}); |
| 8388 | | const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node); |
| 8402 | const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, operand_node); |
| 8389 | 8403 | _ = try gz.addExtendedPayload(tag, Zir.Inst.UnNode{ |
| 8390 | 8404 | .node = gz.nodeIndexToRelative(node), |
| 8391 | 8405 | .operand = operand, |
| 8392 | 8406 | }); |
| 8393 | | return rvalue(gz, rl, .void_value, node); |
| 8407 | return rvalue(gz, ri, .void_value, node); |
| 8394 | 8408 | } |
| 8395 | 8409 | |
| 8396 | 8410 | fn offsetOf( |
| 8397 | 8411 | gz: *GenZir, |
| 8398 | 8412 | scope: *Scope, |
| 8399 | | rl: ResultLoc, |
| 8413 | ri: ResultInfo, |
| 8400 | 8414 | node: Ast.Node.Index, |
| 8401 | 8415 | lhs_node: Ast.Node.Index, |
| 8402 | 8416 | rhs_node: Ast.Node.Index, |
| 8403 | 8417 | tag: Zir.Inst.Tag, |
| 8404 | 8418 | ) InnerError!Zir.Inst.Ref { |
| 8405 | 8419 | const type_inst = try typeExpr(gz, scope, lhs_node); |
| 8406 | | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, rhs_node); |
| 8420 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, rhs_node); |
| 8407 | 8421 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8408 | 8422 | .lhs = type_inst, |
| 8409 | 8423 | .rhs = field_name, |
| 8410 | 8424 | }); |
| 8411 | | return rvalue(gz, rl, result, node); |
| 8425 | return rvalue(gz, ri, result, node); |
| 8412 | 8426 | } |
| 8413 | 8427 | |
| 8414 | 8428 | fn shiftOp( |
| 8415 | 8429 | gz: *GenZir, |
| 8416 | 8430 | scope: *Scope, |
| 8417 | | rl: ResultLoc, |
| 8431 | ri: ResultInfo, |
| 8418 | 8432 | node: Ast.Node.Index, |
| 8419 | 8433 | lhs_node: Ast.Node.Index, |
| 8420 | 8434 | rhs_node: Ast.Node.Index, |
| 8421 | 8435 | tag: Zir.Inst.Tag, |
| 8422 | 8436 | ) InnerError!Zir.Inst.Ref { |
| 8423 | | const lhs = try expr(gz, scope, .none, lhs_node); |
| 8437 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); |
| 8424 | 8438 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); |
| 8425 | | const rhs = try expr(gz, scope, .{ .ty_shift_operand = log2_int_type }, rhs_node); |
| 8439 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node); |
| 8426 | 8440 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8427 | 8441 | .lhs = lhs, |
| 8428 | 8442 | .rhs = rhs, |
| 8429 | 8443 | }); |
| 8430 | | return rvalue(gz, rl, result, node); |
| 8444 | return rvalue(gz, ri, result, node); |
| 8431 | 8445 | } |
| 8432 | 8446 | |
| 8433 | 8447 | fn cImport( |
| ... | ... | @@ -8445,7 +8459,7 @@ fn cImport( |
| 8445 | 8459 | defer block_scope.unstack(); |
| 8446 | 8460 | |
| 8447 | 8461 | const block_inst = try gz.makeBlockInst(.c_import, node); |
| 8448 | | const block_result = try expr(&block_scope, &block_scope.base, .none, body_node); |
| 8462 | const block_result = try expr(&block_scope, &block_scope.base, .{ .rl = .none }, body_node); |
| 8449 | 8463 | _ = try gz.addUnNode(.ensure_result_used, block_result, node); |
| 8450 | 8464 | if (!gz.refIsNoReturn(block_result)) { |
| 8451 | 8465 | _ = try block_scope.addBreak(.break_inline, block_inst, .void_value); |
| ... | ... | @@ -8460,29 +8474,29 @@ fn cImport( |
| 8460 | 8474 | fn overflowArithmetic( |
| 8461 | 8475 | gz: *GenZir, |
| 8462 | 8476 | scope: *Scope, |
| 8463 | | rl: ResultLoc, |
| 8477 | ri: ResultInfo, |
| 8464 | 8478 | node: Ast.Node.Index, |
| 8465 | 8479 | params: []const Ast.Node.Index, |
| 8466 | 8480 | tag: Zir.Inst.Extended, |
| 8467 | 8481 | ) InnerError!Zir.Inst.Ref { |
| 8468 | 8482 | const int_type = try typeExpr(gz, scope, params[0]); |
| 8469 | 8483 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); |
| 8470 | | const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]); |
| 8471 | | const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]); |
| 8472 | | const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]); |
| 8484 | const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]); |
| 8485 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]); |
| 8486 | const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]); |
| 8473 | 8487 | const result = try gz.addExtendedPayload(tag, Zir.Inst.OverflowArithmetic{ |
| 8474 | 8488 | .node = gz.nodeIndexToRelative(node), |
| 8475 | 8489 | .lhs = lhs, |
| 8476 | 8490 | .rhs = rhs, |
| 8477 | 8491 | .ptr = ptr, |
| 8478 | 8492 | }); |
| 8479 | | return rvalue(gz, rl, result, node); |
| 8493 | return rvalue(gz, ri, result, node); |
| 8480 | 8494 | } |
| 8481 | 8495 | |
| 8482 | 8496 | fn callExpr( |
| 8483 | 8497 | gz: *GenZir, |
| 8484 | 8498 | scope: *Scope, |
| 8485 | | rl: ResultLoc, |
| 8499 | ri: ResultInfo, |
| 8486 | 8500 | node: Ast.Node.Index, |
| 8487 | 8501 | call: Ast.full.Call, |
| 8488 | 8502 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -8534,7 +8548,7 @@ fn callExpr( |
| 8534 | 8548 | defer arg_block.unstack(); |
| 8535 | 8549 | |
| 8536 | 8550 | // `call_inst` is reused to provide the param type. |
| 8537 | | const arg_ref = try expr(&arg_block, &arg_block.base, .{ .coerced_ty = call_inst }, param_node); |
| 8551 | const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst } }, param_node); |
| 8538 | 8552 | _ = try arg_block.addBreak(.break_inline, call_index, arg_ref); |
| 8539 | 8553 | |
| 8540 | 8554 | const body = arg_block.instructionsSlice(); |
| ... | ... | @@ -8547,13 +8561,8 @@ fn callExpr( |
| 8547 | 8561 | |
| 8548 | 8562 | // If our result location is a try/catch/error-union-if/return, the error trace propagates. |
| 8549 | 8563 | // Otherwise, it should always be popped (handled in Sema). |
| 8550 | | const propagate_error_trace = switch (rl) { |
| 8551 | | .catch_none, .catch_ref => true, // Propagate to try/catch/error-union-if |
| 8552 | | .ptr, .ty => |ref| b: { // Otherwise, propagate if result loc is a return |
| 8553 | | const inst = refToIndex(ref) orelse break :b false; |
| 8554 | | const zir_tags = astgen.instructions.items(.tag); |
| 8555 | | break :b zir_tags[inst] == .ret_ptr or zir_tags[inst] == .ret_type; |
| 8556 | | }, |
| 8564 | const propagate_error_trace = switch (ri.ctx) { |
| 8565 | .error_handling_expr, .@"return" => true, // Propagate to try/catch/error-union-if and return |
| 8557 | 8566 | else => false, |
| 8558 | 8567 | }; |
| 8559 | 8568 | |
| ... | ... | @@ -8575,7 +8584,7 @@ fn callExpr( |
| 8575 | 8584 | .payload_index = payload_index, |
| 8576 | 8585 | } }, |
| 8577 | 8586 | }); |
| 8578 | | return rvalue(gz, rl, call_inst, node); // TODO function call with result location |
| 8587 | return rvalue(gz, ri, call_inst, node); // TODO function call with result location |
| 8579 | 8588 | } |
| 8580 | 8589 | |
| 8581 | 8590 | /// calleeExpr generates the function part of a call expression (f in f(x)), or the |
| ... | ... | @@ -8596,7 +8605,7 @@ fn calleeExpr( |
| 8596 | 8605 | |
| 8597 | 8606 | const tag = tree.nodes.items(.tag)[node]; |
| 8598 | 8607 | switch (tag) { |
| 8599 | | .field_access => return addFieldAccess(.field_call_bind, gz, scope, .ref, node), |
| 8608 | .field_access => return addFieldAccess(.field_call_bind, gz, scope, .{ .rl = .ref }, node), |
| 8600 | 8609 | |
| 8601 | 8610 | .builtin_call_two, |
| 8602 | 8611 | .builtin_call_two_comma, |
| ... | ... | @@ -8628,8 +8637,8 @@ fn calleeExpr( |
| 8628 | 8637 | // If anything is wrong, fall back to builtinCall. |
| 8629 | 8638 | // It will emit any necessary compile errors and notes. |
| 8630 | 8639 | if (std.mem.eql(u8, builtin_name, "@field") and params.len == 2) { |
| 8631 | | const lhs = try expr(gz, scope, .ref, params[0]); |
| 8632 | | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); |
| 8640 | const lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]); |
| 8641 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]); |
| 8633 | 8642 | return gz.addExtendedPayload(.field_call_bind_named, Zir.Inst.FieldNamedNode{ |
| 8634 | 8643 | .node = gz.nodeIndexToRelative(node), |
| 8635 | 8644 | .lhs = lhs, |
| ... | ... | @@ -8637,9 +8646,9 @@ fn calleeExpr( |
| 8637 | 8646 | }); |
| 8638 | 8647 | } |
| 8639 | 8648 | |
| 8640 | | return builtinCall(gz, scope, .none, node, params); |
| 8649 | return builtinCall(gz, scope, .{ .rl = .none }, node, params); |
| 8641 | 8650 | }, |
| 8642 | | else => return expr(gz, scope, .none, node), |
| 8651 | else => return expr(gz, scope, .{ .rl = .none }, node), |
| 8643 | 8652 | } |
| 8644 | 8653 | } |
| 8645 | 8654 | |
| ... | ... | @@ -9655,7 +9664,7 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { |
| 9655 | 9664 | /// Assumes nothing stacked on `gz`. |
| 9656 | 9665 | fn rvalue( |
| 9657 | 9666 | gz: *GenZir, |
| 9658 | | rl: ResultLoc, |
| 9667 | ri: ResultInfo, |
| 9659 | 9668 | raw_result: Zir.Inst.Ref, |
| 9660 | 9669 | src_node: Ast.Node.Index, |
| 9661 | 9670 | ) InnerError!Zir.Inst.Ref { |
| ... | ... | @@ -9670,14 +9679,14 @@ fn rvalue( |
| 9670 | 9679 | break :r raw_result; |
| 9671 | 9680 | }; |
| 9672 | 9681 | if (gz.endsWithNoReturn()) return result; |
| 9673 | | switch (rl) { |
| 9674 | | .none, .catch_none, .coerced_ty => return result, |
| 9682 | switch (ri.rl) { |
| 9683 | .none, .coerced_ty => return result, |
| 9675 | 9684 | .discard => { |
| 9676 | 9685 | // Emit a compile error for discarding error values. |
| 9677 | 9686 | _ = try gz.addUnNode(.ensure_result_non_error, result, src_node); |
| 9678 | 9687 | return result; |
| 9679 | 9688 | }, |
| 9680 | | .ref, .catch_ref => { |
| 9689 | .ref => { |
| 9681 | 9690 | // We need a pointer but we have a value. |
| 9682 | 9691 | // Unfortunately it's not quite as simple as directly emitting a ref |
| 9683 | 9692 | // instruction here because we need subsequent address-of operator on |
| ... | ... | @@ -9696,7 +9705,7 @@ fn rvalue( |
| 9696 | 9705 | } |
| 9697 | 9706 | return indexToRef(gop.value_ptr.*); |
| 9698 | 9707 | }, |
| 9699 | | .ty, .ty_shift_operand => |ty_inst| { |
| 9708 | .ty => |ty_inst| { |
| 9700 | 9709 | // Quickly eliminate some common, unnecessary type coercion. |
| 9701 | 9710 | const as_ty = @as(u64, @enumToInt(Zir.Inst.Ref.type_type)) << 32; |
| 9702 | 9711 | const as_comptime_int = @as(u64, @enumToInt(Zir.Inst.Ref.comptime_int_type)) << 32; |
| ... | ... | @@ -9757,7 +9766,7 @@ fn rvalue( |
| 9757 | 9766 | => return result, // type of result is already correct |
| 9758 | 9767 | |
| 9759 | 9768 | // Need an explicit type coercion instruction. |
| 9760 | | else => return gz.addPlNode(rl.zirTag(), src_node, Zir.Inst.As{ |
| 9769 | else => return gz.addPlNode(ri.zirTag(), src_node, Zir.Inst.As{ |
| 9761 | 9770 | .dest_type = ty_inst, |
| 9762 | 9771 | .operand = result, |
| 9763 | 9772 | }), |
| ... | ... | @@ -10451,8 +10460,8 @@ const GenZir = struct { |
| 10451 | 10460 | label: ?Label = null, |
| 10452 | 10461 | break_block: Zir.Inst.Index = 0, |
| 10453 | 10462 | continue_block: Zir.Inst.Index = 0, |
| 10454 | | /// Only valid when setBreakResultLoc is called. |
| 10455 | | break_result_loc: AstGen.ResultLoc = undefined, |
| 10463 | /// Only valid when setBreakResultInfo is called. |
| 10464 | break_result_info: AstGen.ResultInfo = undefined, |
| 10456 | 10465 | /// When a block has a pointer result location, here it is. |
| 10457 | 10466 | rl_ptr: Zir.Inst.Ref = .none, |
| 10458 | 10467 | /// When a block has a type result location, here it is. |
| ... | ... | @@ -10562,7 +10571,7 @@ const GenZir = struct { |
| 10562 | 10571 | fn finishCoercion( |
| 10563 | 10572 | as_scope: *GenZir, |
| 10564 | 10573 | parent_gz: *GenZir, |
| 10565 | | rl: ResultLoc, |
| 10574 | ri: ResultInfo, |
| 10566 | 10575 | src_node: Ast.Node.Index, |
| 10567 | 10576 | result: Zir.Inst.Ref, |
| 10568 | 10577 | dest_type: Zir.Inst.Ref, |
| ... | ... | @@ -10588,7 +10597,7 @@ const GenZir = struct { |
| 10588 | 10597 | as_scope.instructions_top = GenZir.unstacked_top; |
| 10589 | 10598 | // as_scope now unstacked, can add new instructions to parent_gz |
| 10590 | 10599 | const casted_result = try parent_gz.addBin(.as, dest_type, result); |
| 10591 | | return rvalue(parent_gz, rl, casted_result, src_node); |
| 10600 | return rvalue(parent_gz, ri, casted_result, src_node); |
| 10592 | 10601 | } else { |
| 10593 | 10602 | // implicitly move all as_scope instructions to parent_gz |
| 10594 | 10603 | as_scope.instructions_top = GenZir.unstacked_top; |
| ... | ... | @@ -10631,7 +10640,7 @@ const GenZir = struct { |
| 10631 | 10640 | return gz.astgen.tree.firstToken(gz.decl_node_index); |
| 10632 | 10641 | } |
| 10633 | 10642 | |
| 10634 | | fn setBreakResultLoc(gz: *GenZir, parent_rl: AstGen.ResultLoc) void { |
| 10643 | fn setBreakResultInfo(gz: *GenZir, parent_ri: AstGen.ResultInfo) void { |
| 10635 | 10644 | // Depending on whether the result location is a pointer or value, different |
| 10636 | 10645 | // ZIR needs to be generated. In the former case we rely on storing to the |
| 10637 | 10646 | // pointer to communicate the result, and use breakvoid; in the latter case |
| ... | ... | @@ -10640,32 +10649,32 @@ const GenZir = struct { |
| 10640 | 10649 | // the scenario where the result location is not consumed. In this case |
| 10641 | 10650 | // we emit ZIR for the block break instructions to have the result values, |
| 10642 | 10651 | // and then rvalue() on that to pass the value to the result location. |
| 10643 | | switch (parent_rl) { |
| 10644 | | .ty, .ty_shift_operand, .coerced_ty => |ty_inst| { |
| 10652 | switch (parent_ri.rl) { |
| 10653 | .ty, .coerced_ty => |ty_inst| { |
| 10645 | 10654 | gz.rl_ty_inst = ty_inst; |
| 10646 | | gz.break_result_loc = parent_rl; |
| 10655 | gz.break_result_info = parent_ri; |
| 10647 | 10656 | }, |
| 10648 | 10657 | |
| 10649 | | .discard, .none, .catch_none, .ref, .catch_ref => { |
| 10658 | .discard, .none, .ref => { |
| 10650 | 10659 | gz.rl_ty_inst = .none; |
| 10651 | | gz.break_result_loc = parent_rl; |
| 10660 | gz.break_result_info = parent_ri; |
| 10652 | 10661 | }, |
| 10653 | 10662 | |
| 10654 | 10663 | .ptr => |ptr_res| { |
| 10655 | 10664 | gz.rl_ty_inst = .none; |
| 10656 | | gz.break_result_loc = .{ .ptr = .{ .inst = ptr_res.inst } }; |
| 10665 | gz.break_result_info = .{ .rl = .{ .ptr = .{ .inst = ptr_res.inst } } }; |
| 10657 | 10666 | }, |
| 10658 | 10667 | |
| 10659 | 10668 | .inferred_ptr => |ptr| { |
| 10660 | 10669 | gz.rl_ty_inst = .none; |
| 10661 | 10670 | gz.rl_ptr = ptr; |
| 10662 | | gz.break_result_loc = .{ .block_ptr = gz }; |
| 10671 | gz.break_result_info = .{ .rl = .{ .block_ptr = gz }, .ctx = parent_ri.ctx }; |
| 10663 | 10672 | }, |
| 10664 | 10673 | |
| 10665 | 10674 | .block_ptr => |parent_block_scope| { |
| 10666 | 10675 | gz.rl_ty_inst = parent_block_scope.rl_ty_inst; |
| 10667 | 10676 | gz.rl_ptr = parent_block_scope.rl_ptr; |
| 10668 | | gz.break_result_loc = .{ .block_ptr = gz }; |
| 10677 | gz.break_result_info = .{ .rl = .{ .block_ptr = gz }, .ctx = parent_ri.ctx }; |
| 10669 | 10678 | }, |
| 10670 | 10679 | } |
| 10671 | 10680 | } |
| ... | ... | @@ -11815,10 +11824,10 @@ const GenZir = struct { |
| 11815 | 11824 | return new_index; |
| 11816 | 11825 | } |
| 11817 | 11826 | |
| 11818 | | fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void { |
| 11819 | | switch (rl) { |
| 11827 | fn addRet(gz: *GenZir, ri: ResultInfo, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void { |
| 11828 | switch (ri.rl) { |
| 11820 | 11829 | .ptr => |ptr_res| _ = try gz.addUnNode(.ret_load, ptr_res.inst, node), |
| 11821 | | .ty, .ty_shift_operand => _ = try gz.addUnNode(.ret_node, operand, node), |
| 11830 | .ty => _ = try gz.addUnNode(.ret_node, operand, node), |
| 11822 | 11831 | else => unreachable, |
| 11823 | 11832 | } |
| 11824 | 11833 | } |