| ... | @@ -213,123 +213,149 @@ pub fn deinit(astgen: *AstGen, gpa: Allocator) void { | ... | @@ -213,123 +213,149 @@ pub fn deinit(astgen: *AstGen, gpa: Allocator) void { |
| 213 | astgen.ref_table.deinit(gpa); | 213 | astgen.ref_table.deinit(gpa); |
| 214 | } | 214 | } |
| 215 | | 215 | |
| 216 | pub const ResultLoc = union(enum) { | 216 | pub const ResultInfo = struct { |
| 217 | /// The expression is the right-hand side of assignment to `_`. Only the side-effects of the | 217 | /// The semantics requested for the result location |
| 218 | /// expression should be generated. The result instruction from the expression must | 218 | rl: Loc, |
| 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 | /// The expression will be coerced into this type, but it will be evaluated as an rvalue. | | |
| 227 | ty: Zir.Inst.Ref, | | |
| 228 | /// Same as `ty` but for shift operands. | | |
| 229 | ty_shift_operand: Zir.Inst.Ref, | | |
| 230 | /// Same as `ty` but it is guaranteed that Sema will additionally perform the coercion, | | |
| 231 | /// so no `as` instruction needs to be emitted. | | |
| 232 | coerced_ty: Zir.Inst.Ref, | | |
| 233 | /// The expression must store its result into this typed pointer. The result instruction | | |
| 234 | /// from the expression must be ignored. | | |
| 235 | ptr: PtrResultLoc, | | |
| 236 | /// The expression must store its result into this allocation, which has an inferred type. | | |
| 237 | /// The result instruction from the expression must be ignored. | | |
| 238 | /// Always an instruction with tag `alloc_inferred`. | | |
| 239 | inferred_ptr: Zir.Inst.Ref, | | |
| 240 | /// There is a pointer for the expression to store its result into, however, its type | | |
| 241 | /// is inferred based on peer type resolution for a `Zir.Inst.Block`. | | |
| 242 | /// The result instruction from the expression must be ignored. | | |
| 243 | block_ptr: *GenZir, | | |
| 244 | | | |
| 245 | const PtrResultLoc = struct { | | |
| 246 | inst: Zir.Inst.Ref, | | |
| 247 | src_node: ?Ast.Node.Index = null, | | |
| 248 | }; | | |
| 249 | | 219 | |
| 250 | pub const Strategy = struct { | 220 | /// The "operator" consuming the result location |
| 251 | elide_store_to_block_ptr_instructions: bool, | 221 | ctx: Context = .none, |
| 252 | tag: Tag, | | |
| 253 | | | |
| 254 | pub const Tag = enum { | | |
| 255 | /// Both branches will use break_void; result location is used to communicate the | | |
| 256 | /// result instruction. | | |
| 257 | break_void, | | |
| 258 | /// Use break statements to pass the block result value, and call rvalue() at | | |
| 259 | /// the end depending on rl. Also elide the store_to_block_ptr instructions | | |
| 260 | /// depending on rl. | | |
| 261 | break_operand, | | |
| 262 | }; | | |
| 263 | }; | | |
| 264 | | 222 | |
| 265 | fn strategy(rl: ResultLoc, block_scope: *GenZir) Strategy { | 223 | /// Turns a `coerced_ty` back into a `ty`. Should be called at branch points |
| 266 | switch (rl) { | 224 | /// such as if and switch expressions. |
| 267 | // In this branch there will not be any store_to_block_ptr instructions. | 225 | fn br(ri: ResultInfo) ResultInfo { |
| 268 | .none, .ty, .ty_shift_operand, .coerced_ty, .ref => return .{ | 226 | return switch (ri.rl) { |
| 269 | .tag = .break_operand, | 227 | .coerced_ty => |ty| .{ |
| 270 | .elide_store_to_block_ptr_instructions = false, | 228 | .rl = .{ .ty = ty }, |
| 271 | }, | 229 | .ctx = ri.ctx, |
| 272 | .discard => return .{ | | |
| 273 | .tag = .break_void, | | |
| 274 | .elide_store_to_block_ptr_instructions = false, | | |
| 275 | }, | | |
| 276 | // The pointer got passed through to the sub-expressions, so we will use | | |
| 277 | // break_void here. | | |
| 278 | // In this branch there will not be any store_to_block_ptr instructions. | | |
| 279 | .ptr => return .{ | | |
| 280 | .tag = .break_void, | | |
| 281 | .elide_store_to_block_ptr_instructions = false, | | |
| 282 | }, | 230 | }, |
| 283 | .inferred_ptr, .block_ptr => { | 231 | else => ri, |
| 284 | if (block_scope.rvalue_rl_count == block_scope.break_count) { | 232 | }; |
| 285 | // Neither prong of the if consumed the result location, so we can | 233 | } |
| 286 | // use break instructions to create an rvalue. | 234 | |
| 287 | return .{ | 235 | fn zirTag(ri: ResultInfo) Zir.Inst.Tag { |
| 288 | .tag = .break_operand, | 236 | switch (ri.rl) { |
| 289 | .elide_store_to_block_ptr_instructions = true, | 237 | .ty => return switch (ri.ctx) { |
| 290 | }; | 238 | .shift_op => .as_shift_operand, |
| 291 | } else { | 239 | else => .as_node, |
| 292 | // Allow the store_to_block_ptr instructions to remain so that | | |
| 293 | // semantic analysis can turn them into bitcasts. | | |
| 294 | return .{ | | |
| 295 | .tag = .break_void, | | |
| 296 | .elide_store_to_block_ptr_instructions = false, | | |
| 297 | }; | | |
| 298 | } | | |
| 299 | }, | 240 | }, |
| | 241 | else => unreachable, |
| 300 | } | 242 | } |
| 301 | } | 243 | } |
| 302 | | 244 | |
| 303 | /// Turns a `coerced_ty` back into a `ty`. Should be called at branch points | 245 | pub const Loc = union(enum) { |
| 304 | /// such as if and switch expressions. | 246 | /// The expression is the right-hand side of assignment to `_`. Only the side-effects of the |
| 305 | fn br(rl: ResultLoc) ResultLoc { | 247 | /// expression should be generated. The result instruction from the expression must |
| 306 | return switch (rl) { | 248 | /// be ignored. |
| 307 | .coerced_ty => |ty| .{ .ty = ty }, | 249 | discard, |
| 308 | else => rl, | 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, |
| 309 | }; | 275 | }; |
| 310 | } | | |
| 311 | | 276 | |
| 312 | fn zirTag(rl: ResultLoc) Zir.Inst.Tag { | 277 | pub const Strategy = struct { |
| 313 | return switch (rl) { | 278 | elide_store_to_block_ptr_instructions: bool, |
| 314 | .ty => .as_node, | 279 | tag: Tag, |
| 315 | .ty_shift_operand => .as_shift_operand, | 280 | |
| 316 | else => unreachable, | 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 | }; |
| 317 | }; | 290 | }; |
| 318 | } | 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 | /// The expression is an argument in a function call. |
| | 339 | fn_arg, |
| | 340 | /// The expression is the right-hand side of an initializer for a `const` variable |
| | 341 | const_init, |
| | 342 | /// No specific operator in particular. |
| | 343 | none, |
| | 344 | }; |
| 319 | }; | 345 | }; |
| 320 | | 346 | |
| 321 | pub const align_rl: ResultLoc = .{ .ty = .u29_type }; | 347 | pub const align_ri: ResultInfo = .{ .rl = .{ .ty = .u29_type } }; |
| 322 | pub const coerced_align_rl: ResultLoc = .{ .coerced_ty = .u29_type }; | 348 | pub const coerced_align_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .u29_type } }; |
| 323 | pub const bool_rl: ResultLoc = .{ .ty = .bool_type }; | 349 | pub const bool_ri: ResultInfo = .{ .rl = .{ .ty = .bool_type } }; |
| 324 | pub const type_rl: ResultLoc = .{ .ty = .type_type }; | 350 | pub const type_ri: ResultInfo = .{ .rl = .{ .ty = .type_type } }; |
| 325 | pub const coerced_type_rl: ResultLoc = .{ .coerced_ty = .type_type }; | 351 | pub const coerced_type_ri: ResultInfo = .{ .rl = .{ .coerced_ty = .type_type } }; |
| 326 | | 352 | |
| 327 | fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 353 | fn typeExpr(gz: *GenZir, scope: *Scope, type_node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 328 | const prev_force_comptime = gz.force_comptime; | 354 | const prev_force_comptime = gz.force_comptime; |
| 329 | gz.force_comptime = true; | 355 | gz.force_comptime = true; |
| 330 | defer gz.force_comptime = prev_force_comptime; | 356 | defer gz.force_comptime = prev_force_comptime; |
| 331 | | 357 | |
| 332 | return expr(gz, scope, coerced_type_rl, type_node); | 358 | return expr(gz, scope, coerced_type_ri, type_node); |
| 333 | } | 359 | } |
| 334 | | 360 | |
| 335 | fn reachableTypeExpr( | 361 | fn reachableTypeExpr( |
| ... | @@ -342,24 +368,24 @@ fn reachableTypeExpr( | ... | @@ -342,24 +368,24 @@ fn reachableTypeExpr( |
| 342 | gz.force_comptime = true; | 368 | gz.force_comptime = true; |
| 343 | defer gz.force_comptime = prev_force_comptime; | 369 | defer gz.force_comptime = prev_force_comptime; |
| 344 | | 370 | |
| 345 | return reachableExpr(gz, scope, coerced_type_rl, type_node, reachable_node); | 371 | return reachableExpr(gz, scope, coerced_type_ri, type_node, reachable_node); |
| 346 | } | 372 | } |
| 347 | | 373 | |
| 348 | /// Same as `expr` but fails with a compile error if the result type is `noreturn`. | 374 | /// Same as `expr` but fails with a compile error if the result type is `noreturn`. |
| 349 | fn reachableExpr( | 375 | fn reachableExpr( |
| 350 | gz: *GenZir, | 376 | gz: *GenZir, |
| 351 | scope: *Scope, | 377 | scope: *Scope, |
| 352 | rl: ResultLoc, | 378 | ri: ResultInfo, |
| 353 | node: Ast.Node.Index, | 379 | node: Ast.Node.Index, |
| 354 | reachable_node: Ast.Node.Index, | 380 | reachable_node: Ast.Node.Index, |
| 355 | ) InnerError!Zir.Inst.Ref { | 381 | ) InnerError!Zir.Inst.Ref { |
| 356 | return reachableExprComptime(gz, scope, rl, node, reachable_node, false); | 382 | return reachableExprComptime(gz, scope, ri, node, reachable_node, false); |
| 357 | } | 383 | } |
| 358 | | 384 | |
| 359 | fn reachableExprComptime( | 385 | fn reachableExprComptime( |
| 360 | gz: *GenZir, | 386 | gz: *GenZir, |
| 361 | scope: *Scope, | 387 | scope: *Scope, |
| 362 | rl: ResultLoc, | 388 | ri: ResultInfo, |
| 363 | node: Ast.Node.Index, | 389 | node: Ast.Node.Index, |
| 364 | reachable_node: Ast.Node.Index, | 390 | reachable_node: Ast.Node.Index, |
| 365 | force_comptime: bool, | 391 | force_comptime: bool, |
| ... | @@ -368,7 +394,7 @@ fn reachableExprComptime( | ... | @@ -368,7 +394,7 @@ fn reachableExprComptime( |
| 368 | gz.force_comptime = prev_force_comptime or force_comptime; | 394 | gz.force_comptime = prev_force_comptime or force_comptime; |
| 369 | defer gz.force_comptime = prev_force_comptime; | 395 | defer gz.force_comptime = prev_force_comptime; |
| 370 | | 396 | |
| 371 | const result_inst = try expr(gz, scope, rl, node); | 397 | const result_inst = try expr(gz, scope, ri, node); |
| 372 | if (gz.refIsNoReturn(result_inst)) { | 398 | if (gz.refIsNoReturn(result_inst)) { |
| 373 | try gz.astgen.appendErrorNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{ | 399 | try gz.astgen.appendErrorNodeNotes(reachable_node, "unreachable code", .{}, &[_]u32{ |
| 374 | try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}), | 400 | try gz.astgen.errNoteNode(node, "control flow is diverted here", .{}), |
| ... | @@ -569,14 +595,14 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins | ... | @@ -569,14 +595,14 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins |
| 569 | .@"orelse", | 595 | .@"orelse", |
| 570 | => {}, | 596 | => {}, |
| 571 | } | 597 | } |
| 572 | return expr(gz, scope, .ref, node); | 598 | return expr(gz, scope, .{ .rl = .ref }, node); |
| 573 | } | 599 | } |
| 574 | | 600 | |
| 575 | /// Turn Zig AST into untyped ZIR instructions. | 601 | /// Turn Zig AST into untyped ZIR instructions. |
| 576 | /// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the | 602 | /// When `rl` is discard, ptr, inferred_ptr, or inferred_ptr, the |
| 577 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, | 603 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, |
| 578 | /// it must otherwise not be used. | 604 | /// it must otherwise not be used. |
| 579 | fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 605 | fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 580 | const astgen = gz.astgen; | 606 | const astgen = gz.astgen; |
| 581 | const tree = astgen.tree; | 607 | const tree = astgen.tree; |
| 582 | const main_tokens = tree.nodes.items(.main_token); | 608 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -617,161 +643,161 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -617,161 +643,161 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 617 | | 643 | |
| 618 | .assign => { | 644 | .assign => { |
| 619 | try assign(gz, scope, node); | 645 | try assign(gz, scope, node); |
| 620 | return rvalue(gz, rl, .void_value, node); | 646 | return rvalue(gz, ri, .void_value, node); |
| 621 | }, | 647 | }, |
| 622 | | 648 | |
| 623 | .assign_shl => { | 649 | .assign_shl => { |
| 624 | try assignShift(gz, scope, node, .shl); | 650 | try assignShift(gz, scope, node, .shl); |
| 625 | return rvalue(gz, rl, .void_value, node); | 651 | return rvalue(gz, ri, .void_value, node); |
| 626 | }, | 652 | }, |
| 627 | .assign_shl_sat => { | 653 | .assign_shl_sat => { |
| 628 | try assignShiftSat(gz, scope, node); | 654 | try assignShiftSat(gz, scope, node); |
| 629 | return rvalue(gz, rl, .void_value, node); | 655 | return rvalue(gz, ri, .void_value, node); |
| 630 | }, | 656 | }, |
| 631 | .assign_shr => { | 657 | .assign_shr => { |
| 632 | try assignShift(gz, scope, node, .shr); | 658 | try assignShift(gz, scope, node, .shr); |
| 633 | return rvalue(gz, rl, .void_value, node); | 659 | return rvalue(gz, ri, .void_value, node); |
| 634 | }, | 660 | }, |
| 635 | | 661 | |
| 636 | .assign_bit_and => { | 662 | .assign_bit_and => { |
| 637 | try assignOp(gz, scope, node, .bit_and); | 663 | try assignOp(gz, scope, node, .bit_and); |
| 638 | return rvalue(gz, rl, .void_value, node); | 664 | return rvalue(gz, ri, .void_value, node); |
| 639 | }, | 665 | }, |
| 640 | .assign_bit_or => { | 666 | .assign_bit_or => { |
| 641 | try assignOp(gz, scope, node, .bit_or); | 667 | try assignOp(gz, scope, node, .bit_or); |
| 642 | return rvalue(gz, rl, .void_value, node); | 668 | return rvalue(gz, ri, .void_value, node); |
| 643 | }, | 669 | }, |
| 644 | .assign_bit_xor => { | 670 | .assign_bit_xor => { |
| 645 | try assignOp(gz, scope, node, .xor); | 671 | try assignOp(gz, scope, node, .xor); |
| 646 | return rvalue(gz, rl, .void_value, node); | 672 | return rvalue(gz, ri, .void_value, node); |
| 647 | }, | 673 | }, |
| 648 | .assign_div => { | 674 | .assign_div => { |
| 649 | try assignOp(gz, scope, node, .div); | 675 | try assignOp(gz, scope, node, .div); |
| 650 | return rvalue(gz, rl, .void_value, node); | 676 | return rvalue(gz, ri, .void_value, node); |
| 651 | }, | 677 | }, |
| 652 | .assign_sub => { | 678 | .assign_sub => { |
| 653 | try assignOp(gz, scope, node, .sub); | 679 | try assignOp(gz, scope, node, .sub); |
| 654 | return rvalue(gz, rl, .void_value, node); | 680 | return rvalue(gz, ri, .void_value, node); |
| 655 | }, | 681 | }, |
| 656 | .assign_sub_wrap => { | 682 | .assign_sub_wrap => { |
| 657 | try assignOp(gz, scope, node, .subwrap); | 683 | try assignOp(gz, scope, node, .subwrap); |
| 658 | return rvalue(gz, rl, .void_value, node); | 684 | return rvalue(gz, ri, .void_value, node); |
| 659 | }, | 685 | }, |
| 660 | .assign_sub_sat => { | 686 | .assign_sub_sat => { |
| 661 | try assignOp(gz, scope, node, .sub_sat); | 687 | try assignOp(gz, scope, node, .sub_sat); |
| 662 | return rvalue(gz, rl, .void_value, node); | 688 | return rvalue(gz, ri, .void_value, node); |
| 663 | }, | 689 | }, |
| 664 | .assign_mod => { | 690 | .assign_mod => { |
| 665 | try assignOp(gz, scope, node, .mod_rem); | 691 | try assignOp(gz, scope, node, .mod_rem); |
| 666 | return rvalue(gz, rl, .void_value, node); | 692 | return rvalue(gz, ri, .void_value, node); |
| 667 | }, | 693 | }, |
| 668 | .assign_add => { | 694 | .assign_add => { |
| 669 | try assignOp(gz, scope, node, .add); | 695 | try assignOp(gz, scope, node, .add); |
| 670 | return rvalue(gz, rl, .void_value, node); | 696 | return rvalue(gz, ri, .void_value, node); |
| 671 | }, | 697 | }, |
| 672 | .assign_add_wrap => { | 698 | .assign_add_wrap => { |
| 673 | try assignOp(gz, scope, node, .addwrap); | 699 | try assignOp(gz, scope, node, .addwrap); |
| 674 | return rvalue(gz, rl, .void_value, node); | 700 | return rvalue(gz, ri, .void_value, node); |
| 675 | }, | 701 | }, |
| 676 | .assign_add_sat => { | 702 | .assign_add_sat => { |
| 677 | try assignOp(gz, scope, node, .add_sat); | 703 | try assignOp(gz, scope, node, .add_sat); |
| 678 | return rvalue(gz, rl, .void_value, node); | 704 | return rvalue(gz, ri, .void_value, node); |
| 679 | }, | 705 | }, |
| 680 | .assign_mul => { | 706 | .assign_mul => { |
| 681 | try assignOp(gz, scope, node, .mul); | 707 | try assignOp(gz, scope, node, .mul); |
| 682 | return rvalue(gz, rl, .void_value, node); | 708 | return rvalue(gz, ri, .void_value, node); |
| 683 | }, | 709 | }, |
| 684 | .assign_mul_wrap => { | 710 | .assign_mul_wrap => { |
| 685 | try assignOp(gz, scope, node, .mulwrap); | 711 | try assignOp(gz, scope, node, .mulwrap); |
| 686 | return rvalue(gz, rl, .void_value, node); | 712 | return rvalue(gz, ri, .void_value, node); |
| 687 | }, | 713 | }, |
| 688 | .assign_mul_sat => { | 714 | .assign_mul_sat => { |
| 689 | try assignOp(gz, scope, node, .mul_sat); | 715 | try assignOp(gz, scope, node, .mul_sat); |
| 690 | return rvalue(gz, rl, .void_value, node); | 716 | return rvalue(gz, ri, .void_value, node); |
| 691 | }, | 717 | }, |
| 692 | | 718 | |
| 693 | // zig fmt: off | 719 | // zig fmt: off |
| 694 | .shl => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shl), | 720 | .shl => return shiftOp(gz, scope, ri, node, node_datas[node].lhs, node_datas[node].rhs, .shl), |
| 695 | .shr => return shiftOp(gz, scope, rl, node, node_datas[node].lhs, node_datas[node].rhs, .shr), | 721 | .shr => return shiftOp(gz, scope, ri, node, node_datas[node].lhs, node_datas[node].rhs, .shr), |
| 696 | | 722 | |
| 697 | .add => return simpleBinOp(gz, scope, rl, node, .add), | 723 | .add => return simpleBinOp(gz, scope, ri, node, .add), |
| 698 | .add_wrap => return simpleBinOp(gz, scope, rl, node, .addwrap), | 724 | .add_wrap => return simpleBinOp(gz, scope, ri, node, .addwrap), |
| 699 | .add_sat => return simpleBinOp(gz, scope, rl, node, .add_sat), | 725 | .add_sat => return simpleBinOp(gz, scope, ri, node, .add_sat), |
| 700 | .sub => return simpleBinOp(gz, scope, rl, node, .sub), | 726 | .sub => return simpleBinOp(gz, scope, ri, node, .sub), |
| 701 | .sub_wrap => return simpleBinOp(gz, scope, rl, node, .subwrap), | 727 | .sub_wrap => return simpleBinOp(gz, scope, ri, node, .subwrap), |
| 702 | .sub_sat => return simpleBinOp(gz, scope, rl, node, .sub_sat), | 728 | .sub_sat => return simpleBinOp(gz, scope, ri, node, .sub_sat), |
| 703 | .mul => return simpleBinOp(gz, scope, rl, node, .mul), | 729 | .mul => return simpleBinOp(gz, scope, ri, node, .mul), |
| 704 | .mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap), | 730 | .mul_wrap => return simpleBinOp(gz, scope, ri, node, .mulwrap), |
| 705 | .mul_sat => return simpleBinOp(gz, scope, rl, node, .mul_sat), | 731 | .mul_sat => return simpleBinOp(gz, scope, ri, node, .mul_sat), |
| 706 | .div => return simpleBinOp(gz, scope, rl, node, .div), | 732 | .div => return simpleBinOp(gz, scope, ri, node, .div), |
| 707 | .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem), | 733 | .mod => return simpleBinOp(gz, scope, ri, node, .mod_rem), |
| 708 | .shl_sat => return simpleBinOp(gz, scope, rl, node, .shl_sat), | 734 | .shl_sat => return simpleBinOp(gz, scope, ri, node, .shl_sat), |
| 709 | | 735 | |
| 710 | .bit_and => return simpleBinOp(gz, scope, rl, node, .bit_and), | 736 | .bit_and => return simpleBinOp(gz, scope, ri, node, .bit_and), |
| 711 | .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or), | 737 | .bit_or => return simpleBinOp(gz, scope, ri, node, .bit_or), |
| 712 | .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor), | 738 | .bit_xor => return simpleBinOp(gz, scope, ri, node, .xor), |
| 713 | .bang_equal => return simpleBinOp(gz, scope, rl, node, .cmp_neq), | 739 | .bang_equal => return simpleBinOp(gz, scope, ri, node, .cmp_neq), |
| 714 | .equal_equal => return simpleBinOp(gz, scope, rl, node, .cmp_eq), | 740 | .equal_equal => return simpleBinOp(gz, scope, ri, node, .cmp_eq), |
| 715 | .greater_than => return simpleBinOp(gz, scope, rl, node, .cmp_gt), | 741 | .greater_than => return simpleBinOp(gz, scope, ri, node, .cmp_gt), |
| 716 | .greater_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_gte), | 742 | .greater_or_equal => return simpleBinOp(gz, scope, ri, node, .cmp_gte), |
| 717 | .less_than => return simpleBinOp(gz, scope, rl, node, .cmp_lt), | 743 | .less_than => return simpleBinOp(gz, scope, ri, node, .cmp_lt), |
| 718 | .less_or_equal => return simpleBinOp(gz, scope, rl, node, .cmp_lte), | 744 | .less_or_equal => return simpleBinOp(gz, scope, ri, node, .cmp_lte), |
| 719 | .array_cat => return simpleBinOp(gz, scope, rl, node, .array_cat), | 745 | .array_cat => return simpleBinOp(gz, scope, ri, node, .array_cat), |
| 720 | | 746 | |
| 721 | .array_mult => { | 747 | .array_mult => { |
| 722 | const result = try gz.addPlNode(.array_mul, node, Zir.Inst.Bin{ | 748 | const result = try gz.addPlNode(.array_mul, node, Zir.Inst.Bin{ |
| 723 | .lhs = try expr(gz, scope, .none, node_datas[node].lhs), | 749 | .lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs), |
| 724 | .rhs = try comptimeExpr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs), | 750 | .rhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs), |
| 725 | }); | 751 | }); |
| 726 | return rvalue(gz, rl, result, node); | 752 | return rvalue(gz, ri, result, node); |
| 727 | }, | 753 | }, |
| 728 | | 754 | |
| 729 | .error_union => return simpleBinOp(gz, scope, rl, node, .error_union_type), | 755 | .error_union => return simpleBinOp(gz, scope, ri, node, .error_union_type), |
| 730 | .merge_error_sets => return simpleBinOp(gz, scope, rl, node, .merge_error_sets), | 756 | .merge_error_sets => return simpleBinOp(gz, scope, ri, node, .merge_error_sets), |
| 731 | | 757 | |
| 732 | .bool_and => return boolBinOp(gz, scope, rl, node, .bool_br_and), | 758 | .bool_and => return boolBinOp(gz, scope, ri, node, .bool_br_and), |
| 733 | .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or), | 759 | .bool_or => return boolBinOp(gz, scope, ri, node, .bool_br_or), |
| 734 | | 760 | |
| 735 | .bool_not => return simpleUnOp(gz, scope, rl, node, bool_rl, node_datas[node].lhs, .bool_not), | 761 | .bool_not => return simpleUnOp(gz, scope, ri, node, bool_ri, node_datas[node].lhs, .bool_not), |
| 736 | .bit_not => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .bit_not), | 762 | .bit_not => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, node_datas[node].lhs, .bit_not), |
| 737 | | 763 | |
| 738 | .negation => return negation(gz, scope, rl, node), | 764 | .negation => return negation(gz, scope, ri, node), |
| 739 | .negation_wrap => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .negate_wrap), | 765 | .negation_wrap => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, node_datas[node].lhs, .negate_wrap), |
| 740 | | 766 | |
| 741 | .identifier => return identifier(gz, scope, rl, node), | 767 | .identifier => return identifier(gz, scope, ri, node), |
| 742 | | 768 | |
| 743 | .asm_simple => return asmExpr(gz, scope, rl, node, tree.asmSimple(node)), | 769 | .asm_simple => return asmExpr(gz, scope, ri, node, tree.asmSimple(node)), |
| 744 | .@"asm" => return asmExpr(gz, scope, rl, node, tree.asmFull(node)), | 770 | .@"asm" => return asmExpr(gz, scope, ri, node, tree.asmFull(node)), |
| 745 | | 771 | |
| 746 | .string_literal => return stringLiteral(gz, rl, node), | 772 | .string_literal => return stringLiteral(gz, ri, node), |
| 747 | .multiline_string_literal => return multilineStringLiteral(gz, rl, node), | 773 | .multiline_string_literal => return multilineStringLiteral(gz, ri, node), |
| 748 | | 774 | |
| 749 | .number_literal => return numberLiteral(gz, rl, node, node, .positive), | 775 | .number_literal => return numberLiteral(gz, ri, node, node, .positive), |
| 750 | // zig fmt: on | 776 | // zig fmt: on |
| 751 | | 777 | |
| 752 | .builtin_call_two, .builtin_call_two_comma => { | 778 | .builtin_call_two, .builtin_call_two_comma => { |
| 753 | if (node_datas[node].lhs == 0) { | 779 | if (node_datas[node].lhs == 0) { |
| 754 | const params = [_]Ast.Node.Index{}; | 780 | const params = [_]Ast.Node.Index{}; |
| 755 | return builtinCall(gz, scope, rl, node, &params); | 781 | return builtinCall(gz, scope, ri, node, &params); |
| 756 | } else if (node_datas[node].rhs == 0) { | 782 | } else if (node_datas[node].rhs == 0) { |
| 757 | const params = [_]Ast.Node.Index{node_datas[node].lhs}; | 783 | const params = [_]Ast.Node.Index{node_datas[node].lhs}; |
| 758 | return builtinCall(gz, scope, rl, node, &params); | 784 | return builtinCall(gz, scope, ri, node, &params); |
| 759 | } else { | 785 | } else { |
| 760 | const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; | 786 | const params = [_]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; |
| 761 | return builtinCall(gz, scope, rl, node, &params); | 787 | return builtinCall(gz, scope, ri, node, &params); |
| 762 | } | 788 | } |
| 763 | }, | 789 | }, |
| 764 | .builtin_call, .builtin_call_comma => { | 790 | .builtin_call, .builtin_call_comma => { |
| 765 | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | 791 | const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; |
| 766 | return builtinCall(gz, scope, rl, node, params); | 792 | return builtinCall(gz, scope, ri, node, params); |
| 767 | }, | 793 | }, |
| 768 | | 794 | |
| 769 | .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => { | 795 | .call_one, .call_one_comma, .async_call_one, .async_call_one_comma => { |
| 770 | var params: [1]Ast.Node.Index = undefined; | 796 | var params: [1]Ast.Node.Index = undefined; |
| 771 | return callExpr(gz, scope, rl, node, tree.callOne(&params, node)); | 797 | return callExpr(gz, scope, ri, node, tree.callOne(&params, node)); |
| 772 | }, | 798 | }, |
| 773 | .call, .call_comma, .async_call, .async_call_comma => { | 799 | .call, .call_comma, .async_call, .async_call_comma => { |
| 774 | return callExpr(gz, scope, rl, node, tree.callFull(node)); | 800 | return callExpr(gz, scope, ri, node, tree.callFull(node)); |
| 775 | }, | 801 | }, |
| 776 | | 802 | |
| 777 | .unreachable_literal => { | 803 | .unreachable_literal => { |
| ... | @@ -786,112 +812,112 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -786,112 +812,112 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 786 | return Zir.Inst.Ref.unreachable_value; | 812 | return Zir.Inst.Ref.unreachable_value; |
| 787 | }, | 813 | }, |
| 788 | .@"return" => return ret(gz, scope, node), | 814 | .@"return" => return ret(gz, scope, node), |
| 789 | .field_access => return fieldAccess(gz, scope, rl, node), | 815 | .field_access => return fieldAccess(gz, scope, ri, node), |
| 790 | | 816 | |
| 791 | .if_simple => return ifExpr(gz, scope, rl.br(), node, tree.ifSimple(node)), | 817 | .if_simple => return ifExpr(gz, scope, ri.br(), node, tree.ifSimple(node)), |
| 792 | .@"if" => return ifExpr(gz, scope, rl.br(), node, tree.ifFull(node)), | 818 | .@"if" => return ifExpr(gz, scope, ri.br(), node, tree.ifFull(node)), |
| 793 | | 819 | |
| 794 | .while_simple => return whileExpr(gz, scope, rl.br(), node, tree.whileSimple(node), false), | 820 | .while_simple => return whileExpr(gz, scope, ri.br(), node, tree.whileSimple(node), false), |
| 795 | .while_cont => return whileExpr(gz, scope, rl.br(), node, tree.whileCont(node), false), | 821 | .while_cont => return whileExpr(gz, scope, ri.br(), node, tree.whileCont(node), false), |
| 796 | .@"while" => return whileExpr(gz, scope, rl.br(), node, tree.whileFull(node), false), | 822 | .@"while" => return whileExpr(gz, scope, ri.br(), node, tree.whileFull(node), false), |
| 797 | | 823 | |
| 798 | .for_simple => return forExpr(gz, scope, rl.br(), node, tree.forSimple(node), false), | 824 | .for_simple => return forExpr(gz, scope, ri.br(), node, tree.forSimple(node), false), |
| 799 | .@"for" => return forExpr(gz, scope, rl.br(), node, tree.forFull(node), false), | 825 | .@"for" => return forExpr(gz, scope, ri.br(), node, tree.forFull(node), false), |
| 800 | | 826 | |
| 801 | .slice_open => { | 827 | .slice_open => { |
| 802 | const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); | 828 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 803 | const start = try expr(gz, scope, .{ .coerced_ty = .usize_type }, node_datas[node].rhs); | 829 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[node].rhs); |
| 804 | const result = try gz.addPlNode(.slice_start, node, Zir.Inst.SliceStart{ | 830 | const result = try gz.addPlNode(.slice_start, node, Zir.Inst.SliceStart{ |
| 805 | .lhs = lhs, | 831 | .lhs = lhs, |
| 806 | .start = start, | 832 | .start = start, |
| 807 | }); | 833 | }); |
| 808 | return rvalue(gz, rl, result, node); | 834 | return rvalue(gz, ri, result, node); |
| 809 | }, | 835 | }, |
| 810 | .slice => { | 836 | .slice => { |
| 811 | const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); | 837 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 812 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); | 838 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.Slice); |
| 813 | const start = try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.start); | 839 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start); |
| 814 | const end = try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.end); | 840 | const end = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end); |
| 815 | const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{ | 841 | const result = try gz.addPlNode(.slice_end, node, Zir.Inst.SliceEnd{ |
| 816 | .lhs = lhs, | 842 | .lhs = lhs, |
| 817 | .start = start, | 843 | .start = start, |
| 818 | .end = end, | 844 | .end = end, |
| 819 | }); | 845 | }); |
| 820 | return rvalue(gz, rl, result, node); | 846 | return rvalue(gz, ri, result, node); |
| 821 | }, | 847 | }, |
| 822 | .slice_sentinel => { | 848 | .slice_sentinel => { |
| 823 | const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); | 849 | const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 824 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); | 850 | const extra = tree.extraData(node_datas[node].rhs, Ast.Node.SliceSentinel); |
| 825 | const start = try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.start); | 851 | const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.start); |
| 826 | const end = if (extra.end != 0) try expr(gz, scope, .{ .coerced_ty = .usize_type }, extra.end) else .none; | 852 | const end = if (extra.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, extra.end) else .none; |
| 827 | const sentinel = try expr(gz, scope, .none, extra.sentinel); | 853 | const sentinel = try expr(gz, scope, .{ .rl = .none }, extra.sentinel); |
| 828 | const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{ | 854 | const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{ |
| 829 | .lhs = lhs, | 855 | .lhs = lhs, |
| 830 | .start = start, | 856 | .start = start, |
| 831 | .end = end, | 857 | .end = end, |
| 832 | .sentinel = sentinel, | 858 | .sentinel = sentinel, |
| 833 | }); | 859 | }); |
| 834 | return rvalue(gz, rl, result, node); | 860 | return rvalue(gz, ri, result, node); |
| 835 | }, | 861 | }, |
| 836 | | 862 | |
| 837 | .deref => { | 863 | .deref => { |
| 838 | const lhs = try expr(gz, scope, .none, node_datas[node].lhs); | 864 | const lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs); |
| 839 | _ = try gz.addUnNode(.validate_deref, lhs, node); | 865 | _ = try gz.addUnNode(.validate_deref, lhs, node); |
| 840 | switch (rl) { | 866 | switch (ri.rl) { |
| 841 | .ref => return lhs, | 867 | .ref => return lhs, |
| 842 | else => { | 868 | else => { |
| 843 | const result = try gz.addUnNode(.load, lhs, node); | 869 | const result = try gz.addUnNode(.load, lhs, node); |
| 844 | return rvalue(gz, rl, result, node); | 870 | return rvalue(gz, ri, result, node); |
| 845 | }, | 871 | }, |
| 846 | } | 872 | } |
| 847 | }, | 873 | }, |
| 848 | .address_of => { | 874 | .address_of => { |
| 849 | const result = try expr(gz, scope, .ref, node_datas[node].lhs); | 875 | const result = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs); |
| 850 | return rvalue(gz, rl, result, node); | 876 | return rvalue(gz, ri, result, node); |
| 851 | }, | 877 | }, |
| 852 | .optional_type => { | 878 | .optional_type => { |
| 853 | const operand = try typeExpr(gz, scope, node_datas[node].lhs); | 879 | const operand = try typeExpr(gz, scope, node_datas[node].lhs); |
| 854 | const result = try gz.addUnNode(.optional_type, operand, node); | 880 | const result = try gz.addUnNode(.optional_type, operand, node); |
| 855 | return rvalue(gz, rl, result, node); | 881 | return rvalue(gz, ri, result, node); |
| 856 | }, | 882 | }, |
| 857 | .unwrap_optional => switch (rl) { | 883 | .unwrap_optional => switch (ri.rl) { |
| 858 | .ref => return gz.addUnNode( | 884 | .ref => return gz.addUnNode( |
| 859 | .optional_payload_safe_ptr, | 885 | .optional_payload_safe_ptr, |
| 860 | try expr(gz, scope, .ref, node_datas[node].lhs), | 886 | try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs), |
| 861 | node, | 887 | node, |
| 862 | ), | 888 | ), |
| 863 | else => return rvalue(gz, rl, try gz.addUnNode( | 889 | else => return rvalue(gz, ri, try gz.addUnNode( |
| 864 | .optional_payload_safe, | 890 | .optional_payload_safe, |
| 865 | try expr(gz, scope, .none, node_datas[node].lhs), | 891 | try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs), |
| 866 | node, | 892 | node, |
| 867 | ), node), | 893 | ), node), |
| 868 | }, | 894 | }, |
| 869 | .block_two, .block_two_semicolon => { | 895 | .block_two, .block_two_semicolon => { |
| 870 | const statements = [2]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; | 896 | const statements = [2]Ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; |
| 871 | if (node_datas[node].lhs == 0) { | 897 | if (node_datas[node].lhs == 0) { |
| 872 | return blockExpr(gz, scope, rl, node, statements[0..0]); | 898 | return blockExpr(gz, scope, ri, node, statements[0..0]); |
| 873 | } else if (node_datas[node].rhs == 0) { | 899 | } else if (node_datas[node].rhs == 0) { |
| 874 | return blockExpr(gz, scope, rl, node, statements[0..1]); | 900 | return blockExpr(gz, scope, ri, node, statements[0..1]); |
| 875 | } else { | 901 | } else { |
| 876 | return blockExpr(gz, scope, rl, node, statements[0..2]); | 902 | return blockExpr(gz, scope, ri, node, statements[0..2]); |
| 877 | } | 903 | } |
| 878 | }, | 904 | }, |
| 879 | .block, .block_semicolon => { | 905 | .block, .block_semicolon => { |
| 880 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; | 906 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; |
| 881 | return blockExpr(gz, scope, rl, node, statements); | 907 | return blockExpr(gz, scope, ri, node, statements); |
| 882 | }, | 908 | }, |
| 883 | .enum_literal => return simpleStrTok(gz, rl, main_tokens[node], node, .enum_literal), | 909 | .enum_literal => return simpleStrTok(gz, ri, main_tokens[node], node, .enum_literal), |
| 884 | .error_value => return simpleStrTok(gz, rl, node_datas[node].rhs, node, .error_value), | 910 | .error_value => return simpleStrTok(gz, ri, node_datas[node].rhs, node, .error_value), |
| 885 | // TODO restore this when implementing https://github.com/ziglang/zig/issues/6025 | 911 | // TODO restore this when implementing https://github.com/ziglang/zig/issues/6025 |
| 886 | // .anyframe_literal => return rvalue(gz, rl, .anyframe_type, node), | 912 | // .anyframe_literal => return rvalue(gz, ri, .anyframe_type, node), |
| 887 | .anyframe_literal => { | 913 | .anyframe_literal => { |
| 888 | const result = try gz.addUnNode(.anyframe_type, .void_type, node); | 914 | const result = try gz.addUnNode(.anyframe_type, .void_type, node); |
| 889 | return rvalue(gz, rl, result, node); | 915 | return rvalue(gz, ri, result, node); |
| 890 | }, | 916 | }, |
| 891 | .anyframe_type => { | 917 | .anyframe_type => { |
| 892 | const return_type = try typeExpr(gz, scope, node_datas[node].rhs); | 918 | const return_type = try typeExpr(gz, scope, node_datas[node].rhs); |
| 893 | const result = try gz.addUnNode(.anyframe_type, return_type, node); | 919 | const result = try gz.addUnNode(.anyframe_type, return_type, node); |
| 894 | return rvalue(gz, rl, result, node); | 920 | return rvalue(gz, ri, result, node); |
| 895 | }, | 921 | }, |
| 896 | .@"catch" => { | 922 | .@"catch" => { |
| 897 | const catch_token = main_tokens[node]; | 923 | const catch_token = main_tokens[node]; |
| ... | @@ -899,11 +925,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -899,11 +925,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 899 | catch_token + 2 | 925 | catch_token + 2 |
| 900 | else | 926 | else |
| 901 | null; | 927 | null; |
| 902 | switch (rl) { | 928 | switch (ri.rl) { |
| 903 | .ref => return orelseCatchExpr( | 929 | .ref => return orelseCatchExpr( |
| 904 | gz, | 930 | gz, |
| 905 | scope, | 931 | scope, |
| 906 | rl, | 932 | ri, |
| 907 | node, | 933 | node, |
| 908 | node_datas[node].lhs, | 934 | node_datas[node].lhs, |
| 909 | .is_non_err_ptr, | 935 | .is_non_err_ptr, |
| ... | @@ -915,7 +941,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -915,7 +941,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 915 | else => return orelseCatchExpr( | 941 | else => return orelseCatchExpr( |
| 916 | gz, | 942 | gz, |
| 917 | scope, | 943 | scope, |
| 918 | rl, | 944 | ri, |
| 919 | node, | 945 | node, |
| 920 | node_datas[node].lhs, | 946 | node_datas[node].lhs, |
| 921 | .is_non_err, | 947 | .is_non_err, |
| ... | @@ -926,11 +952,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -926,11 +952,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 926 | ), | 952 | ), |
| 927 | } | 953 | } |
| 928 | }, | 954 | }, |
| 929 | .@"orelse" => switch (rl) { | 955 | .@"orelse" => switch (ri.rl) { |
| 930 | .ref => return orelseCatchExpr( | 956 | .ref => return orelseCatchExpr( |
| 931 | gz, | 957 | gz, |
| 932 | scope, | 958 | scope, |
| 933 | rl, | 959 | ri, |
| 934 | node, | 960 | node, |
| 935 | node_datas[node].lhs, | 961 | node_datas[node].lhs, |
| 936 | .is_non_null_ptr, | 962 | .is_non_null_ptr, |
| ... | @@ -942,7 +968,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -942,7 +968,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 942 | else => return orelseCatchExpr( | 968 | else => return orelseCatchExpr( |
| 943 | gz, | 969 | gz, |
| 944 | scope, | 970 | scope, |
| 945 | rl, | 971 | ri, |
| 946 | node, | 972 | node, |
| 947 | node_datas[node].lhs, | 973 | node_datas[node].lhs, |
| 948 | .is_non_null, | 974 | .is_non_null, |
| ... | @@ -953,94 +979,94 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -953,94 +979,94 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 953 | ), | 979 | ), |
| 954 | }, | 980 | }, |
| 955 | | 981 | |
| 956 | .ptr_type_aligned => return ptrType(gz, scope, rl, node, tree.ptrTypeAligned(node)), | 982 | .ptr_type_aligned => return ptrType(gz, scope, ri, node, tree.ptrTypeAligned(node)), |
| 957 | .ptr_type_sentinel => return ptrType(gz, scope, rl, node, tree.ptrTypeSentinel(node)), | 983 | .ptr_type_sentinel => return ptrType(gz, scope, ri, node, tree.ptrTypeSentinel(node)), |
| 958 | .ptr_type => return ptrType(gz, scope, rl, node, tree.ptrType(node)), | 984 | .ptr_type => return ptrType(gz, scope, ri, node, tree.ptrType(node)), |
| 959 | .ptr_type_bit_range => return ptrType(gz, scope, rl, node, tree.ptrTypeBitRange(node)), | 985 | .ptr_type_bit_range => return ptrType(gz, scope, ri, node, tree.ptrTypeBitRange(node)), |
| 960 | | 986 | |
| 961 | .container_decl, | 987 | .container_decl, |
| 962 | .container_decl_trailing, | 988 | .container_decl_trailing, |
| 963 | => return containerDecl(gz, scope, rl, node, tree.containerDecl(node)), | 989 | => return containerDecl(gz, scope, ri, node, tree.containerDecl(node)), |
| 964 | .container_decl_two, .container_decl_two_trailing => { | 990 | .container_decl_two, .container_decl_two_trailing => { |
| 965 | var buffer: [2]Ast.Node.Index = undefined; | 991 | var buffer: [2]Ast.Node.Index = undefined; |
| 966 | return containerDecl(gz, scope, rl, node, tree.containerDeclTwo(&buffer, node)); | 992 | return containerDecl(gz, scope, ri, node, tree.containerDeclTwo(&buffer, node)); |
| 967 | }, | 993 | }, |
| 968 | .container_decl_arg, | 994 | .container_decl_arg, |
| 969 | .container_decl_arg_trailing, | 995 | .container_decl_arg_trailing, |
| 970 | => return containerDecl(gz, scope, rl, node, tree.containerDeclArg(node)), | 996 | => return containerDecl(gz, scope, ri, node, tree.containerDeclArg(node)), |
| 971 | | 997 | |
| 972 | .tagged_union, | 998 | .tagged_union, |
| 973 | .tagged_union_trailing, | 999 | .tagged_union_trailing, |
| 974 | => return containerDecl(gz, scope, rl, node, tree.taggedUnion(node)), | 1000 | => return containerDecl(gz, scope, ri, node, tree.taggedUnion(node)), |
| 975 | .tagged_union_two, .tagged_union_two_trailing => { | 1001 | .tagged_union_two, .tagged_union_two_trailing => { |
| 976 | var buffer: [2]Ast.Node.Index = undefined; | 1002 | var buffer: [2]Ast.Node.Index = undefined; |
| 977 | return containerDecl(gz, scope, rl, node, tree.taggedUnionTwo(&buffer, node)); | 1003 | return containerDecl(gz, scope, ri, node, tree.taggedUnionTwo(&buffer, node)); |
| 978 | }, | 1004 | }, |
| 979 | .tagged_union_enum_tag, | 1005 | .tagged_union_enum_tag, |
| 980 | .tagged_union_enum_tag_trailing, | 1006 | .tagged_union_enum_tag_trailing, |
| 981 | => return containerDecl(gz, scope, rl, node, tree.taggedUnionEnumTag(node)), | 1007 | => return containerDecl(gz, scope, ri, node, tree.taggedUnionEnumTag(node)), |
| 982 | | 1008 | |
| 983 | .@"break" => return breakExpr(gz, scope, node), | 1009 | .@"break" => return breakExpr(gz, scope, node), |
| 984 | .@"continue" => return continueExpr(gz, scope, node), | 1010 | .@"continue" => return continueExpr(gz, scope, node), |
| 985 | .grouped_expression => return expr(gz, scope, rl, node_datas[node].lhs), | 1011 | .grouped_expression => return expr(gz, scope, ri, node_datas[node].lhs), |
| 986 | .array_type => return arrayType(gz, scope, rl, node), | 1012 | .array_type => return arrayType(gz, scope, ri, node), |
| 987 | .array_type_sentinel => return arrayTypeSentinel(gz, scope, rl, node), | 1013 | .array_type_sentinel => return arrayTypeSentinel(gz, scope, ri, node), |
| 988 | .char_literal => return charLiteral(gz, rl, node), | 1014 | .char_literal => return charLiteral(gz, ri, node), |
| 989 | .error_set_decl => return errorSetDecl(gz, rl, node), | 1015 | .error_set_decl => return errorSetDecl(gz, ri, node), |
| 990 | .array_access => return arrayAccess(gz, scope, rl, node), | 1016 | .array_access => return arrayAccess(gz, scope, ri, node), |
| 991 | .@"comptime" => return comptimeExprAst(gz, scope, rl, node), | 1017 | .@"comptime" => return comptimeExprAst(gz, scope, ri, node), |
| 992 | .@"switch", .switch_comma => return switchExpr(gz, scope, rl.br(), node), | 1018 | .@"switch", .switch_comma => return switchExpr(gz, scope, ri.br(), node), |
| 993 | | 1019 | |
| 994 | .@"nosuspend" => return nosuspendExpr(gz, scope, rl, node), | 1020 | .@"nosuspend" => return nosuspendExpr(gz, scope, ri, node), |
| 995 | .@"suspend" => return suspendExpr(gz, scope, node), | 1021 | .@"suspend" => return suspendExpr(gz, scope, node), |
| 996 | .@"await" => return awaitExpr(gz, scope, rl, node), | 1022 | .@"await" => return awaitExpr(gz, scope, ri, node), |
| 997 | .@"resume" => return resumeExpr(gz, scope, rl, node), | 1023 | .@"resume" => return resumeExpr(gz, scope, ri, node), |
| 998 | | 1024 | |
| 999 | .@"try" => return tryExpr(gz, scope, rl, node, node_datas[node].lhs), | 1025 | .@"try" => return tryExpr(gz, scope, ri, node, node_datas[node].lhs), |
| 1000 | | 1026 | |
| 1001 | .array_init_one, .array_init_one_comma => { | 1027 | .array_init_one, .array_init_one_comma => { |
| 1002 | var elements: [1]Ast.Node.Index = undefined; | 1028 | var elements: [1]Ast.Node.Index = undefined; |
| 1003 | return arrayInitExpr(gz, scope, rl, node, tree.arrayInitOne(&elements, node)); | 1029 | return arrayInitExpr(gz, scope, ri, node, tree.arrayInitOne(&elements, node)); |
| 1004 | }, | 1030 | }, |
| 1005 | .array_init_dot_two, .array_init_dot_two_comma => { | 1031 | .array_init_dot_two, .array_init_dot_two_comma => { |
| 1006 | var elements: [2]Ast.Node.Index = undefined; | 1032 | var elements: [2]Ast.Node.Index = undefined; |
| 1007 | return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDotTwo(&elements, node)); | 1033 | return arrayInitExpr(gz, scope, ri, node, tree.arrayInitDotTwo(&elements, node)); |
| 1008 | }, | 1034 | }, |
| 1009 | .array_init_dot, | 1035 | .array_init_dot, |
| 1010 | .array_init_dot_comma, | 1036 | .array_init_dot_comma, |
| 1011 | => return arrayInitExpr(gz, scope, rl, node, tree.arrayInitDot(node)), | 1037 | => return arrayInitExpr(gz, scope, ri, node, tree.arrayInitDot(node)), |
| 1012 | .array_init, | 1038 | .array_init, |
| 1013 | .array_init_comma, | 1039 | .array_init_comma, |
| 1014 | => return arrayInitExpr(gz, scope, rl, node, tree.arrayInit(node)), | 1040 | => return arrayInitExpr(gz, scope, ri, node, tree.arrayInit(node)), |
| 1015 | | 1041 | |
| 1016 | .struct_init_one, .struct_init_one_comma => { | 1042 | .struct_init_one, .struct_init_one_comma => { |
| 1017 | var fields: [1]Ast.Node.Index = undefined; | 1043 | var fields: [1]Ast.Node.Index = undefined; |
| 1018 | return structInitExpr(gz, scope, rl, node, tree.structInitOne(&fields, node)); | 1044 | return structInitExpr(gz, scope, ri, node, tree.structInitOne(&fields, node)); |
| 1019 | }, | 1045 | }, |
| 1020 | .struct_init_dot_two, .struct_init_dot_two_comma => { | 1046 | .struct_init_dot_two, .struct_init_dot_two_comma => { |
| 1021 | var fields: [2]Ast.Node.Index = undefined; | 1047 | var fields: [2]Ast.Node.Index = undefined; |
| 1022 | return structInitExpr(gz, scope, rl, node, tree.structInitDotTwo(&fields, node)); | 1048 | return structInitExpr(gz, scope, ri, node, tree.structInitDotTwo(&fields, node)); |
| 1023 | }, | 1049 | }, |
| 1024 | .struct_init_dot, | 1050 | .struct_init_dot, |
| 1025 | .struct_init_dot_comma, | 1051 | .struct_init_dot_comma, |
| 1026 | => return structInitExpr(gz, scope, rl, node, tree.structInitDot(node)), | 1052 | => return structInitExpr(gz, scope, ri, node, tree.structInitDot(node)), |
| 1027 | .struct_init, | 1053 | .struct_init, |
| 1028 | .struct_init_comma, | 1054 | .struct_init_comma, |
| 1029 | => return structInitExpr(gz, scope, rl, node, tree.structInit(node)), | 1055 | => return structInitExpr(gz, scope, ri, node, tree.structInit(node)), |
| 1030 | | 1056 | |
| 1031 | .fn_proto_simple => { | 1057 | .fn_proto_simple => { |
| 1032 | var params: [1]Ast.Node.Index = undefined; | 1058 | var params: [1]Ast.Node.Index = undefined; |
| 1033 | return fnProtoExpr(gz, scope, rl, node, tree.fnProtoSimple(&params, node)); | 1059 | return fnProtoExpr(gz, scope, ri, node, tree.fnProtoSimple(&params, node)); |
| 1034 | }, | 1060 | }, |
| 1035 | .fn_proto_multi => { | 1061 | .fn_proto_multi => { |
| 1036 | return fnProtoExpr(gz, scope, rl, node, tree.fnProtoMulti(node)); | 1062 | return fnProtoExpr(gz, scope, ri, node, tree.fnProtoMulti(node)); |
| 1037 | }, | 1063 | }, |
| 1038 | .fn_proto_one => { | 1064 | .fn_proto_one => { |
| 1039 | var params: [1]Ast.Node.Index = undefined; | 1065 | var params: [1]Ast.Node.Index = undefined; |
| 1040 | return fnProtoExpr(gz, scope, rl, node, tree.fnProtoOne(&params, node)); | 1066 | return fnProtoExpr(gz, scope, ri, node, tree.fnProtoOne(&params, node)); |
| 1041 | }, | 1067 | }, |
| 1042 | .fn_proto => { | 1068 | .fn_proto => { |
| 1043 | return fnProtoExpr(gz, scope, rl, node, tree.fnProto(node)); | 1069 | return fnProtoExpr(gz, scope, ri, node, tree.fnProto(node)); |
| 1044 | }, | 1070 | }, |
| 1045 | } | 1071 | } |
| 1046 | } | 1072 | } |
| ... | @@ -1048,7 +1074,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -1048,7 +1074,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 1048 | fn nosuspendExpr( | 1074 | fn nosuspendExpr( |
| 1049 | gz: *GenZir, | 1075 | gz: *GenZir, |
| 1050 | scope: *Scope, | 1076 | scope: *Scope, |
| 1051 | rl: ResultLoc, | 1077 | ri: ResultInfo, |
| 1052 | node: Ast.Node.Index, | 1078 | node: Ast.Node.Index, |
| 1053 | ) InnerError!Zir.Inst.Ref { | 1079 | ) InnerError!Zir.Inst.Ref { |
| 1054 | const astgen = gz.astgen; | 1080 | const astgen = gz.astgen; |
| ... | @@ -1063,7 +1089,7 @@ fn nosuspendExpr( | ... | @@ -1063,7 +1089,7 @@ fn nosuspendExpr( |
| 1063 | } | 1089 | } |
| 1064 | gz.nosuspend_node = node; | 1090 | gz.nosuspend_node = node; |
| 1065 | defer gz.nosuspend_node = 0; | 1091 | defer gz.nosuspend_node = 0; |
| 1066 | return expr(gz, scope, rl, body_node); | 1092 | return expr(gz, scope, ri, body_node); |
| 1067 | } | 1093 | } |
| 1068 | | 1094 | |
| 1069 | fn suspendExpr( | 1095 | fn suspendExpr( |
| ... | @@ -1096,7 +1122,7 @@ fn suspendExpr( | ... | @@ -1096,7 +1122,7 @@ fn suspendExpr( |
| 1096 | suspend_scope.suspend_node = node; | 1122 | suspend_scope.suspend_node = node; |
| 1097 | defer suspend_scope.unstack(); | 1123 | defer suspend_scope.unstack(); |
| 1098 | | 1124 | |
| 1099 | const body_result = try expr(&suspend_scope, &suspend_scope.base, .none, body_node); | 1125 | const body_result = try expr(&suspend_scope, &suspend_scope.base, .{ .rl = .none }, body_node); |
| 1100 | if (!gz.refIsNoReturn(body_result)) { | 1126 | if (!gz.refIsNoReturn(body_result)) { |
| 1101 | _ = try suspend_scope.addBreak(.break_inline, suspend_inst, .void_value); | 1127 | _ = try suspend_scope.addBreak(.break_inline, suspend_inst, .void_value); |
| 1102 | } | 1128 | } |
| ... | @@ -1108,7 +1134,7 @@ fn suspendExpr( | ... | @@ -1108,7 +1134,7 @@ fn suspendExpr( |
| 1108 | fn awaitExpr( | 1134 | fn awaitExpr( |
| 1109 | gz: *GenZir, | 1135 | gz: *GenZir, |
| 1110 | scope: *Scope, | 1136 | scope: *Scope, |
| 1111 | rl: ResultLoc, | 1137 | ri: ResultInfo, |
| 1112 | node: Ast.Node.Index, | 1138 | node: Ast.Node.Index, |
| 1113 | ) InnerError!Zir.Inst.Ref { | 1139 | ) InnerError!Zir.Inst.Ref { |
| 1114 | const astgen = gz.astgen; | 1140 | const astgen = gz.astgen; |
| ... | @@ -1121,7 +1147,7 @@ fn awaitExpr( | ... | @@ -1121,7 +1147,7 @@ fn awaitExpr( |
| 1121 | try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), | 1147 | try astgen.errNoteNode(gz.suspend_node, "suspend block here", .{}), |
| 1122 | }); | 1148 | }); |
| 1123 | } | 1149 | } |
| 1124 | const operand = try expr(gz, scope, .none, rhs_node); | 1150 | const operand = try expr(gz, scope, .{ .rl = .none }, rhs_node); |
| 1125 | const result = if (gz.nosuspend_node != 0) | 1151 | const result = if (gz.nosuspend_node != 0) |
| 1126 | try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ | 1152 | try gz.addExtendedPayload(.await_nosuspend, Zir.Inst.UnNode{ |
| 1127 | .node = gz.nodeIndexToRelative(node), | 1153 | .node = gz.nodeIndexToRelative(node), |
| ... | @@ -1130,28 +1156,28 @@ fn awaitExpr( | ... | @@ -1130,28 +1156,28 @@ fn awaitExpr( |
| 1130 | else | 1156 | else |
| 1131 | try gz.addUnNode(.@"await", operand, node); | 1157 | try gz.addUnNode(.@"await", operand, node); |
| 1132 | | 1158 | |
| 1133 | return rvalue(gz, rl, result, node); | 1159 | return rvalue(gz, ri, result, node); |
| 1134 | } | 1160 | } |
| 1135 | | 1161 | |
| 1136 | fn resumeExpr( | 1162 | fn resumeExpr( |
| 1137 | gz: *GenZir, | 1163 | gz: *GenZir, |
| 1138 | scope: *Scope, | 1164 | scope: *Scope, |
| 1139 | rl: ResultLoc, | 1165 | ri: ResultInfo, |
| 1140 | node: Ast.Node.Index, | 1166 | node: Ast.Node.Index, |
| 1141 | ) InnerError!Zir.Inst.Ref { | 1167 | ) InnerError!Zir.Inst.Ref { |
| 1142 | const astgen = gz.astgen; | 1168 | const astgen = gz.astgen; |
| 1143 | const tree = astgen.tree; | 1169 | const tree = astgen.tree; |
| 1144 | const node_datas = tree.nodes.items(.data); | 1170 | const node_datas = tree.nodes.items(.data); |
| 1145 | const rhs_node = node_datas[node].lhs; | 1171 | const rhs_node = node_datas[node].lhs; |
| 1146 | const operand = try expr(gz, scope, .none, rhs_node); | 1172 | const operand = try expr(gz, scope, .{ .rl = .none }, rhs_node); |
| 1147 | const result = try gz.addUnNode(.@"resume", operand, node); | 1173 | const result = try gz.addUnNode(.@"resume", operand, node); |
| 1148 | return rvalue(gz, rl, result, node); | 1174 | return rvalue(gz, ri, result, node); |
| 1149 | } | 1175 | } |
| 1150 | | 1176 | |
| 1151 | fn fnProtoExpr( | 1177 | fn fnProtoExpr( |
| 1152 | gz: *GenZir, | 1178 | gz: *GenZir, |
| 1153 | scope: *Scope, | 1179 | scope: *Scope, |
| 1154 | rl: ResultLoc, | 1180 | ri: ResultInfo, |
| 1155 | node: Ast.Node.Index, | 1181 | node: Ast.Node.Index, |
| 1156 | fn_proto: Ast.full.FnProto, | 1182 | fn_proto: Ast.full.FnProto, |
| 1157 | ) InnerError!Zir.Inst.Ref { | 1183 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -1217,7 +1243,7 @@ fn fnProtoExpr( | ... | @@ -1217,7 +1243,7 @@ fn fnProtoExpr( |
| 1217 | assert(param_type_node != 0); | 1243 | assert(param_type_node != 0); |
| 1218 | var param_gz = block_scope.makeSubBlock(scope); | 1244 | var param_gz = block_scope.makeSubBlock(scope); |
| 1219 | defer param_gz.unstack(); | 1245 | defer param_gz.unstack(); |
| 1220 | const param_type = try expr(&param_gz, scope, coerced_type_rl, param_type_node); | 1246 | const param_type = try expr(&param_gz, scope, coerced_type_ri, param_type_node); |
| 1221 | const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); | 1247 | const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); |
| 1222 | _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); | 1248 | _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); |
| 1223 | const main_tokens = tree.nodes.items(.main_token); | 1249 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -1231,7 +1257,7 @@ fn fnProtoExpr( | ... | @@ -1231,7 +1257,7 @@ fn fnProtoExpr( |
| 1231 | }; | 1257 | }; |
| 1232 | | 1258 | |
| 1233 | const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { | 1259 | const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { |
| 1234 | break :inst try expr(&block_scope, scope, align_rl, fn_proto.ast.align_expr); | 1260 | break :inst try expr(&block_scope, scope, align_ri, fn_proto.ast.align_expr); |
| 1235 | }; | 1261 | }; |
| 1236 | | 1262 | |
| 1237 | if (fn_proto.ast.addrspace_expr != 0) { | 1263 | if (fn_proto.ast.addrspace_expr != 0) { |
| ... | @@ -1246,7 +1272,7 @@ fn fnProtoExpr( | ... | @@ -1246,7 +1272,7 @@ fn fnProtoExpr( |
| 1246 | try expr( | 1272 | try expr( |
| 1247 | &block_scope, | 1273 | &block_scope, |
| 1248 | scope, | 1274 | scope, |
| 1249 | .{ .ty = .calling_convention_type }, | 1275 | .{ .rl = .{ .ty = .calling_convention_type } }, |
| 1250 | fn_proto.ast.callconv_expr, | 1276 | fn_proto.ast.callconv_expr, |
| 1251 | ) | 1277 | ) |
| 1252 | else | 1278 | else |
| ... | @@ -1257,7 +1283,7 @@ fn fnProtoExpr( | ... | @@ -1257,7 +1283,7 @@ fn fnProtoExpr( |
| 1257 | if (is_inferred_error) { | 1283 | if (is_inferred_error) { |
| 1258 | return astgen.failTok(maybe_bang, "function prototype may not have inferred error set", .{}); | 1284 | return astgen.failTok(maybe_bang, "function prototype may not have inferred error set", .{}); |
| 1259 | } | 1285 | } |
| 1260 | const ret_ty = try expr(&block_scope, scope, coerced_type_rl, fn_proto.ast.return_type); | 1286 | const ret_ty = try expr(&block_scope, scope, coerced_type_ri, fn_proto.ast.return_type); |
| 1261 | | 1287 | |
| 1262 | const result = try block_scope.addFunc(.{ | 1288 | const result = try block_scope.addFunc(.{ |
| 1263 | .src_node = fn_proto.ast.proto_node, | 1289 | .src_node = fn_proto.ast.proto_node, |
| ... | @@ -1288,13 +1314,13 @@ fn fnProtoExpr( | ... | @@ -1288,13 +1314,13 @@ fn fnProtoExpr( |
| 1288 | try block_scope.setBlockBody(block_inst); | 1314 | try block_scope.setBlockBody(block_inst); |
| 1289 | try gz.instructions.append(astgen.gpa, block_inst); | 1315 | try gz.instructions.append(astgen.gpa, block_inst); |
| 1290 | | 1316 | |
| 1291 | return rvalue(gz, rl, indexToRef(block_inst), fn_proto.ast.proto_node); | 1317 | return rvalue(gz, ri, indexToRef(block_inst), fn_proto.ast.proto_node); |
| 1292 | } | 1318 | } |
| 1293 | | 1319 | |
| 1294 | fn arrayInitExpr( | 1320 | fn arrayInitExpr( |
| 1295 | gz: *GenZir, | 1321 | gz: *GenZir, |
| 1296 | scope: *Scope, | 1322 | scope: *Scope, |
| 1297 | rl: ResultLoc, | 1323 | ri: ResultInfo, |
| 1298 | node: Ast.Node.Index, | 1324 | node: Ast.Node.Index, |
| 1299 | array_init: Ast.full.ArrayInit, | 1325 | array_init: Ast.full.ArrayInit, |
| 1300 | ) InnerError!Zir.Inst.Ref { | 1326 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -1336,7 +1362,7 @@ fn arrayInitExpr( | ... | @@ -1336,7 +1362,7 @@ fn arrayInitExpr( |
| 1336 | .elem = elem_type, | 1362 | .elem = elem_type, |
| 1337 | }; | 1363 | }; |
| 1338 | } else { | 1364 | } else { |
| 1339 | const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); | 1365 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, array_type.ast.sentinel); |
| 1340 | const array_type_inst = try gz.addPlNode( | 1366 | const array_type_inst = try gz.addPlNode( |
| 1341 | .array_type_sentinel, | 1367 | .array_type_sentinel, |
| 1342 | array_init.ast.type_expr, | 1368 | array_init.ast.type_expr, |
| ... | @@ -1364,11 +1390,11 @@ fn arrayInitExpr( | ... | @@ -1364,11 +1390,11 @@ fn arrayInitExpr( |
| 1364 | }; | 1390 | }; |
| 1365 | }; | 1391 | }; |
| 1366 | | 1392 | |
| 1367 | switch (rl) { | 1393 | switch (ri.rl) { |
| 1368 | .discard => { | 1394 | .discard => { |
| 1369 | // TODO elements should still be coerced if type is provided | 1395 | // TODO elements should still be coerced if type is provided |
| 1370 | for (array_init.ast.elements) |elem_init| { | 1396 | for (array_init.ast.elements) |elem_init| { |
| 1371 | _ = try expr(gz, scope, .discard, elem_init); | 1397 | _ = try expr(gz, scope, .{ .rl = .discard }, elem_init); |
| 1372 | } | 1398 | } |
| 1373 | return Zir.Inst.Ref.void_value; | 1399 | return Zir.Inst.Ref.void_value; |
| 1374 | }, | 1400 | }, |
| ... | @@ -1380,13 +1406,13 @@ fn arrayInitExpr( | ... | @@ -1380,13 +1406,13 @@ fn arrayInitExpr( |
| 1380 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; | 1406 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; |
| 1381 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); | 1407 | return arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1382 | }, | 1408 | }, |
| 1383 | .ty, .ty_shift_operand, .coerced_ty => { | 1409 | .ty, .coerced_ty => { |
| 1384 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; | 1410 | const tag: Zir.Inst.Tag = if (types.array != .none) .array_init else .array_init_anon; |
| 1385 | const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); | 1411 | const result = try arrayInitExprInner(gz, scope, node, array_init.ast.elements, types.array, types.elem, tag); |
| 1386 | return rvalue(gz, rl, result, node); | 1412 | return rvalue(gz, ri, result, node); |
| 1387 | }, | 1413 | }, |
| 1388 | .ptr => |ptr_res| { | 1414 | .ptr => |ptr_res| { |
| 1389 | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_res.inst, array_init.ast.elements, types.array); | 1415 | return arrayInitExprRlPtr(gz, scope, ri, node, ptr_res.inst, array_init.ast.elements, types.array); |
| 1390 | }, | 1416 | }, |
| 1391 | .inferred_ptr => |ptr_inst| { | 1417 | .inferred_ptr => |ptr_inst| { |
| 1392 | if (types.array == .none) { | 1418 | if (types.array == .none) { |
| ... | @@ -1394,9 +1420,9 @@ fn arrayInitExpr( | ... | @@ -1394,9 +1420,9 @@ fn arrayInitExpr( |
| 1394 | // analyzing array_base_ptr against an alloc_inferred_mut. | 1420 | // analyzing array_base_ptr against an alloc_inferred_mut. |
| 1395 | // See corresponding logic in structInitExpr. | 1421 | // See corresponding logic in structInitExpr. |
| 1396 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); | 1422 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); |
| 1397 | return rvalue(gz, rl, result, node); | 1423 | return rvalue(gz, ri, result, node); |
| 1398 | } else { | 1424 | } else { |
| 1399 | return arrayInitExprRlPtr(gz, scope, rl, node, ptr_inst, array_init.ast.elements, types.array); | 1425 | return arrayInitExprRlPtr(gz, scope, ri, node, ptr_inst, array_init.ast.elements, types.array); |
| 1400 | } | 1426 | } |
| 1401 | }, | 1427 | }, |
| 1402 | .block_ptr => |block_gz| { | 1428 | .block_ptr => |block_gz| { |
| ... | @@ -1404,9 +1430,9 @@ fn arrayInitExpr( | ... | @@ -1404,9 +1430,9 @@ fn arrayInitExpr( |
| 1404 | // See corresponding logic in structInitExpr. | 1430 | // See corresponding logic in structInitExpr. |
| 1405 | if (types.array == .none and astgen.isInferred(block_gz.rl_ptr)) { | 1431 | if (types.array == .none and astgen.isInferred(block_gz.rl_ptr)) { |
| 1406 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); | 1432 | const result = try arrayInitExprRlNone(gz, scope, node, array_init.ast.elements, .array_init_anon); |
| 1407 | return rvalue(gz, rl, result, node); | 1433 | return rvalue(gz, ri, result, node); |
| 1408 | } | 1434 | } |
| 1409 | return arrayInitExprRlPtr(gz, scope, rl, node, block_gz.rl_ptr, array_init.ast.elements, types.array); | 1435 | return arrayInitExprRlPtr(gz, scope, ri, node, block_gz.rl_ptr, array_init.ast.elements, types.array); |
| 1410 | }, | 1436 | }, |
| 1411 | } | 1437 | } |
| 1412 | } | 1438 | } |
| ... | @@ -1426,7 +1452,7 @@ fn arrayInitExprRlNone( | ... | @@ -1426,7 +1452,7 @@ fn arrayInitExprRlNone( |
| 1426 | var extra_index = try reserveExtra(astgen, elements.len); | 1452 | var extra_index = try reserveExtra(astgen, elements.len); |
| 1427 | | 1453 | |
| 1428 | for (elements) |elem_init| { | 1454 | for (elements) |elem_init| { |
| 1429 | const elem_ref = try expr(gz, scope, .none, elem_init); | 1455 | const elem_ref = try expr(gz, scope, .{ .rl = .none }, elem_init); |
| 1430 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); | 1456 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); |
| 1431 | extra_index += 1; | 1457 | extra_index += 1; |
| 1432 | } | 1458 | } |
| ... | @@ -1455,9 +1481,9 @@ fn arrayInitExprInner( | ... | @@ -1455,9 +1481,9 @@ fn arrayInitExprInner( |
| 1455 | } | 1481 | } |
| 1456 | | 1482 | |
| 1457 | for (elements) |elem_init, i| { | 1483 | for (elements) |elem_init, i| { |
| 1458 | const rl = if (elem_ty != .none) | 1484 | const ri = if (elem_ty != .none) |
| 1459 | ResultLoc{ .coerced_ty = elem_ty } | 1485 | ResultInfo{ .rl = .{ .coerced_ty = elem_ty } } |
| 1460 | else if (array_ty_inst != .none and nodeMayNeedMemoryLocation(astgen.tree, elem_init, true)) rl: { | 1486 | else if (array_ty_inst != .none and nodeMayNeedMemoryLocation(astgen.tree, elem_init, true)) ri: { |
| 1461 | const ty_expr = try gz.add(.{ | 1487 | const ty_expr = try gz.add(.{ |
| 1462 | .tag = .elem_type_index, | 1488 | .tag = .elem_type_index, |
| 1463 | .data = .{ .bin = .{ | 1489 | .data = .{ .bin = .{ |
| ... | @@ -1465,10 +1491,10 @@ fn arrayInitExprInner( | ... | @@ -1465,10 +1491,10 @@ fn arrayInitExprInner( |
| 1465 | .rhs = @intToEnum(Zir.Inst.Ref, i), | 1491 | .rhs = @intToEnum(Zir.Inst.Ref, i), |
| 1466 | } }, | 1492 | } }, |
| 1467 | }); | 1493 | }); |
| 1468 | break :rl ResultLoc{ .coerced_ty = ty_expr }; | 1494 | break :ri ResultInfo{ .rl = .{ .coerced_ty = ty_expr } }; |
| 1469 | } else ResultLoc{ .none = {} }; | 1495 | } else ResultInfo{ .rl = .{ .none = {} } }; |
| 1470 | | 1496 | |
| 1471 | const elem_ref = try expr(gz, scope, rl, elem_init); | 1497 | const elem_ref = try expr(gz, scope, ri, elem_init); |
| 1472 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); | 1498 | astgen.extra.items[extra_index] = @enumToInt(elem_ref); |
| 1473 | extra_index += 1; | 1499 | extra_index += 1; |
| 1474 | } | 1500 | } |
| ... | @@ -1479,7 +1505,7 @@ fn arrayInitExprInner( | ... | @@ -1479,7 +1505,7 @@ fn arrayInitExprInner( |
| 1479 | fn arrayInitExprRlPtr( | 1505 | fn arrayInitExprRlPtr( |
| 1480 | gz: *GenZir, | 1506 | gz: *GenZir, |
| 1481 | scope: *Scope, | 1507 | scope: *Scope, |
| 1482 | rl: ResultLoc, | 1508 | ri: ResultInfo, |
| 1483 | node: Ast.Node.Index, | 1509 | node: Ast.Node.Index, |
| 1484 | result_ptr: Zir.Inst.Ref, | 1510 | result_ptr: Zir.Inst.Ref, |
| 1485 | elements: []const Ast.Node.Index, | 1511 | elements: []const Ast.Node.Index, |
| ... | @@ -1494,7 +1520,7 @@ fn arrayInitExprRlPtr( | ... | @@ -1494,7 +1520,7 @@ fn arrayInitExprRlPtr( |
| 1494 | defer as_scope.unstack(); | 1520 | defer as_scope.unstack(); |
| 1495 | | 1521 | |
| 1496 | const result = try arrayInitExprRlPtrInner(&as_scope, scope, node, as_scope.rl_ptr, elements); | 1522 | const result = try arrayInitExprRlPtrInner(&as_scope, scope, node, as_scope.rl_ptr, elements); |
| 1497 | return as_scope.finishCoercion(gz, rl, node, result, array_ty); | 1523 | return as_scope.finishCoercion(gz, ri, node, result, array_ty); |
| 1498 | } | 1524 | } |
| 1499 | | 1525 | |
| 1500 | fn arrayInitExprRlPtrInner( | 1526 | fn arrayInitExprRlPtrInner( |
| ... | @@ -1518,7 +1544,7 @@ fn arrayInitExprRlPtrInner( | ... | @@ -1518,7 +1544,7 @@ fn arrayInitExprRlPtrInner( |
| 1518 | }); | 1544 | }); |
| 1519 | astgen.extra.items[extra_index] = refToIndex(elem_ptr).?; | 1545 | astgen.extra.items[extra_index] = refToIndex(elem_ptr).?; |
| 1520 | extra_index += 1; | 1546 | extra_index += 1; |
| 1521 | _ = try expr(gz, scope, .{ .ptr = .{ .inst = elem_ptr } }, elem_init); | 1547 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = elem_ptr } } }, elem_init); |
| 1522 | } | 1548 | } |
| 1523 | | 1549 | |
| 1524 | const tag: Zir.Inst.Tag = if (gz.force_comptime) | 1550 | const tag: Zir.Inst.Tag = if (gz.force_comptime) |
| ... | @@ -1533,7 +1559,7 @@ fn arrayInitExprRlPtrInner( | ... | @@ -1533,7 +1559,7 @@ fn arrayInitExprRlPtrInner( |
| 1533 | fn structInitExpr( | 1559 | fn structInitExpr( |
| 1534 | gz: *GenZir, | 1560 | gz: *GenZir, |
| 1535 | scope: *Scope, | 1561 | scope: *Scope, |
| 1536 | rl: ResultLoc, | 1562 | ri: ResultInfo, |
| 1537 | node: Ast.Node.Index, | 1563 | node: Ast.Node.Index, |
| 1538 | struct_init: Ast.full.StructInit, | 1564 | struct_init: Ast.full.StructInit, |
| 1539 | ) InnerError!Zir.Inst.Ref { | 1565 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -1542,7 +1568,7 @@ fn structInitExpr( | ... | @@ -1542,7 +1568,7 @@ fn structInitExpr( |
| 1542 | | 1568 | |
| 1543 | if (struct_init.ast.type_expr == 0) { | 1569 | if (struct_init.ast.type_expr == 0) { |
| 1544 | if (struct_init.ast.fields.len == 0) { | 1570 | if (struct_init.ast.fields.len == 0) { |
| 1545 | return rvalue(gz, rl, .empty_struct, node); | 1571 | return rvalue(gz, ri, .empty_struct, node); |
| 1546 | } | 1572 | } |
| 1547 | } else array: { | 1573 | } else array: { |
| 1548 | const node_tags = tree.nodes.items(.tag); | 1574 | const node_tags = tree.nodes.items(.tag); |
| ... | @@ -1554,7 +1580,7 @@ fn structInitExpr( | ... | @@ -1554,7 +1580,7 @@ fn structInitExpr( |
| 1554 | if (struct_init.ast.fields.len == 0) { | 1580 | if (struct_init.ast.fields.len == 0) { |
| 1555 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1581 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1556 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); | 1582 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1557 | return rvalue(gz, rl, result, node); | 1583 | return rvalue(gz, ri, result, node); |
| 1558 | } | 1584 | } |
| 1559 | break :array; | 1585 | break :array; |
| 1560 | }, | 1586 | }, |
| ... | @@ -1571,7 +1597,7 @@ fn structInitExpr( | ... | @@ -1571,7 +1597,7 @@ fn structInitExpr( |
| 1571 | .rhs = elem_type, | 1597 | .rhs = elem_type, |
| 1572 | }); | 1598 | }); |
| 1573 | } else blk: { | 1599 | } else blk: { |
| 1574 | const sentinel = try comptimeExpr(gz, scope, .{ .ty = elem_type }, array_type.ast.sentinel); | 1600 | const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, array_type.ast.sentinel); |
| 1575 | break :blk try gz.addPlNode( | 1601 | break :blk try gz.addPlNode( |
| 1576 | .array_type_sentinel, | 1602 | .array_type_sentinel, |
| 1577 | struct_init.ast.type_expr, | 1603 | struct_init.ast.type_expr, |
| ... | @@ -1583,11 +1609,11 @@ fn structInitExpr( | ... | @@ -1583,11 +1609,11 @@ fn structInitExpr( |
| 1583 | ); | 1609 | ); |
| 1584 | }; | 1610 | }; |
| 1585 | const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node); | 1611 | const result = try gz.addUnNode(.struct_init_empty, array_type_inst, node); |
| 1586 | return rvalue(gz, rl, result, node); | 1612 | return rvalue(gz, ri, result, node); |
| 1587 | } | 1613 | } |
| 1588 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1614 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1589 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); | 1615 | const result = try gz.addUnNode(.struct_init_empty, ty_inst, node); |
| 1590 | return rvalue(gz, rl, result, node); | 1616 | return rvalue(gz, ri, result, node); |
| 1591 | } else { | 1617 | } else { |
| 1592 | return astgen.failNode( | 1618 | return astgen.failNode( |
| 1593 | struct_init.ast.type_expr, | 1619 | struct_init.ast.type_expr, |
| ... | @@ -1597,7 +1623,7 @@ fn structInitExpr( | ... | @@ -1597,7 +1623,7 @@ fn structInitExpr( |
| 1597 | } | 1623 | } |
| 1598 | } | 1624 | } |
| 1599 | | 1625 | |
| 1600 | switch (rl) { | 1626 | switch (ri.rl) { |
| 1601 | .discard => { | 1627 | .discard => { |
| 1602 | if (struct_init.ast.type_expr != 0) { | 1628 | if (struct_init.ast.type_expr != 0) { |
| 1603 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1629 | const ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| ... | @@ -1626,26 +1652,26 @@ fn structInitExpr( | ... | @@ -1626,26 +1652,26 @@ fn structInitExpr( |
| 1626 | return structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); | 1652 | return structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); |
| 1627 | } | 1653 | } |
| 1628 | }, | 1654 | }, |
| 1629 | .ty, .ty_shift_operand, .coerced_ty => |ty_inst| { | 1655 | .ty, .coerced_ty => |ty_inst| { |
| 1630 | if (struct_init.ast.type_expr == 0) { | 1656 | if (struct_init.ast.type_expr == 0) { |
| 1631 | const result = try structInitExprRlNone(gz, scope, node, struct_init, ty_inst, .struct_init_anon); | 1657 | const result = try structInitExprRlNone(gz, scope, node, struct_init, ty_inst, .struct_init_anon); |
| 1632 | return rvalue(gz, rl, result, node); | 1658 | return rvalue(gz, ri, result, node); |
| 1633 | } | 1659 | } |
| 1634 | const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); | 1660 | const inner_ty_inst = try typeExpr(gz, scope, struct_init.ast.type_expr); |
| 1635 | _ = try gz.addUnNode(.validate_struct_init_ty, inner_ty_inst, node); | 1661 | _ = try gz.addUnNode(.validate_struct_init_ty, inner_ty_inst, node); |
| 1636 | const result = try structInitExprRlTy(gz, scope, node, struct_init, inner_ty_inst, .struct_init); | 1662 | const result = try structInitExprRlTy(gz, scope, node, struct_init, inner_ty_inst, .struct_init); |
| 1637 | return rvalue(gz, rl, result, node); | 1663 | return rvalue(gz, ri, result, node); |
| 1638 | }, | 1664 | }, |
| 1639 | .ptr => |ptr_res| return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_res.inst), | 1665 | .ptr => |ptr_res| return structInitExprRlPtr(gz, scope, ri, node, struct_init, ptr_res.inst), |
| 1640 | .inferred_ptr => |ptr_inst| { | 1666 | .inferred_ptr => |ptr_inst| { |
| 1641 | if (struct_init.ast.type_expr == 0) { | 1667 | if (struct_init.ast.type_expr == 0) { |
| 1642 | // We treat this case differently so that we don't get a crash when | 1668 | // We treat this case differently so that we don't get a crash when |
| 1643 | // analyzing field_base_ptr against an alloc_inferred_mut. | 1669 | // analyzing field_base_ptr against an alloc_inferred_mut. |
| 1644 | // See corresponding logic in arrayInitExpr. | 1670 | // See corresponding logic in arrayInitExpr. |
| 1645 | const result = try structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); | 1671 | const result = try structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); |
| 1646 | return rvalue(gz, rl, result, node); | 1672 | return rvalue(gz, ri, result, node); |
| 1647 | } else { | 1673 | } else { |
| 1648 | return structInitExprRlPtr(gz, scope, rl, node, struct_init, ptr_inst); | 1674 | return structInitExprRlPtr(gz, scope, ri, node, struct_init, ptr_inst); |
| 1649 | } | 1675 | } |
| 1650 | }, | 1676 | }, |
| 1651 | .block_ptr => |block_gz| { | 1677 | .block_ptr => |block_gz| { |
| ... | @@ -1653,10 +1679,10 @@ fn structInitExpr( | ... | @@ -1653,10 +1679,10 @@ fn structInitExpr( |
| 1653 | // See corresponding logic in arrayInitExpr. | 1679 | // See corresponding logic in arrayInitExpr. |
| 1654 | if (struct_init.ast.type_expr == 0 and astgen.isInferred(block_gz.rl_ptr)) { | 1680 | if (struct_init.ast.type_expr == 0 and astgen.isInferred(block_gz.rl_ptr)) { |
| 1655 | const result = try structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); | 1681 | const result = try structInitExprRlNone(gz, scope, node, struct_init, .none, .struct_init_anon); |
| 1656 | return rvalue(gz, rl, result, node); | 1682 | return rvalue(gz, ri, result, node); |
| 1657 | } | 1683 | } |
| 1658 | | 1684 | |
| 1659 | return structInitExprRlPtr(gz, scope, rl, node, struct_init, block_gz.rl_ptr); | 1685 | return structInitExprRlPtr(gz, scope, ri, node, struct_init, block_gz.rl_ptr); |
| 1660 | }, | 1686 | }, |
| 1661 | } | 1687 | } |
| 1662 | } | 1688 | } |
| ... | @@ -1681,16 +1707,15 @@ fn structInitExprRlNone( | ... | @@ -1681,16 +1707,15 @@ fn structInitExprRlNone( |
| 1681 | for (struct_init.ast.fields) |field_init| { | 1707 | for (struct_init.ast.fields) |field_init| { |
| 1682 | const name_token = tree.firstToken(field_init) - 2; | 1708 | const name_token = tree.firstToken(field_init) - 2; |
| 1683 | const str_index = try astgen.identAsString(name_token); | 1709 | const str_index = try astgen.identAsString(name_token); |
| 1684 | const sub_rl: ResultLoc = if (ty_inst != .none) | 1710 | const sub_ri: ResultInfo = if (ty_inst != .none) |
| 1685 | ResultLoc{ .ty = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ | 1711 | ResultInfo{ .rl = .{ .ty = try gz.addPlNode(.field_type, field_init, Zir.Inst.FieldType{ |
| 1686 | .container_type = ty_inst, | 1712 | .container_type = ty_inst, |
| 1687 | .name_start = str_index, | 1713 | .name_start = str_index, |
| 1688 | }) } | 1714 | }) } } |
| 1689 | else | 1715 | else .{ .rl = .none }; |
| 1690 | .none; | | |
| 1691 | setExtra(astgen, extra_index, Zir.Inst.StructInitAnon.Item{ | 1716 | setExtra(astgen, extra_index, Zir.Inst.StructInitAnon.Item{ |
| 1692 | .field_name = str_index, | 1717 | .field_name = str_index, |
| 1693 | .init = try expr(gz, scope, sub_rl, field_init), | 1718 | .init = try expr(gz, scope, sub_ri, field_init), |
| 1694 | }); | 1719 | }); |
| 1695 | extra_index += field_size; | 1720 | extra_index += field_size; |
| 1696 | } | 1721 | } |
| ... | @@ -1701,7 +1726,7 @@ fn structInitExprRlNone( | ... | @@ -1701,7 +1726,7 @@ fn structInitExprRlNone( |
| 1701 | fn structInitExprRlPtr( | 1726 | fn structInitExprRlPtr( |
| 1702 | gz: *GenZir, | 1727 | gz: *GenZir, |
| 1703 | scope: *Scope, | 1728 | scope: *Scope, |
| 1704 | rl: ResultLoc, | 1729 | ri: ResultInfo, |
| 1705 | node: Ast.Node.Index, | 1730 | node: Ast.Node.Index, |
| 1706 | struct_init: Ast.full.StructInit, | 1731 | struct_init: Ast.full.StructInit, |
| 1707 | result_ptr: Zir.Inst.Ref, | 1732 | result_ptr: Zir.Inst.Ref, |
| ... | @@ -1717,7 +1742,7 @@ fn structInitExprRlPtr( | ... | @@ -1717,7 +1742,7 @@ fn structInitExprRlPtr( |
| 1717 | defer as_scope.unstack(); | 1742 | defer as_scope.unstack(); |
| 1718 | | 1743 | |
| 1719 | const result = try structInitExprRlPtrInner(&as_scope, scope, node, struct_init, as_scope.rl_ptr); | 1744 | const result = try structInitExprRlPtrInner(&as_scope, scope, node, struct_init, as_scope.rl_ptr); |
| 1720 | return as_scope.finishCoercion(gz, rl, node, result, ty_inst); | 1745 | return as_scope.finishCoercion(gz, ri, node, result, ty_inst); |
| 1721 | } | 1746 | } |
| 1722 | | 1747 | |
| 1723 | fn structInitExprRlPtrInner( | 1748 | fn structInitExprRlPtrInner( |
| ... | @@ -1744,7 +1769,7 @@ fn structInitExprRlPtrInner( | ... | @@ -1744,7 +1769,7 @@ fn structInitExprRlPtrInner( |
| 1744 | }); | 1769 | }); |
| 1745 | astgen.extra.items[extra_index] = refToIndex(field_ptr).?; | 1770 | astgen.extra.items[extra_index] = refToIndex(field_ptr).?; |
| 1746 | extra_index += 1; | 1771 | extra_index += 1; |
| 1747 | _ = try expr(gz, scope, .{ .ptr = .{ .inst = field_ptr } }, field_init); | 1772 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ .inst = field_ptr } } }, field_init); |
| 1748 | } | 1773 | } |
| 1749 | | 1774 | |
| 1750 | const tag: Zir.Inst.Tag = if (gz.force_comptime) | 1775 | const tag: Zir.Inst.Tag = if (gz.force_comptime) |
| ... | @@ -1782,7 +1807,7 @@ fn structInitExprRlTy( | ... | @@ -1782,7 +1807,7 @@ fn structInitExprRlTy( |
| 1782 | }); | 1807 | }); |
| 1783 | setExtra(astgen, extra_index, Zir.Inst.StructInit.Item{ | 1808 | setExtra(astgen, extra_index, Zir.Inst.StructInit.Item{ |
| 1784 | .field_type = refToIndex(field_ty_inst).?, | 1809 | .field_type = refToIndex(field_ty_inst).?, |
| 1785 | .init = try expr(gz, scope, .{ .ty = field_ty_inst }, field_init), | 1810 | .init = try expr(gz, scope, .{ .rl = .{ .ty = field_ty_inst } }, field_init), |
| 1786 | }); | 1811 | }); |
| 1787 | extra_index += field_size; | 1812 | extra_index += field_size; |
| 1788 | } | 1813 | } |
| ... | @@ -1795,14 +1820,14 @@ fn structInitExprRlTy( | ... | @@ -1795,14 +1820,14 @@ fn structInitExprRlTy( |
| 1795 | fn comptimeExpr( | 1820 | fn comptimeExpr( |
| 1796 | gz: *GenZir, | 1821 | gz: *GenZir, |
| 1797 | scope: *Scope, | 1822 | scope: *Scope, |
| 1798 | rl: ResultLoc, | 1823 | ri: ResultInfo, |
| 1799 | node: Ast.Node.Index, | 1824 | node: Ast.Node.Index, |
| 1800 | ) InnerError!Zir.Inst.Ref { | 1825 | ) InnerError!Zir.Inst.Ref { |
| 1801 | const prev_force_comptime = gz.force_comptime; | 1826 | const prev_force_comptime = gz.force_comptime; |
| 1802 | gz.force_comptime = true; | 1827 | gz.force_comptime = true; |
| 1803 | defer gz.force_comptime = prev_force_comptime; | 1828 | defer gz.force_comptime = prev_force_comptime; |
| 1804 | | 1829 | |
| 1805 | return expr(gz, scope, rl, node); | 1830 | return expr(gz, scope, ri, node); |
| 1806 | } | 1831 | } |
| 1807 | | 1832 | |
| 1808 | /// This one is for an actual `comptime` syntax, and will emit a compile error if | 1833 | /// This one is for an actual `comptime` syntax, and will emit a compile error if |
| ... | @@ -1811,7 +1836,7 @@ fn comptimeExpr( | ... | @@ -1811,7 +1836,7 @@ fn comptimeExpr( |
| 1811 | fn comptimeExprAst( | 1836 | fn comptimeExprAst( |
| 1812 | gz: *GenZir, | 1837 | gz: *GenZir, |
| 1813 | scope: *Scope, | 1838 | scope: *Scope, |
| 1814 | rl: ResultLoc, | 1839 | ri: ResultInfo, |
| 1815 | node: Ast.Node.Index, | 1840 | node: Ast.Node.Index, |
| 1816 | ) InnerError!Zir.Inst.Ref { | 1841 | ) InnerError!Zir.Inst.Ref { |
| 1817 | const astgen = gz.astgen; | 1842 | const astgen = gz.astgen; |
| ... | @@ -1822,11 +1847,50 @@ fn comptimeExprAst( | ... | @@ -1822,11 +1847,50 @@ fn comptimeExprAst( |
| 1822 | const node_datas = tree.nodes.items(.data); | 1847 | const node_datas = tree.nodes.items(.data); |
| 1823 | const body_node = node_datas[node].lhs; | 1848 | const body_node = node_datas[node].lhs; |
| 1824 | gz.force_comptime = true; | 1849 | gz.force_comptime = true; |
| 1825 | const result = try expr(gz, scope, rl, body_node); | 1850 | const result = try expr(gz, scope, ri, body_node); |
| 1826 | gz.force_comptime = false; | 1851 | gz.force_comptime = false; |
| 1827 | return result; | 1852 | return result; |
| 1828 | } | 1853 | } |
| 1829 | | 1854 | |
| | 1855 | /// Restore the error return trace index. Performs the restore only if the result is a non-error or |
| | 1856 | /// if the result location is a non-error-handling expression. |
| | 1857 | fn restoreErrRetIndex( |
| | 1858 | gz: *GenZir, |
| | 1859 | bt: GenZir.BranchTarget, |
| | 1860 | ri: ResultInfo, |
| | 1861 | node: Ast.Node.Index, |
| | 1862 | result: Zir.Inst.Ref, |
| | 1863 | ) !void { |
| | 1864 | const op = switch (nodeMayEvalToError(gz.astgen.tree, node)) { |
| | 1865 | .always => return, // never restore/pop |
| | 1866 | .never => .none, // always restore/pop |
| | 1867 | .maybe => switch (ri.ctx) { |
| | 1868 | .error_handling_expr, .@"return", .fn_arg, .const_init => switch (ri.rl) { |
| | 1869 | .ptr => |ptr_res| try gz.addUnNode(.load, ptr_res.inst, node), |
| | 1870 | .inferred_ptr => |ptr| try gz.addUnNode(.load, ptr, node), |
| | 1871 | .block_ptr => |block_scope| if (block_scope.rvalue_rl_count != block_scope.break_count) b: { |
| | 1872 | // The result location may have been used by this expression, in which case |
| | 1873 | // the operand is not the result and we need to load the rl ptr. |
| | 1874 | switch (gz.astgen.instructions.items(.tag)[Zir.refToIndex(block_scope.rl_ptr).?]) { |
| | 1875 | .alloc_inferred, .alloc_inferred_mut => { |
| | 1876 | // This is a terrible workaround for Sema's inability to load from a .alloc_inferred ptr |
| | 1877 | // before its type has been resolved. The operand we use here instead is not guaranteed |
| | 1878 | // to be valid, and when it's not, we will pop error traces prematurely. |
| | 1879 | // |
| | 1880 | // TODO: Update this to do a proper load from the rl_ptr, once Sema can support it. |
| | 1881 | break :b result; |
| | 1882 | }, |
| | 1883 | else => break :b try gz.addUnNode(.load, block_scope.rl_ptr, node), |
| | 1884 | } |
| | 1885 | } else result, |
| | 1886 | else => result, |
| | 1887 | }, |
| | 1888 | else => .none, // always restore/pop |
| | 1889 | }, |
| | 1890 | }; |
| | 1891 | _ = try gz.addRestoreErrRetIndex(bt, .{ .if_non_error = op }); |
| | 1892 | } |
| | 1893 | |
| 1830 | fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 1894 | fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 1831 | const astgen = parent_gz.astgen; | 1895 | const astgen = parent_gz.astgen; |
| 1832 | const tree = astgen.tree; | 1896 | const tree = astgen.tree; |
| ... | @@ -1842,6 +1906,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -1842,6 +1906,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1842 | const block_gz = scope.cast(GenZir).?; | 1906 | const block_gz = scope.cast(GenZir).?; |
| 1843 | | 1907 | |
| 1844 | if (block_gz.cur_defer_node != 0) { | 1908 | if (block_gz.cur_defer_node != 0) { |
| | 1909 | // We are breaking out of a `defer` block. |
| 1845 | return astgen.failNodeNotes(node, "cannot break out of defer expression", .{}, &.{ | 1910 | return astgen.failNodeNotes(node, "cannot break out of defer expression", .{}, &.{ |
| 1846 | try astgen.errNoteNode( | 1911 | try astgen.errNoteNode( |
| 1847 | block_gz.cur_defer_node, | 1912 | block_gz.cur_defer_node, |
| ... | @@ -1862,9 +1927,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -1862,9 +1927,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1862 | } else if (block_gz.break_block != 0) { | 1927 | } else if (block_gz.break_block != 0) { |
| 1863 | break :blk block_gz.break_block; | 1928 | break :blk block_gz.break_block; |
| 1864 | } | 1929 | } |
| | 1930 | // If not the target, start over with the parent |
| 1865 | scope = block_gz.parent; | 1931 | scope = block_gz.parent; |
| 1866 | continue; | 1932 | continue; |
| 1867 | }; | 1933 | }; |
| | 1934 | // If we made it here, this block is the target of the break expr |
| 1868 | | 1935 | |
| 1869 | const break_tag: Zir.Inst.Tag = if (block_gz.is_inline or block_gz.force_comptime) | 1936 | const break_tag: Zir.Inst.Tag = if (block_gz.is_inline or block_gz.force_comptime) |
| 1870 | .break_inline | 1937 | .break_inline |
| ... | @@ -1874,17 +1941,25 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn | ... | @@ -1874,17 +1941,25 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn |
| 1874 | if (rhs == 0) { | 1941 | if (rhs == 0) { |
| 1875 | try genDefers(parent_gz, scope, parent_scope, .normal_only); | 1942 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| 1876 | | 1943 | |
| | 1944 | // As our last action before the break, "pop" the error trace if needed |
| | 1945 | if (!block_gz.force_comptime) |
| | 1946 | _ = try parent_gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); |
| | 1947 | |
| 1877 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); | 1948 | _ = try parent_gz.addBreak(break_tag, block_inst, .void_value); |
| 1878 | return Zir.Inst.Ref.unreachable_value; | 1949 | return Zir.Inst.Ref.unreachable_value; |
| 1879 | } | 1950 | } |
| 1880 | block_gz.break_count += 1; | 1951 | block_gz.break_count += 1; |
| 1881 | | 1952 | |
| 1882 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_loc, rhs, node); | 1953 | const operand = try reachableExpr(parent_gz, parent_scope, block_gz.break_result_info, rhs, node); |
| 1883 | const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len); | 1954 | const search_index = @intCast(Zir.Inst.Index, astgen.instructions.len); |
| 1884 | | 1955 | |
| 1885 | try genDefers(parent_gz, scope, parent_scope, .normal_only); | 1956 | try genDefers(parent_gz, scope, parent_scope, .normal_only); |
| 1886 | | 1957 | |
| 1887 | switch (block_gz.break_result_loc) { | 1958 | // As our last action before the break, "pop" the error trace if needed |
| | 1959 | if (!block_gz.force_comptime) |
| | 1960 | try restoreErrRetIndex(parent_gz, .{ .block = block_inst }, block_gz.break_result_info, rhs, operand); |
| | 1961 | |
| | 1962 | switch (block_gz.break_result_info.rl) { |
| 1888 | .block_ptr => { | 1963 | .block_ptr => { |
| 1889 | const br = try parent_gz.addBreak(break_tag, block_inst, operand); | 1964 | const br = try parent_gz.addBreak(break_tag, block_inst, operand); |
| 1890 | try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index }); | 1965 | try block_gz.labeled_breaks.append(astgen.gpa, .{ .br = br, .search = search_index }); |
| ... | @@ -1990,7 +2065,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) | ... | @@ -1990,7 +2065,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) |
| 1990 | fn blockExpr( | 2065 | fn blockExpr( |
| 1991 | gz: *GenZir, | 2066 | gz: *GenZir, |
| 1992 | scope: *Scope, | 2067 | scope: *Scope, |
| 1993 | rl: ResultLoc, | 2068 | ri: ResultInfo, |
| 1994 | block_node: Ast.Node.Index, | 2069 | block_node: Ast.Node.Index, |
| 1995 | statements: []const Ast.Node.Index, | 2070 | statements: []const Ast.Node.Index, |
| 1996 | ) InnerError!Zir.Inst.Ref { | 2071 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -2006,12 +2081,38 @@ fn blockExpr( | ... | @@ -2006,12 +2081,38 @@ fn blockExpr( |
| 2006 | if (token_tags[lbrace - 1] == .colon and | 2081 | if (token_tags[lbrace - 1] == .colon and |
| 2007 | token_tags[lbrace - 2] == .identifier) | 2082 | token_tags[lbrace - 2] == .identifier) |
| 2008 | { | 2083 | { |
| 2009 | return labeledBlockExpr(gz, scope, rl, block_node, statements); | 2084 | return labeledBlockExpr(gz, scope, ri, block_node, statements); |
| | 2085 | } |
| | 2086 | |
| | 2087 | if (!gz.force_comptime) { |
| | 2088 | // Since this block is unlabeled, its control flow is effectively linear and we |
| | 2089 | // can *almost* get away with inlining the block here. However, we actually need |
| | 2090 | // to preserve the .block for Sema, to properly pop the error return trace. |
| | 2091 | |
| | 2092 | const block_tag: Zir.Inst.Tag = .block; |
| | 2093 | const block_inst = try gz.makeBlockInst(block_tag, block_node); |
| | 2094 | try gz.instructions.append(astgen.gpa, block_inst); |
| | 2095 | |
| | 2096 | var block_scope = gz.makeSubBlock(scope); |
| | 2097 | defer block_scope.unstack(); |
| | 2098 | |
| | 2099 | try blockExprStmts(&block_scope, &block_scope.base, statements); |
| | 2100 | |
| | 2101 | if (!block_scope.endsWithNoReturn()) { |
| | 2102 | // As our last action before the break, "pop" the error trace if needed |
| | 2103 | _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); |
| | 2104 | |
| | 2105 | const break_tag: Zir.Inst.Tag = if (block_scope.force_comptime) .break_inline else .@"break"; |
| | 2106 | _ = try block_scope.addBreak(break_tag, block_inst, .void_value); |
| | 2107 | } |
| | 2108 | |
| | 2109 | try block_scope.setBlockBody(block_inst); |
| | 2110 | } else { |
| | 2111 | var sub_gz = gz.makeSubBlock(scope); |
| | 2112 | try blockExprStmts(&sub_gz, &sub_gz.base, statements); |
| 2010 | } | 2113 | } |
| 2011 | | 2114 | |
| 2012 | var sub_gz = gz.makeSubBlock(scope); | 2115 | return rvalue(gz, ri, .void_value, block_node); |
| 2013 | try blockExprStmts(&sub_gz, &sub_gz.base, statements); | | |
| 2014 | return rvalue(gz, rl, .void_value, block_node); | | |
| 2015 | } | 2116 | } |
| 2016 | | 2117 | |
| 2017 | fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void { | 2118 | fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void { |
| ... | @@ -2049,7 +2150,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.Toke | ... | @@ -2049,7 +2150,7 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.Toke |
| 2049 | fn labeledBlockExpr( | 2150 | fn labeledBlockExpr( |
| 2050 | gz: *GenZir, | 2151 | gz: *GenZir, |
| 2051 | parent_scope: *Scope, | 2152 | parent_scope: *Scope, |
| 2052 | rl: ResultLoc, | 2153 | ri: ResultInfo, |
| 2053 | block_node: Ast.Node.Index, | 2154 | block_node: Ast.Node.Index, |
| 2054 | statements: []const Ast.Node.Index, | 2155 | statements: []const Ast.Node.Index, |
| 2055 | ) InnerError!Zir.Inst.Ref { | 2156 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -2078,12 +2179,15 @@ fn labeledBlockExpr( | ... | @@ -2078,12 +2179,15 @@ fn labeledBlockExpr( |
| 2078 | .token = label_token, | 2179 | .token = label_token, |
| 2079 | .block_inst = block_inst, | 2180 | .block_inst = block_inst, |
| 2080 | }; | 2181 | }; |
| 2081 | block_scope.setBreakResultLoc(rl); | 2182 | block_scope.setBreakResultInfo(ri); |
| 2082 | defer block_scope.unstack(); | 2183 | defer block_scope.unstack(); |
| 2083 | defer block_scope.labeled_breaks.deinit(astgen.gpa); | 2184 | defer block_scope.labeled_breaks.deinit(astgen.gpa); |
| 2084 | | 2185 | |
| 2085 | try blockExprStmts(&block_scope, &block_scope.base, statements); | 2186 | try blockExprStmts(&block_scope, &block_scope.base, statements); |
| 2086 | if (!block_scope.endsWithNoReturn()) { | 2187 | if (!block_scope.endsWithNoReturn()) { |
| | 2188 | // As our last action before the return, "pop" the error trace if needed |
| | 2189 | _ = try gz.addRestoreErrRetIndex(.{ .block = block_inst }, .always); |
| | 2190 | |
| 2087 | const break_tag: Zir.Inst.Tag = if (block_scope.force_comptime) .break_inline else .@"break"; | 2191 | const break_tag: Zir.Inst.Tag = if (block_scope.force_comptime) .break_inline else .@"break"; |
| 2088 | _ = try block_scope.addBreak(break_tag, block_inst, .void_value); | 2192 | _ = try block_scope.addBreak(break_tag, block_inst, .void_value); |
| 2089 | } | 2193 | } |
| ... | @@ -2094,7 +2198,7 @@ fn labeledBlockExpr( | ... | @@ -2094,7 +2198,7 @@ fn labeledBlockExpr( |
| 2094 | | 2198 | |
| 2095 | const zir_datas = gz.astgen.instructions.items(.data); | 2199 | const zir_datas = gz.astgen.instructions.items(.data); |
| 2096 | const zir_tags = gz.astgen.instructions.items(.tag); | 2200 | const zir_tags = gz.astgen.instructions.items(.tag); |
| 2097 | const strat = rl.strategy(&block_scope); | 2201 | const strat = ri.rl.strategy(&block_scope); |
| 2098 | switch (strat.tag) { | 2202 | switch (strat.tag) { |
| 2099 | .break_void => { | 2203 | .break_void => { |
| 2100 | // The code took advantage of the result location as a pointer. | 2204 | // The code took advantage of the result location as a pointer. |
| ... | @@ -2107,7 +2211,8 @@ fn labeledBlockExpr( | ... | @@ -2107,7 +2211,8 @@ fn labeledBlockExpr( |
| 2107 | return indexToRef(block_inst); | 2211 | return indexToRef(block_inst); |
| 2108 | }, | 2212 | }, |
| 2109 | .break_operand => { | 2213 | .break_operand => { |
| 2110 | // All break operands are values that did not use the result location pointer. | 2214 | // All break operands are values that did not use the result location pointer |
| | 2215 | // (except for a single .store_to_block_ptr inst which we re-write here). |
| 2111 | // The break instructions need to have their operands coerced if the | 2216 | // The break instructions need to have their operands coerced if the |
| 2112 | // block's result location is a `ty`. In this case we overwrite the | 2217 | // block's result location is a `ty`. In this case we overwrite the |
| 2113 | // `store_to_block_ptr` instruction with an `as` instruction and repurpose | 2218 | // `store_to_block_ptr` instruction with an `as` instruction and repurpose |
| ... | @@ -2135,9 +2240,9 @@ fn labeledBlockExpr( | ... | @@ -2135,9 +2240,9 @@ fn labeledBlockExpr( |
| 2135 | } | 2240 | } |
| 2136 | try block_scope.setBlockBody(block_inst); | 2241 | try block_scope.setBlockBody(block_inst); |
| 2137 | const block_ref = indexToRef(block_inst); | 2242 | const block_ref = indexToRef(block_inst); |
| 2138 | switch (rl) { | 2243 | switch (ri.rl) { |
| 2139 | .ref => return block_ref, | 2244 | .ref => return block_ref, |
| 2140 | else => return rvalue(gz, rl, block_ref, block_node), | 2245 | else => return rvalue(gz, ri, block_ref, block_node), |
| 2141 | } | 2246 | } |
| 2142 | }, | 2247 | }, |
| 2143 | } | 2248 | } |
| ... | @@ -2208,12 +2313,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod | ... | @@ -2208,12 +2313,12 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod |
| 2208 | continue; | 2313 | continue; |
| 2209 | }, | 2314 | }, |
| 2210 | | 2315 | |
| 2211 | .while_simple => _ = try whileExpr(gz, scope, .discard, inner_node, tree.whileSimple(inner_node), true), | 2316 | .while_simple => _ = try whileExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.whileSimple(inner_node), true), |
| 2212 | .while_cont => _ = try whileExpr(gz, scope, .discard, inner_node, tree.whileCont(inner_node), true), | 2317 | .while_cont => _ = try whileExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.whileCont(inner_node), true), |
| 2213 | .@"while" => _ = try whileExpr(gz, scope, .discard, inner_node, tree.whileFull(inner_node), true), | 2318 | .@"while" => _ = try whileExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.whileFull(inner_node), true), |
| 2214 | | 2319 | |
| 2215 | .for_simple => _ = try forExpr(gz, scope, .discard, inner_node, tree.forSimple(inner_node), true), | 2320 | .for_simple => _ = try forExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.forSimple(inner_node), true), |
| 2216 | .@"for" => _ = try forExpr(gz, scope, .discard, inner_node, tree.forFull(inner_node), true), | 2321 | .@"for" => _ = try forExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.forFull(inner_node), true), |
| 2217 | | 2322 | |
| 2218 | else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node), | 2323 | else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node), |
| 2219 | // zig fmt: on | 2324 | // zig fmt: on |
| ... | @@ -2234,7 +2339,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner | ... | @@ -2234,7 +2339,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner |
| 2234 | try emitDbgNode(gz, statement); | 2339 | try emitDbgNode(gz, statement); |
| 2235 | // We need to emit an error if the result is not `noreturn` or `void`, but | 2340 | // We need to emit an error if the result is not `noreturn` or `void`, but |
| 2236 | // we want to avoid adding the ZIR instruction if possible for performance. | 2341 | // we want to avoid adding the ZIR instruction if possible for performance. |
| 2237 | const maybe_unused_result = try expr(gz, scope, .none, statement); | 2342 | const maybe_unused_result = try expr(gz, scope, .{ .rl = .none }, statement); |
| 2238 | return addEnsureResult(gz, maybe_unused_result, statement); | 2343 | return addEnsureResult(gz, maybe_unused_result, statement); |
| 2239 | } | 2344 | } |
| 2240 | | 2345 | |
| ... | @@ -2533,6 +2638,8 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2533,6 +2638,8 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2533 | .validate_array_init_ty, | 2638 | .validate_array_init_ty, |
| 2534 | .validate_struct_init_ty, | 2639 | .validate_struct_init_ty, |
| 2535 | .validate_deref, | 2640 | .validate_deref, |
| | 2641 | .save_err_ret_index, |
| | 2642 | .restore_err_ret_index, |
| 2536 | => break :b true, | 2643 | => break :b true, |
| 2537 | | 2644 | |
| 2538 | .@"defer" => unreachable, | 2645 | .@"defer" => unreachable, |
| ... | @@ -2799,7 +2906,7 @@ fn varDecl( | ... | @@ -2799,7 +2906,7 @@ fn varDecl( |
| 2799 | } | 2906 | } |
| 2800 | | 2907 | |
| 2801 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node != 0) | 2908 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node != 0) |
| 2802 | try expr(gz, scope, align_rl, var_decl.ast.align_node) | 2909 | try expr(gz, scope, align_ri, var_decl.ast.align_node) |
| 2803 | else | 2910 | else |
| 2804 | .none; | 2911 | .none; |
| 2805 | | 2912 | |
| ... | @@ -2816,16 +2923,22 @@ fn varDecl( | ... | @@ -2816,16 +2923,22 @@ fn varDecl( |
| 2816 | if (align_inst == .none and | 2923 | if (align_inst == .none and |
| 2817 | !nodeMayNeedMemoryLocation(tree, var_decl.ast.init_node, type_node != 0)) | 2924 | !nodeMayNeedMemoryLocation(tree, var_decl.ast.init_node, type_node != 0)) |
| 2818 | { | 2925 | { |
| 2819 | const result_loc: ResultLoc = if (type_node != 0) .{ | 2926 | const result_info: ResultInfo = if (type_node != 0) .{ |
| 2820 | .ty = try typeExpr(gz, scope, type_node), | 2927 | .rl = .{ .ty = try typeExpr(gz, scope, type_node) }, |
| 2821 | } else .none; | 2928 | .ctx = .const_init, |
| | 2929 | } else .{ .rl = .none, .ctx = .const_init }; |
| 2822 | const prev_anon_name_strategy = gz.anon_name_strategy; | 2930 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 2823 | gz.anon_name_strategy = .dbg_var; | 2931 | gz.anon_name_strategy = .dbg_var; |
| 2824 | const init_inst = try reachableExpr(gz, scope, result_loc, var_decl.ast.init_node, node); | 2932 | const init_inst = try reachableExpr(gz, scope, result_info, var_decl.ast.init_node, node); |
| 2825 | gz.anon_name_strategy = prev_anon_name_strategy; | 2933 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 2826 | | 2934 | |
| 2827 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); | 2935 | try gz.addDbgVar(.dbg_var_val, ident_name, init_inst); |
| 2828 | | 2936 | |
| | 2937 | // The const init expression may have modified the error return trace, so signal |
| | 2938 | // to Sema that it should save the new index for restoring later. |
| | 2939 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) |
| | 2940 | _ = try gz.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| | 2941 | |
| 2829 | const sub_scope = try block_arena.create(Scope.LocalVal); | 2942 | const sub_scope = try block_arena.create(Scope.LocalVal); |
| 2830 | sub_scope.* = .{ | 2943 | sub_scope.* = .{ |
| 2831 | .parent = scope, | 2944 | .parent = scope, |
| ... | @@ -2891,8 +3004,13 @@ fn varDecl( | ... | @@ -2891,8 +3004,13 @@ fn varDecl( |
| 2891 | init_scope.rl_ptr = alloc; | 3004 | init_scope.rl_ptr = alloc; |
| 2892 | init_scope.rl_ty_inst = .none; | 3005 | init_scope.rl_ty_inst = .none; |
| 2893 | } | 3006 | } |
| 2894 | const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope }; | 3007 | const init_result_info: ResultInfo = .{ .rl = .{ .block_ptr = &init_scope }, .ctx = .const_init }; |
| 2895 | const init_inst = try reachableExpr(&init_scope, &init_scope.base, init_result_loc, var_decl.ast.init_node, node); | 3008 | const init_inst = try reachableExpr(&init_scope, &init_scope.base, init_result_info, var_decl.ast.init_node, node); |
| | 3009 | |
| | 3010 | // The const init expression may have modified the error return trace, so signal |
| | 3011 | // to Sema that it should save the new index for restoring later. |
| | 3012 | if (nodeMayAppendToErrorTrace(tree, var_decl.ast.init_node)) |
| | 3013 | _ = try init_scope.addSaveErrRetIndex(.{ .if_of_error_type = init_inst }); |
| 2896 | | 3014 | |
| 2897 | const zir_tags = astgen.instructions.items(.tag); | 3015 | const zir_tags = astgen.instructions.items(.tag); |
| 2898 | const zir_datas = astgen.instructions.items(.data); | 3016 | const zir_datas = astgen.instructions.items(.data); |
| ... | @@ -2981,7 +3099,7 @@ fn varDecl( | ... | @@ -2981,7 +3099,7 @@ fn varDecl( |
| 2981 | const is_comptime = var_decl.comptime_token != null or gz.force_comptime; | 3099 | const is_comptime = var_decl.comptime_token != null or gz.force_comptime; |
| 2982 | var resolve_inferred_alloc: Zir.Inst.Ref = .none; | 3100 | var resolve_inferred_alloc: Zir.Inst.Ref = .none; |
| 2983 | const var_data: struct { | 3101 | const var_data: struct { |
| 2984 | result_loc: ResultLoc, | 3102 | result_info: ResultInfo, |
| 2985 | alloc: Zir.Inst.Ref, | 3103 | alloc: Zir.Inst.Ref, |
| 2986 | } = if (var_decl.ast.type_node != 0) a: { | 3104 | } = if (var_decl.ast.type_node != 0) a: { |
| 2987 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); | 3105 | const type_inst = try typeExpr(gz, scope, var_decl.ast.type_node); |
| ... | @@ -3003,7 +3121,7 @@ fn varDecl( | ... | @@ -3003,7 +3121,7 @@ fn varDecl( |
| 3003 | } | 3121 | } |
| 3004 | }; | 3122 | }; |
| 3005 | gz.rl_ty_inst = type_inst; | 3123 | gz.rl_ty_inst = type_inst; |
| 3006 | break :a .{ .alloc = alloc, .result_loc = .{ .ptr = .{ .inst = alloc } } }; | 3124 | break :a .{ .alloc = alloc, .result_info = .{ .rl = .{ .ptr = .{ .inst = alloc } } } }; |
| 3007 | } else a: { | 3125 | } else a: { |
| 3008 | const alloc = alloc: { | 3126 | const alloc = alloc: { |
| 3009 | if (align_inst == .none) { | 3127 | if (align_inst == .none) { |
| ... | @@ -3024,11 +3142,11 @@ fn varDecl( | ... | @@ -3024,11 +3142,11 @@ fn varDecl( |
| 3024 | }; | 3142 | }; |
| 3025 | gz.rl_ty_inst = .none; | 3143 | gz.rl_ty_inst = .none; |
| 3026 | resolve_inferred_alloc = alloc; | 3144 | resolve_inferred_alloc = alloc; |
| 3027 | break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } }; | 3145 | break :a .{ .alloc = alloc, .result_info = .{ .rl = .{ .inferred_ptr = alloc } } }; |
| 3028 | }; | 3146 | }; |
| 3029 | const prev_anon_name_strategy = gz.anon_name_strategy; | 3147 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 3030 | gz.anon_name_strategy = .dbg_var; | 3148 | gz.anon_name_strategy = .dbg_var; |
| 3031 | _ = try reachableExprComptime(gz, scope, var_data.result_loc, var_decl.ast.init_node, node, is_comptime); | 3149 | _ = try reachableExprComptime(gz, scope, var_data.result_info, var_decl.ast.init_node, node, is_comptime); |
| 3032 | gz.anon_name_strategy = prev_anon_name_strategy; | 3150 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 3033 | if (resolve_inferred_alloc != .none) { | 3151 | if (resolve_inferred_alloc != .none) { |
| 3034 | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); | 3152 | _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); |
| ... | @@ -3098,15 +3216,15 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi | ... | @@ -3098,15 +3216,15 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi |
| 3098 | // This intentionally does not support `@"_"` syntax. | 3216 | // This intentionally does not support `@"_"` syntax. |
| 3099 | const ident_name = tree.tokenSlice(main_tokens[lhs]); | 3217 | const ident_name = tree.tokenSlice(main_tokens[lhs]); |
| 3100 | if (mem.eql(u8, ident_name, "_")) { | 3218 | if (mem.eql(u8, ident_name, "_")) { |
| 3101 | _ = try expr(gz, scope, .discard, rhs); | 3219 | _ = try expr(gz, scope, .{ .rl = .discard }, rhs); |
| 3102 | return; | 3220 | return; |
| 3103 | } | 3221 | } |
| 3104 | } | 3222 | } |
| 3105 | const lvalue = try lvalExpr(gz, scope, lhs); | 3223 | const lvalue = try lvalExpr(gz, scope, lhs); |
| 3106 | _ = try expr(gz, scope, .{ .ptr = .{ | 3224 | _ = try expr(gz, scope, .{ .rl = .{ .ptr = .{ |
| 3107 | .inst = lvalue, | 3225 | .inst = lvalue, |
| 3108 | .src_node = infix_node, | 3226 | .src_node = infix_node, |
| 3109 | } }, rhs); | 3227 | } } }, rhs); |
| 3110 | } | 3228 | } |
| 3111 | | 3229 | |
| 3112 | fn assignOp( | 3230 | fn assignOp( |
| ... | @@ -3123,7 +3241,7 @@ fn assignOp( | ... | @@ -3123,7 +3241,7 @@ fn assignOp( |
| 3123 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 3241 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| 3124 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); | 3242 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3125 | const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node); | 3243 | const lhs_type = try gz.addUnNode(.typeof, lhs, infix_node); |
| 3126 | const rhs = try expr(gz, scope, .{ .coerced_ty = lhs_type }, node_datas[infix_node].rhs); | 3244 | const rhs = try expr(gz, scope, .{ .rl = .{ .coerced_ty = lhs_type } }, node_datas[infix_node].rhs); |
| 3127 | | 3245 | |
| 3128 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ | 3246 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ |
| 3129 | .lhs = lhs, | 3247 | .lhs = lhs, |
| ... | @@ -3146,7 +3264,7 @@ fn assignShift( | ... | @@ -3146,7 +3264,7 @@ fn assignShift( |
| 3146 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 3264 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| 3147 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); | 3265 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3148 | const rhs_type = try gz.addUnNode(.typeof_log2_int_type, lhs, infix_node); | 3266 | const rhs_type = try gz.addUnNode(.typeof_log2_int_type, lhs, infix_node); |
| 3149 | const rhs = try expr(gz, scope, .{ .ty = rhs_type }, node_datas[infix_node].rhs); | 3267 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = rhs_type } }, node_datas[infix_node].rhs); |
| 3150 | | 3268 | |
| 3151 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ | 3269 | const result = try gz.addPlNode(op_inst_tag, infix_node, Zir.Inst.Bin{ |
| 3152 | .lhs = lhs, | 3270 | .lhs = lhs, |
| ... | @@ -3164,7 +3282,7 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE | ... | @@ -3164,7 +3282,7 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE |
| 3164 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); | 3282 | const lhs_ptr = try lvalExpr(gz, scope, node_datas[infix_node].lhs); |
| 3165 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); | 3283 | const lhs = try gz.addUnNode(.load, lhs_ptr, infix_node); |
| 3166 | // Saturating shift-left allows any integer type for both the LHS and RHS. | 3284 | // Saturating shift-left allows any integer type for both the LHS and RHS. |
| 3167 | const rhs = try expr(gz, scope, .none, node_datas[infix_node].rhs); | 3285 | const rhs = try expr(gz, scope, .{ .rl = .none }, node_datas[infix_node].rhs); |
| 3168 | | 3286 | |
| 3169 | const result = try gz.addPlNode(.shl_sat, infix_node, Zir.Inst.Bin{ | 3287 | const result = try gz.addPlNode(.shl_sat, infix_node, Zir.Inst.Bin{ |
| 3170 | .lhs = lhs, | 3288 | .lhs = lhs, |
| ... | @@ -3176,7 +3294,7 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE | ... | @@ -3176,7 +3294,7 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE |
| 3176 | fn ptrType( | 3294 | fn ptrType( |
| 3177 | gz: *GenZir, | 3295 | gz: *GenZir, |
| 3178 | scope: *Scope, | 3296 | scope: *Scope, |
| 3179 | rl: ResultLoc, | 3297 | ri: ResultInfo, |
| 3180 | node: Ast.Node.Index, | 3298 | node: Ast.Node.Index, |
| 3181 | ptr_info: Ast.full.PtrType, | 3299 | ptr_info: Ast.full.PtrType, |
| 3182 | ) InnerError!Zir.Inst.Ref { | 3300 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -3194,21 +3312,21 @@ fn ptrType( | ... | @@ -3194,21 +3312,21 @@ fn ptrType( |
| 3194 | var trailing_count: u32 = 0; | 3312 | var trailing_count: u32 = 0; |
| 3195 | | 3313 | |
| 3196 | if (ptr_info.ast.sentinel != 0) { | 3314 | if (ptr_info.ast.sentinel != 0) { |
| 3197 | sentinel_ref = try expr(gz, scope, .{ .ty = elem_type }, ptr_info.ast.sentinel); | 3315 | sentinel_ref = try expr(gz, scope, .{ .rl = .{ .ty = elem_type } }, ptr_info.ast.sentinel); |
| 3198 | trailing_count += 1; | 3316 | trailing_count += 1; |
| 3199 | } | 3317 | } |
| 3200 | if (ptr_info.ast.align_node != 0) { | 3318 | if (ptr_info.ast.align_node != 0) { |
| 3201 | align_ref = try expr(gz, scope, coerced_align_rl, ptr_info.ast.align_node); | 3319 | align_ref = try expr(gz, scope, coerced_align_ri, ptr_info.ast.align_node); |
| 3202 | trailing_count += 1; | 3320 | trailing_count += 1; |
| 3203 | } | 3321 | } |
| 3204 | if (ptr_info.ast.addrspace_node != 0) { | 3322 | if (ptr_info.ast.addrspace_node != 0) { |
| 3205 | addrspace_ref = try expr(gz, scope, .{ .ty = .address_space_type }, ptr_info.ast.addrspace_node); | 3323 | addrspace_ref = try expr(gz, scope, .{ .rl = .{ .ty = .address_space_type } }, ptr_info.ast.addrspace_node); |
| 3206 | trailing_count += 1; | 3324 | trailing_count += 1; |
| 3207 | } | 3325 | } |
| 3208 | if (ptr_info.ast.bit_range_start != 0) { | 3326 | if (ptr_info.ast.bit_range_start != 0) { |
| 3209 | assert(ptr_info.ast.bit_range_end != 0); | 3327 | assert(ptr_info.ast.bit_range_end != 0); |
| 3210 | bit_start_ref = try expr(gz, scope, .{ .coerced_ty = .u16_type }, ptr_info.ast.bit_range_start); | 3328 | bit_start_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_start); |
| 3211 | bit_end_ref = try expr(gz, scope, .{ .coerced_ty = .u16_type }, ptr_info.ast.bit_range_end); | 3329 | bit_end_ref = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, ptr_info.ast.bit_range_end); |
| 3212 | trailing_count += 2; | 3330 | trailing_count += 2; |
| 3213 | } | 3331 | } |
| 3214 | | 3332 | |
| ... | @@ -3255,10 +3373,10 @@ fn ptrType( | ... | @@ -3255,10 +3373,10 @@ fn ptrType( |
| 3255 | } }); | 3373 | } }); |
| 3256 | gz.instructions.appendAssumeCapacity(new_index); | 3374 | gz.instructions.appendAssumeCapacity(new_index); |
| 3257 | | 3375 | |
| 3258 | return rvalue(gz, rl, result, node); | 3376 | return rvalue(gz, ri, result, node); |
| 3259 | } | 3377 | } |
| 3260 | | 3378 | |
| 3261 | fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref { | 3379 | fn arrayType(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 3262 | const astgen = gz.astgen; | 3380 | const astgen = gz.astgen; |
| 3263 | const tree = astgen.tree; | 3381 | const tree = astgen.tree; |
| 3264 | const node_datas = tree.nodes.items(.data); | 3382 | const node_datas = tree.nodes.items(.data); |
| ... | @@ -3271,17 +3389,17 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Z | ... | @@ -3271,17 +3389,17 @@ fn arrayType(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Z |
| 3271 | { | 3389 | { |
| 3272 | return astgen.failNode(len_node, "unable to infer array size", .{}); | 3390 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 3273 | } | 3391 | } |
| 3274 | const len = try expr(gz, scope, .{ .coerced_ty = .usize_type }, len_node); | 3392 | const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node); |
| 3275 | const elem_type = try typeExpr(gz, scope, node_datas[node].rhs); | 3393 | const elem_type = try typeExpr(gz, scope, node_datas[node].rhs); |
| 3276 | | 3394 | |
| 3277 | const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ | 3395 | const result = try gz.addPlNode(.array_type, node, Zir.Inst.Bin{ |
| 3278 | .lhs = len, | 3396 | .lhs = len, |
| 3279 | .rhs = elem_type, | 3397 | .rhs = elem_type, |
| 3280 | }); | 3398 | }); |
| 3281 | return rvalue(gz, rl, result, node); | 3399 | return rvalue(gz, ri, result, node); |
| 3282 | } | 3400 | } |
| 3283 | | 3401 | |
| 3284 | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) !Zir.Inst.Ref { | 3402 | fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) !Zir.Inst.Ref { |
| 3285 | const astgen = gz.astgen; | 3403 | const astgen = gz.astgen; |
| 3286 | const tree = astgen.tree; | 3404 | const tree = astgen.tree; |
| 3287 | const node_datas = tree.nodes.items(.data); | 3405 | const node_datas = tree.nodes.items(.data); |
| ... | @@ -3295,16 +3413,16 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.I | ... | @@ -3295,16 +3413,16 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.I |
| 3295 | { | 3413 | { |
| 3296 | return astgen.failNode(len_node, "unable to infer array size", .{}); | 3414 | return astgen.failNode(len_node, "unable to infer array size", .{}); |
| 3297 | } | 3415 | } |
| 3298 | const len = try reachableExpr(gz, scope, .{ .coerced_ty = .usize_type }, len_node, node); | 3416 | const len = try reachableExpr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node, node); |
| 3299 | const elem_type = try typeExpr(gz, scope, extra.elem_type); | 3417 | const elem_type = try typeExpr(gz, scope, extra.elem_type); |
| 3300 | const sentinel = try reachableExpr(gz, scope, .{ .coerced_ty = elem_type }, extra.sentinel, node); | 3418 | const sentinel = try reachableExpr(gz, scope, .{ .rl = .{ .coerced_ty = elem_type } }, extra.sentinel, node); |
| 3301 | | 3419 | |
| 3302 | const result = try gz.addPlNode(.array_type_sentinel, node, Zir.Inst.ArrayTypeSentinel{ | 3420 | const result = try gz.addPlNode(.array_type_sentinel, node, Zir.Inst.ArrayTypeSentinel{ |
| 3303 | .len = len, | 3421 | .len = len, |
| 3304 | .elem_type = elem_type, | 3422 | .elem_type = elem_type, |
| 3305 | .sentinel = sentinel, | 3423 | .sentinel = sentinel, |
| 3306 | }); | 3424 | }); |
| 3307 | return rvalue(gz, rl, result, node); | 3425 | return rvalue(gz, ri, result, node); |
| 3308 | } | 3426 | } |
| 3309 | | 3427 | |
| 3310 | const WipMembers = struct { | 3428 | const WipMembers = struct { |
| ... | @@ -3540,7 +3658,7 @@ fn fnDecl( | ... | @@ -3540,7 +3658,7 @@ fn fnDecl( |
| 3540 | assert(param_type_node != 0); | 3658 | assert(param_type_node != 0); |
| 3541 | var param_gz = decl_gz.makeSubBlock(scope); | 3659 | var param_gz = decl_gz.makeSubBlock(scope); |
| 3542 | defer param_gz.unstack(); | 3660 | defer param_gz.unstack(); |
| 3543 | const param_type = try expr(&param_gz, params_scope, coerced_type_rl, param_type_node); | 3661 | const param_type = try expr(&param_gz, params_scope, coerced_type_ri, param_type_node); |
| 3544 | const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); | 3662 | const param_inst_expected = @intCast(u32, astgen.instructions.len + 1); |
| 3545 | _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); | 3663 | _ = try param_gz.addBreak(.break_inline, param_inst_expected, param_type); |
| 3546 | | 3664 | |
| ... | @@ -3589,7 +3707,7 @@ fn fnDecl( | ... | @@ -3589,7 +3707,7 @@ fn fnDecl( |
| 3589 | var align_gz = decl_gz.makeSubBlock(params_scope); | 3707 | var align_gz = decl_gz.makeSubBlock(params_scope); |
| 3590 | defer align_gz.unstack(); | 3708 | defer align_gz.unstack(); |
| 3591 | const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { | 3709 | const align_ref: Zir.Inst.Ref = if (fn_proto.ast.align_expr == 0) .none else inst: { |
| 3592 | const inst = try expr(&decl_gz, params_scope, coerced_align_rl, fn_proto.ast.align_expr); | 3710 | const inst = try expr(&decl_gz, params_scope, coerced_align_ri, fn_proto.ast.align_expr); |
| 3593 | if (align_gz.instructionsSlice().len == 0) { | 3711 | if (align_gz.instructionsSlice().len == 0) { |
| 3594 | // In this case we will send a len=0 body which can be encoded more efficiently. | 3712 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3595 | break :inst inst; | 3713 | break :inst inst; |
| ... | @@ -3601,7 +3719,7 @@ fn fnDecl( | ... | @@ -3601,7 +3719,7 @@ fn fnDecl( |
| 3601 | var addrspace_gz = decl_gz.makeSubBlock(params_scope); | 3719 | var addrspace_gz = decl_gz.makeSubBlock(params_scope); |
| 3602 | defer addrspace_gz.unstack(); | 3720 | defer addrspace_gz.unstack(); |
| 3603 | const addrspace_ref: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: { | 3721 | const addrspace_ref: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: { |
| 3604 | const inst = try expr(&decl_gz, params_scope, .{ .coerced_ty = .address_space_type }, fn_proto.ast.addrspace_expr); | 3722 | const inst = try expr(&decl_gz, params_scope, .{ .rl = .{ .coerced_ty = .address_space_type } }, fn_proto.ast.addrspace_expr); |
| 3605 | if (addrspace_gz.instructionsSlice().len == 0) { | 3723 | if (addrspace_gz.instructionsSlice().len == 0) { |
| 3606 | // In this case we will send a len=0 body which can be encoded more efficiently. | 3724 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3607 | break :inst inst; | 3725 | break :inst inst; |
| ... | @@ -3613,7 +3731,7 @@ fn fnDecl( | ... | @@ -3613,7 +3731,7 @@ fn fnDecl( |
| 3613 | var section_gz = decl_gz.makeSubBlock(params_scope); | 3731 | var section_gz = decl_gz.makeSubBlock(params_scope); |
| 3614 | defer section_gz.unstack(); | 3732 | defer section_gz.unstack(); |
| 3615 | const section_ref: Zir.Inst.Ref = if (fn_proto.ast.section_expr == 0) .none else inst: { | 3733 | const section_ref: Zir.Inst.Ref = if (fn_proto.ast.section_expr == 0) .none else inst: { |
| 3616 | const inst = try expr(&decl_gz, params_scope, .{ .coerced_ty = .const_slice_u8_type }, fn_proto.ast.section_expr); | 3734 | const inst = try expr(&decl_gz, params_scope, .{ .rl = .{ .coerced_ty = .const_slice_u8_type } }, fn_proto.ast.section_expr); |
| 3617 | if (section_gz.instructionsSlice().len == 0) { | 3735 | if (section_gz.instructionsSlice().len == 0) { |
| 3618 | // In this case we will send a len=0 body which can be encoded more efficiently. | 3736 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3619 | break :inst inst; | 3737 | break :inst inst; |
| ... | @@ -3636,7 +3754,7 @@ fn fnDecl( | ... | @@ -3636,7 +3754,7 @@ fn fnDecl( |
| 3636 | const inst = try expr( | 3754 | const inst = try expr( |
| 3637 | &decl_gz, | 3755 | &decl_gz, |
| 3638 | params_scope, | 3756 | params_scope, |
| 3639 | .{ .coerced_ty = .calling_convention_type }, | 3757 | .{ .rl = .{ .coerced_ty = .calling_convention_type } }, |
| 3640 | fn_proto.ast.callconv_expr, | 3758 | fn_proto.ast.callconv_expr, |
| 3641 | ); | 3759 | ); |
| 3642 | if (cc_gz.instructionsSlice().len == 0) { | 3760 | if (cc_gz.instructionsSlice().len == 0) { |
| ... | @@ -3658,7 +3776,7 @@ fn fnDecl( | ... | @@ -3658,7 +3776,7 @@ fn fnDecl( |
| 3658 | var ret_gz = decl_gz.makeSubBlock(params_scope); | 3776 | var ret_gz = decl_gz.makeSubBlock(params_scope); |
| 3659 | defer ret_gz.unstack(); | 3777 | defer ret_gz.unstack(); |
| 3660 | const ret_ref: Zir.Inst.Ref = inst: { | 3778 | const ret_ref: Zir.Inst.Ref = inst: { |
| 3661 | const inst = try expr(&ret_gz, params_scope, coerced_type_rl, fn_proto.ast.return_type); | 3779 | const inst = try expr(&ret_gz, params_scope, coerced_type_ri, fn_proto.ast.return_type); |
| 3662 | if (ret_gz.instructionsSlice().len == 0) { | 3780 | if (ret_gz.instructionsSlice().len == 0) { |
| 3663 | // In this case we will send a len=0 body which can be encoded more efficiently. | 3781 | // In this case we will send a len=0 body which can be encoded more efficiently. |
| 3664 | break :inst inst; | 3782 | break :inst inst; |
| ... | @@ -3712,10 +3830,13 @@ fn fnDecl( | ... | @@ -3712,10 +3830,13 @@ fn fnDecl( |
| 3712 | const lbrace_line = astgen.source_line - decl_gz.decl_line; | 3830 | const lbrace_line = astgen.source_line - decl_gz.decl_line; |
| 3713 | const lbrace_column = astgen.source_column; | 3831 | const lbrace_column = astgen.source_column; |
| 3714 | | 3832 | |
| 3715 | _ = try expr(&fn_gz, params_scope, .none, body_node); | 3833 | _ = try expr(&fn_gz, params_scope, .{ .rl = .none }, body_node); |
| 3716 | try checkUsed(gz, &fn_gz.base, params_scope); | 3834 | try checkUsed(gz, &fn_gz.base, params_scope); |
| 3717 | | 3835 | |
| 3718 | if (!fn_gz.endsWithNoReturn()) { | 3836 | if (!fn_gz.endsWithNoReturn()) { |
| | 3837 | // As our last action before the return, "pop" the error trace if needed |
| | 3838 | _ = try gz.addRestoreErrRetIndex(.ret, .always); |
| | 3839 | |
| 3719 | // Since we are adding the return instruction here, we must handle the coercion. | 3840 | // Since we are adding the return instruction here, we must handle the coercion. |
| 3720 | // We do this by using the `ret_tok` instruction. | 3841 | // We do this by using the `ret_tok` instruction. |
| 3721 | _ = try fn_gz.addUnTok(.ret_tok, .void_value, tree.lastToken(body_node)); | 3842 | _ = try fn_gz.addUnTok(.ret_tok, .void_value, tree.lastToken(body_node)); |
| ... | @@ -3808,13 +3929,13 @@ fn globalVarDecl( | ... | @@ -3808,13 +3929,13 @@ fn globalVarDecl( |
| 3808 | break :blk token_tags[maybe_extern_token] == .keyword_extern; | 3929 | break :blk token_tags[maybe_extern_token] == .keyword_extern; |
| 3809 | }; | 3930 | }; |
| 3810 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node == 0) .none else inst: { | 3931 | const align_inst: Zir.Inst.Ref = if (var_decl.ast.align_node == 0) .none else inst: { |
| 3811 | break :inst try expr(&block_scope, &block_scope.base, align_rl, var_decl.ast.align_node); | 3932 | break :inst try expr(&block_scope, &block_scope.base, align_ri, var_decl.ast.align_node); |
| 3812 | }; | 3933 | }; |
| 3813 | const addrspace_inst: Zir.Inst.Ref = if (var_decl.ast.addrspace_node == 0) .none else inst: { | 3934 | const addrspace_inst: Zir.Inst.Ref = if (var_decl.ast.addrspace_node == 0) .none else inst: { |
| 3814 | break :inst try expr(&block_scope, &block_scope.base, .{ .ty = .address_space_type }, var_decl.ast.addrspace_node); | 3935 | break :inst try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = .address_space_type } }, var_decl.ast.addrspace_node); |
| 3815 | }; | 3936 | }; |
| 3816 | const section_inst: Zir.Inst.Ref = if (var_decl.ast.section_node == 0) .none else inst: { | 3937 | const section_inst: Zir.Inst.Ref = if (var_decl.ast.section_node == 0) .none else inst: { |
| 3817 | break :inst try comptimeExpr(&block_scope, &block_scope.base, .{ .ty = .const_slice_u8_type }, var_decl.ast.section_node); | 3938 | break :inst try comptimeExpr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = .const_slice_u8_type } }, var_decl.ast.section_node); |
| 3818 | }; | 3939 | }; |
| 3819 | const has_section_or_addrspace = section_inst != .none or addrspace_inst != .none; | 3940 | const has_section_or_addrspace = section_inst != .none or addrspace_inst != .none; |
| 3820 | wip_members.nextDecl(is_pub, is_export, align_inst != .none, has_section_or_addrspace); | 3941 | wip_members.nextDecl(is_pub, is_export, align_inst != .none, has_section_or_addrspace); |
| ... | @@ -3854,7 +3975,7 @@ fn globalVarDecl( | ... | @@ -3854,7 +3975,7 @@ fn globalVarDecl( |
| 3854 | try expr( | 3975 | try expr( |
| 3855 | &block_scope, | 3976 | &block_scope, |
| 3856 | &block_scope.base, | 3977 | &block_scope.base, |
| 3857 | .{ .ty = .type_type }, | 3978 | .{ .rl = .{ .ty = .type_type } }, |
| 3858 | var_decl.ast.type_node, | 3979 | var_decl.ast.type_node, |
| 3859 | ) | 3980 | ) |
| 3860 | else | 3981 | else |
| ... | @@ -3863,7 +3984,7 @@ fn globalVarDecl( | ... | @@ -3863,7 +3984,7 @@ fn globalVarDecl( |
| 3863 | const init_inst = try expr( | 3984 | const init_inst = try expr( |
| 3864 | &block_scope, | 3985 | &block_scope, |
| 3865 | &block_scope.base, | 3986 | &block_scope.base, |
| 3866 | if (type_inst != .none) .{ .ty = type_inst } else .none, | 3987 | if (type_inst != .none) .{ .rl = .{ .ty = type_inst } } else .{ .rl = .none }, |
| 3867 | var_decl.ast.init_node, | 3988 | var_decl.ast.init_node, |
| 3868 | ); | 3989 | ); |
| 3869 | | 3990 | |
| ... | @@ -3952,7 +4073,7 @@ fn comptimeDecl( | ... | @@ -3952,7 +4073,7 @@ fn comptimeDecl( |
| 3952 | }; | 4073 | }; |
| 3953 | defer decl_block.unstack(); | 4074 | defer decl_block.unstack(); |
| 3954 | | 4075 | |
| 3955 | const block_result = try expr(&decl_block, &decl_block.base, .none, body_node); | 4076 | const block_result = try expr(&decl_block, &decl_block.base, .{ .rl = .none }, body_node); |
| 3956 | if (decl_block.isEmpty() or !decl_block.refIsNoReturn(block_result)) { | 4077 | if (decl_block.isEmpty() or !decl_block.refIsNoReturn(block_result)) { |
| 3957 | _ = try decl_block.addBreak(.break_inline, block_inst, .void_value); | 4078 | _ = try decl_block.addBreak(.break_inline, block_inst, .void_value); |
| 3958 | } | 4079 | } |
| ... | @@ -4156,8 +4277,12 @@ fn testDecl( | ... | @@ -4156,8 +4277,12 @@ fn testDecl( |
| 4156 | const lbrace_line = astgen.source_line - decl_block.decl_line; | 4277 | const lbrace_line = astgen.source_line - decl_block.decl_line; |
| 4157 | const lbrace_column = astgen.source_column; | 4278 | const lbrace_column = astgen.source_column; |
| 4158 | | 4279 | |
| 4159 | const block_result = try expr(&fn_block, &fn_block.base, .none, body_node); | 4280 | const block_result = try expr(&fn_block, &fn_block.base, .{ .rl = .none }, body_node); |
| 4160 | if (fn_block.isEmpty() or !fn_block.refIsNoReturn(block_result)) { | 4281 | if (fn_block.isEmpty() or !fn_block.refIsNoReturn(block_result)) { |
| | 4282 | |
| | 4283 | // As our last action before the return, "pop" the error trace if needed |
| | 4284 | _ = try gz.addRestoreErrRetIndex(.ret, .always); |
| | 4285 | |
| 4161 | // Since we are adding the return instruction here, we must handle the coercion. | 4286 | // Since we are adding the return instruction here, we must handle the coercion. |
| 4162 | // We do this by using the `ret_tok` instruction. | 4287 | // We do this by using the `ret_tok` instruction. |
| 4163 | _ = try fn_block.addUnTok(.ret_tok, .void_value, tree.lastToken(body_node)); | 4288 | _ = try fn_block.addUnTok(.ret_tok, .void_value, tree.lastToken(body_node)); |
| ... | @@ -4370,7 +4495,7 @@ fn structDeclInner( | ... | @@ -4370,7 +4495,7 @@ fn structDeclInner( |
| 4370 | if (layout == .Packed) { | 4495 | if (layout == .Packed) { |
| 4371 | try astgen.appendErrorNode(member.ast.align_expr, "unable to override alignment of packed struct fields", .{}); | 4496 | try astgen.appendErrorNode(member.ast.align_expr, "unable to override alignment of packed struct fields", .{}); |
| 4372 | } | 4497 | } |
| 4373 | const align_ref = try expr(&block_scope, &namespace.base, coerced_align_rl, member.ast.align_expr); | 4498 | const align_ref = try expr(&block_scope, &namespace.base, coerced_align_ri, member.ast.align_expr); |
| 4374 | if (!block_scope.endsWithNoReturn()) { | 4499 | if (!block_scope.endsWithNoReturn()) { |
| 4375 | _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref); | 4500 | _ = try block_scope.addBreak(.break_inline, decl_inst, align_ref); |
| 4376 | } | 4501 | } |
| ... | @@ -4383,9 +4508,9 @@ fn structDeclInner( | ... | @@ -4383,9 +4508,9 @@ fn structDeclInner( |
| 4383 | } | 4508 | } |
| 4384 | | 4509 | |
| 4385 | if (have_value) { | 4510 | if (have_value) { |
| 4386 | const rl: ResultLoc = if (field_type == .none) .none else .{ .coerced_ty = field_type }; | 4511 | const ri: ResultInfo = .{ .rl = if (field_type == .none) .none else .{ .coerced_ty = field_type } }; |
| 4387 | | 4512 | |
| 4388 | const default_inst = try expr(&block_scope, &namespace.base, rl, member.ast.value_expr); | 4513 | const default_inst = try expr(&block_scope, &namespace.base, ri, member.ast.value_expr); |
| 4389 | if (!block_scope.endsWithNoReturn()) { | 4514 | if (!block_scope.endsWithNoReturn()) { |
| 4390 | _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst); | 4515 | _ = try block_scope.addBreak(.break_inline, decl_inst, default_inst); |
| 4391 | } | 4516 | } |
| ... | @@ -4514,7 +4639,7 @@ fn unionDeclInner( | ... | @@ -4514,7 +4639,7 @@ fn unionDeclInner( |
| 4514 | return astgen.failNode(member_node, "union field missing type", .{}); | 4639 | return astgen.failNode(member_node, "union field missing type", .{}); |
| 4515 | } | 4640 | } |
| 4516 | if (have_align) { | 4641 | if (have_align) { |
| 4517 | const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr); | 4642 | const align_inst = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = .u32_type } }, member.ast.align_expr); |
| 4518 | wip_members.appendToField(@enumToInt(align_inst)); | 4643 | wip_members.appendToField(@enumToInt(align_inst)); |
| 4519 | } | 4644 | } |
| 4520 | if (have_value) { | 4645 | if (have_value) { |
| ... | @@ -4546,7 +4671,7 @@ fn unionDeclInner( | ... | @@ -4546,7 +4671,7 @@ fn unionDeclInner( |
| 4546 | }, | 4671 | }, |
| 4547 | ); | 4672 | ); |
| 4548 | } | 4673 | } |
| 4549 | const tag_value = try expr(&block_scope, &block_scope.base, .{ .ty = arg_inst }, member.ast.value_expr); | 4674 | const tag_value = try expr(&block_scope, &block_scope.base, .{ .rl = .{ .ty = arg_inst } }, member.ast.value_expr); |
| 4550 | wip_members.appendToField(@enumToInt(tag_value)); | 4675 | wip_members.appendToField(@enumToInt(tag_value)); |
| 4551 | } | 4676 | } |
| 4552 | } | 4677 | } |
| ... | @@ -4584,7 +4709,7 @@ fn unionDeclInner( | ... | @@ -4584,7 +4709,7 @@ fn unionDeclInner( |
| 4584 | fn containerDecl( | 4709 | fn containerDecl( |
| 4585 | gz: *GenZir, | 4710 | gz: *GenZir, |
| 4586 | scope: *Scope, | 4711 | scope: *Scope, |
| 4587 | rl: ResultLoc, | 4712 | ri: ResultInfo, |
| 4588 | node: Ast.Node.Index, | 4713 | node: Ast.Node.Index, |
| 4589 | container_decl: Ast.full.ContainerDecl, | 4714 | container_decl: Ast.full.ContainerDecl, |
| 4590 | ) InnerError!Zir.Inst.Ref { | 4715 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -4610,7 +4735,7 @@ fn containerDecl( | ... | @@ -4610,7 +4735,7 @@ fn containerDecl( |
| 4610 | } else std.builtin.Type.ContainerLayout.Auto; | 4735 | } else std.builtin.Type.ContainerLayout.Auto; |
| 4611 | | 4736 | |
| 4612 | const result = try structDeclInner(gz, scope, node, container_decl, layout, container_decl.ast.arg); | 4737 | const result = try structDeclInner(gz, scope, node, container_decl, layout, container_decl.ast.arg); |
| 4613 | return rvalue(gz, rl, result, node); | 4738 | return rvalue(gz, ri, result, node); |
| 4614 | }, | 4739 | }, |
| 4615 | .keyword_union => { | 4740 | .keyword_union => { |
| 4616 | const layout = if (container_decl.layout_token) |t| switch (token_tags[t]) { | 4741 | const layout = if (container_decl.layout_token) |t| switch (token_tags[t]) { |
| ... | @@ -4620,7 +4745,7 @@ fn containerDecl( | ... | @@ -4620,7 +4745,7 @@ fn containerDecl( |
| 4620 | } else std.builtin.Type.ContainerLayout.Auto; | 4745 | } else std.builtin.Type.ContainerLayout.Auto; |
| 4621 | | 4746 | |
| 4622 | const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, container_decl.ast.enum_token); | 4747 | const result = try unionDeclInner(gz, scope, node, container_decl.ast.members, layout, container_decl.ast.arg, container_decl.ast.enum_token); |
| 4623 | return rvalue(gz, rl, result, node); | 4748 | return rvalue(gz, ri, result, node); |
| 4624 | }, | 4749 | }, |
| 4625 | .keyword_enum => { | 4750 | .keyword_enum => { |
| 4626 | if (container_decl.layout_token) |t| { | 4751 | if (container_decl.layout_token) |t| { |
| ... | @@ -4750,7 +4875,7 @@ fn containerDecl( | ... | @@ -4750,7 +4875,7 @@ fn containerDecl( |
| 4750 | _ = try astgen.scanDecls(&namespace, container_decl.ast.members); | 4875 | _ = try astgen.scanDecls(&namespace, container_decl.ast.members); |
| 4751 | | 4876 | |
| 4752 | const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0) | 4877 | const arg_inst: Zir.Inst.Ref = if (container_decl.ast.arg != 0) |
| 4753 | try comptimeExpr(&block_scope, &namespace.base, .{ .ty = .type_type }, container_decl.ast.arg) | 4878 | try comptimeExpr(&block_scope, &namespace.base, .{ .rl = .{ .ty = .type_type } }, container_decl.ast.arg) |
| 4754 | else | 4879 | else |
| 4755 | .none; | 4880 | .none; |
| 4756 | | 4881 | |
| ... | @@ -4794,7 +4919,7 @@ fn containerDecl( | ... | @@ -4794,7 +4919,7 @@ fn containerDecl( |
| 4794 | }, | 4919 | }, |
| 4795 | ); | 4920 | ); |
| 4796 | } | 4921 | } |
| 4797 | const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .ty = arg_inst }, member.ast.value_expr); | 4922 | const tag_value_inst = try expr(&block_scope, &namespace.base, .{ .rl = .{ .ty = arg_inst } }, member.ast.value_expr); |
| 4798 | wip_members.appendToField(@enumToInt(tag_value_inst)); | 4923 | wip_members.appendToField(@enumToInt(tag_value_inst)); |
| 4799 | } | 4924 | } |
| 4800 | } | 4925 | } |
| ... | @@ -4825,7 +4950,7 @@ fn containerDecl( | ... | @@ -4825,7 +4950,7 @@ fn containerDecl( |
| 4825 | | 4950 | |
| 4826 | block_scope.unstack(); | 4951 | block_scope.unstack(); |
| 4827 | try gz.addNamespaceCaptures(&namespace); | 4952 | try gz.addNamespaceCaptures(&namespace); |
| 4828 | return rvalue(gz, rl, indexToRef(decl_inst), node); | 4953 | return rvalue(gz, ri, indexToRef(decl_inst), node); |
| 4829 | }, | 4954 | }, |
| 4830 | .keyword_opaque => { | 4955 | .keyword_opaque => { |
| 4831 | assert(container_decl.ast.arg == 0); | 4956 | assert(container_decl.ast.arg == 0); |
| ... | @@ -4875,7 +5000,7 @@ fn containerDecl( | ... | @@ -4875,7 +5000,7 @@ fn containerDecl( |
| 4875 | astgen.extra.appendSliceAssumeCapacity(decls_slice); | 5000 | astgen.extra.appendSliceAssumeCapacity(decls_slice); |
| 4876 | | 5001 | |
| 4877 | try gz.addNamespaceCaptures(&namespace); | 5002 | try gz.addNamespaceCaptures(&namespace); |
| 4878 | return rvalue(gz, rl, indexToRef(decl_inst), node); | 5003 | return rvalue(gz, ri, indexToRef(decl_inst), node); |
| 4879 | }, | 5004 | }, |
| 4880 | else => unreachable, | 5005 | else => unreachable, |
| 4881 | } | 5006 | } |
| ... | @@ -5006,7 +5131,7 @@ fn containerMember( | ... | @@ -5006,7 +5131,7 @@ fn containerMember( |
| 5006 | return .decl; | 5131 | return .decl; |
| 5007 | } | 5132 | } |
| 5008 | | 5133 | |
| 5009 | fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 5134 | fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 5010 | const astgen = gz.astgen; | 5135 | const astgen = gz.astgen; |
| 5011 | const gpa = astgen.gpa; | 5136 | const gpa = astgen.gpa; |
| 5012 | const tree = astgen.tree; | 5137 | const tree = astgen.tree; |
| ... | @@ -5061,13 +5186,13 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir | ... | @@ -5061,13 +5186,13 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir |
| 5061 | .fields_len = @intCast(u32, fields_len), | 5186 | .fields_len = @intCast(u32, fields_len), |
| 5062 | }); | 5187 | }); |
| 5063 | const result = try gz.addPlNodePayloadIndex(.error_set_decl, node, payload_index); | 5188 | const result = try gz.addPlNodePayloadIndex(.error_set_decl, node, payload_index); |
| 5064 | return rvalue(gz, rl, result, node); | 5189 | return rvalue(gz, ri, result, node); |
| 5065 | } | 5190 | } |
| 5066 | | 5191 | |
| 5067 | fn tryExpr( | 5192 | fn tryExpr( |
| 5068 | parent_gz: *GenZir, | 5193 | parent_gz: *GenZir, |
| 5069 | scope: *Scope, | 5194 | scope: *Scope, |
| 5070 | rl: ResultLoc, | 5195 | ri: ResultInfo, |
| 5071 | node: Ast.Node.Index, | 5196 | node: Ast.Node.Index, |
| 5072 | operand_node: Ast.Node.Index, | 5197 | operand_node: Ast.Node.Index, |
| 5073 | ) InnerError!Zir.Inst.Ref { | 5198 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -5097,15 +5222,15 @@ fn tryExpr( | ... | @@ -5097,15 +5222,15 @@ fn tryExpr( |
| 5097 | const try_line = astgen.source_line - parent_gz.decl_line; | 5222 | const try_line = astgen.source_line - parent_gz.decl_line; |
| 5098 | const try_column = astgen.source_column; | 5223 | const try_column = astgen.source_column; |
| 5099 | | 5224 | |
| 5100 | const operand_rl: ResultLoc = switch (rl) { | 5225 | const operand_ri: ResultInfo = switch (ri.rl) { |
| 5101 | .ref => .ref, | 5226 | .ref => .{ .rl = .ref, .ctx = .error_handling_expr }, |
| 5102 | else => .none, | 5227 | else => .{ .rl = .none, .ctx = .error_handling_expr }, |
| 5103 | }; | 5228 | }; |
| 5104 | // This could be a pointer or value depending on the `rl` parameter. | 5229 | // This could be a pointer or value depending on the `ri` parameter. |
| 5105 | const operand = try reachableExpr(parent_gz, scope, operand_rl, operand_node, node); | 5230 | const operand = try reachableExpr(parent_gz, scope, operand_ri, operand_node, node); |
| 5106 | const is_inline = parent_gz.force_comptime; | 5231 | const is_inline = parent_gz.force_comptime; |
| 5107 | const is_inline_bit = @as(u2, @boolToInt(is_inline)); | 5232 | const is_inline_bit = @as(u2, @boolToInt(is_inline)); |
| 5108 | const is_ptr_bit = @as(u2, @boolToInt(operand_rl == .ref)) << 1; | 5233 | const is_ptr_bit = @as(u2, @boolToInt(operand_ri.rl == .ref)) << 1; |
| 5109 | const block_tag: Zir.Inst.Tag = switch (is_inline_bit | is_ptr_bit) { | 5234 | const block_tag: Zir.Inst.Tag = switch (is_inline_bit | is_ptr_bit) { |
| 5110 | 0b00 => .@"try", | 5235 | 0b00 => .@"try", |
| 5111 | 0b01 => .@"try", | 5236 | 0b01 => .@"try", |
| ... | @@ -5120,7 +5245,7 @@ fn tryExpr( | ... | @@ -5120,7 +5245,7 @@ fn tryExpr( |
| 5120 | var else_scope = parent_gz.makeSubBlock(scope); | 5245 | var else_scope = parent_gz.makeSubBlock(scope); |
| 5121 | defer else_scope.unstack(); | 5246 | defer else_scope.unstack(); |
| 5122 | | 5247 | |
| 5123 | const err_tag = switch (rl) { | 5248 | const err_tag = switch (ri.rl) { |
| 5124 | .ref => Zir.Inst.Tag.err_union_code_ptr, | 5249 | .ref => Zir.Inst.Tag.err_union_code_ptr, |
| 5125 | else => Zir.Inst.Tag.err_union_code, | 5250 | else => Zir.Inst.Tag.err_union_code, |
| 5126 | }; | 5251 | }; |
| ... | @@ -5131,16 +5256,16 @@ fn tryExpr( | ... | @@ -5131,16 +5256,16 @@ fn tryExpr( |
| 5131 | | 5256 | |
| 5132 | try else_scope.setTryBody(try_inst, operand); | 5257 | try else_scope.setTryBody(try_inst, operand); |
| 5133 | const result = indexToRef(try_inst); | 5258 | const result = indexToRef(try_inst); |
| 5134 | switch (rl) { | 5259 | switch (ri.rl) { |
| 5135 | .ref => return result, | 5260 | .ref => return result, |
| 5136 | else => return rvalue(parent_gz, rl, result, node), | 5261 | else => return rvalue(parent_gz, ri, result, node), |
| 5137 | } | 5262 | } |
| 5138 | } | 5263 | } |
| 5139 | | 5264 | |
| 5140 | fn orelseCatchExpr( | 5265 | fn orelseCatchExpr( |
| 5141 | parent_gz: *GenZir, | 5266 | parent_gz: *GenZir, |
| 5142 | scope: *Scope, | 5267 | scope: *Scope, |
| 5143 | rl: ResultLoc, | 5268 | ri: ResultInfo, |
| 5144 | node: Ast.Node.Index, | 5269 | node: Ast.Node.Index, |
| 5145 | lhs: Ast.Node.Index, | 5270 | lhs: Ast.Node.Index, |
| 5146 | cond_op: Zir.Inst.Tag, | 5271 | cond_op: Zir.Inst.Tag, |
| ... | @@ -5152,20 +5277,22 @@ fn orelseCatchExpr( | ... | @@ -5152,20 +5277,22 @@ fn orelseCatchExpr( |
| 5152 | const astgen = parent_gz.astgen; | 5277 | const astgen = parent_gz.astgen; |
| 5153 | const tree = astgen.tree; | 5278 | const tree = astgen.tree; |
| 5154 | | 5279 | |
| | 5280 | const do_err_trace = astgen.fn_block != null and (cond_op == .is_non_err or cond_op == .is_non_err_ptr); |
| | 5281 | |
| 5155 | var block_scope = parent_gz.makeSubBlock(scope); | 5282 | var block_scope = parent_gz.makeSubBlock(scope); |
| 5156 | block_scope.setBreakResultLoc(rl); | 5283 | block_scope.setBreakResultInfo(ri); |
| 5157 | defer block_scope.unstack(); | 5284 | defer block_scope.unstack(); |
| 5158 | | 5285 | |
| 5159 | const operand_rl: ResultLoc = switch (block_scope.break_result_loc) { | 5286 | const operand_ri: ResultInfo = switch (block_scope.break_result_info.rl) { |
| 5160 | .ref => .ref, | 5287 | .ref => .{ .rl = .ref, .ctx = if (do_err_trace) .error_handling_expr else .none }, |
| 5161 | else => .none, | 5288 | else => .{ .rl = .none, .ctx = if (do_err_trace) .error_handling_expr else .none }, |
| 5162 | }; | 5289 | }; |
| 5163 | block_scope.break_count += 1; | 5290 | block_scope.break_count += 1; |
| 5164 | // This could be a pointer or value depending on the `operand_rl` parameter. | 5291 | // This could be a pointer or value depending on the `operand_ri` parameter. |
| 5165 | // We cannot use `block_scope.break_result_loc` because that has the bare | 5292 | // We cannot use `block_scope.break_result_info` because that has the bare |
| 5166 | // type, whereas this expression has the optional type. Later we make | 5293 | // type, whereas this expression has the optional type. Later we make |
| 5167 | // up for this fact by calling rvalue on the else branch. | 5294 | // up for this fact by calling rvalue on the else branch. |
| 5168 | const operand = try reachableExpr(&block_scope, &block_scope.base, operand_rl, lhs, rhs); | 5295 | const operand = try reachableExpr(&block_scope, &block_scope.base, operand_ri, lhs, rhs); |
| 5169 | const cond = try block_scope.addUnNode(cond_op, operand, node); | 5296 | const cond = try block_scope.addUnNode(cond_op, operand, node); |
| 5170 | const condbr = try block_scope.addCondBr(.condbr, node); | 5297 | const condbr = try block_scope.addCondBr(.condbr, node); |
| 5171 | | 5298 | |
| ... | @@ -5179,14 +5306,19 @@ fn orelseCatchExpr( | ... | @@ -5179,14 +5306,19 @@ fn orelseCatchExpr( |
| 5179 | | 5306 | |
| 5180 | // This could be a pointer or value depending on `unwrap_op`. | 5307 | // This could be a pointer or value depending on `unwrap_op`. |
| 5181 | const unwrapped_payload = try then_scope.addUnNode(unwrap_op, operand, node); | 5308 | const unwrapped_payload = try then_scope.addUnNode(unwrap_op, operand, node); |
| 5182 | const then_result = switch (rl) { | 5309 | const then_result = switch (ri.rl) { |
| 5183 | .ref => unwrapped_payload, | 5310 | .ref => unwrapped_payload, |
| 5184 | else => try rvalue(&then_scope, block_scope.break_result_loc, unwrapped_payload, node), | 5311 | else => try rvalue(&then_scope, block_scope.break_result_info, unwrapped_payload, node), |
| 5185 | }; | 5312 | }; |
| 5186 | | 5313 | |
| 5187 | var else_scope = block_scope.makeSubBlock(scope); | 5314 | var else_scope = block_scope.makeSubBlock(scope); |
| 5188 | defer else_scope.unstack(); | 5315 | defer else_scope.unstack(); |
| 5189 | | 5316 | |
| | 5317 | // We know that the operand (almost certainly) modified the error return trace, |
| | 5318 | // so signal to Sema that it should save the new index for restoring later. |
| | 5319 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, lhs)) |
| | 5320 | _ = try else_scope.addSaveErrRetIndex(.always); |
| | 5321 | |
| 5190 | var err_val_scope: Scope.LocalVal = undefined; | 5322 | var err_val_scope: Scope.LocalVal = undefined; |
| 5191 | const else_sub_scope = blk: { | 5323 | const else_sub_scope = blk: { |
| 5192 | const payload = payload_token orelse break :blk &else_scope.base; | 5324 | const payload = payload_token orelse break :blk &else_scope.base; |
| ... | @@ -5209,9 +5341,13 @@ fn orelseCatchExpr( | ... | @@ -5209,9 +5341,13 @@ fn orelseCatchExpr( |
| 5209 | break :blk &err_val_scope.base; | 5341 | break :blk &err_val_scope.base; |
| 5210 | }; | 5342 | }; |
| 5211 | | 5343 | |
| 5212 | const else_result = try expr(&else_scope, else_sub_scope, block_scope.break_result_loc, rhs); | 5344 | const else_result = try expr(&else_scope, else_sub_scope, block_scope.break_result_info, rhs); |
| 5213 | if (!else_scope.endsWithNoReturn()) { | 5345 | if (!else_scope.endsWithNoReturn()) { |
| 5214 | block_scope.break_count += 1; | 5346 | block_scope.break_count += 1; |
| | 5347 | |
| | 5348 | // As our last action before the break, "pop" the error trace if needed |
| | 5349 | if (do_err_trace) |
| | 5350 | try restoreErrRetIndex(&else_scope, .{ .block = block }, block_scope.break_result_info, rhs, else_result); |
| 5215 | } | 5351 | } |
| 5216 | try checkUsed(parent_gz, &else_scope.base, else_sub_scope); | 5352 | try checkUsed(parent_gz, &else_scope.base, else_sub_scope); |
| 5217 | | 5353 | |
| ... | @@ -5220,9 +5356,9 @@ fn orelseCatchExpr( | ... | @@ -5220,9 +5356,9 @@ fn orelseCatchExpr( |
| 5220 | // instructions or not. | 5356 | // instructions or not. |
| 5221 | | 5357 | |
| 5222 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; | 5358 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; |
| 5223 | return finishThenElseBlock( | 5359 | const result = try finishThenElseBlock( |
| 5224 | parent_gz, | 5360 | parent_gz, |
| 5225 | rl, | 5361 | ri, |
| 5226 | node, | 5362 | node, |
| 5227 | &block_scope, | 5363 | &block_scope, |
| 5228 | &then_scope, | 5364 | &then_scope, |
| ... | @@ -5235,12 +5371,13 @@ fn orelseCatchExpr( | ... | @@ -5235,12 +5371,13 @@ fn orelseCatchExpr( |
| 5235 | block, | 5371 | block, |
| 5236 | break_tag, | 5372 | break_tag, |
| 5237 | ); | 5373 | ); |
| | 5374 | return result; |
| 5238 | } | 5375 | } |
| 5239 | | 5376 | |
| 5240 | /// Supports `else_scope` stacked on `then_scope` stacked on `block_scope`. Unstacks `else_scope` then `then_scope`. | 5377 | /// Supports `else_scope` stacked on `then_scope` stacked on `block_scope`. Unstacks `else_scope` then `then_scope`. |
| 5241 | fn finishThenElseBlock( | 5378 | fn finishThenElseBlock( |
| 5242 | parent_gz: *GenZir, | 5379 | parent_gz: *GenZir, |
| 5243 | rl: ResultLoc, | 5380 | ri: ResultInfo, |
| 5244 | node: Ast.Node.Index, | 5381 | node: Ast.Node.Index, |
| 5245 | block_scope: *GenZir, | 5382 | block_scope: *GenZir, |
| 5246 | then_scope: *GenZir, | 5383 | then_scope: *GenZir, |
| ... | @@ -5255,7 +5392,7 @@ fn finishThenElseBlock( | ... | @@ -5255,7 +5392,7 @@ fn finishThenElseBlock( |
| 5255 | ) InnerError!Zir.Inst.Ref { | 5392 | ) InnerError!Zir.Inst.Ref { |
| 5256 | // We now have enough information to decide whether the result instruction should | 5393 | // We now have enough information to decide whether the result instruction should |
| 5257 | // be communicated via result location pointer or break instructions. | 5394 | // be communicated via result location pointer or break instructions. |
| 5258 | const strat = rl.strategy(block_scope); | 5395 | const strat = ri.rl.strategy(block_scope); |
| 5259 | // else_scope may be stacked on then_scope, so check for no-return on then_scope manually | 5396 | // else_scope may be stacked on then_scope, so check for no-return on then_scope manually |
| 5260 | const tags = parent_gz.astgen.instructions.items(.tag); | 5397 | const tags = parent_gz.astgen.instructions.items(.tag); |
| 5261 | const then_slice = then_scope.instructionsSliceUpto(else_scope); | 5398 | const then_slice = then_scope.instructionsSliceUpto(else_scope); |
| ... | @@ -5285,9 +5422,9 @@ fn finishThenElseBlock( | ... | @@ -5285,9 +5422,9 @@ fn finishThenElseBlock( |
| 5285 | try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break); | 5422 | try setCondBrPayload(condbr, cond, then_scope, then_break, else_scope, else_break); |
| 5286 | } | 5423 | } |
| 5287 | const block_ref = indexToRef(main_block); | 5424 | const block_ref = indexToRef(main_block); |
| 5288 | switch (rl) { | 5425 | switch (ri.rl) { |
| 5289 | .ref => return block_ref, | 5426 | .ref => return block_ref, |
| 5290 | else => return rvalue(parent_gz, rl, block_ref, node), | 5427 | else => return rvalue(parent_gz, ri, block_ref, node), |
| 5291 | } | 5428 | } |
| 5292 | }, | 5429 | }, |
| 5293 | } | 5430 | } |
| ... | @@ -5306,14 +5443,14 @@ fn tokenIdentEql(astgen: *AstGen, token1: Ast.TokenIndex, token2: Ast.TokenIndex | ... | @@ -5306,14 +5443,14 @@ fn tokenIdentEql(astgen: *AstGen, token1: Ast.TokenIndex, token2: Ast.TokenIndex |
| 5306 | fn fieldAccess( | 5443 | fn fieldAccess( |
| 5307 | gz: *GenZir, | 5444 | gz: *GenZir, |
| 5308 | scope: *Scope, | 5445 | scope: *Scope, |
| 5309 | rl: ResultLoc, | 5446 | ri: ResultInfo, |
| 5310 | node: Ast.Node.Index, | 5447 | node: Ast.Node.Index, |
| 5311 | ) InnerError!Zir.Inst.Ref { | 5448 | ) InnerError!Zir.Inst.Ref { |
| 5312 | switch (rl) { | 5449 | switch (ri.rl) { |
| 5313 | .ref => return addFieldAccess(.field_ptr, gz, scope, .ref, node), | 5450 | .ref => return addFieldAccess(.field_ptr, gz, scope, .{ .rl = .ref }, node), |
| 5314 | else => { | 5451 | else => { |
| 5315 | const access = try addFieldAccess(.field_val, gz, scope, .none, node); | 5452 | const access = try addFieldAccess(.field_val, gz, scope, .{ .rl = .none }, node); |
| 5316 | return rvalue(gz, rl, access, node); | 5453 | return rvalue(gz, ri, access, node); |
| 5317 | }, | 5454 | }, |
| 5318 | } | 5455 | } |
| 5319 | } | 5456 | } |
| ... | @@ -5322,7 +5459,7 @@ fn addFieldAccess( | ... | @@ -5322,7 +5459,7 @@ fn addFieldAccess( |
| 5322 | tag: Zir.Inst.Tag, | 5459 | tag: Zir.Inst.Tag, |
| 5323 | gz: *GenZir, | 5460 | gz: *GenZir, |
| 5324 | scope: *Scope, | 5461 | scope: *Scope, |
| 5325 | lhs_rl: ResultLoc, | 5462 | lhs_ri: ResultInfo, |
| 5326 | node: Ast.Node.Index, | 5463 | node: Ast.Node.Index, |
| 5327 | ) InnerError!Zir.Inst.Ref { | 5464 | ) InnerError!Zir.Inst.Ref { |
| 5328 | const astgen = gz.astgen; | 5465 | const astgen = gz.astgen; |
| ... | @@ -5336,7 +5473,7 @@ fn addFieldAccess( | ... | @@ -5336,7 +5473,7 @@ fn addFieldAccess( |
| 5336 | const str_index = try astgen.identAsString(field_ident); | 5473 | const str_index = try astgen.identAsString(field_ident); |
| 5337 | | 5474 | |
| 5338 | return gz.addPlNode(tag, node, Zir.Inst.Field{ | 5475 | return gz.addPlNode(tag, node, Zir.Inst.Field{ |
| 5339 | .lhs = try expr(gz, scope, lhs_rl, object_node), | 5476 | .lhs = try expr(gz, scope, lhs_ri, object_node), |
| 5340 | .field_name_start = str_index, | 5477 | .field_name_start = str_index, |
| 5341 | }); | 5478 | }); |
| 5342 | } | 5479 | } |
| ... | @@ -5344,20 +5481,20 @@ fn addFieldAccess( | ... | @@ -5344,20 +5481,20 @@ fn addFieldAccess( |
| 5344 | fn arrayAccess( | 5481 | fn arrayAccess( |
| 5345 | gz: *GenZir, | 5482 | gz: *GenZir, |
| 5346 | scope: *Scope, | 5483 | scope: *Scope, |
| 5347 | rl: ResultLoc, | 5484 | ri: ResultInfo, |
| 5348 | node: Ast.Node.Index, | 5485 | node: Ast.Node.Index, |
| 5349 | ) InnerError!Zir.Inst.Ref { | 5486 | ) InnerError!Zir.Inst.Ref { |
| 5350 | const astgen = gz.astgen; | 5487 | const astgen = gz.astgen; |
| 5351 | const tree = astgen.tree; | 5488 | const tree = astgen.tree; |
| 5352 | const node_datas = tree.nodes.items(.data); | 5489 | const node_datas = tree.nodes.items(.data); |
| 5353 | switch (rl) { | 5490 | switch (ri.rl) { |
| 5354 | .ref => return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ | 5491 | .ref => return gz.addPlNode(.elem_ptr_node, node, Zir.Inst.Bin{ |
| 5355 | .lhs = try expr(gz, scope, .ref, node_datas[node].lhs), | 5492 | .lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[node].lhs), |
| 5356 | .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), | 5493 | .rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs), |
| 5357 | }), | 5494 | }), |
| 5358 | else => return rvalue(gz, rl, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ | 5495 | else => return rvalue(gz, ri, try gz.addPlNode(.elem_val_node, node, Zir.Inst.Bin{ |
| 5359 | .lhs = try expr(gz, scope, .none, node_datas[node].lhs), | 5496 | .lhs = try expr(gz, scope, .{ .rl = .none }, node_datas[node].lhs), |
| 5360 | .rhs = try expr(gz, scope, .{ .ty = .usize_type }, node_datas[node].rhs), | 5497 | .rhs = try expr(gz, scope, .{ .rl = .{ .ty = .usize_type } }, node_datas[node].rhs), |
| 5361 | }), node), | 5498 | }), node), |
| 5362 | } | 5499 | } |
| 5363 | } | 5500 | } |
| ... | @@ -5365,7 +5502,7 @@ fn arrayAccess( | ... | @@ -5365,7 +5502,7 @@ fn arrayAccess( |
| 5365 | fn simpleBinOp( | 5502 | fn simpleBinOp( |
| 5366 | gz: *GenZir, | 5503 | gz: *GenZir, |
| 5367 | scope: *Scope, | 5504 | scope: *Scope, |
| 5368 | rl: ResultLoc, | 5505 | ri: ResultInfo, |
| 5369 | node: Ast.Node.Index, | 5506 | node: Ast.Node.Index, |
| 5370 | op_inst_tag: Zir.Inst.Tag, | 5507 | op_inst_tag: Zir.Inst.Tag, |
| 5371 | ) InnerError!Zir.Inst.Ref { | 5508 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -5374,15 +5511,15 @@ fn simpleBinOp( | ... | @@ -5374,15 +5511,15 @@ fn simpleBinOp( |
| 5374 | const node_datas = tree.nodes.items(.data); | 5511 | const node_datas = tree.nodes.items(.data); |
| 5375 | | 5512 | |
| 5376 | const result = try gz.addPlNode(op_inst_tag, node, Zir.Inst.Bin{ | 5513 | const result = try gz.addPlNode(op_inst_tag, node, Zir.Inst.Bin{ |
| 5377 | .lhs = try reachableExpr(gz, scope, .none, node_datas[node].lhs, node), | 5514 | .lhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].lhs, node), |
| 5378 | .rhs = try reachableExpr(gz, scope, .none, node_datas[node].rhs, node), | 5515 | .rhs = try reachableExpr(gz, scope, .{ .rl = .none }, node_datas[node].rhs, node), |
| 5379 | }); | 5516 | }); |
| 5380 | return rvalue(gz, rl, result, node); | 5517 | return rvalue(gz, ri, result, node); |
| 5381 | } | 5518 | } |
| 5382 | | 5519 | |
| 5383 | fn simpleStrTok( | 5520 | fn simpleStrTok( |
| 5384 | gz: *GenZir, | 5521 | gz: *GenZir, |
| 5385 | rl: ResultLoc, | 5522 | ri: ResultInfo, |
| 5386 | ident_token: Ast.TokenIndex, | 5523 | ident_token: Ast.TokenIndex, |
| 5387 | node: Ast.Node.Index, | 5524 | node: Ast.Node.Index, |
| 5388 | op_inst_tag: Zir.Inst.Tag, | 5525 | op_inst_tag: Zir.Inst.Tag, |
| ... | @@ -5390,13 +5527,13 @@ fn simpleStrTok( | ... | @@ -5390,13 +5527,13 @@ fn simpleStrTok( |
| 5390 | const astgen = gz.astgen; | 5527 | const astgen = gz.astgen; |
| 5391 | const str_index = try astgen.identAsString(ident_token); | 5528 | const str_index = try astgen.identAsString(ident_token); |
| 5392 | const result = try gz.addStrTok(op_inst_tag, str_index, ident_token); | 5529 | const result = try gz.addStrTok(op_inst_tag, str_index, ident_token); |
| 5393 | return rvalue(gz, rl, result, node); | 5530 | return rvalue(gz, ri, result, node); |
| 5394 | } | 5531 | } |
| 5395 | | 5532 | |
| 5396 | fn boolBinOp( | 5533 | fn boolBinOp( |
| 5397 | gz: *GenZir, | 5534 | gz: *GenZir, |
| 5398 | scope: *Scope, | 5535 | scope: *Scope, |
| 5399 | rl: ResultLoc, | 5536 | ri: ResultInfo, |
| 5400 | node: Ast.Node.Index, | 5537 | node: Ast.Node.Index, |
| 5401 | zir_tag: Zir.Inst.Tag, | 5538 | zir_tag: Zir.Inst.Tag, |
| 5402 | ) InnerError!Zir.Inst.Ref { | 5539 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -5404,25 +5541,25 @@ fn boolBinOp( | ... | @@ -5404,25 +5541,25 @@ fn boolBinOp( |
| 5404 | const tree = astgen.tree; | 5541 | const tree = astgen.tree; |
| 5405 | const node_datas = tree.nodes.items(.data); | 5542 | const node_datas = tree.nodes.items(.data); |
| 5406 | | 5543 | |
| 5407 | const lhs = try expr(gz, scope, bool_rl, node_datas[node].lhs); | 5544 | const lhs = try expr(gz, scope, bool_ri, node_datas[node].lhs); |
| 5408 | const bool_br = try gz.addBoolBr(zir_tag, lhs); | 5545 | const bool_br = try gz.addBoolBr(zir_tag, lhs); |
| 5409 | | 5546 | |
| 5410 | var rhs_scope = gz.makeSubBlock(scope); | 5547 | var rhs_scope = gz.makeSubBlock(scope); |
| 5411 | defer rhs_scope.unstack(); | 5548 | defer rhs_scope.unstack(); |
| 5412 | const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_rl, node_datas[node].rhs); | 5549 | const rhs = try expr(&rhs_scope, &rhs_scope.base, bool_ri, node_datas[node].rhs); |
| 5413 | if (!gz.refIsNoReturn(rhs)) { | 5550 | if (!gz.refIsNoReturn(rhs)) { |
| 5414 | _ = try rhs_scope.addBreak(.break_inline, bool_br, rhs); | 5551 | _ = try rhs_scope.addBreak(.break_inline, bool_br, rhs); |
| 5415 | } | 5552 | } |
| 5416 | try rhs_scope.setBoolBrBody(bool_br); | 5553 | try rhs_scope.setBoolBrBody(bool_br); |
| 5417 | | 5554 | |
| 5418 | const block_ref = indexToRef(bool_br); | 5555 | const block_ref = indexToRef(bool_br); |
| 5419 | return rvalue(gz, rl, block_ref, node); | 5556 | return rvalue(gz, ri, block_ref, node); |
| 5420 | } | 5557 | } |
| 5421 | | 5558 | |
| 5422 | fn ifExpr( | 5559 | fn ifExpr( |
| 5423 | parent_gz: *GenZir, | 5560 | parent_gz: *GenZir, |
| 5424 | scope: *Scope, | 5561 | scope: *Scope, |
| 5425 | rl: ResultLoc, | 5562 | ri: ResultInfo, |
| 5426 | node: Ast.Node.Index, | 5563 | node: Ast.Node.Index, |
| 5427 | if_full: Ast.full.If, | 5564 | if_full: Ast.full.If, |
| 5428 | ) InnerError!Zir.Inst.Ref { | 5565 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -5430,8 +5567,10 @@ fn ifExpr( | ... | @@ -5430,8 +5567,10 @@ fn ifExpr( |
| 5430 | const tree = astgen.tree; | 5567 | const tree = astgen.tree; |
| 5431 | const token_tags = tree.tokens.items(.tag); | 5568 | const token_tags = tree.tokens.items(.tag); |
| 5432 | | 5569 | |
| | 5570 | const do_err_trace = astgen.fn_block != null and if_full.error_token != null; |
| | 5571 | |
| 5433 | var block_scope = parent_gz.makeSubBlock(scope); | 5572 | var block_scope = parent_gz.makeSubBlock(scope); |
| 5434 | block_scope.setBreakResultLoc(rl); | 5573 | block_scope.setBreakResultInfo(ri); |
| 5435 | defer block_scope.unstack(); | 5574 | defer block_scope.unstack(); |
| 5436 | | 5575 | |
| 5437 | const payload_is_ref = if (if_full.payload_token) |payload_token| | 5576 | const payload_is_ref = if (if_full.payload_token) |payload_token| |
| ... | @@ -5445,23 +5584,23 @@ fn ifExpr( | ... | @@ -5445,23 +5584,23 @@ fn ifExpr( |
| 5445 | bool_bit: Zir.Inst.Ref, | 5584 | bool_bit: Zir.Inst.Ref, |
| 5446 | } = c: { | 5585 | } = c: { |
| 5447 | if (if_full.error_token) |_| { | 5586 | if (if_full.error_token) |_| { |
| 5448 | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; | 5587 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none, .ctx = .error_handling_expr }; |
| 5449 | const err_union = try expr(&block_scope, &block_scope.base, cond_rl, if_full.ast.cond_expr); | 5588 | const err_union = try expr(&block_scope, &block_scope.base, cond_ri, if_full.ast.cond_expr); |
| 5450 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err; | 5589 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err; |
| 5451 | break :c .{ | 5590 | break :c .{ |
| 5452 | .inst = err_union, | 5591 | .inst = err_union, |
| 5453 | .bool_bit = try block_scope.addUnNode(tag, err_union, if_full.ast.cond_expr), | 5592 | .bool_bit = try block_scope.addUnNode(tag, err_union, if_full.ast.cond_expr), |
| 5454 | }; | 5593 | }; |
| 5455 | } else if (if_full.payload_token) |_| { | 5594 | } else if (if_full.payload_token) |_| { |
| 5456 | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; | 5595 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 5457 | const optional = try expr(&block_scope, &block_scope.base, cond_rl, if_full.ast.cond_expr); | 5596 | const optional = try expr(&block_scope, &block_scope.base, cond_ri, if_full.ast.cond_expr); |
| 5458 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null; | 5597 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null; |
| 5459 | break :c .{ | 5598 | break :c .{ |
| 5460 | .inst = optional, | 5599 | .inst = optional, |
| 5461 | .bool_bit = try block_scope.addUnNode(tag, optional, if_full.ast.cond_expr), | 5600 | .bool_bit = try block_scope.addUnNode(tag, optional, if_full.ast.cond_expr), |
| 5462 | }; | 5601 | }; |
| 5463 | } else { | 5602 | } else { |
| 5464 | const cond = try expr(&block_scope, &block_scope.base, bool_rl, if_full.ast.cond_expr); | 5603 | const cond = try expr(&block_scope, &block_scope.base, bool_ri, if_full.ast.cond_expr); |
| 5465 | break :c .{ | 5604 | break :c .{ |
| 5466 | .inst = cond, | 5605 | .inst = cond, |
| 5467 | .bool_bit = cond, | 5606 | .bool_bit = cond, |
| ... | @@ -5537,7 +5676,7 @@ fn ifExpr( | ... | @@ -5537,7 +5676,7 @@ fn ifExpr( |
| 5537 | } | 5676 | } |
| 5538 | }; | 5677 | }; |
| 5539 | | 5678 | |
| 5540 | const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_loc, if_full.ast.then_expr); | 5679 | const then_result = try expr(&then_scope, then_sub_scope, block_scope.break_result_info, if_full.ast.then_expr); |
| 5541 | if (!then_scope.endsWithNoReturn()) { | 5680 | if (!then_scope.endsWithNoReturn()) { |
| 5542 | block_scope.break_count += 1; | 5681 | block_scope.break_count += 1; |
| 5543 | } | 5682 | } |
| ... | @@ -5550,6 +5689,11 @@ fn ifExpr( | ... | @@ -5550,6 +5689,11 @@ fn ifExpr( |
| 5550 | var else_scope = parent_gz.makeSubBlock(scope); | 5689 | var else_scope = parent_gz.makeSubBlock(scope); |
| 5551 | defer else_scope.unstack(); | 5690 | defer else_scope.unstack(); |
| 5552 | | 5691 | |
| | 5692 | // We know that the operand (almost certainly) modified the error return trace, |
| | 5693 | // so signal to Sema that it should save the new index for restoring later. |
| | 5694 | if (do_err_trace and nodeMayAppendToErrorTrace(tree, if_full.ast.cond_expr)) |
| | 5695 | _ = try else_scope.addSaveErrRetIndex(.always); |
| | 5696 | |
| 5553 | const else_node = if_full.ast.else_expr; | 5697 | const else_node = if_full.ast.else_expr; |
| 5554 | const else_info: struct { | 5698 | const else_info: struct { |
| 5555 | src: Ast.Node.Index, | 5699 | src: Ast.Node.Index, |
| ... | @@ -5582,9 +5726,13 @@ fn ifExpr( | ... | @@ -5582,9 +5726,13 @@ fn ifExpr( |
| 5582 | break :s &else_scope.base; | 5726 | break :s &else_scope.base; |
| 5583 | } | 5727 | } |
| 5584 | }; | 5728 | }; |
| 5585 | const e = try expr(&else_scope, sub_scope, block_scope.break_result_loc, else_node); | 5729 | const e = try expr(&else_scope, sub_scope, block_scope.break_result_info, else_node); |
| 5586 | if (!else_scope.endsWithNoReturn()) { | 5730 | if (!else_scope.endsWithNoReturn()) { |
| 5587 | block_scope.break_count += 1; | 5731 | block_scope.break_count += 1; |
| | 5732 | |
| | 5733 | // As our last action before the break, "pop" the error trace if needed |
| | 5734 | if (do_err_trace) |
| | 5735 | try restoreErrRetIndex(&else_scope, .{ .block = block }, block_scope.break_result_info, else_node, e); |
| 5588 | } | 5736 | } |
| 5589 | try checkUsed(parent_gz, &else_scope.base, sub_scope); | 5737 | try checkUsed(parent_gz, &else_scope.base, sub_scope); |
| 5590 | try else_scope.addDbgBlockEnd(); | 5738 | try else_scope.addDbgBlockEnd(); |
| ... | @@ -5594,17 +5742,17 @@ fn ifExpr( | ... | @@ -5594,17 +5742,17 @@ fn ifExpr( |
| 5594 | }; | 5742 | }; |
| 5595 | } else .{ | 5743 | } else .{ |
| 5596 | .src = if_full.ast.then_expr, | 5744 | .src = if_full.ast.then_expr, |
| 5597 | .result = switch (rl) { | 5745 | .result = switch (ri.rl) { |
| 5598 | // Explicitly store void to ptr result loc if there is no else branch | 5746 | // Explicitly store void to ptr result loc if there is no else branch |
| 5599 | .ptr, .block_ptr => try rvalue(&else_scope, rl, .void_value, node), | 5747 | .ptr, .block_ptr => try rvalue(&else_scope, ri, .void_value, node), |
| 5600 | else => .none, | 5748 | else => .none, |
| 5601 | }, | 5749 | }, |
| 5602 | }; | 5750 | }; |
| 5603 | | 5751 | |
| 5604 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; | 5752 | const break_tag: Zir.Inst.Tag = if (parent_gz.force_comptime) .break_inline else .@"break"; |
| 5605 | return finishThenElseBlock( | 5753 | const result = try finishThenElseBlock( |
| 5606 | parent_gz, | 5754 | parent_gz, |
| 5607 | rl, | 5755 | ri, |
| 5608 | node, | 5756 | node, |
| 5609 | &block_scope, | 5757 | &block_scope, |
| 5610 | &then_scope, | 5758 | &then_scope, |
| ... | @@ -5617,6 +5765,7 @@ fn ifExpr( | ... | @@ -5617,6 +5765,7 @@ fn ifExpr( |
| 5617 | block, | 5765 | block, |
| 5618 | break_tag, | 5766 | break_tag, |
| 5619 | ); | 5767 | ); |
| | 5768 | return result; |
| 5620 | } | 5769 | } |
| 5621 | | 5770 | |
| 5622 | /// Supports `else_scope` stacked on `then_scope`. Unstacks `else_scope` then `then_scope`. | 5771 | /// Supports `else_scope` stacked on `then_scope`. Unstacks `else_scope` then `then_scope`. |
| ... | @@ -5737,7 +5886,7 @@ fn setCondBrPayloadElideBlockStorePtr( | ... | @@ -5737,7 +5886,7 @@ fn setCondBrPayloadElideBlockStorePtr( |
| 5737 | fn whileExpr( | 5886 | fn whileExpr( |
| 5738 | parent_gz: *GenZir, | 5887 | parent_gz: *GenZir, |
| 5739 | scope: *Scope, | 5888 | scope: *Scope, |
| 5740 | rl: ResultLoc, | 5889 | ri: ResultInfo, |
| 5741 | node: Ast.Node.Index, | 5890 | node: Ast.Node.Index, |
| 5742 | while_full: Ast.full.While, | 5891 | while_full: Ast.full.While, |
| 5743 | is_statement: bool, | 5892 | is_statement: bool, |
| ... | @@ -5757,7 +5906,7 @@ fn whileExpr( | ... | @@ -5757,7 +5906,7 @@ fn whileExpr( |
| 5757 | | 5906 | |
| 5758 | var loop_scope = parent_gz.makeSubBlock(scope); | 5907 | var loop_scope = parent_gz.makeSubBlock(scope); |
| 5759 | loop_scope.is_inline = is_inline; | 5908 | loop_scope.is_inline = is_inline; |
| 5760 | loop_scope.setBreakResultLoc(rl); | 5909 | loop_scope.setBreakResultInfo(ri); |
| 5761 | defer loop_scope.unstack(); | 5910 | defer loop_scope.unstack(); |
| 5762 | defer loop_scope.labeled_breaks.deinit(astgen.gpa); | 5911 | defer loop_scope.labeled_breaks.deinit(astgen.gpa); |
| 5763 | | 5912 | |
| ... | @@ -5775,23 +5924,23 @@ fn whileExpr( | ... | @@ -5775,23 +5924,23 @@ fn whileExpr( |
| 5775 | bool_bit: Zir.Inst.Ref, | 5924 | bool_bit: Zir.Inst.Ref, |
| 5776 | } = c: { | 5925 | } = c: { |
| 5777 | if (while_full.error_token) |_| { | 5926 | if (while_full.error_token) |_| { |
| 5778 | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; | 5927 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 5779 | const err_union = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr); | 5928 | const err_union = try expr(&continue_scope, &continue_scope.base, cond_ri, while_full.ast.cond_expr); |
| 5780 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err; | 5929 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_err_ptr else .is_non_err; |
| 5781 | break :c .{ | 5930 | break :c .{ |
| 5782 | .inst = err_union, | 5931 | .inst = err_union, |
| 5783 | .bool_bit = try continue_scope.addUnNode(tag, err_union, while_full.ast.then_expr), | 5932 | .bool_bit = try continue_scope.addUnNode(tag, err_union, while_full.ast.then_expr), |
| 5784 | }; | 5933 | }; |
| 5785 | } else if (while_full.payload_token) |_| { | 5934 | } else if (while_full.payload_token) |_| { |
| 5786 | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; | 5935 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 5787 | const optional = try expr(&continue_scope, &continue_scope.base, cond_rl, while_full.ast.cond_expr); | 5936 | const optional = try expr(&continue_scope, &continue_scope.base, cond_ri, while_full.ast.cond_expr); |
| 5788 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null; | 5937 | const tag: Zir.Inst.Tag = if (payload_is_ref) .is_non_null_ptr else .is_non_null; |
| 5789 | break :c .{ | 5938 | break :c .{ |
| 5790 | .inst = optional, | 5939 | .inst = optional, |
| 5791 | .bool_bit = try continue_scope.addUnNode(tag, optional, while_full.ast.then_expr), | 5940 | .bool_bit = try continue_scope.addUnNode(tag, optional, while_full.ast.then_expr), |
| 5792 | }; | 5941 | }; |
| 5793 | } else { | 5942 | } else { |
| 5794 | const cond = try expr(&continue_scope, &continue_scope.base, bool_rl, while_full.ast.cond_expr); | 5943 | const cond = try expr(&continue_scope, &continue_scope.base, bool_ri, while_full.ast.cond_expr); |
| 5795 | break :c .{ | 5944 | break :c .{ |
| 5796 | .inst = cond, | 5945 | .inst = cond, |
| 5797 | .bool_bit = cond, | 5946 | .bool_bit = cond, |
| ... | @@ -5910,7 +6059,7 @@ fn whileExpr( | ... | @@ -5910,7 +6059,7 @@ fn whileExpr( |
| 5910 | if (dbg_var_name) |some| { | 6059 | if (dbg_var_name) |some| { |
| 5911 | try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst); | 6060 | try then_scope.addDbgVar(.dbg_var_val, some, dbg_var_inst); |
| 5912 | } | 6061 | } |
| 5913 | const then_result = try expr(&then_scope, then_sub_scope, .none, while_full.ast.then_expr); | 6062 | const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, while_full.ast.then_expr); |
| 5914 | _ = try addEnsureResult(&then_scope, then_result, while_full.ast.then_expr); | 6063 | _ = try addEnsureResult(&then_scope, then_result, while_full.ast.then_expr); |
| 5915 | | 6064 | |
| 5916 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6065 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| ... | @@ -5955,7 +6104,7 @@ fn whileExpr( | ... | @@ -5955,7 +6104,7 @@ fn whileExpr( |
| 5955 | // control flow apply to outer loops; not this one. | 6104 | // control flow apply to outer loops; not this one. |
| 5956 | loop_scope.continue_block = 0; | 6105 | loop_scope.continue_block = 0; |
| 5957 | loop_scope.break_block = 0; | 6106 | loop_scope.break_block = 0; |
| 5958 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node); | 6107 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); |
| 5959 | if (is_statement) { | 6108 | if (is_statement) { |
| 5960 | _ = try addEnsureResult(&else_scope, else_result, else_node); | 6109 | _ = try addEnsureResult(&else_scope, else_result, else_node); |
| 5961 | } | 6110 | } |
| ... | @@ -5982,7 +6131,7 @@ fn whileExpr( | ... | @@ -5982,7 +6131,7 @@ fn whileExpr( |
| 5982 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; | 6131 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 5983 | const result = try finishThenElseBlock( | 6132 | const result = try finishThenElseBlock( |
| 5984 | parent_gz, | 6133 | parent_gz, |
| 5985 | rl, | 6134 | ri, |
| 5986 | node, | 6135 | node, |
| 5987 | &loop_scope, | 6136 | &loop_scope, |
| 5988 | &then_scope, | 6137 | &then_scope, |
| ... | @@ -6004,7 +6153,7 @@ fn whileExpr( | ... | @@ -6004,7 +6153,7 @@ fn whileExpr( |
| 6004 | fn forExpr( | 6153 | fn forExpr( |
| 6005 | parent_gz: *GenZir, | 6154 | parent_gz: *GenZir, |
| 6006 | scope: *Scope, | 6155 | scope: *Scope, |
| 6007 | rl: ResultLoc, | 6156 | ri: ResultInfo, |
| 6008 | node: Ast.Node.Index, | 6157 | node: Ast.Node.Index, |
| 6009 | for_full: Ast.full.While, | 6158 | for_full: Ast.full.While, |
| 6010 | is_statement: bool, | 6159 | is_statement: bool, |
| ... | @@ -6027,8 +6176,8 @@ fn forExpr( | ... | @@ -6027,8 +6176,8 @@ fn forExpr( |
| 6027 | | 6176 | |
| 6028 | try emitDbgNode(parent_gz, for_full.ast.cond_expr); | 6177 | try emitDbgNode(parent_gz, for_full.ast.cond_expr); |
| 6029 | | 6178 | |
| 6030 | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; | 6179 | const cond_ri: ResultInfo = .{ .rl = if (payload_is_ref) .ref else .none }; |
| 6031 | const array_ptr = try expr(parent_gz, scope, cond_rl, for_full.ast.cond_expr); | 6180 | const array_ptr = try expr(parent_gz, scope, cond_ri, for_full.ast.cond_expr); |
| 6032 | const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr); | 6181 | const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr); |
| 6033 | | 6182 | |
| 6034 | const index_ptr = blk: { | 6183 | const index_ptr = blk: { |
| ... | @@ -6045,7 +6194,7 @@ fn forExpr( | ... | @@ -6045,7 +6194,7 @@ fn forExpr( |
| 6045 | | 6194 | |
| 6046 | var loop_scope = parent_gz.makeSubBlock(scope); | 6195 | var loop_scope = parent_gz.makeSubBlock(scope); |
| 6047 | loop_scope.is_inline = is_inline; | 6196 | loop_scope.is_inline = is_inline; |
| 6048 | loop_scope.setBreakResultLoc(rl); | 6197 | loop_scope.setBreakResultInfo(ri); |
| 6049 | defer loop_scope.unstack(); | 6198 | defer loop_scope.unstack(); |
| 6050 | defer loop_scope.labeled_breaks.deinit(astgen.gpa); | 6199 | defer loop_scope.labeled_breaks.deinit(astgen.gpa); |
| 6051 | | 6200 | |
| ... | @@ -6149,7 +6298,7 @@ fn forExpr( | ... | @@ -6149,7 +6298,7 @@ fn forExpr( |
| 6149 | break :blk &index_scope.base; | 6298 | break :blk &index_scope.base; |
| 6150 | }; | 6299 | }; |
| 6151 | | 6300 | |
| 6152 | const then_result = try expr(&then_scope, then_sub_scope, .none, for_full.ast.then_expr); | 6301 | const then_result = try expr(&then_scope, then_sub_scope, .{ .rl = .none }, for_full.ast.then_expr); |
| 6153 | _ = try addEnsureResult(&then_scope, then_result, for_full.ast.then_expr); | 6302 | _ = try addEnsureResult(&then_scope, then_result, for_full.ast.then_expr); |
| 6154 | | 6303 | |
| 6155 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); | 6304 | try checkUsed(parent_gz, &then_scope.base, then_sub_scope); |
| ... | @@ -6168,7 +6317,7 @@ fn forExpr( | ... | @@ -6168,7 +6317,7 @@ fn forExpr( |
| 6168 | // control flow apply to outer loops; not this one. | 6317 | // control flow apply to outer loops; not this one. |
| 6169 | loop_scope.continue_block = 0; | 6318 | loop_scope.continue_block = 0; |
| 6170 | loop_scope.break_block = 0; | 6319 | loop_scope.break_block = 0; |
| 6171 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_loc, else_node); | 6320 | const else_result = try expr(&else_scope, sub_scope, loop_scope.break_result_info, else_node); |
| 6172 | if (is_statement) { | 6321 | if (is_statement) { |
| 6173 | _ = try addEnsureResult(&else_scope, else_result, else_node); | 6322 | _ = try addEnsureResult(&else_scope, else_result, else_node); |
| 6174 | } | 6323 | } |
| ... | @@ -6193,7 +6342,7 @@ fn forExpr( | ... | @@ -6193,7 +6342,7 @@ fn forExpr( |
| 6193 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; | 6342 | const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break"; |
| 6194 | const result = try finishThenElseBlock( | 6343 | const result = try finishThenElseBlock( |
| 6195 | parent_gz, | 6344 | parent_gz, |
| 6196 | rl, | 6345 | ri, |
| 6197 | node, | 6346 | node, |
| 6198 | &loop_scope, | 6347 | &loop_scope, |
| 6199 | &then_scope, | 6348 | &then_scope, |
| ... | @@ -6215,7 +6364,7 @@ fn forExpr( | ... | @@ -6215,7 +6364,7 @@ fn forExpr( |
| 6215 | fn switchExpr( | 6364 | fn switchExpr( |
| 6216 | parent_gz: *GenZir, | 6365 | parent_gz: *GenZir, |
| 6217 | scope: *Scope, | 6366 | scope: *Scope, |
| 6218 | rl: ResultLoc, | 6367 | ri: ResultInfo, |
| 6219 | switch_node: Ast.Node.Index, | 6368 | switch_node: Ast.Node.Index, |
| 6220 | ) InnerError!Zir.Inst.Ref { | 6369 | ) InnerError!Zir.Inst.Ref { |
| 6221 | const astgen = parent_gz.astgen; | 6370 | const astgen = parent_gz.astgen; |
| ... | @@ -6346,13 +6495,13 @@ fn switchExpr( | ... | @@ -6346,13 +6495,13 @@ fn switchExpr( |
| 6346 | } | 6495 | } |
| 6347 | } | 6496 | } |
| 6348 | | 6497 | |
| 6349 | const operand_rl: ResultLoc = if (any_payload_is_ref) .ref else .none; | 6498 | const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none }; |
| 6350 | const raw_operand = try expr(parent_gz, scope, operand_rl, operand_node); | 6499 | const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node); |
| 6351 | const cond_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_cond_ref else .switch_cond; | 6500 | const cond_tag: Zir.Inst.Tag = if (any_payload_is_ref) .switch_cond_ref else .switch_cond; |
| 6352 | const cond = try parent_gz.addUnNode(cond_tag, raw_operand, operand_node); | 6501 | const cond = try parent_gz.addUnNode(cond_tag, raw_operand, operand_node); |
| 6353 | // We need the type of the operand to use as the result location for all the prong items. | 6502 | // We need the type of the operand to use as the result location for all the prong items. |
| 6354 | const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node); | 6503 | const cond_ty_inst = try parent_gz.addUnNode(.typeof, cond, operand_node); |
| 6355 | const item_rl: ResultLoc = .{ .ty = cond_ty_inst }; | 6504 | const item_ri: ResultInfo = .{ .rl = .{ .ty = cond_ty_inst } }; |
| 6356 | | 6505 | |
| 6357 | // This contains the data that goes into the `extra` array for the SwitchBlock/SwitchBlockMulti, | 6506 | // This contains the data that goes into the `extra` array for the SwitchBlock/SwitchBlockMulti, |
| 6358 | // except the first cases_nodes.len slots are a table that indexes payloads later in the array, with | 6507 | // except the first cases_nodes.len slots are a table that indexes payloads later in the array, with |
| ... | @@ -6369,7 +6518,7 @@ fn switchExpr( | ... | @@ -6369,7 +6518,7 @@ fn switchExpr( |
| 6369 | var block_scope = parent_gz.makeSubBlock(scope); | 6518 | var block_scope = parent_gz.makeSubBlock(scope); |
| 6370 | // block_scope not used for collecting instructions | 6519 | // block_scope not used for collecting instructions |
| 6371 | block_scope.instructions_top = GenZir.unstacked_top; | 6520 | block_scope.instructions_top = GenZir.unstacked_top; |
| 6372 | block_scope.setBreakResultLoc(rl); | 6521 | block_scope.setBreakResultInfo(ri); |
| 6373 | | 6522 | |
| 6374 | // This gets added to the parent block later, after the item expressions. | 6523 | // This gets added to the parent block later, after the item expressions. |
| 6375 | const switch_block = try parent_gz.makeBlockInst(.switch_block, switch_node); | 6524 | const switch_block = try parent_gz.makeBlockInst(.switch_block, switch_node); |
| ... | @@ -6510,7 +6659,7 @@ fn switchExpr( | ... | @@ -6510,7 +6659,7 @@ fn switchExpr( |
| 6510 | if (node_tags[item_node] == .switch_range) continue; | 6659 | if (node_tags[item_node] == .switch_range) continue; |
| 6511 | items_len += 1; | 6660 | items_len += 1; |
| 6512 | | 6661 | |
| 6513 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); | 6662 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node); |
| 6514 | try payloads.append(gpa, @enumToInt(item_inst)); | 6663 | try payloads.append(gpa, @enumToInt(item_inst)); |
| 6515 | } | 6664 | } |
| 6516 | | 6665 | |
| ... | @@ -6520,8 +6669,8 @@ fn switchExpr( | ... | @@ -6520,8 +6669,8 @@ fn switchExpr( |
| 6520 | if (node_tags[range] != .switch_range) continue; | 6669 | if (node_tags[range] != .switch_range) continue; |
| 6521 | ranges_len += 1; | 6670 | ranges_len += 1; |
| 6522 | | 6671 | |
| 6523 | const first = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].lhs); | 6672 | const first = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].lhs); |
| 6524 | const last = try comptimeExpr(parent_gz, scope, item_rl, node_datas[range].rhs); | 6673 | const last = try comptimeExpr(parent_gz, scope, item_ri, node_datas[range].rhs); |
| 6525 | try payloads.appendSlice(gpa, &[_]u32{ | 6674 | try payloads.appendSlice(gpa, &[_]u32{ |
| 6526 | @enumToInt(first), @enumToInt(last), | 6675 | @enumToInt(first), @enumToInt(last), |
| 6527 | }); | 6676 | }); |
| ... | @@ -6539,7 +6688,7 @@ fn switchExpr( | ... | @@ -6539,7 +6688,7 @@ fn switchExpr( |
| 6539 | scalar_case_index += 1; | 6688 | scalar_case_index += 1; |
| 6540 | try payloads.resize(gpa, header_index + 2); // item, body_len | 6689 | try payloads.resize(gpa, header_index + 2); // item, body_len |
| 6541 | const item_node = case.ast.values[0]; | 6690 | const item_node = case.ast.values[0]; |
| 6542 | const item_inst = try comptimeExpr(parent_gz, scope, item_rl, item_node); | 6691 | const item_inst = try comptimeExpr(parent_gz, scope, item_ri, item_node); |
| 6543 | payloads.items[header_index] = @enumToInt(item_inst); | 6692 | payloads.items[header_index] = @enumToInt(item_inst); |
| 6544 | break :blk header_index + 1; | 6693 | break :blk header_index + 1; |
| 6545 | }; | 6694 | }; |
| ... | @@ -6558,7 +6707,7 @@ fn switchExpr( | ... | @@ -6558,7 +6707,7 @@ fn switchExpr( |
| 6558 | if (dbg_var_tag_name) |some| { | 6707 | if (dbg_var_tag_name) |some| { |
| 6559 | try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst); | 6708 | try case_scope.addDbgVar(.dbg_var_val, some, dbg_var_tag_inst); |
| 6560 | } | 6709 | } |
| 6561 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_loc, case.ast.target_expr); | 6710 | const case_result = try expr(&case_scope, sub_scope, block_scope.break_result_info, case.ast.target_expr); |
| 6562 | try checkUsed(parent_gz, &case_scope.base, sub_scope); | 6711 | try checkUsed(parent_gz, &case_scope.base, sub_scope); |
| 6563 | try case_scope.addDbgBlockEnd(); | 6712 | try case_scope.addDbgBlockEnd(); |
| 6564 | if (!parent_gz.refIsNoReturn(case_result)) { | 6713 | if (!parent_gz.refIsNoReturn(case_result)) { |
| ... | @@ -6600,7 +6749,7 @@ fn switchExpr( | ... | @@ -6600,7 +6749,7 @@ fn switchExpr( |
| 6600 | | 6749 | |
| 6601 | zir_datas[switch_block].pl_node.payload_index = payload_index; | 6750 | zir_datas[switch_block].pl_node.payload_index = payload_index; |
| 6602 | | 6751 | |
| 6603 | const strat = rl.strategy(&block_scope); | 6752 | const strat = ri.rl.strategy(&block_scope); |
| 6604 | for (payloads.items[case_table_start..case_table_end]) |start_index, i| { | 6753 | for (payloads.items[case_table_start..case_table_end]) |start_index, i| { |
| 6605 | var body_len_index = start_index; | 6754 | var body_len_index = start_index; |
| 6606 | var end_index = start_index; | 6755 | var end_index = start_index; |
| ... | @@ -6672,8 +6821,8 @@ fn switchExpr( | ... | @@ -6672,8 +6821,8 @@ fn switchExpr( |
| 6672 | } | 6821 | } |
| 6673 | | 6822 | |
| 6674 | const block_ref = indexToRef(switch_block); | 6823 | const block_ref = indexToRef(switch_block); |
| 6675 | if (strat.tag == .break_operand and strat.elide_store_to_block_ptr_instructions and rl != .ref) | 6824 | if (strat.tag == .break_operand and strat.elide_store_to_block_ptr_instructions and ri.rl != .ref) |
| 6676 | return rvalue(parent_gz, rl, block_ref, switch_node); | 6825 | return rvalue(parent_gz, ri, block_ref, switch_node); |
| 6677 | return block_ref; | 6826 | return block_ref; |
| 6678 | } | 6827 | } |
| 6679 | | 6828 | |
| ... | @@ -6713,6 +6862,10 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -6713,6 +6862,10 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6713 | if (operand_node == 0) { | 6862 | if (operand_node == 0) { |
| 6714 | // Returning a void value; skip error defers. | 6863 | // Returning a void value; skip error defers. |
| 6715 | try genDefers(gz, defer_outer, scope, .normal_only); | 6864 | try genDefers(gz, defer_outer, scope, .normal_only); |
| | 6865 | |
| | 6866 | // As our last action before the return, "pop" the error trace if needed |
| | 6867 | _ = try gz.addRestoreErrRetIndex(.ret, .always); |
| | 6868 | |
| 6716 | _ = try gz.addUnNode(.ret_node, .void_value, node); | 6869 | _ = try gz.addUnNode(.ret_node, .void_value, node); |
| 6717 | return Zir.Inst.Ref.unreachable_value; | 6870 | return Zir.Inst.Ref.unreachable_value; |
| 6718 | } | 6871 | } |
| ... | @@ -6736,30 +6889,36 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -6736,30 +6889,36 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6736 | return Zir.Inst.Ref.unreachable_value; | 6889 | return Zir.Inst.Ref.unreachable_value; |
| 6737 | } | 6890 | } |
| 6738 | | 6891 | |
| 6739 | const rl: ResultLoc = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{ | 6892 | const ri: ResultInfo = if (nodeMayNeedMemoryLocation(tree, operand_node, true)) .{ |
| 6740 | .ptr = .{ .inst = try gz.addNode(.ret_ptr, node) }, | 6893 | .rl = .{ .ptr = .{ .inst = try gz.addNode(.ret_ptr, node) } }, |
| | 6894 | .ctx = .@"return", |
| 6741 | } else .{ | 6895 | } else .{ |
| 6742 | .ty = try gz.addNode(.ret_type, node), | 6896 | .rl = .{ .ty = try gz.addNode(.ret_type, node) }, |
| | 6897 | .ctx = .@"return", |
| 6743 | }; | 6898 | }; |
| 6744 | const prev_anon_name_strategy = gz.anon_name_strategy; | 6899 | const prev_anon_name_strategy = gz.anon_name_strategy; |
| 6745 | gz.anon_name_strategy = .func; | 6900 | gz.anon_name_strategy = .func; |
| 6746 | const operand = try reachableExpr(gz, scope, rl, operand_node, node); | 6901 | const operand = try reachableExpr(gz, scope, ri, operand_node, node); |
| 6747 | gz.anon_name_strategy = prev_anon_name_strategy; | 6902 | gz.anon_name_strategy = prev_anon_name_strategy; |
| 6748 | | 6903 | |
| 6749 | switch (nodeMayEvalToError(tree, operand_node)) { | 6904 | switch (nodeMayEvalToError(tree, operand_node)) { |
| 6750 | .never => { | 6905 | .never => { |
| 6751 | // Returning a value that cannot be an error; skip error defers. | 6906 | // Returning a value that cannot be an error; skip error defers. |
| 6752 | try genDefers(gz, defer_outer, scope, .normal_only); | 6907 | try genDefers(gz, defer_outer, scope, .normal_only); |
| | 6908 | |
| | 6909 | // As our last action before the return, "pop" the error trace if needed |
| | 6910 | _ = try gz.addRestoreErrRetIndex(.ret, .always); |
| | 6911 | |
| 6753 | try emitDbgStmt(gz, ret_line, ret_column); | 6912 | try emitDbgStmt(gz, ret_line, ret_column); |
| 6754 | try gz.addRet(rl, operand, node); | 6913 | try gz.addRet(ri, operand, node); |
| 6755 | return Zir.Inst.Ref.unreachable_value; | 6914 | return Zir.Inst.Ref.unreachable_value; |
| 6756 | }, | 6915 | }, |
| 6757 | .always => { | 6916 | .always => { |
| 6758 | // Value is always an error. Emit both error defers and regular defers. | 6917 | // Value is always an error. Emit both error defers and regular defers. |
| 6759 | const err_code = if (rl == .ptr) try gz.addUnNode(.load, rl.ptr.inst, node) else operand; | 6918 | const err_code = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; |
| 6760 | try genDefers(gz, defer_outer, scope, .{ .both = err_code }); | 6919 | try genDefers(gz, defer_outer, scope, .{ .both = err_code }); |
| 6761 | try emitDbgStmt(gz, ret_line, ret_column); | 6920 | try emitDbgStmt(gz, ret_line, ret_column); |
| 6762 | try gz.addRet(rl, operand, node); | 6921 | try gz.addRet(ri, operand, node); |
| 6763 | return Zir.Inst.Ref.unreachable_value; | 6922 | return Zir.Inst.Ref.unreachable_value; |
| 6764 | }, | 6923 | }, |
| 6765 | .maybe => { | 6924 | .maybe => { |
| ... | @@ -6768,12 +6927,17 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -6768,12 +6927,17 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6768 | // Only regular defers; no branch needed. | 6927 | // Only regular defers; no branch needed. |
| 6769 | try genDefers(gz, defer_outer, scope, .normal_only); | 6928 | try genDefers(gz, defer_outer, scope, .normal_only); |
| 6770 | try emitDbgStmt(gz, ret_line, ret_column); | 6929 | try emitDbgStmt(gz, ret_line, ret_column); |
| 6771 | try gz.addRet(rl, operand, node); | 6930 | |
| | 6931 | // As our last action before the return, "pop" the error trace if needed |
| | 6932 | const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; |
| | 6933 | _ = try gz.addRestoreErrRetIndex(.ret, .{ .if_non_error = result }); |
| | 6934 | |
| | 6935 | try gz.addRet(ri, operand, node); |
| 6772 | return Zir.Inst.Ref.unreachable_value; | 6936 | return Zir.Inst.Ref.unreachable_value; |
| 6773 | } | 6937 | } |
| 6774 | | 6938 | |
| 6775 | // Emit conditional branch for generating errdefers. | 6939 | // Emit conditional branch for generating errdefers. |
| 6776 | const result = if (rl == .ptr) try gz.addUnNode(.load, rl.ptr.inst, node) else operand; | 6940 | const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand; |
| 6777 | const is_non_err = try gz.addUnNode(.is_non_err, result, node); | 6941 | const is_non_err = try gz.addUnNode(.is_non_err, result, node); |
| 6778 | const condbr = try gz.addCondBr(.condbr, node); | 6942 | const condbr = try gz.addCondBr(.condbr, node); |
| 6779 | | 6943 | |
| ... | @@ -6781,8 +6945,12 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -6781,8 +6945,12 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6781 | defer then_scope.unstack(); | 6945 | defer then_scope.unstack(); |
| 6782 | | 6946 | |
| 6783 | try genDefers(&then_scope, defer_outer, scope, .normal_only); | 6947 | try genDefers(&then_scope, defer_outer, scope, .normal_only); |
| | 6948 | |
| | 6949 | // As our last action before the return, "pop" the error trace if needed |
| | 6950 | _ = try then_scope.addRestoreErrRetIndex(.ret, .always); |
| | 6951 | |
| 6784 | try emitDbgStmt(&then_scope, ret_line, ret_column); | 6952 | try emitDbgStmt(&then_scope, ret_line, ret_column); |
| 6785 | try then_scope.addRet(rl, operand, node); | 6953 | try then_scope.addRet(ri, operand, node); |
| 6786 | | 6954 | |
| 6787 | var else_scope = gz.makeSubBlock(scope); | 6955 | var else_scope = gz.makeSubBlock(scope); |
| 6788 | defer else_scope.unstack(); | 6956 | defer else_scope.unstack(); |
| ... | @@ -6792,7 +6960,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref | ... | @@ -6792,7 +6960,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref |
| 6792 | }; | 6960 | }; |
| 6793 | try genDefers(&else_scope, defer_outer, scope, which_ones); | 6961 | try genDefers(&else_scope, defer_outer, scope, which_ones); |
| 6794 | try emitDbgStmt(&else_scope, ret_line, ret_column); | 6962 | try emitDbgStmt(&else_scope, ret_line, ret_column); |
| 6795 | try else_scope.addRet(rl, operand, node); | 6963 | try else_scope.addRet(ri, operand, node); |
| 6796 | | 6964 | |
| 6797 | try setCondBrPayload(condbr, is_non_err, &then_scope, 0, &else_scope, 0); | 6965 | try setCondBrPayload(condbr, is_non_err, &then_scope, 0, &else_scope, 0); |
| 6798 | | 6966 | |
| ... | @@ -6825,7 +6993,7 @@ fn parseBitCount(buf: []const u8) std.fmt.ParseIntError!u16 { | ... | @@ -6825,7 +6993,7 @@ fn parseBitCount(buf: []const u8) std.fmt.ParseIntError!u16 { |
| 6825 | fn identifier( | 6993 | fn identifier( |
| 6826 | gz: *GenZir, | 6994 | gz: *GenZir, |
| 6827 | scope: *Scope, | 6995 | scope: *Scope, |
| 6828 | rl: ResultLoc, | 6996 | ri: ResultInfo, |
| 6829 | ident: Ast.Node.Index, | 6997 | ident: Ast.Node.Index, |
| 6830 | ) InnerError!Zir.Inst.Ref { | 6998 | ) InnerError!Zir.Inst.Ref { |
| 6831 | const tracy = trace(@src()); | 6999 | const tracy = trace(@src()); |
| ... | @@ -6844,7 +7012,7 @@ fn identifier( | ... | @@ -6844,7 +7012,7 @@ fn identifier( |
| 6844 | // if not @"" syntax, just use raw token slice | 7012 | // if not @"" syntax, just use raw token slice |
| 6845 | if (ident_name_raw[0] != '@') { | 7013 | if (ident_name_raw[0] != '@') { |
| 6846 | if (primitives.get(ident_name_raw)) |zir_const_ref| { | 7014 | if (primitives.get(ident_name_raw)) |zir_const_ref| { |
| 6847 | return rvalue(gz, rl, zir_const_ref, ident); | 7015 | return rvalue(gz, ri, zir_const_ref, ident); |
| 6848 | } | 7016 | } |
| 6849 | | 7017 | |
| 6850 | if (ident_name_raw.len >= 2) integer: { | 7018 | if (ident_name_raw.len >= 2) integer: { |
| ... | @@ -6877,19 +7045,19 @@ fn identifier( | ... | @@ -6877,19 +7045,19 @@ fn identifier( |
| 6877 | .bit_count = bit_count, | 7045 | .bit_count = bit_count, |
| 6878 | } }, | 7046 | } }, |
| 6879 | }); | 7047 | }); |
| 6880 | return rvalue(gz, rl, result, ident); | 7048 | return rvalue(gz, ri, result, ident); |
| 6881 | } | 7049 | } |
| 6882 | } | 7050 | } |
| 6883 | } | 7051 | } |
| 6884 | | 7052 | |
| 6885 | // Local variables, including function parameters. | 7053 | // Local variables, including function parameters. |
| 6886 | return localVarRef(gz, scope, rl, ident, ident_token); | 7054 | return localVarRef(gz, scope, ri, ident, ident_token); |
| 6887 | } | 7055 | } |
| 6888 | | 7056 | |
| 6889 | fn localVarRef( | 7057 | fn localVarRef( |
| 6890 | gz: *GenZir, | 7058 | gz: *GenZir, |
| 6891 | scope: *Scope, | 7059 | scope: *Scope, |
| 6892 | rl: ResultLoc, | 7060 | ri: ResultInfo, |
| 6893 | ident: Ast.Node.Index, | 7061 | ident: Ast.Node.Index, |
| 6894 | ident_token: Ast.TokenIndex, | 7062 | ident_token: Ast.TokenIndex, |
| 6895 | ) InnerError!Zir.Inst.Ref { | 7063 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -6907,7 +7075,7 @@ fn localVarRef( | ... | @@ -6907,7 +7075,7 @@ fn localVarRef( |
| 6907 | if (local_val.name == name_str_index) { | 7075 | if (local_val.name == name_str_index) { |
| 6908 | // Locals cannot shadow anything, so we do not need to look for ambiguous | 7076 | // Locals cannot shadow anything, so we do not need to look for ambiguous |
| 6909 | // references in this case. | 7077 | // references in this case. |
| 6910 | if (rl == .discard) { | 7078 | if (ri.rl == .discard) { |
| 6911 | local_val.discarded = ident_token; | 7079 | local_val.discarded = ident_token; |
| 6912 | } else { | 7080 | } else { |
| 6913 | local_val.used = ident_token; | 7081 | local_val.used = ident_token; |
| ... | @@ -6923,14 +7091,14 @@ fn localVarRef( | ... | @@ -6923,14 +7091,14 @@ fn localVarRef( |
| 6923 | gpa, | 7091 | gpa, |
| 6924 | ); | 7092 | ); |
| 6925 | | 7093 | |
| 6926 | return rvalue(gz, rl, value_inst, ident); | 7094 | return rvalue(gz, ri, value_inst, ident); |
| 6927 | } | 7095 | } |
| 6928 | s = local_val.parent; | 7096 | s = local_val.parent; |
| 6929 | }, | 7097 | }, |
| 6930 | .local_ptr => { | 7098 | .local_ptr => { |
| 6931 | const local_ptr = s.cast(Scope.LocalPtr).?; | 7099 | const local_ptr = s.cast(Scope.LocalPtr).?; |
| 6932 | if (local_ptr.name == name_str_index) { | 7100 | if (local_ptr.name == name_str_index) { |
| 6933 | if (rl == .discard) { | 7101 | if (ri.rl == .discard) { |
| 6934 | local_ptr.discarded = ident_token; | 7102 | local_ptr.discarded = ident_token; |
| 6935 | } else { | 7103 | } else { |
| 6936 | local_ptr.used = ident_token; | 7104 | local_ptr.used = ident_token; |
| ... | @@ -6955,11 +7123,11 @@ fn localVarRef( | ... | @@ -6955,11 +7123,11 @@ fn localVarRef( |
| 6955 | gpa, | 7123 | gpa, |
| 6956 | ); | 7124 | ); |
| 6957 | | 7125 | |
| 6958 | switch (rl) { | 7126 | switch (ri.rl) { |
| 6959 | .ref => return ptr_inst, | 7127 | .ref => return ptr_inst, |
| 6960 | else => { | 7128 | else => { |
| 6961 | const loaded = try gz.addUnNode(.load, ptr_inst, ident); | 7129 | const loaded = try gz.addUnNode(.load, ptr_inst, ident); |
| 6962 | return rvalue(gz, rl, loaded, ident); | 7130 | return rvalue(gz, ri, loaded, ident); |
| 6963 | }, | 7131 | }, |
| 6964 | } | 7132 | } |
| 6965 | } | 7133 | } |
| ... | @@ -6992,11 +7160,11 @@ fn localVarRef( | ... | @@ -6992,11 +7160,11 @@ fn localVarRef( |
| 6992 | | 7160 | |
| 6993 | // Decl references happen by name rather than ZIR index so that when unrelated | 7161 | // Decl references happen by name rather than ZIR index so that when unrelated |
| 6994 | // decls are modified, ZIR code containing references to them can be unmodified. | 7162 | // decls are modified, ZIR code containing references to them can be unmodified. |
| 6995 | switch (rl) { | 7163 | switch (ri.rl) { |
| 6996 | .ref => return gz.addStrTok(.decl_ref, name_str_index, ident_token), | 7164 | .ref => return gz.addStrTok(.decl_ref, name_str_index, ident_token), |
| 6997 | else => { | 7165 | else => { |
| 6998 | const result = try gz.addStrTok(.decl_val, name_str_index, ident_token); | 7166 | const result = try gz.addStrTok(.decl_val, name_str_index, ident_token); |
| 6999 | return rvalue(gz, rl, result, ident); | 7167 | return rvalue(gz, ri, result, ident); |
| 7000 | }, | 7168 | }, |
| 7001 | } | 7169 | } |
| 7002 | } | 7170 | } |
| ... | @@ -7040,7 +7208,7 @@ fn tunnelThroughClosure( | ... | @@ -7040,7 +7208,7 @@ fn tunnelThroughClosure( |
| 7040 | | 7208 | |
| 7041 | fn stringLiteral( | 7209 | fn stringLiteral( |
| 7042 | gz: *GenZir, | 7210 | gz: *GenZir, |
| 7043 | rl: ResultLoc, | 7211 | ri: ResultInfo, |
| 7044 | node: Ast.Node.Index, | 7212 | node: Ast.Node.Index, |
| 7045 | ) InnerError!Zir.Inst.Ref { | 7213 | ) InnerError!Zir.Inst.Ref { |
| 7046 | const astgen = gz.astgen; | 7214 | const astgen = gz.astgen; |
| ... | @@ -7055,12 +7223,12 @@ fn stringLiteral( | ... | @@ -7055,12 +7223,12 @@ fn stringLiteral( |
| 7055 | .len = str.len, | 7223 | .len = str.len, |
| 7056 | } }, | 7224 | } }, |
| 7057 | }); | 7225 | }); |
| 7058 | return rvalue(gz, rl, result, node); | 7226 | return rvalue(gz, ri, result, node); |
| 7059 | } | 7227 | } |
| 7060 | | 7228 | |
| 7061 | fn multilineStringLiteral( | 7229 | fn multilineStringLiteral( |
| 7062 | gz: *GenZir, | 7230 | gz: *GenZir, |
| 7063 | rl: ResultLoc, | 7231 | ri: ResultInfo, |
| 7064 | node: Ast.Node.Index, | 7232 | node: Ast.Node.Index, |
| 7065 | ) InnerError!Zir.Inst.Ref { | 7233 | ) InnerError!Zir.Inst.Ref { |
| 7066 | const astgen = gz.astgen; | 7234 | const astgen = gz.astgen; |
| ... | @@ -7072,10 +7240,10 @@ fn multilineStringLiteral( | ... | @@ -7072,10 +7240,10 @@ fn multilineStringLiteral( |
| 7072 | .len = str.len, | 7240 | .len = str.len, |
| 7073 | } }, | 7241 | } }, |
| 7074 | }); | 7242 | }); |
| 7075 | return rvalue(gz, rl, result, node); | 7243 | return rvalue(gz, ri, result, node); |
| 7076 | } | 7244 | } |
| 7077 | | 7245 | |
| 7078 | fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 7246 | fn charLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { |
| 7079 | const astgen = gz.astgen; | 7247 | const astgen = gz.astgen; |
| 7080 | const tree = astgen.tree; | 7248 | const tree = astgen.tree; |
| 7081 | const main_tokens = tree.nodes.items(.main_token); | 7249 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -7085,7 +7253,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir. | ... | @@ -7085,7 +7253,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir. |
| 7085 | switch (std.zig.parseCharLiteral(slice)) { | 7253 | switch (std.zig.parseCharLiteral(slice)) { |
| 7086 | .success => |codepoint| { | 7254 | .success => |codepoint| { |
| 7087 | const result = try gz.addInt(codepoint); | 7255 | const result = try gz.addInt(codepoint); |
| 7088 | return rvalue(gz, rl, result, node); | 7256 | return rvalue(gz, ri, result, node); |
| 7089 | }, | 7257 | }, |
| 7090 | .failure => |err| return astgen.failWithStrLitError(err, main_token, slice, 0), | 7258 | .failure => |err| return astgen.failWithStrLitError(err, main_token, slice, 0), |
| 7091 | } | 7259 | } |
| ... | @@ -7093,7 +7261,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir. | ... | @@ -7093,7 +7261,7 @@ fn charLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir. |
| 7093 | | 7261 | |
| 7094 | const Sign = enum { negative, positive }; | 7262 | const Sign = enum { negative, positive }; |
| 7095 | | 7263 | |
| 7096 | fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { | 7264 | fn numberLiteral(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index, source_node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { |
| 7097 | const astgen = gz.astgen; | 7265 | const astgen = gz.astgen; |
| 7098 | const tree = astgen.tree; | 7266 | const tree = astgen.tree; |
| 7099 | const main_tokens = tree.nodes.items(.main_token); | 7267 | const main_tokens = tree.nodes.items(.main_token); |
| ... | @@ -7135,7 +7303,7 @@ fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: | ... | @@ -7135,7 +7303,7 @@ fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: |
| 7135 | const bigger_again: f128 = smaller_float; | 7303 | const bigger_again: f128 = smaller_float; |
| 7136 | if (bigger_again == float_number) { | 7304 | if (bigger_again == float_number) { |
| 7137 | const result = try gz.addFloat(smaller_float); | 7305 | const result = try gz.addFloat(smaller_float); |
| 7138 | return rvalue(gz, rl, result, source_node); | 7306 | return rvalue(gz, ri, result, source_node); |
| 7139 | } | 7307 | } |
| 7140 | // We need to use 128 bits. Break the float into 4 u32 values so we can | 7308 | // We need to use 128 bits. Break the float into 4 u32 values so we can |
| 7141 | // put it into the `extra` array. | 7309 | // put it into the `extra` array. |
| ... | @@ -7146,16 +7314,16 @@ fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: | ... | @@ -7146,16 +7314,16 @@ fn numberLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, source_node: |
| 7146 | .piece2 = @truncate(u32, int_bits >> 64), | 7314 | .piece2 = @truncate(u32, int_bits >> 64), |
| 7147 | .piece3 = @truncate(u32, int_bits >> 96), | 7315 | .piece3 = @truncate(u32, int_bits >> 96), |
| 7148 | }); | 7316 | }); |
| 7149 | return rvalue(gz, rl, result, source_node); | 7317 | return rvalue(gz, ri, result, source_node); |
| 7150 | }, | 7318 | }, |
| 7151 | .failure => |err| return astgen.failWithNumberError(err, num_token, bytes), | 7319 | .failure => |err| return astgen.failWithNumberError(err, num_token, bytes), |
| 7152 | }; | 7320 | }; |
| 7153 | | 7321 | |
| 7154 | if (sign == .positive) { | 7322 | if (sign == .positive) { |
| 7155 | return rvalue(gz, rl, result, source_node); | 7323 | return rvalue(gz, ri, result, source_node); |
| 7156 | } else { | 7324 | } else { |
| 7157 | const negated = try gz.addUnNode(.negate, result, source_node); | 7325 | const negated = try gz.addUnNode(.negate, result, source_node); |
| 7158 | return rvalue(gz, rl, negated, source_node); | 7326 | return rvalue(gz, ri, negated, source_node); |
| 7159 | } | 7327 | } |
| 7160 | } | 7328 | } |
| 7161 | | 7329 | |
| ... | @@ -7191,7 +7359,7 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token | ... | @@ -7191,7 +7359,7 @@ fn failWithNumberError(astgen: *AstGen, err: std.zig.number_literal.Error, token |
| 7191 | fn asmExpr( | 7359 | fn asmExpr( |
| 7192 | gz: *GenZir, | 7360 | gz: *GenZir, |
| 7193 | scope: *Scope, | 7361 | scope: *Scope, |
| 7194 | rl: ResultLoc, | 7362 | ri: ResultInfo, |
| 7195 | node: Ast.Node.Index, | 7363 | node: Ast.Node.Index, |
| 7196 | full: Ast.full.Asm, | 7364 | full: Ast.full.Asm, |
| 7197 | ) InnerError!Zir.Inst.Ref { | 7365 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -7214,7 +7382,7 @@ fn asmExpr( | ... | @@ -7214,7 +7382,7 @@ fn asmExpr( |
| 7214 | }, | 7382 | }, |
| 7215 | else => .{ | 7383 | else => .{ |
| 7216 | .tag = .asm_expr, | 7384 | .tag = .asm_expr, |
| 7217 | .tmpl = @enumToInt(try comptimeExpr(gz, scope, .none, full.ast.template)), | 7385 | .tmpl = @enumToInt(try comptimeExpr(gz, scope, .{ .rl = .none }, full.ast.template)), |
| 7218 | }, | 7386 | }, |
| 7219 | }; | 7387 | }; |
| 7220 | | 7388 | |
| ... | @@ -7266,7 +7434,7 @@ fn asmExpr( | ... | @@ -7266,7 +7434,7 @@ fn asmExpr( |
| 7266 | outputs[i] = .{ | 7434 | outputs[i] = .{ |
| 7267 | .name = name, | 7435 | .name = name, |
| 7268 | .constraint = constraint, | 7436 | .constraint = constraint, |
| 7269 | .operand = try localVarRef(gz, scope, .ref, node, ident_token), | 7437 | .operand = try localVarRef(gz, scope, .{ .rl = .ref }, node, ident_token), |
| 7270 | }; | 7438 | }; |
| 7271 | } | 7439 | } |
| 7272 | } | 7440 | } |
| ... | @@ -7282,7 +7450,7 @@ fn asmExpr( | ... | @@ -7282,7 +7450,7 @@ fn asmExpr( |
| 7282 | const name = try astgen.identAsString(symbolic_name); | 7450 | const name = try astgen.identAsString(symbolic_name); |
| 7283 | const constraint_token = symbolic_name + 2; | 7451 | const constraint_token = symbolic_name + 2; |
| 7284 | const constraint = (try astgen.strLitAsString(constraint_token)).index; | 7452 | const constraint = (try astgen.strLitAsString(constraint_token)).index; |
| 7285 | const operand = try expr(gz, scope, .none, node_datas[input_node].lhs); | 7453 | const operand = try expr(gz, scope, .{ .rl = .none }, node_datas[input_node].lhs); |
| 7286 | inputs[i] = .{ | 7454 | inputs[i] = .{ |
| 7287 | .name = name, | 7455 | .name = name, |
| 7288 | .constraint = constraint, | 7456 | .constraint = constraint, |
| ... | @@ -7327,31 +7495,31 @@ fn asmExpr( | ... | @@ -7327,31 +7495,31 @@ fn asmExpr( |
| 7327 | .inputs = inputs, | 7495 | .inputs = inputs, |
| 7328 | .clobbers = clobbers_buffer[0..clobber_i], | 7496 | .clobbers = clobbers_buffer[0..clobber_i], |
| 7329 | }); | 7497 | }); |
| 7330 | return rvalue(gz, rl, result, node); | 7498 | return rvalue(gz, ri, result, node); |
| 7331 | } | 7499 | } |
| 7332 | | 7500 | |
| 7333 | fn as( | 7501 | fn as( |
| 7334 | gz: *GenZir, | 7502 | gz: *GenZir, |
| 7335 | scope: *Scope, | 7503 | scope: *Scope, |
| 7336 | rl: ResultLoc, | 7504 | ri: ResultInfo, |
| 7337 | node: Ast.Node.Index, | 7505 | node: Ast.Node.Index, |
| 7338 | lhs: Ast.Node.Index, | 7506 | lhs: Ast.Node.Index, |
| 7339 | rhs: Ast.Node.Index, | 7507 | rhs: Ast.Node.Index, |
| 7340 | ) InnerError!Zir.Inst.Ref { | 7508 | ) InnerError!Zir.Inst.Ref { |
| 7341 | const dest_type = try typeExpr(gz, scope, lhs); | 7509 | const dest_type = try typeExpr(gz, scope, lhs); |
| 7342 | switch (rl) { | 7510 | switch (ri.rl) { |
| 7343 | .none, .discard, .ref, .ty, .ty_shift_operand, .coerced_ty => { | 7511 | .none, .discard, .ref, .ty, .coerced_ty => { |
| 7344 | const result = try reachableExpr(gz, scope, .{ .ty = dest_type }, rhs, node); | 7512 | const result = try reachableExpr(gz, scope, .{ .rl = .{ .ty = dest_type } }, rhs, node); |
| 7345 | return rvalue(gz, rl, result, node); | 7513 | return rvalue(gz, ri, result, node); |
| 7346 | }, | 7514 | }, |
| 7347 | .ptr => |result_ptr| { | 7515 | .ptr => |result_ptr| { |
| 7348 | return asRlPtr(gz, scope, rl, node, result_ptr.inst, rhs, dest_type); | 7516 | return asRlPtr(gz, scope, ri, node, result_ptr.inst, rhs, dest_type); |
| 7349 | }, | 7517 | }, |
| 7350 | .inferred_ptr => |result_ptr| { | 7518 | .inferred_ptr => |result_ptr| { |
| 7351 | return asRlPtr(gz, scope, rl, node, result_ptr, rhs, dest_type); | 7519 | return asRlPtr(gz, scope, ri, node, result_ptr, rhs, dest_type); |
| 7352 | }, | 7520 | }, |
| 7353 | .block_ptr => |block_scope| { | 7521 | .block_ptr => |block_scope| { |
| 7354 | return asRlPtr(gz, scope, rl, node, block_scope.rl_ptr, rhs, dest_type); | 7522 | return asRlPtr(gz, scope, ri, node, block_scope.rl_ptr, rhs, dest_type); |
| 7355 | }, | 7523 | }, |
| 7356 | } | 7524 | } |
| 7357 | } | 7525 | } |
| ... | @@ -7359,29 +7527,29 @@ fn as( | ... | @@ -7359,29 +7527,29 @@ fn as( |
| 7359 | fn unionInit( | 7527 | fn unionInit( |
| 7360 | gz: *GenZir, | 7528 | gz: *GenZir, |
| 7361 | scope: *Scope, | 7529 | scope: *Scope, |
| 7362 | rl: ResultLoc, | 7530 | ri: ResultInfo, |
| 7363 | node: Ast.Node.Index, | 7531 | node: Ast.Node.Index, |
| 7364 | params: []const Ast.Node.Index, | 7532 | params: []const Ast.Node.Index, |
| 7365 | ) InnerError!Zir.Inst.Ref { | 7533 | ) InnerError!Zir.Inst.Ref { |
| 7366 | const union_type = try typeExpr(gz, scope, params[0]); | 7534 | const union_type = try typeExpr(gz, scope, params[0]); |
| 7367 | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); | 7535 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]); |
| 7368 | const field_type = try gz.addPlNode(.field_type_ref, params[1], Zir.Inst.FieldTypeRef{ | 7536 | const field_type = try gz.addPlNode(.field_type_ref, params[1], Zir.Inst.FieldTypeRef{ |
| 7369 | .container_type = union_type, | 7537 | .container_type = union_type, |
| 7370 | .field_name = field_name, | 7538 | .field_name = field_name, |
| 7371 | }); | 7539 | }); |
| 7372 | const init = try reachableExpr(gz, scope, .{ .ty = field_type }, params[2], node); | 7540 | const init = try reachableExpr(gz, scope, .{ .rl = .{ .ty = field_type } }, params[2], node); |
| 7373 | const result = try gz.addPlNode(.union_init, node, Zir.Inst.UnionInit{ | 7541 | const result = try gz.addPlNode(.union_init, node, Zir.Inst.UnionInit{ |
| 7374 | .union_type = union_type, | 7542 | .union_type = union_type, |
| 7375 | .init = init, | 7543 | .init = init, |
| 7376 | .field_name = field_name, | 7544 | .field_name = field_name, |
| 7377 | }); | 7545 | }); |
| 7378 | return rvalue(gz, rl, result, node); | 7546 | return rvalue(gz, ri, result, node); |
| 7379 | } | 7547 | } |
| 7380 | | 7548 | |
| 7381 | fn asRlPtr( | 7549 | fn asRlPtr( |
| 7382 | parent_gz: *GenZir, | 7550 | parent_gz: *GenZir, |
| 7383 | scope: *Scope, | 7551 | scope: *Scope, |
| 7384 | rl: ResultLoc, | 7552 | ri: ResultInfo, |
| 7385 | src_node: Ast.Node.Index, | 7553 | src_node: Ast.Node.Index, |
| 7386 | result_ptr: Zir.Inst.Ref, | 7554 | result_ptr: Zir.Inst.Ref, |
| 7387 | operand_node: Ast.Node.Index, | 7555 | operand_node: Ast.Node.Index, |
| ... | @@ -7390,31 +7558,31 @@ fn asRlPtr( | ... | @@ -7390,31 +7558,31 @@ fn asRlPtr( |
| 7390 | var as_scope = try parent_gz.makeCoercionScope(scope, dest_type, result_ptr, src_node); | 7558 | var as_scope = try parent_gz.makeCoercionScope(scope, dest_type, result_ptr, src_node); |
| 7391 | defer as_scope.unstack(); | 7559 | defer as_scope.unstack(); |
| 7392 | | 7560 | |
| 7393 | const result = try reachableExpr(&as_scope, &as_scope.base, .{ .block_ptr = &as_scope }, operand_node, src_node); | 7561 | const result = try reachableExpr(&as_scope, &as_scope.base, .{ .rl = .{ .block_ptr = &as_scope } }, operand_node, src_node); |
| 7394 | return as_scope.finishCoercion(parent_gz, rl, operand_node, result, dest_type); | 7562 | return as_scope.finishCoercion(parent_gz, ri, operand_node, result, dest_type); |
| 7395 | } | 7563 | } |
| 7396 | | 7564 | |
| 7397 | fn bitCast( | 7565 | fn bitCast( |
| 7398 | gz: *GenZir, | 7566 | gz: *GenZir, |
| 7399 | scope: *Scope, | 7567 | scope: *Scope, |
| 7400 | rl: ResultLoc, | 7568 | ri: ResultInfo, |
| 7401 | node: Ast.Node.Index, | 7569 | node: Ast.Node.Index, |
| 7402 | lhs: Ast.Node.Index, | 7570 | lhs: Ast.Node.Index, |
| 7403 | rhs: Ast.Node.Index, | 7571 | rhs: Ast.Node.Index, |
| 7404 | ) InnerError!Zir.Inst.Ref { | 7572 | ) InnerError!Zir.Inst.Ref { |
| 7405 | const dest_type = try reachableTypeExpr(gz, scope, lhs, node); | 7573 | const dest_type = try reachableTypeExpr(gz, scope, lhs, node); |
| 7406 | const operand = try reachableExpr(gz, scope, .none, rhs, node); | 7574 | const operand = try reachableExpr(gz, scope, .{ .rl = .none }, rhs, node); |
| 7407 | const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{ | 7575 | const result = try gz.addPlNode(.bitcast, node, Zir.Inst.Bin{ |
| 7408 | .lhs = dest_type, | 7576 | .lhs = dest_type, |
| 7409 | .rhs = operand, | 7577 | .rhs = operand, |
| 7410 | }); | 7578 | }); |
| 7411 | return rvalue(gz, rl, result, node); | 7579 | return rvalue(gz, ri, result, node); |
| 7412 | } | 7580 | } |
| 7413 | | 7581 | |
| 7414 | fn typeOf( | 7582 | fn typeOf( |
| 7415 | gz: *GenZir, | 7583 | gz: *GenZir, |
| 7416 | scope: *Scope, | 7584 | scope: *Scope, |
| 7417 | rl: ResultLoc, | 7585 | ri: ResultInfo, |
| 7418 | node: Ast.Node.Index, | 7586 | node: Ast.Node.Index, |
| 7419 | args: []const Ast.Node.Index, | 7587 | args: []const Ast.Node.Index, |
| 7420 | ) InnerError!Zir.Inst.Ref { | 7588 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -7430,7 +7598,7 @@ fn typeOf( | ... | @@ -7430,7 +7598,7 @@ fn typeOf( |
| 7430 | typeof_scope.force_comptime = false; | 7598 | typeof_scope.force_comptime = false; |
| 7431 | defer typeof_scope.unstack(); | 7599 | defer typeof_scope.unstack(); |
| 7432 | | 7600 | |
| 7433 | const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .none, args[0], node); | 7601 | const ty_expr = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, args[0], node); |
| 7434 | if (!gz.refIsNoReturn(ty_expr)) { | 7602 | if (!gz.refIsNoReturn(ty_expr)) { |
| 7435 | _ = try typeof_scope.addBreak(.break_inline, typeof_inst, ty_expr); | 7603 | _ = try typeof_scope.addBreak(.break_inline, typeof_inst, ty_expr); |
| 7436 | } | 7604 | } |
| ... | @@ -7438,7 +7606,7 @@ fn typeOf( | ... | @@ -7438,7 +7606,7 @@ fn typeOf( |
| 7438 | | 7606 | |
| 7439 | // typeof_scope unstacked now, can add new instructions to gz | 7607 | // typeof_scope unstacked now, can add new instructions to gz |
| 7440 | try gz.instructions.append(gpa, typeof_inst); | 7608 | try gz.instructions.append(gpa, typeof_inst); |
| 7441 | return rvalue(gz, rl, indexToRef(typeof_inst), node); | 7609 | return rvalue(gz, ri, indexToRef(typeof_inst), node); |
| 7442 | } | 7610 | } |
| 7443 | const payload_size: u32 = std.meta.fields(Zir.Inst.TypeOfPeer).len; | 7611 | const payload_size: u32 = std.meta.fields(Zir.Inst.TypeOfPeer).len; |
| 7444 | const payload_index = try reserveExtra(astgen, payload_size + args.len); | 7612 | const payload_index = try reserveExtra(astgen, payload_size + args.len); |
| ... | @@ -7450,7 +7618,7 @@ fn typeOf( | ... | @@ -7450,7 +7618,7 @@ fn typeOf( |
| 7450 | typeof_scope.force_comptime = false; | 7618 | typeof_scope.force_comptime = false; |
| 7451 | | 7619 | |
| 7452 | for (args) |arg, i| { | 7620 | for (args) |arg, i| { |
| 7453 | const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .none, arg, node); | 7621 | const param_ref = try reachableExpr(&typeof_scope, &typeof_scope.base, .{ .rl = .none }, arg, node); |
| 7454 | astgen.extra.items[args_index + i] = @enumToInt(param_ref); | 7622 | astgen.extra.items[args_index + i] = @enumToInt(param_ref); |
| 7455 | } | 7623 | } |
| 7456 | _ = try typeof_scope.addBreak(.break_inline, refToIndex(typeof_inst).?, .void_value); | 7624 | _ = try typeof_scope.addBreak(.break_inline, refToIndex(typeof_inst).?, .void_value); |
| ... | @@ -7466,13 +7634,13 @@ fn typeOf( | ... | @@ -7466,13 +7634,13 @@ fn typeOf( |
| 7466 | astgen.appendBodyWithFixups(body); | 7634 | astgen.appendBodyWithFixups(body); |
| 7467 | typeof_scope.unstack(); | 7635 | typeof_scope.unstack(); |
| 7468 | | 7636 | |
| 7469 | return rvalue(gz, rl, typeof_inst, node); | 7637 | return rvalue(gz, ri, typeof_inst, node); |
| 7470 | } | 7638 | } |
| 7471 | | 7639 | |
| 7472 | fn builtinCall( | 7640 | fn builtinCall( |
| 7473 | gz: *GenZir, | 7641 | gz: *GenZir, |
| 7474 | scope: *Scope, | 7642 | scope: *Scope, |
| 7475 | rl: ResultLoc, | 7643 | ri: ResultInfo, |
| 7476 | node: Ast.Node.Index, | 7644 | node: Ast.Node.Index, |
| 7477 | params: []const Ast.Node.Index, | 7645 | params: []const Ast.Node.Index, |
| 7478 | ) InnerError!Zir.Inst.Ref { | 7646 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -7524,7 +7692,7 @@ fn builtinCall( | ... | @@ -7524,7 +7692,7 @@ fn builtinCall( |
| 7524 | if (!gop.found_existing) { | 7692 | if (!gop.found_existing) { |
| 7525 | gop.value_ptr.* = str_lit_token; | 7693 | gop.value_ptr.* = str_lit_token; |
| 7526 | } | 7694 | } |
| 7527 | return rvalue(gz, rl, result, node); | 7695 | return rvalue(gz, ri, result, node); |
| 7528 | }, | 7696 | }, |
| 7529 | .compile_log => { | 7697 | .compile_log => { |
| 7530 | const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{ | 7698 | const payload_index = try addExtra(gz.astgen, Zir.Inst.NodeMultiOp{ |
| ... | @@ -7532,32 +7700,32 @@ fn builtinCall( | ... | @@ -7532,32 +7700,32 @@ fn builtinCall( |
| 7532 | }); | 7700 | }); |
| 7533 | var extra_index = try reserveExtra(gz.astgen, params.len); | 7701 | var extra_index = try reserveExtra(gz.astgen, params.len); |
| 7534 | for (params) |param| { | 7702 | for (params) |param| { |
| 7535 | const param_ref = try expr(gz, scope, .none, param); | 7703 | const param_ref = try expr(gz, scope, .{ .rl = .none }, param); |
| 7536 | astgen.extra.items[extra_index] = @enumToInt(param_ref); | 7704 | astgen.extra.items[extra_index] = @enumToInt(param_ref); |
| 7537 | extra_index += 1; | 7705 | extra_index += 1; |
| 7538 | } | 7706 | } |
| 7539 | const result = try gz.addExtendedMultiOpPayloadIndex(.compile_log, payload_index, params.len); | 7707 | const result = try gz.addExtendedMultiOpPayloadIndex(.compile_log, payload_index, params.len); |
| 7540 | return rvalue(gz, rl, result, node); | 7708 | return rvalue(gz, ri, result, node); |
| 7541 | }, | 7709 | }, |
| 7542 | .field => { | 7710 | .field => { |
| 7543 | if (rl == .ref) { | 7711 | if (ri.rl == .ref) { |
| 7544 | return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{ | 7712 | return gz.addPlNode(.field_ptr_named, node, Zir.Inst.FieldNamed{ |
| 7545 | .lhs = try expr(gz, scope, .ref, params[0]), | 7713 | .lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]), |
| 7546 | .field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]), | 7714 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]), |
| 7547 | }); | 7715 | }); |
| 7548 | } | 7716 | } |
| 7549 | const result = try gz.addPlNode(.field_val_named, node, Zir.Inst.FieldNamed{ | 7717 | const result = try gz.addPlNode(.field_val_named, node, Zir.Inst.FieldNamed{ |
| 7550 | .lhs = try expr(gz, scope, .none, params[0]), | 7718 | .lhs = try expr(gz, scope, .{ .rl = .none }, params[0]), |
| 7551 | .field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]), | 7719 | .field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]), |
| 7552 | }); | 7720 | }); |
| 7553 | return rvalue(gz, rl, result, node); | 7721 | return rvalue(gz, ri, result, node); |
| 7554 | }, | 7722 | }, |
| 7555 | | 7723 | |
| 7556 | // zig fmt: off | 7724 | // zig fmt: off |
| 7557 | .as => return as( gz, scope, rl, node, params[0], params[1]), | 7725 | .as => return as( gz, scope, ri, node, params[0], params[1]), |
| 7558 | .bit_cast => return bitCast( gz, scope, rl, node, params[0], params[1]), | 7726 | .bit_cast => return bitCast( gz, scope, ri, node, params[0], params[1]), |
| 7559 | .TypeOf => return typeOf( gz, scope, rl, node, params), | 7727 | .TypeOf => return typeOf( gz, scope, ri, node, params), |
| 7560 | .union_init => return unionInit(gz, scope, rl, node, params), | 7728 | .union_init => return unionInit(gz, scope, ri, node, params), |
| 7561 | .c_import => return cImport( gz, scope, node, params[0]), | 7729 | .c_import => return cImport( gz, scope, node, params[0]), |
| 7562 | // zig fmt: on | 7730 | // zig fmt: on |
| 7563 | | 7731 | |
| ... | @@ -7582,9 +7750,9 @@ fn builtinCall( | ... | @@ -7582,9 +7750,9 @@ fn builtinCall( |
| 7582 | local_val.used = ident_token; | 7750 | local_val.used = ident_token; |
| 7583 | _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ | 7751 | _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ |
| 7584 | .operand = local_val.inst, | 7752 | .operand = local_val.inst, |
| 7585 | .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]), | 7753 | .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]), |
| 7586 | }); | 7754 | }); |
| 7587 | return rvalue(gz, rl, .void_value, node); | 7755 | return rvalue(gz, ri, .void_value, node); |
| 7588 | } | 7756 | } |
| 7589 | s = local_val.parent; | 7757 | s = local_val.parent; |
| 7590 | }, | 7758 | }, |
| ... | @@ -7597,9 +7765,9 @@ fn builtinCall( | ... | @@ -7597,9 +7765,9 @@ fn builtinCall( |
| 7597 | const loaded = try gz.addUnNode(.load, local_ptr.ptr, node); | 7765 | const loaded = try gz.addUnNode(.load, local_ptr.ptr, node); |
| 7598 | _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ | 7766 | _ = try gz.addPlNode(.export_value, node, Zir.Inst.ExportValue{ |
| 7599 | .operand = loaded, | 7767 | .operand = loaded, |
| 7600 | .options = try comptimeExpr(gz, scope, .{ .coerced_ty = .export_options_type }, params[1]), | 7768 | .options = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .export_options_type } }, params[1]), |
| 7601 | }); | 7769 | }); |
| 7602 | return rvalue(gz, rl, .void_value, node); | 7770 | return rvalue(gz, ri, .void_value, node); |
| 7603 | } | 7771 | } |
| 7604 | s = local_ptr.parent; | 7772 | s = local_ptr.parent; |
| 7605 | }, | 7773 | }, |
| ... | @@ -7631,47 +7799,47 @@ fn builtinCall( | ... | @@ -7631,47 +7799,47 @@ fn builtinCall( |
| 7631 | }, | 7799 | }, |
| 7632 | else => return astgen.failNode(params[0], "symbol to export must identify a declaration", .{}), | 7800 | else => return astgen.failNode(params[0], "symbol to export must identify a declaration", .{}), |
| 7633 | } | 7801 | } |
| 7634 | const options = try comptimeExpr(gz, scope, .{ .ty = .export_options_type }, params[1]); | 7802 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .export_options_type } }, params[1]); |
| 7635 | _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{ | 7803 | _ = try gz.addPlNode(.@"export", node, Zir.Inst.Export{ |
| 7636 | .namespace = namespace, | 7804 | .namespace = namespace, |
| 7637 | .decl_name = decl_name, | 7805 | .decl_name = decl_name, |
| 7638 | .options = options, | 7806 | .options = options, |
| 7639 | }); | 7807 | }); |
| 7640 | return rvalue(gz, rl, .void_value, node); | 7808 | return rvalue(gz, ri, .void_value, node); |
| 7641 | }, | 7809 | }, |
| 7642 | .@"extern" => { | 7810 | .@"extern" => { |
| 7643 | const type_inst = try typeExpr(gz, scope, params[0]); | 7811 | const type_inst = try typeExpr(gz, scope, params[0]); |
| 7644 | const options = try comptimeExpr(gz, scope, .{ .ty = .extern_options_type }, params[1]); | 7812 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .extern_options_type } }, params[1]); |
| 7645 | const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{ | 7813 | const result = try gz.addExtendedPayload(.builtin_extern, Zir.Inst.BinNode{ |
| 7646 | .node = gz.nodeIndexToRelative(node), | 7814 | .node = gz.nodeIndexToRelative(node), |
| 7647 | .lhs = type_inst, | 7815 | .lhs = type_inst, |
| 7648 | .rhs = options, | 7816 | .rhs = options, |
| 7649 | }); | 7817 | }); |
| 7650 | return rvalue(gz, rl, result, node); | 7818 | return rvalue(gz, ri, result, node); |
| 7651 | }, | 7819 | }, |
| 7652 | .fence => { | 7820 | .fence => { |
| 7653 | const order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[0]); | 7821 | const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[0]); |
| 7654 | const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{ | 7822 | const result = try gz.addExtendedPayload(.fence, Zir.Inst.UnNode{ |
| 7655 | .node = gz.nodeIndexToRelative(node), | 7823 | .node = gz.nodeIndexToRelative(node), |
| 7656 | .operand = order, | 7824 | .operand = order, |
| 7657 | }); | 7825 | }); |
| 7658 | return rvalue(gz, rl, result, node); | 7826 | return rvalue(gz, ri, result, node); |
| 7659 | }, | 7827 | }, |
| 7660 | .set_float_mode => { | 7828 | .set_float_mode => { |
| 7661 | const order = try expr(gz, scope, .{ .coerced_ty = .float_mode_type }, params[0]); | 7829 | const order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .float_mode_type } }, params[0]); |
| 7662 | const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{ | 7830 | const result = try gz.addExtendedPayload(.set_float_mode, Zir.Inst.UnNode{ |
| 7663 | .node = gz.nodeIndexToRelative(node), | 7831 | .node = gz.nodeIndexToRelative(node), |
| 7664 | .operand = order, | 7832 | .operand = order, |
| 7665 | }); | 7833 | }); |
| 7666 | return rvalue(gz, rl, result, node); | 7834 | return rvalue(gz, ri, result, node); |
| 7667 | }, | 7835 | }, |
| 7668 | .set_align_stack => { | 7836 | .set_align_stack => { |
| 7669 | const order = try expr(gz, scope, align_rl, params[0]); | 7837 | const order = try expr(gz, scope, align_ri, params[0]); |
| 7670 | const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{ | 7838 | const result = try gz.addExtendedPayload(.set_align_stack, Zir.Inst.UnNode{ |
| 7671 | .node = gz.nodeIndexToRelative(node), | 7839 | .node = gz.nodeIndexToRelative(node), |
| 7672 | .operand = order, | 7840 | .operand = order, |
| 7673 | }); | 7841 | }); |
| 7674 | return rvalue(gz, rl, result, node); | 7842 | return rvalue(gz, ri, result, node); |
| 7675 | }, | 7843 | }, |
| 7676 | | 7844 | |
| 7677 | .src => { | 7845 | .src => { |
| ... | @@ -7683,62 +7851,62 @@ fn builtinCall( | ... | @@ -7683,62 +7851,62 @@ fn builtinCall( |
| 7683 | .line = astgen.source_line, | 7851 | .line = astgen.source_line, |
| 7684 | .column = astgen.source_column, | 7852 | .column = astgen.source_column, |
| 7685 | }); | 7853 | }); |
| 7686 | return rvalue(gz, rl, result, node); | 7854 | return rvalue(gz, ri, result, node); |
| 7687 | }, | 7855 | }, |
| 7688 | | 7856 | |
| 7689 | // zig fmt: off | 7857 | // zig fmt: off |
| 7690 | .This => return rvalue(gz, rl, try gz.addNodeExtended(.this, node), node), | 7858 | .This => return rvalue(gz, ri, try gz.addNodeExtended(.this, node), node), |
| 7691 | .return_address => return rvalue(gz, rl, try gz.addNodeExtended(.ret_addr, node), node), | 7859 | .return_address => return rvalue(gz, ri, try gz.addNodeExtended(.ret_addr, node), node), |
| 7692 | .error_return_trace => return rvalue(gz, rl, try gz.addNodeExtended(.error_return_trace, node), node), | 7860 | .error_return_trace => return rvalue(gz, ri, try gz.addNodeExtended(.error_return_trace, node), node), |
| 7693 | .frame => return rvalue(gz, rl, try gz.addNodeExtended(.frame, node), node), | 7861 | .frame => return rvalue(gz, ri, try gz.addNodeExtended(.frame, node), node), |
| 7694 | .frame_address => return rvalue(gz, rl, try gz.addNodeExtended(.frame_address, node), node), | 7862 | .frame_address => return rvalue(gz, ri, try gz.addNodeExtended(.frame_address, node), node), |
| 7695 | .breakpoint => return rvalue(gz, rl, try gz.addNodeExtended(.breakpoint, node), node), | 7863 | .breakpoint => return rvalue(gz, ri, try gz.addNodeExtended(.breakpoint, node), node), |
| 7696 | | 7864 | |
| 7697 | .type_info => return simpleUnOpType(gz, scope, rl, node, params[0], .type_info), | 7865 | .type_info => return simpleUnOpType(gz, scope, ri, node, params[0], .type_info), |
| 7698 | .size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .size_of), | 7866 | .size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .size_of), |
| 7699 | .bit_size_of => return simpleUnOpType(gz, scope, rl, node, params[0], .bit_size_of), | 7867 | .bit_size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .bit_size_of), |
| 7700 | .align_of => return simpleUnOpType(gz, scope, rl, node, params[0], .align_of), | 7868 | .align_of => return simpleUnOpType(gz, scope, ri, node, params[0], .align_of), |
| 7701 | | 7869 | |
| 7702 | .ptr_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .ptr_to_int), | 7870 | .ptr_to_int => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .ptr_to_int), |
| 7703 | .compile_error => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .compile_error), | 7871 | .compile_error => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], .compile_error), |
| 7704 | .set_eval_branch_quota => return simpleUnOp(gz, scope, rl, node, .{ .coerced_ty = .u32_type }, params[0], .set_eval_branch_quota), | 7872 | .set_eval_branch_quota => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0], .set_eval_branch_quota), |
| 7705 | .enum_to_int => return simpleUnOp(gz, scope, rl, node, .none, params[0], .enum_to_int), | 7873 | .enum_to_int => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .enum_to_int), |
| 7706 | .bool_to_int => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .bool_to_int), | 7874 | .bool_to_int => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .bool_to_int), |
| 7707 | .embed_file => return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], .embed_file), | 7875 | .embed_file => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], .embed_file), |
| 7708 | .error_name => return simpleUnOp(gz, scope, rl, node, .{ .ty = .anyerror_type }, params[0], .error_name), | 7876 | .error_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .anyerror_type } }, params[0], .error_name), |
| 7709 | .set_cold => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_cold), | 7877 | .set_cold => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_cold), |
| 7710 | .set_runtime_safety => return simpleUnOp(gz, scope, rl, node, bool_rl, params[0], .set_runtime_safety), | 7878 | .set_runtime_safety => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_runtime_safety), |
| 7711 | .sqrt => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sqrt), | 7879 | .sqrt => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sqrt), |
| 7712 | .sin => return simpleUnOp(gz, scope, rl, node, .none, params[0], .sin), | 7880 | .sin => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .sin), |
| 7713 | .cos => return simpleUnOp(gz, scope, rl, node, .none, params[0], .cos), | 7881 | .cos => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .cos), |
| 7714 | .tan => return simpleUnOp(gz, scope, rl, node, .none, params[0], .tan), | 7882 | .tan => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tan), |
| 7715 | .exp => return simpleUnOp(gz, scope, rl, node, .none, params[0], .exp), | 7883 | .exp => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp), |
| 7716 | .exp2 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .exp2), | 7884 | .exp2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .exp2), |
| 7717 | .log => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log), | 7885 | .log => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log), |
| 7718 | .log2 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log2), | 7886 | .log2 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log2), |
| 7719 | .log10 => return simpleUnOp(gz, scope, rl, node, .none, params[0], .log10), | 7887 | .log10 => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .log10), |
| 7720 | .fabs => return simpleUnOp(gz, scope, rl, node, .none, params[0], .fabs), | 7888 | .fabs => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .fabs), |
| 7721 | .floor => return simpleUnOp(gz, scope, rl, node, .none, params[0], .floor), | 7889 | .floor => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .floor), |
| 7722 | .ceil => return simpleUnOp(gz, scope, rl, node, .none, params[0], .ceil), | 7890 | .ceil => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .ceil), |
| 7723 | .trunc => return simpleUnOp(gz, scope, rl, node, .none, params[0], .trunc), | 7891 | .trunc => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .trunc), |
| 7724 | .round => return simpleUnOp(gz, scope, rl, node, .none, params[0], .round), | 7892 | .round => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .round), |
| 7725 | .tag_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .tag_name), | 7893 | .tag_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .tag_name), |
| 7726 | .type_name => return simpleUnOp(gz, scope, rl, node, .none, params[0], .type_name), | 7894 | .type_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .type_name), |
| 7727 | .Frame => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_type), | 7895 | .Frame => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_type), |
| 7728 | .frame_size => return simpleUnOp(gz, scope, rl, node, .none, params[0], .frame_size), | 7896 | .frame_size => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .frame_size), |
| 7729 | | 7897 | |
| 7730 | .float_to_int => return typeCast(gz, scope, rl, node, params[0], params[1], .float_to_int), | 7898 | .float_to_int => return typeCast(gz, scope, ri, node, params[0], params[1], .float_to_int), |
| 7731 | .int_to_float => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_float), | 7899 | .int_to_float => return typeCast(gz, scope, ri, node, params[0], params[1], .int_to_float), |
| 7732 | .int_to_ptr => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_ptr), | 7900 | .int_to_ptr => return typeCast(gz, scope, ri, node, params[0], params[1], .int_to_ptr), |
| 7733 | .int_to_enum => return typeCast(gz, scope, rl, node, params[0], params[1], .int_to_enum), | 7901 | .int_to_enum => return typeCast(gz, scope, ri, node, params[0], params[1], .int_to_enum), |
| 7734 | .float_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .float_cast), | 7902 | .float_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .float_cast), |
| 7735 | .int_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .int_cast), | 7903 | .int_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .int_cast), |
| 7736 | .ptr_cast => return typeCast(gz, scope, rl, node, params[0], params[1], .ptr_cast), | 7904 | .ptr_cast => return typeCast(gz, scope, ri, node, params[0], params[1], .ptr_cast), |
| 7737 | .truncate => return typeCast(gz, scope, rl, node, params[0], params[1], .truncate), | 7905 | .truncate => return typeCast(gz, scope, ri, node, params[0], params[1], .truncate), |
| 7738 | // zig fmt: on | 7906 | // zig fmt: on |
| 7739 | | 7907 | |
| 7740 | .Type => { | 7908 | .Type => { |
| 7741 | const operand = try expr(gz, scope, .{ .coerced_ty = .type_info_type }, params[0]); | 7909 | const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .type_info_type } }, params[0]); |
| 7742 | | 7910 | |
| 7743 | const gpa = gz.astgen.gpa; | 7911 | const gpa = gz.astgen.gpa; |
| 7744 | | 7912 | |
| ... | @@ -7760,219 +7928,219 @@ fn builtinCall( | ... | @@ -7760,219 +7928,219 @@ fn builtinCall( |
| 7760 | }); | 7928 | }); |
| 7761 | gz.instructions.appendAssumeCapacity(new_index); | 7929 | gz.instructions.appendAssumeCapacity(new_index); |
| 7762 | const result = indexToRef(new_index); | 7930 | const result = indexToRef(new_index); |
| 7763 | return rvalue(gz, rl, result, node); | 7931 | return rvalue(gz, ri, result, node); |
| 7764 | }, | 7932 | }, |
| 7765 | .panic => { | 7933 | .panic => { |
| 7766 | try emitDbgNode(gz, node); | 7934 | try emitDbgNode(gz, node); |
| 7767 | return simpleUnOp(gz, scope, rl, node, .{ .ty = .const_slice_u8_type }, params[0], if (gz.force_comptime) .panic_comptime else .panic); | 7935 | return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0], if (gz.force_comptime) .panic_comptime else .panic); |
| 7768 | }, | 7936 | }, |
| 7769 | .error_to_int => { | 7937 | .error_to_int => { |
| 7770 | const operand = try expr(gz, scope, .none, params[0]); | 7938 | const operand = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 7771 | const result = try gz.addExtendedPayload(.error_to_int, Zir.Inst.UnNode{ | 7939 | const result = try gz.addExtendedPayload(.error_to_int, Zir.Inst.UnNode{ |
| 7772 | .node = gz.nodeIndexToRelative(node), | 7940 | .node = gz.nodeIndexToRelative(node), |
| 7773 | .operand = operand, | 7941 | .operand = operand, |
| 7774 | }); | 7942 | }); |
| 7775 | return rvalue(gz, rl, result, node); | 7943 | return rvalue(gz, ri, result, node); |
| 7776 | }, | 7944 | }, |
| 7777 | .int_to_error => { | 7945 | .int_to_error => { |
| 7778 | const operand = try expr(gz, scope, .{ .coerced_ty = .u16_type }, params[0]); | 7946 | const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, params[0]); |
| 7779 | const result = try gz.addExtendedPayload(.int_to_error, Zir.Inst.UnNode{ | 7947 | const result = try gz.addExtendedPayload(.int_to_error, Zir.Inst.UnNode{ |
| 7780 | .node = gz.nodeIndexToRelative(node), | 7948 | .node = gz.nodeIndexToRelative(node), |
| 7781 | .operand = operand, | 7949 | .operand = operand, |
| 7782 | }); | 7950 | }); |
| 7783 | return rvalue(gz, rl, result, node); | 7951 | return rvalue(gz, ri, result, node); |
| 7784 | }, | 7952 | }, |
| 7785 | .align_cast => { | 7953 | .align_cast => { |
| 7786 | const dest_align = try comptimeExpr(gz, scope, align_rl, params[0]); | 7954 | const dest_align = try comptimeExpr(gz, scope, align_ri, params[0]); |
| 7787 | const rhs = try expr(gz, scope, .none, params[1]); | 7955 | const rhs = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 7788 | const result = try gz.addPlNode(.align_cast, node, Zir.Inst.Bin{ | 7956 | const result = try gz.addPlNode(.align_cast, node, Zir.Inst.Bin{ |
| 7789 | .lhs = dest_align, | 7957 | .lhs = dest_align, |
| 7790 | .rhs = rhs, | 7958 | .rhs = rhs, |
| 7791 | }); | 7959 | }); |
| 7792 | return rvalue(gz, rl, result, node); | 7960 | return rvalue(gz, ri, result, node); |
| 7793 | }, | 7961 | }, |
| 7794 | .err_set_cast => { | 7962 | .err_set_cast => { |
| 7795 | const result = try gz.addExtendedPayload(.err_set_cast, Zir.Inst.BinNode{ | 7963 | const result = try gz.addExtendedPayload(.err_set_cast, Zir.Inst.BinNode{ |
| 7796 | .lhs = try typeExpr(gz, scope, params[0]), | 7964 | .lhs = try typeExpr(gz, scope, params[0]), |
| 7797 | .rhs = try expr(gz, scope, .none, params[1]), | 7965 | .rhs = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 7798 | .node = gz.nodeIndexToRelative(node), | 7966 | .node = gz.nodeIndexToRelative(node), |
| 7799 | }); | 7967 | }); |
| 7800 | return rvalue(gz, rl, result, node); | 7968 | return rvalue(gz, ri, result, node); |
| 7801 | }, | 7969 | }, |
| 7802 | .addrspace_cast => { | 7970 | .addrspace_cast => { |
| 7803 | const result = try gz.addExtendedPayload(.addrspace_cast, Zir.Inst.BinNode{ | 7971 | const result = try gz.addExtendedPayload(.addrspace_cast, Zir.Inst.BinNode{ |
| 7804 | .lhs = try comptimeExpr(gz, scope, .{ .ty = .address_space_type }, params[0]), | 7972 | .lhs = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .address_space_type } }, params[0]), |
| 7805 | .rhs = try expr(gz, scope, .none, params[1]), | 7973 | .rhs = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 7806 | .node = gz.nodeIndexToRelative(node), | 7974 | .node = gz.nodeIndexToRelative(node), |
| 7807 | }); | 7975 | }); |
| 7808 | return rvalue(gz, rl, result, node); | 7976 | return rvalue(gz, ri, result, node); |
| 7809 | }, | 7977 | }, |
| 7810 | | 7978 | |
| 7811 | // zig fmt: off | 7979 | // zig fmt: off |
| 7812 | .has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl), | 7980 | .has_decl => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_decl), |
| 7813 | .has_field => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_field), | 7981 | .has_field => return hasDeclOrField(gz, scope, ri, node, params[0], params[1], .has_field), |
| 7814 | | 7982 | |
| 7815 | .clz => return bitBuiltin(gz, scope, rl, node, params[0], .clz), | 7983 | .clz => return bitBuiltin(gz, scope, ri, node, params[0], .clz), |
| 7816 | .ctz => return bitBuiltin(gz, scope, rl, node, params[0], .ctz), | 7984 | .ctz => return bitBuiltin(gz, scope, ri, node, params[0], .ctz), |
| 7817 | .pop_count => return bitBuiltin(gz, scope, rl, node, params[0], .pop_count), | 7985 | .pop_count => return bitBuiltin(gz, scope, ri, node, params[0], .pop_count), |
| 7818 | .byte_swap => return bitBuiltin(gz, scope, rl, node, params[0], .byte_swap), | 7986 | .byte_swap => return bitBuiltin(gz, scope, ri, node, params[0], .byte_swap), |
| 7819 | .bit_reverse => return bitBuiltin(gz, scope, rl, node, params[0], .bit_reverse), | 7987 | .bit_reverse => return bitBuiltin(gz, scope, ri, node, params[0], .bit_reverse), |
| 7820 | | 7988 | |
| 7821 | .div_exact => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_exact), | 7989 | .div_exact => return divBuiltin(gz, scope, ri, node, params[0], params[1], .div_exact), |
| 7822 | .div_floor => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_floor), | 7990 | .div_floor => return divBuiltin(gz, scope, ri, node, params[0], params[1], .div_floor), |
| 7823 | .div_trunc => return divBuiltin(gz, scope, rl, node, params[0], params[1], .div_trunc), | 7991 | .div_trunc => return divBuiltin(gz, scope, ri, node, params[0], params[1], .div_trunc), |
| 7824 | .mod => return divBuiltin(gz, scope, rl, node, params[0], params[1], .mod), | 7992 | .mod => return divBuiltin(gz, scope, ri, node, params[0], params[1], .mod), |
| 7825 | .rem => return divBuiltin(gz, scope, rl, node, params[0], params[1], .rem), | 7993 | .rem => return divBuiltin(gz, scope, ri, node, params[0], params[1], .rem), |
| 7826 | | 7994 | |
| 7827 | .shl_exact => return shiftOp(gz, scope, rl, node, params[0], params[1], .shl_exact), | 7995 | .shl_exact => return shiftOp(gz, scope, ri, node, params[0], params[1], .shl_exact), |
| 7828 | .shr_exact => return shiftOp(gz, scope, rl, node, params[0], params[1], .shr_exact), | 7996 | .shr_exact => return shiftOp(gz, scope, ri, node, params[0], params[1], .shr_exact), |
| 7829 | | 7997 | |
| 7830 | .bit_offset_of => return offsetOf(gz, scope, rl, node, params[0], params[1], .bit_offset_of), | 7998 | .bit_offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .bit_offset_of), |
| 7831 | .offset_of => return offsetOf(gz, scope, rl, node, params[0], params[1], .offset_of), | 7999 | .offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .offset_of), |
| 7832 | | 8000 | |
| 7833 | .c_undef => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_undef), | 8001 | .c_undef => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_undef), |
| 7834 | .c_include => return simpleCBuiltin(gz, scope, rl, node, params[0], .c_include), | 8002 | .c_include => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_include), |
| 7835 | | 8003 | |
| 7836 | .cmpxchg_strong => return cmpxchg(gz, scope, rl, node, params, 1), | 8004 | .cmpxchg_strong => return cmpxchg(gz, scope, ri, node, params, 1), |
| 7837 | .cmpxchg_weak => return cmpxchg(gz, scope, rl, node, params, 0), | 8005 | .cmpxchg_weak => return cmpxchg(gz, scope, ri, node, params, 0), |
| 7838 | // zig fmt: on | 8006 | // zig fmt: on |
| 7839 | | 8007 | |
| 7840 | .wasm_memory_size => { | 8008 | .wasm_memory_size => { |
| 7841 | const operand = try comptimeExpr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]); | 8009 | const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); |
| 7842 | const result = try gz.addExtendedPayload(.wasm_memory_size, Zir.Inst.UnNode{ | 8010 | const result = try gz.addExtendedPayload(.wasm_memory_size, Zir.Inst.UnNode{ |
| 7843 | .node = gz.nodeIndexToRelative(node), | 8011 | .node = gz.nodeIndexToRelative(node), |
| 7844 | .operand = operand, | 8012 | .operand = operand, |
| 7845 | }); | 8013 | }); |
| 7846 | return rvalue(gz, rl, result, node); | 8014 | return rvalue(gz, ri, result, node); |
| 7847 | }, | 8015 | }, |
| 7848 | .wasm_memory_grow => { | 8016 | .wasm_memory_grow => { |
| 7849 | const index_arg = try comptimeExpr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]); | 8017 | const index_arg = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); |
| 7850 | const delta_arg = try expr(gz, scope, .{ .coerced_ty = .u32_type }, params[1]); | 8018 | const delta_arg = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[1]); |
| 7851 | const result = try gz.addExtendedPayload(.wasm_memory_grow, Zir.Inst.BinNode{ | 8019 | const result = try gz.addExtendedPayload(.wasm_memory_grow, Zir.Inst.BinNode{ |
| 7852 | .node = gz.nodeIndexToRelative(node), | 8020 | .node = gz.nodeIndexToRelative(node), |
| 7853 | .lhs = index_arg, | 8021 | .lhs = index_arg, |
| 7854 | .rhs = delta_arg, | 8022 | .rhs = delta_arg, |
| 7855 | }); | 8023 | }); |
| 7856 | return rvalue(gz, rl, result, node); | 8024 | return rvalue(gz, ri, result, node); |
| 7857 | }, | 8025 | }, |
| 7858 | .c_define => { | 8026 | .c_define => { |
| 7859 | if (!gz.c_import) return gz.astgen.failNode(node, "C define valid only inside C import block", .{}); | 8027 | if (!gz.c_import) return gz.astgen.failNode(node, "C define valid only inside C import block", .{}); |
| 7860 | const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[0]); | 8028 | const name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[0]); |
| 7861 | const value = try comptimeExpr(gz, scope, .none, params[1]); | 8029 | const value = try comptimeExpr(gz, scope, .{ .rl = .none }, params[1]); |
| 7862 | const result = try gz.addExtendedPayload(.c_define, Zir.Inst.BinNode{ | 8030 | const result = try gz.addExtendedPayload(.c_define, Zir.Inst.BinNode{ |
| 7863 | .node = gz.nodeIndexToRelative(node), | 8031 | .node = gz.nodeIndexToRelative(node), |
| 7864 | .lhs = name, | 8032 | .lhs = name, |
| 7865 | .rhs = value, | 8033 | .rhs = value, |
| 7866 | }); | 8034 | }); |
| 7867 | return rvalue(gz, rl, result, node); | 8035 | return rvalue(gz, ri, result, node); |
| 7868 | }, | 8036 | }, |
| 7869 | | 8037 | |
| 7870 | .splat => { | 8038 | .splat => { |
| 7871 | const len = try expr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]); | 8039 | const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]); |
| 7872 | const scalar = try expr(gz, scope, .none, params[1]); | 8040 | const scalar = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 7873 | const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{ | 8041 | const result = try gz.addPlNode(.splat, node, Zir.Inst.Bin{ |
| 7874 | .lhs = len, | 8042 | .lhs = len, |
| 7875 | .rhs = scalar, | 8043 | .rhs = scalar, |
| 7876 | }); | 8044 | }); |
| 7877 | return rvalue(gz, rl, result, node); | 8045 | return rvalue(gz, ri, result, node); |
| 7878 | }, | 8046 | }, |
| 7879 | .reduce => { | 8047 | .reduce => { |
| 7880 | const op = try expr(gz, scope, .{ .ty = .reduce_op_type }, params[0]); | 8048 | const op = try expr(gz, scope, .{ .rl = .{ .ty = .reduce_op_type } }, params[0]); |
| 7881 | const scalar = try expr(gz, scope, .none, params[1]); | 8049 | const scalar = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 7882 | const result = try gz.addPlNode(.reduce, node, Zir.Inst.Bin{ | 8050 | const result = try gz.addPlNode(.reduce, node, Zir.Inst.Bin{ |
| 7883 | .lhs = op, | 8051 | .lhs = op, |
| 7884 | .rhs = scalar, | 8052 | .rhs = scalar, |
| 7885 | }); | 8053 | }); |
| 7886 | return rvalue(gz, rl, result, node); | 8054 | return rvalue(gz, ri, result, node); |
| 7887 | }, | 8055 | }, |
| 7888 | | 8056 | |
| 7889 | .max => { | 8057 | .max => { |
| 7890 | const a = try expr(gz, scope, .none, params[0]); | 8058 | const a = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 7891 | const b = try expr(gz, scope, .none, params[1]); | 8059 | const b = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 7892 | const result = try gz.addPlNode(.max, node, Zir.Inst.Bin{ | 8060 | const result = try gz.addPlNode(.max, node, Zir.Inst.Bin{ |
| 7893 | .lhs = a, | 8061 | .lhs = a, |
| 7894 | .rhs = b, | 8062 | .rhs = b, |
| 7895 | }); | 8063 | }); |
| 7896 | return rvalue(gz, rl, result, node); | 8064 | return rvalue(gz, ri, result, node); |
| 7897 | }, | 8065 | }, |
| 7898 | .min => { | 8066 | .min => { |
| 7899 | const a = try expr(gz, scope, .none, params[0]); | 8067 | const a = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 7900 | const b = try expr(gz, scope, .none, params[1]); | 8068 | const b = try expr(gz, scope, .{ .rl = .none }, params[1]); |
| 7901 | const result = try gz.addPlNode(.min, node, Zir.Inst.Bin{ | 8069 | const result = try gz.addPlNode(.min, node, Zir.Inst.Bin{ |
| 7902 | .lhs = a, | 8070 | .lhs = a, |
| 7903 | .rhs = b, | 8071 | .rhs = b, |
| 7904 | }); | 8072 | }); |
| 7905 | return rvalue(gz, rl, result, node); | 8073 | return rvalue(gz, ri, result, node); |
| 7906 | }, | 8074 | }, |
| 7907 | | 8075 | |
| 7908 | .add_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .add_with_overflow), | 8076 | .add_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .add_with_overflow), |
| 7909 | .sub_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .sub_with_overflow), | 8077 | .sub_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .sub_with_overflow), |
| 7910 | .mul_with_overflow => return overflowArithmetic(gz, scope, rl, node, params, .mul_with_overflow), | 8078 | .mul_with_overflow => return overflowArithmetic(gz, scope, ri, node, params, .mul_with_overflow), |
| 7911 | .shl_with_overflow => { | 8079 | .shl_with_overflow => { |
| 7912 | const int_type = try typeExpr(gz, scope, params[0]); | 8080 | const int_type = try typeExpr(gz, scope, params[0]); |
| 7913 | const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]); | 8081 | const log2_int_type = try gz.addUnNode(.log2_int_type, int_type, params[0]); |
| 7914 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); | 8082 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); |
| 7915 | const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]); | 8083 | const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]); |
| 7916 | const rhs = try expr(gz, scope, .{ .ty = log2_int_type }, params[2]); | 8084 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type } }, params[2]); |
| 7917 | const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]); | 8085 | const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]); |
| 7918 | const result = try gz.addExtendedPayload(.shl_with_overflow, Zir.Inst.OverflowArithmetic{ | 8086 | const result = try gz.addExtendedPayload(.shl_with_overflow, Zir.Inst.OverflowArithmetic{ |
| 7919 | .node = gz.nodeIndexToRelative(node), | 8087 | .node = gz.nodeIndexToRelative(node), |
| 7920 | .lhs = lhs, | 8088 | .lhs = lhs, |
| 7921 | .rhs = rhs, | 8089 | .rhs = rhs, |
| 7922 | .ptr = ptr, | 8090 | .ptr = ptr, |
| 7923 | }); | 8091 | }); |
| 7924 | return rvalue(gz, rl, result, node); | 8092 | return rvalue(gz, ri, result, node); |
| 7925 | }, | 8093 | }, |
| 7926 | | 8094 | |
| 7927 | .atomic_load => { | 8095 | .atomic_load => { |
| 7928 | const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.AtomicLoad{ | 8096 | const result = try gz.addPlNode(.atomic_load, node, Zir.Inst.AtomicLoad{ |
| 7929 | // zig fmt: off | 8097 | // zig fmt: off |
| 7930 | .elem_type = try typeExpr(gz, scope, params[0]), | 8098 | .elem_type = try typeExpr(gz, scope, params[0]), |
| 7931 | .ptr = try expr (gz, scope, .none, params[1]), | 8099 | .ptr = try expr (gz, scope, .{ .rl = .none }, params[1]), |
| 7932 | .ordering = try expr (gz, scope, .{ .coerced_ty = .atomic_order_type }, params[2]), | 8100 | .ordering = try expr (gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[2]), |
| 7933 | // zig fmt: on | 8101 | // zig fmt: on |
| 7934 | }); | 8102 | }); |
| 7935 | return rvalue(gz, rl, result, node); | 8103 | return rvalue(gz, ri, result, node); |
| 7936 | }, | 8104 | }, |
| 7937 | .atomic_rmw => { | 8105 | .atomic_rmw => { |
| 7938 | const int_type = try typeExpr(gz, scope, params[0]); | 8106 | const int_type = try typeExpr(gz, scope, params[0]); |
| 7939 | const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{ | 8107 | const result = try gz.addPlNode(.atomic_rmw, node, Zir.Inst.AtomicRmw{ |
| 7940 | // zig fmt: off | 8108 | // zig fmt: off |
| 7941 | .ptr = try expr(gz, scope, .none, params[1]), | 8109 | .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 7942 | .operation = try expr(gz, scope, .{ .coerced_ty = .atomic_rmw_op_type }, params[2]), | 8110 | .operation = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_rmw_op_type } }, params[2]), |
| 7943 | .operand = try expr(gz, scope, .{ .ty = int_type }, params[3]), | 8111 | .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[3]), |
| 7944 | .ordering = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[4]), | 8112 | .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[4]), |
| 7945 | // zig fmt: on | 8113 | // zig fmt: on |
| 7946 | }); | 8114 | }); |
| 7947 | return rvalue(gz, rl, result, node); | 8115 | return rvalue(gz, ri, result, node); |
| 7948 | }, | 8116 | }, |
| 7949 | .atomic_store => { | 8117 | .atomic_store => { |
| 7950 | const int_type = try typeExpr(gz, scope, params[0]); | 8118 | const int_type = try typeExpr(gz, scope, params[0]); |
| 7951 | const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{ | 8119 | const result = try gz.addPlNode(.atomic_store, node, Zir.Inst.AtomicStore{ |
| 7952 | // zig fmt: off | 8120 | // zig fmt: off |
| 7953 | .ptr = try expr(gz, scope, .none, params[1]), | 8121 | .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 7954 | .operand = try expr(gz, scope, .{ .ty = int_type }, params[2]), | 8122 | .operand = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), |
| 7955 | .ordering = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[3]), | 8123 | .ordering = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[3]), |
| 7956 | // zig fmt: on | 8124 | // zig fmt: on |
| 7957 | }); | 8125 | }); |
| 7958 | return rvalue(gz, rl, result, node); | 8126 | return rvalue(gz, ri, result, node); |
| 7959 | }, | 8127 | }, |
| 7960 | .mul_add => { | 8128 | .mul_add => { |
| 7961 | const float_type = try typeExpr(gz, scope, params[0]); | 8129 | const float_type = try typeExpr(gz, scope, params[0]); |
| 7962 | const mulend1 = try expr(gz, scope, .{ .coerced_ty = float_type }, params[1]); | 8130 | const mulend1 = try expr(gz, scope, .{ .rl = .{ .coerced_ty = float_type } }, params[1]); |
| 7963 | const mulend2 = try expr(gz, scope, .{ .coerced_ty = float_type }, params[2]); | 8131 | const mulend2 = try expr(gz, scope, .{ .rl = .{ .coerced_ty = float_type } }, params[2]); |
| 7964 | const addend = try expr(gz, scope, .{ .ty = float_type }, params[3]); | 8132 | const addend = try expr(gz, scope, .{ .rl = .{ .ty = float_type } }, params[3]); |
| 7965 | const result = try gz.addPlNode(.mul_add, node, Zir.Inst.MulAdd{ | 8133 | const result = try gz.addPlNode(.mul_add, node, Zir.Inst.MulAdd{ |
| 7966 | .mulend1 = mulend1, | 8134 | .mulend1 = mulend1, |
| 7967 | .mulend2 = mulend2, | 8135 | .mulend2 = mulend2, |
| 7968 | .addend = addend, | 8136 | .addend = addend, |
| 7969 | }); | 8137 | }); |
| 7970 | return rvalue(gz, rl, result, node); | 8138 | return rvalue(gz, ri, result, node); |
| 7971 | }, | 8139 | }, |
| 7972 | .call => { | 8140 | .call => { |
| 7973 | const options = try comptimeExpr(gz, scope, .{ .ty = .call_options_type }, params[0]); | 8141 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .call_options_type } }, params[0]); |
| 7974 | const callee = try calleeExpr(gz, scope, params[1]); | 8142 | const callee = try calleeExpr(gz, scope, params[1]); |
| 7975 | const args = try expr(gz, scope, .none, params[2]); | 8143 | const args = try expr(gz, scope, .{ .rl = .none }, params[2]); |
| 7976 | const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{ | 8144 | const result = try gz.addPlNode(.builtin_call, node, Zir.Inst.BuiltinCall{ |
| 7977 | .options = options, | 8145 | .options = options, |
| 7978 | .callee = callee, | 8146 | .callee = callee, |
| ... | @@ -7983,115 +8151,115 @@ fn builtinCall( | ... | @@ -7983,115 +8151,115 @@ fn builtinCall( |
| 7983 | .ensure_result_used = false, | 8151 | .ensure_result_used = false, |
| 7984 | }, | 8152 | }, |
| 7985 | }); | 8153 | }); |
| 7986 | return rvalue(gz, rl, result, node); | 8154 | return rvalue(gz, ri, result, node); |
| 7987 | }, | 8155 | }, |
| 7988 | .field_parent_ptr => { | 8156 | .field_parent_ptr => { |
| 7989 | const parent_type = try typeExpr(gz, scope, params[0]); | 8157 | const parent_type = try typeExpr(gz, scope, params[0]); |
| 7990 | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); | 8158 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]); |
| 7991 | const result = try gz.addPlNode(.field_parent_ptr, node, Zir.Inst.FieldParentPtr{ | 8159 | const result = try gz.addPlNode(.field_parent_ptr, node, Zir.Inst.FieldParentPtr{ |
| 7992 | .parent_type = parent_type, | 8160 | .parent_type = parent_type, |
| 7993 | .field_name = field_name, | 8161 | .field_name = field_name, |
| 7994 | .field_ptr = try expr(gz, scope, .none, params[2]), | 8162 | .field_ptr = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 7995 | }); | 8163 | }); |
| 7996 | return rvalue(gz, rl, result, node); | 8164 | return rvalue(gz, ri, result, node); |
| 7997 | }, | 8165 | }, |
| 7998 | .memcpy => { | 8166 | .memcpy => { |
| 7999 | const result = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{ | 8167 | const result = try gz.addPlNode(.memcpy, node, Zir.Inst.Memcpy{ |
| 8000 | .dest = try expr(gz, scope, .{ .coerced_ty = .manyptr_u8_type }, params[0]), | 8168 | .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), |
| 8001 | .source = try expr(gz, scope, .{ .coerced_ty = .manyptr_const_u8_type }, params[1]), | 8169 | .source = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_const_u8_type } }, params[1]), |
| 8002 | .byte_count = try expr(gz, scope, .{ .coerced_ty = .usize_type }, params[2]), | 8170 | .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), |
| 8003 | }); | 8171 | }); |
| 8004 | return rvalue(gz, rl, result, node); | 8172 | return rvalue(gz, ri, result, node); |
| 8005 | }, | 8173 | }, |
| 8006 | .memset => { | 8174 | .memset => { |
| 8007 | const result = try gz.addPlNode(.memset, node, Zir.Inst.Memset{ | 8175 | const result = try gz.addPlNode(.memset, node, Zir.Inst.Memset{ |
| 8008 | .dest = try expr(gz, scope, .{ .coerced_ty = .manyptr_u8_type }, params[0]), | 8176 | .dest = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .manyptr_u8_type } }, params[0]), |
| 8009 | .byte = try expr(gz, scope, .{ .coerced_ty = .u8_type }, params[1]), | 8177 | .byte = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .u8_type } }, params[1]), |
| 8010 | .byte_count = try expr(gz, scope, .{ .coerced_ty = .usize_type }, params[2]), | 8178 | .byte_count = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, params[2]), |
| 8011 | }); | 8179 | }); |
| 8012 | return rvalue(gz, rl, result, node); | 8180 | return rvalue(gz, ri, result, node); |
| 8013 | }, | 8181 | }, |
| 8014 | .shuffle => { | 8182 | .shuffle => { |
| 8015 | const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{ | 8183 | const result = try gz.addPlNode(.shuffle, node, Zir.Inst.Shuffle{ |
| 8016 | .elem_type = try typeExpr(gz, scope, params[0]), | 8184 | .elem_type = try typeExpr(gz, scope, params[0]), |
| 8017 | .a = try expr(gz, scope, .none, params[1]), | 8185 | .a = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8018 | .b = try expr(gz, scope, .none, params[2]), | 8186 | .b = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 8019 | .mask = try comptimeExpr(gz, scope, .none, params[3]), | 8187 | .mask = try comptimeExpr(gz, scope, .{ .rl = .none }, params[3]), |
| 8020 | }); | 8188 | }); |
| 8021 | return rvalue(gz, rl, result, node); | 8189 | return rvalue(gz, ri, result, node); |
| 8022 | }, | 8190 | }, |
| 8023 | .select => { | 8191 | .select => { |
| 8024 | const result = try gz.addExtendedPayload(.select, Zir.Inst.Select{ | 8192 | const result = try gz.addExtendedPayload(.select, Zir.Inst.Select{ |
| 8025 | .node = gz.nodeIndexToRelative(node), | 8193 | .node = gz.nodeIndexToRelative(node), |
| 8026 | .elem_type = try typeExpr(gz, scope, params[0]), | 8194 | .elem_type = try typeExpr(gz, scope, params[0]), |
| 8027 | .pred = try expr(gz, scope, .none, params[1]), | 8195 | .pred = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8028 | .a = try expr(gz, scope, .none, params[2]), | 8196 | .a = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 8029 | .b = try expr(gz, scope, .none, params[3]), | 8197 | .b = try expr(gz, scope, .{ .rl = .none }, params[3]), |
| 8030 | }); | 8198 | }); |
| 8031 | return rvalue(gz, rl, result, node); | 8199 | return rvalue(gz, ri, result, node); |
| 8032 | }, | 8200 | }, |
| 8033 | .async_call => { | 8201 | .async_call => { |
| 8034 | const result = try gz.addExtendedPayload(.builtin_async_call, Zir.Inst.AsyncCall{ | 8202 | const result = try gz.addExtendedPayload(.builtin_async_call, Zir.Inst.AsyncCall{ |
| 8035 | .node = gz.nodeIndexToRelative(node), | 8203 | .node = gz.nodeIndexToRelative(node), |
| 8036 | .frame_buffer = try expr(gz, scope, .none, params[0]), | 8204 | .frame_buffer = try expr(gz, scope, .{ .rl = .none }, params[0]), |
| 8037 | .result_ptr = try expr(gz, scope, .none, params[1]), | 8205 | .result_ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8038 | .fn_ptr = try expr(gz, scope, .none, params[2]), | 8206 | .fn_ptr = try expr(gz, scope, .{ .rl = .none }, params[2]), |
| 8039 | .args = try expr(gz, scope, .none, params[3]), | 8207 | .args = try expr(gz, scope, .{ .rl = .none }, params[3]), |
| 8040 | }); | 8208 | }); |
| 8041 | return rvalue(gz, rl, result, node); | 8209 | return rvalue(gz, ri, result, node); |
| 8042 | }, | 8210 | }, |
| 8043 | .Vector => { | 8211 | .Vector => { |
| 8044 | const result = try gz.addPlNode(.vector_type, node, Zir.Inst.Bin{ | 8212 | const result = try gz.addPlNode(.vector_type, node, Zir.Inst.Bin{ |
| 8045 | .lhs = try comptimeExpr(gz, scope, .{ .coerced_ty = .u32_type }, params[0]), | 8213 | .lhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0]), |
| 8046 | .rhs = try typeExpr(gz, scope, params[1]), | 8214 | .rhs = try typeExpr(gz, scope, params[1]), |
| 8047 | }); | 8215 | }); |
| 8048 | return rvalue(gz, rl, result, node); | 8216 | return rvalue(gz, ri, result, node); |
| 8049 | }, | 8217 | }, |
| 8050 | .prefetch => { | 8218 | .prefetch => { |
| 8051 | const ptr = try expr(gz, scope, .none, params[0]); | 8219 | const ptr = try expr(gz, scope, .{ .rl = .none }, params[0]); |
| 8052 | const options = try comptimeExpr(gz, scope, .{ .ty = .prefetch_options_type }, params[1]); | 8220 | const options = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .prefetch_options_type } }, params[1]); |
| 8053 | const result = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{ | 8221 | const result = try gz.addExtendedPayload(.prefetch, Zir.Inst.BinNode{ |
| 8054 | .node = gz.nodeIndexToRelative(node), | 8222 | .node = gz.nodeIndexToRelative(node), |
| 8055 | .lhs = ptr, | 8223 | .lhs = ptr, |
| 8056 | .rhs = options, | 8224 | .rhs = options, |
| 8057 | }); | 8225 | }); |
| 8058 | return rvalue(gz, rl, result, node); | 8226 | return rvalue(gz, ri, result, node); |
| 8059 | }, | 8227 | }, |
| 8060 | } | 8228 | } |
| 8061 | } | 8229 | } |
| 8062 | | 8230 | |
| 8063 | fn simpleNoOpVoid( | 8231 | fn simpleNoOpVoid( |
| 8064 | gz: *GenZir, | 8232 | gz: *GenZir, |
| 8065 | rl: ResultLoc, | 8233 | ri: ResultInfo, |
| 8066 | node: Ast.Node.Index, | 8234 | node: Ast.Node.Index, |
| 8067 | tag: Zir.Inst.Tag, | 8235 | tag: Zir.Inst.Tag, |
| 8068 | ) InnerError!Zir.Inst.Ref { | 8236 | ) InnerError!Zir.Inst.Ref { |
| 8069 | _ = try gz.addNode(tag, node); | 8237 | _ = try gz.addNode(tag, node); |
| 8070 | return rvalue(gz, rl, .void_value, node); | 8238 | return rvalue(gz, ri, .void_value, node); |
| 8071 | } | 8239 | } |
| 8072 | | 8240 | |
| 8073 | fn hasDeclOrField( | 8241 | fn hasDeclOrField( |
| 8074 | gz: *GenZir, | 8242 | gz: *GenZir, |
| 8075 | scope: *Scope, | 8243 | scope: *Scope, |
| 8076 | rl: ResultLoc, | 8244 | ri: ResultInfo, |
| 8077 | node: Ast.Node.Index, | 8245 | node: Ast.Node.Index, |
| 8078 | lhs_node: Ast.Node.Index, | 8246 | lhs_node: Ast.Node.Index, |
| 8079 | rhs_node: Ast.Node.Index, | 8247 | rhs_node: Ast.Node.Index, |
| 8080 | tag: Zir.Inst.Tag, | 8248 | tag: Zir.Inst.Tag, |
| 8081 | ) InnerError!Zir.Inst.Ref { | 8249 | ) InnerError!Zir.Inst.Ref { |
| 8082 | const container_type = try typeExpr(gz, scope, lhs_node); | 8250 | const container_type = try typeExpr(gz, scope, lhs_node); |
| 8083 | const name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, rhs_node); | 8251 | const name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, rhs_node); |
| 8084 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ | 8252 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8085 | .lhs = container_type, | 8253 | .lhs = container_type, |
| 8086 | .rhs = name, | 8254 | .rhs = name, |
| 8087 | }); | 8255 | }); |
| 8088 | return rvalue(gz, rl, result, node); | 8256 | return rvalue(gz, ri, result, node); |
| 8089 | } | 8257 | } |
| 8090 | | 8258 | |
| 8091 | fn typeCast( | 8259 | fn typeCast( |
| 8092 | gz: *GenZir, | 8260 | gz: *GenZir, |
| 8093 | scope: *Scope, | 8261 | scope: *Scope, |
| 8094 | rl: ResultLoc, | 8262 | ri: ResultInfo, |
| 8095 | node: Ast.Node.Index, | 8263 | node: Ast.Node.Index, |
| 8096 | lhs_node: Ast.Node.Index, | 8264 | lhs_node: Ast.Node.Index, |
| 8097 | rhs_node: Ast.Node.Index, | 8265 | rhs_node: Ast.Node.Index, |
| ... | @@ -8099,42 +8267,42 @@ fn typeCast( | ... | @@ -8099,42 +8267,42 @@ fn typeCast( |
| 8099 | ) InnerError!Zir.Inst.Ref { | 8267 | ) InnerError!Zir.Inst.Ref { |
| 8100 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ | 8268 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8101 | .lhs = try typeExpr(gz, scope, lhs_node), | 8269 | .lhs = try typeExpr(gz, scope, lhs_node), |
| 8102 | .rhs = try expr(gz, scope, .none, rhs_node), | 8270 | .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node), |
| 8103 | }); | 8271 | }); |
| 8104 | return rvalue(gz, rl, result, node); | 8272 | return rvalue(gz, ri, result, node); |
| 8105 | } | 8273 | } |
| 8106 | | 8274 | |
| 8107 | fn simpleUnOpType( | 8275 | fn simpleUnOpType( |
| 8108 | gz: *GenZir, | 8276 | gz: *GenZir, |
| 8109 | scope: *Scope, | 8277 | scope: *Scope, |
| 8110 | rl: ResultLoc, | 8278 | ri: ResultInfo, |
| 8111 | node: Ast.Node.Index, | 8279 | node: Ast.Node.Index, |
| 8112 | operand_node: Ast.Node.Index, | 8280 | operand_node: Ast.Node.Index, |
| 8113 | tag: Zir.Inst.Tag, | 8281 | tag: Zir.Inst.Tag, |
| 8114 | ) InnerError!Zir.Inst.Ref { | 8282 | ) InnerError!Zir.Inst.Ref { |
| 8115 | const operand = try typeExpr(gz, scope, operand_node); | 8283 | const operand = try typeExpr(gz, scope, operand_node); |
| 8116 | const result = try gz.addUnNode(tag, operand, node); | 8284 | const result = try gz.addUnNode(tag, operand, node); |
| 8117 | return rvalue(gz, rl, result, node); | 8285 | return rvalue(gz, ri, result, node); |
| 8118 | } | 8286 | } |
| 8119 | | 8287 | |
| 8120 | fn simpleUnOp( | 8288 | fn simpleUnOp( |
| 8121 | gz: *GenZir, | 8289 | gz: *GenZir, |
| 8122 | scope: *Scope, | 8290 | scope: *Scope, |
| 8123 | rl: ResultLoc, | 8291 | ri: ResultInfo, |
| 8124 | node: Ast.Node.Index, | 8292 | node: Ast.Node.Index, |
| 8125 | operand_rl: ResultLoc, | 8293 | operand_ri: ResultInfo, |
| 8126 | operand_node: Ast.Node.Index, | 8294 | operand_node: Ast.Node.Index, |
| 8127 | tag: Zir.Inst.Tag, | 8295 | tag: Zir.Inst.Tag, |
| 8128 | ) InnerError!Zir.Inst.Ref { | 8296 | ) InnerError!Zir.Inst.Ref { |
| 8129 | const operand = try expr(gz, scope, operand_rl, operand_node); | 8297 | const operand = try expr(gz, scope, operand_ri, operand_node); |
| 8130 | const result = try gz.addUnNode(tag, operand, node); | 8298 | const result = try gz.addUnNode(tag, operand, node); |
| 8131 | return rvalue(gz, rl, result, node); | 8299 | return rvalue(gz, ri, result, node); |
| 8132 | } | 8300 | } |
| 8133 | | 8301 | |
| 8134 | fn negation( | 8302 | fn negation( |
| 8135 | gz: *GenZir, | 8303 | gz: *GenZir, |
| 8136 | scope: *Scope, | 8304 | scope: *Scope, |
| 8137 | rl: ResultLoc, | 8305 | ri: ResultInfo, |
| 8138 | node: Ast.Node.Index, | 8306 | node: Ast.Node.Index, |
| 8139 | ) InnerError!Zir.Inst.Ref { | 8307 | ) InnerError!Zir.Inst.Ref { |
| 8140 | const astgen = gz.astgen; | 8308 | const astgen = gz.astgen; |
| ... | @@ -8146,18 +8314,18 @@ fn negation( | ... | @@ -8146,18 +8314,18 @@ fn negation( |
| 8146 | // its negativity rather than having it go through comptime subtraction. | 8314 | // its negativity rather than having it go through comptime subtraction. |
| 8147 | const operand_node = node_datas[node].lhs; | 8315 | const operand_node = node_datas[node].lhs; |
| 8148 | if (node_tags[operand_node] == .number_literal) { | 8316 | if (node_tags[operand_node] == .number_literal) { |
| 8149 | return numberLiteral(gz, rl, operand_node, node, .negative); | 8317 | return numberLiteral(gz, ri, operand_node, node, .negative); |
| 8150 | } | 8318 | } |
| 8151 | | 8319 | |
| 8152 | const operand = try expr(gz, scope, .none, operand_node); | 8320 | const operand = try expr(gz, scope, .{ .rl = .none }, operand_node); |
| 8153 | const result = try gz.addUnNode(.negate, operand, node); | 8321 | const result = try gz.addUnNode(.negate, operand, node); |
| 8154 | return rvalue(gz, rl, result, node); | 8322 | return rvalue(gz, ri, result, node); |
| 8155 | } | 8323 | } |
| 8156 | | 8324 | |
| 8157 | fn cmpxchg( | 8325 | fn cmpxchg( |
| 8158 | gz: *GenZir, | 8326 | gz: *GenZir, |
| 8159 | scope: *Scope, | 8327 | scope: *Scope, |
| 8160 | rl: ResultLoc, | 8328 | ri: ResultInfo, |
| 8161 | node: Ast.Node.Index, | 8329 | node: Ast.Node.Index, |
| 8162 | params: []const Ast.Node.Index, | 8330 | params: []const Ast.Node.Index, |
| 8163 | small: u16, | 8331 | small: u16, |
| ... | @@ -8166,98 +8334,98 @@ fn cmpxchg( | ... | @@ -8166,98 +8334,98 @@ fn cmpxchg( |
| 8166 | const result = try gz.addExtendedPayloadSmall(.cmpxchg, small, Zir.Inst.Cmpxchg{ | 8334 | const result = try gz.addExtendedPayloadSmall(.cmpxchg, small, Zir.Inst.Cmpxchg{ |
| 8167 | // zig fmt: off | 8335 | // zig fmt: off |
| 8168 | .node = gz.nodeIndexToRelative(node), | 8336 | .node = gz.nodeIndexToRelative(node), |
| 8169 | .ptr = try expr(gz, scope, .none, params[1]), | 8337 | .ptr = try expr(gz, scope, .{ .rl = .none }, params[1]), |
| 8170 | .expected_value = try expr(gz, scope, .{ .ty = int_type }, params[2]), | 8338 | .expected_value = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]), |
| 8171 | .new_value = try expr(gz, scope, .{ .coerced_ty = int_type }, params[3]), | 8339 | .new_value = try expr(gz, scope, .{ .rl = .{ .coerced_ty = int_type } }, params[3]), |
| 8172 | .success_order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[4]), | 8340 | .success_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[4]), |
| 8173 | .failure_order = try expr(gz, scope, .{ .coerced_ty = .atomic_order_type }, params[5]), | 8341 | .failure_order = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .atomic_order_type } }, params[5]), |
| 8174 | // zig fmt: on | 8342 | // zig fmt: on |
| 8175 | }); | 8343 | }); |
| 8176 | return rvalue(gz, rl, result, node); | 8344 | return rvalue(gz, ri, result, node); |
| 8177 | } | 8345 | } |
| 8178 | | 8346 | |
| 8179 | fn bitBuiltin( | 8347 | fn bitBuiltin( |
| 8180 | gz: *GenZir, | 8348 | gz: *GenZir, |
| 8181 | scope: *Scope, | 8349 | scope: *Scope, |
| 8182 | rl: ResultLoc, | 8350 | ri: ResultInfo, |
| 8183 | node: Ast.Node.Index, | 8351 | node: Ast.Node.Index, |
| 8184 | operand_node: Ast.Node.Index, | 8352 | operand_node: Ast.Node.Index, |
| 8185 | tag: Zir.Inst.Tag, | 8353 | tag: Zir.Inst.Tag, |
| 8186 | ) InnerError!Zir.Inst.Ref { | 8354 | ) InnerError!Zir.Inst.Ref { |
| 8187 | const operand = try expr(gz, scope, .none, operand_node); | 8355 | const operand = try expr(gz, scope, .{ .rl = .none }, operand_node); |
| 8188 | const result = try gz.addUnNode(tag, operand, node); | 8356 | const result = try gz.addUnNode(tag, operand, node); |
| 8189 | return rvalue(gz, rl, result, node); | 8357 | return rvalue(gz, ri, result, node); |
| 8190 | } | 8358 | } |
| 8191 | | 8359 | |
| 8192 | fn divBuiltin( | 8360 | fn divBuiltin( |
| 8193 | gz: *GenZir, | 8361 | gz: *GenZir, |
| 8194 | scope: *Scope, | 8362 | scope: *Scope, |
| 8195 | rl: ResultLoc, | 8363 | ri: ResultInfo, |
| 8196 | node: Ast.Node.Index, | 8364 | node: Ast.Node.Index, |
| 8197 | lhs_node: Ast.Node.Index, | 8365 | lhs_node: Ast.Node.Index, |
| 8198 | rhs_node: Ast.Node.Index, | 8366 | rhs_node: Ast.Node.Index, |
| 8199 | tag: Zir.Inst.Tag, | 8367 | tag: Zir.Inst.Tag, |
| 8200 | ) InnerError!Zir.Inst.Ref { | 8368 | ) InnerError!Zir.Inst.Ref { |
| 8201 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ | 8369 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8202 | .lhs = try expr(gz, scope, .none, lhs_node), | 8370 | .lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node), |
| 8203 | .rhs = try expr(gz, scope, .none, rhs_node), | 8371 | .rhs = try expr(gz, scope, .{ .rl = .none }, rhs_node), |
| 8204 | }); | 8372 | }); |
| 8205 | return rvalue(gz, rl, result, node); | 8373 | return rvalue(gz, ri, result, node); |
| 8206 | } | 8374 | } |
| 8207 | | 8375 | |
| 8208 | fn simpleCBuiltin( | 8376 | fn simpleCBuiltin( |
| 8209 | gz: *GenZir, | 8377 | gz: *GenZir, |
| 8210 | scope: *Scope, | 8378 | scope: *Scope, |
| 8211 | rl: ResultLoc, | 8379 | ri: ResultInfo, |
| 8212 | node: Ast.Node.Index, | 8380 | node: Ast.Node.Index, |
| 8213 | operand_node: Ast.Node.Index, | 8381 | operand_node: Ast.Node.Index, |
| 8214 | tag: Zir.Inst.Extended, | 8382 | tag: Zir.Inst.Extended, |
| 8215 | ) InnerError!Zir.Inst.Ref { | 8383 | ) InnerError!Zir.Inst.Ref { |
| 8216 | const name: []const u8 = if (tag == .c_undef) "C undef" else "C include"; | 8384 | const name: []const u8 = if (tag == .c_undef) "C undef" else "C include"; |
| 8217 | if (!gz.c_import) return gz.astgen.failNode(node, "{s} valid only inside C import block", .{name}); | 8385 | if (!gz.c_import) return gz.astgen.failNode(node, "{s} valid only inside C import block", .{name}); |
| 8218 | const operand = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, operand_node); | 8386 | const operand = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, operand_node); |
| 8219 | _ = try gz.addExtendedPayload(tag, Zir.Inst.UnNode{ | 8387 | _ = try gz.addExtendedPayload(tag, Zir.Inst.UnNode{ |
| 8220 | .node = gz.nodeIndexToRelative(node), | 8388 | .node = gz.nodeIndexToRelative(node), |
| 8221 | .operand = operand, | 8389 | .operand = operand, |
| 8222 | }); | 8390 | }); |
| 8223 | return rvalue(gz, rl, .void_value, node); | 8391 | return rvalue(gz, ri, .void_value, node); |
| 8224 | } | 8392 | } |
| 8225 | | 8393 | |
| 8226 | fn offsetOf( | 8394 | fn offsetOf( |
| 8227 | gz: *GenZir, | 8395 | gz: *GenZir, |
| 8228 | scope: *Scope, | 8396 | scope: *Scope, |
| 8229 | rl: ResultLoc, | 8397 | ri: ResultInfo, |
| 8230 | node: Ast.Node.Index, | 8398 | node: Ast.Node.Index, |
| 8231 | lhs_node: Ast.Node.Index, | 8399 | lhs_node: Ast.Node.Index, |
| 8232 | rhs_node: Ast.Node.Index, | 8400 | rhs_node: Ast.Node.Index, |
| 8233 | tag: Zir.Inst.Tag, | 8401 | tag: Zir.Inst.Tag, |
| 8234 | ) InnerError!Zir.Inst.Ref { | 8402 | ) InnerError!Zir.Inst.Ref { |
| 8235 | const type_inst = try typeExpr(gz, scope, lhs_node); | 8403 | const type_inst = try typeExpr(gz, scope, lhs_node); |
| 8236 | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, rhs_node); | 8404 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, rhs_node); |
| 8237 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ | 8405 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8238 | .lhs = type_inst, | 8406 | .lhs = type_inst, |
| 8239 | .rhs = field_name, | 8407 | .rhs = field_name, |
| 8240 | }); | 8408 | }); |
| 8241 | return rvalue(gz, rl, result, node); | 8409 | return rvalue(gz, ri, result, node); |
| 8242 | } | 8410 | } |
| 8243 | | 8411 | |
| 8244 | fn shiftOp( | 8412 | fn shiftOp( |
| 8245 | gz: *GenZir, | 8413 | gz: *GenZir, |
| 8246 | scope: *Scope, | 8414 | scope: *Scope, |
| 8247 | rl: ResultLoc, | 8415 | ri: ResultInfo, |
| 8248 | node: Ast.Node.Index, | 8416 | node: Ast.Node.Index, |
| 8249 | lhs_node: Ast.Node.Index, | 8417 | lhs_node: Ast.Node.Index, |
| 8250 | rhs_node: Ast.Node.Index, | 8418 | rhs_node: Ast.Node.Index, |
| 8251 | tag: Zir.Inst.Tag, | 8419 | tag: Zir.Inst.Tag, |
| 8252 | ) InnerError!Zir.Inst.Ref { | 8420 | ) InnerError!Zir.Inst.Ref { |
| 8253 | const lhs = try expr(gz, scope, .none, lhs_node); | 8421 | const lhs = try expr(gz, scope, .{ .rl = .none }, lhs_node); |
| 8254 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); | 8422 | const log2_int_type = try gz.addUnNode(.typeof_log2_int_type, lhs, lhs_node); |
| 8255 | const rhs = try expr(gz, scope, .{ .ty_shift_operand = log2_int_type }, rhs_node); | 8423 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = log2_int_type }, .ctx = .shift_op }, rhs_node); |
| 8256 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ | 8424 | const result = try gz.addPlNode(tag, node, Zir.Inst.Bin{ |
| 8257 | .lhs = lhs, | 8425 | .lhs = lhs, |
| 8258 | .rhs = rhs, | 8426 | .rhs = rhs, |
| 8259 | }); | 8427 | }); |
| 8260 | return rvalue(gz, rl, result, node); | 8428 | return rvalue(gz, ri, result, node); |
| 8261 | } | 8429 | } |
| 8262 | | 8430 | |
| 8263 | fn cImport( | 8431 | fn cImport( |
| ... | @@ -8275,7 +8443,7 @@ fn cImport( | ... | @@ -8275,7 +8443,7 @@ fn cImport( |
| 8275 | defer block_scope.unstack(); | 8443 | defer block_scope.unstack(); |
| 8276 | | 8444 | |
| 8277 | const block_inst = try gz.makeBlockInst(.c_import, node); | 8445 | const block_inst = try gz.makeBlockInst(.c_import, node); |
| 8278 | const block_result = try expr(&block_scope, &block_scope.base, .none, body_node); | 8446 | const block_result = try expr(&block_scope, &block_scope.base, .{ .rl = .none }, body_node); |
| 8279 | _ = try gz.addUnNode(.ensure_result_used, block_result, node); | 8447 | _ = try gz.addUnNode(.ensure_result_used, block_result, node); |
| 8280 | if (!gz.refIsNoReturn(block_result)) { | 8448 | if (!gz.refIsNoReturn(block_result)) { |
| 8281 | _ = try block_scope.addBreak(.break_inline, block_inst, .void_value); | 8449 | _ = try block_scope.addBreak(.break_inline, block_inst, .void_value); |
| ... | @@ -8290,29 +8458,29 @@ fn cImport( | ... | @@ -8290,29 +8458,29 @@ fn cImport( |
| 8290 | fn overflowArithmetic( | 8458 | fn overflowArithmetic( |
| 8291 | gz: *GenZir, | 8459 | gz: *GenZir, |
| 8292 | scope: *Scope, | 8460 | scope: *Scope, |
| 8293 | rl: ResultLoc, | 8461 | ri: ResultInfo, |
| 8294 | node: Ast.Node.Index, | 8462 | node: Ast.Node.Index, |
| 8295 | params: []const Ast.Node.Index, | 8463 | params: []const Ast.Node.Index, |
| 8296 | tag: Zir.Inst.Extended, | 8464 | tag: Zir.Inst.Extended, |
| 8297 | ) InnerError!Zir.Inst.Ref { | 8465 | ) InnerError!Zir.Inst.Ref { |
| 8298 | const int_type = try typeExpr(gz, scope, params[0]); | 8466 | const int_type = try typeExpr(gz, scope, params[0]); |
| 8299 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); | 8467 | const ptr_type = try gz.addUnNode(.overflow_arithmetic_ptr, int_type, params[0]); |
| 8300 | const lhs = try expr(gz, scope, .{ .ty = int_type }, params[1]); | 8468 | const lhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[1]); |
| 8301 | const rhs = try expr(gz, scope, .{ .ty = int_type }, params[2]); | 8469 | const rhs = try expr(gz, scope, .{ .rl = .{ .ty = int_type } }, params[2]); |
| 8302 | const ptr = try expr(gz, scope, .{ .ty = ptr_type }, params[3]); | 8470 | const ptr = try expr(gz, scope, .{ .rl = .{ .ty = ptr_type } }, params[3]); |
| 8303 | const result = try gz.addExtendedPayload(tag, Zir.Inst.OverflowArithmetic{ | 8471 | const result = try gz.addExtendedPayload(tag, Zir.Inst.OverflowArithmetic{ |
| 8304 | .node = gz.nodeIndexToRelative(node), | 8472 | .node = gz.nodeIndexToRelative(node), |
| 8305 | .lhs = lhs, | 8473 | .lhs = lhs, |
| 8306 | .rhs = rhs, | 8474 | .rhs = rhs, |
| 8307 | .ptr = ptr, | 8475 | .ptr = ptr, |
| 8308 | }); | 8476 | }); |
| 8309 | return rvalue(gz, rl, result, node); | 8477 | return rvalue(gz, ri, result, node); |
| 8310 | } | 8478 | } |
| 8311 | | 8479 | |
| 8312 | fn callExpr( | 8480 | fn callExpr( |
| 8313 | gz: *GenZir, | 8481 | gz: *GenZir, |
| 8314 | scope: *Scope, | 8482 | scope: *Scope, |
| 8315 | rl: ResultLoc, | 8483 | ri: ResultInfo, |
| 8316 | node: Ast.Node.Index, | 8484 | node: Ast.Node.Index, |
| 8317 | call: Ast.full.Call, | 8485 | call: Ast.full.Call, |
| 8318 | ) InnerError!Zir.Inst.Ref { | 8486 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -8364,7 +8532,7 @@ fn callExpr( | ... | @@ -8364,7 +8532,7 @@ fn callExpr( |
| 8364 | defer arg_block.unstack(); | 8532 | defer arg_block.unstack(); |
| 8365 | | 8533 | |
| 8366 | // `call_inst` is reused to provide the param type. | 8534 | // `call_inst` is reused to provide the param type. |
| 8367 | const arg_ref = try expr(&arg_block, &arg_block.base, .{ .coerced_ty = call_inst }, param_node); | 8535 | const arg_ref = try expr(&arg_block, &arg_block.base, .{ .rl = .{ .coerced_ty = call_inst }, .ctx = .fn_arg }, param_node); |
| 8368 | _ = try arg_block.addBreak(.break_inline, call_index, arg_ref); | 8536 | _ = try arg_block.addBreak(.break_inline, call_index, arg_ref); |
| 8369 | | 8537 | |
| 8370 | const body = arg_block.instructionsSlice(); | 8538 | const body = arg_block.instructionsSlice(); |
| ... | @@ -8375,9 +8543,18 @@ fn callExpr( | ... | @@ -8375,9 +8543,18 @@ fn callExpr( |
| 8375 | scratch_index += 1; | 8543 | scratch_index += 1; |
| 8376 | } | 8544 | } |
| 8377 | | 8545 | |
| | 8546 | // If our result location is a try/catch/error-union-if/return, a function argument, |
| | 8547 | // or an initializer for a `const` variable, the error trace propagates. |
| | 8548 | // Otherwise, it should always be popped (handled in Sema). |
| | 8549 | const propagate_error_trace = switch (ri.ctx) { |
| | 8550 | .error_handling_expr, .@"return", .fn_arg, .const_init => true, |
| | 8551 | else => false, |
| | 8552 | }; |
| | 8553 | |
| 8378 | const payload_index = try addExtra(astgen, Zir.Inst.Call{ | 8554 | const payload_index = try addExtra(astgen, Zir.Inst.Call{ |
| 8379 | .callee = callee, | 8555 | .callee = callee, |
| 8380 | .flags = .{ | 8556 | .flags = .{ |
| | 8557 | .pop_error_return_trace = !propagate_error_trace, |
| 8381 | .packed_modifier = @intCast(Zir.Inst.Call.Flags.PackedModifier, @enumToInt(modifier)), | 8558 | .packed_modifier = @intCast(Zir.Inst.Call.Flags.PackedModifier, @enumToInt(modifier)), |
| 8382 | .args_len = @intCast(Zir.Inst.Call.Flags.PackedArgsLen, call.ast.params.len), | 8559 | .args_len = @intCast(Zir.Inst.Call.Flags.PackedArgsLen, call.ast.params.len), |
| 8383 | }, | 8560 | }, |
| ... | @@ -8392,7 +8569,7 @@ fn callExpr( | ... | @@ -8392,7 +8569,7 @@ fn callExpr( |
| 8392 | .payload_index = payload_index, | 8569 | .payload_index = payload_index, |
| 8393 | } }, | 8570 | } }, |
| 8394 | }); | 8571 | }); |
| 8395 | return rvalue(gz, rl, call_inst, node); // TODO function call with result location | 8572 | return rvalue(gz, ri, call_inst, node); // TODO function call with result location |
| 8396 | } | 8573 | } |
| 8397 | | 8574 | |
| 8398 | /// calleeExpr generates the function part of a call expression (f in f(x)), or the | 8575 | /// calleeExpr generates the function part of a call expression (f in f(x)), or the |
| ... | @@ -8413,7 +8590,7 @@ fn calleeExpr( | ... | @@ -8413,7 +8590,7 @@ fn calleeExpr( |
| 8413 | | 8590 | |
| 8414 | const tag = tree.nodes.items(.tag)[node]; | 8591 | const tag = tree.nodes.items(.tag)[node]; |
| 8415 | switch (tag) { | 8592 | switch (tag) { |
| 8416 | .field_access => return addFieldAccess(.field_call_bind, gz, scope, .ref, node), | 8593 | .field_access => return addFieldAccess(.field_call_bind, gz, scope, .{ .rl = .ref }, node), |
| 8417 | | 8594 | |
| 8418 | .builtin_call_two, | 8595 | .builtin_call_two, |
| 8419 | .builtin_call_two_comma, | 8596 | .builtin_call_two_comma, |
| ... | @@ -8445,8 +8622,8 @@ fn calleeExpr( | ... | @@ -8445,8 +8622,8 @@ fn calleeExpr( |
| 8445 | // If anything is wrong, fall back to builtinCall. | 8622 | // If anything is wrong, fall back to builtinCall. |
| 8446 | // It will emit any necessary compile errors and notes. | 8623 | // It will emit any necessary compile errors and notes. |
| 8447 | if (std.mem.eql(u8, builtin_name, "@field") and params.len == 2) { | 8624 | if (std.mem.eql(u8, builtin_name, "@field") and params.len == 2) { |
| 8448 | const lhs = try expr(gz, scope, .ref, params[0]); | 8625 | const lhs = try expr(gz, scope, .{ .rl = .ref }, params[0]); |
| 8449 | const field_name = try comptimeExpr(gz, scope, .{ .ty = .const_slice_u8_type }, params[1]); | 8626 | const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = .const_slice_u8_type } }, params[1]); |
| 8450 | return gz.addExtendedPayload(.field_call_bind_named, Zir.Inst.FieldNamedNode{ | 8627 | return gz.addExtendedPayload(.field_call_bind_named, Zir.Inst.FieldNamedNode{ |
| 8451 | .node = gz.nodeIndexToRelative(node), | 8628 | .node = gz.nodeIndexToRelative(node), |
| 8452 | .lhs = lhs, | 8629 | .lhs = lhs, |
| ... | @@ -8454,9 +8631,9 @@ fn calleeExpr( | ... | @@ -8454,9 +8631,9 @@ fn calleeExpr( |
| 8454 | }); | 8631 | }); |
| 8455 | } | 8632 | } |
| 8456 | | 8633 | |
| 8457 | return builtinCall(gz, scope, .none, node, params); | 8634 | return builtinCall(gz, scope, .{ .rl = .none }, node, params); |
| 8458 | }, | 8635 | }, |
| 8459 | else => return expr(gz, scope, .none, node), | 8636 | else => return expr(gz, scope, .{ .rl = .none }, node), |
| 8460 | } | 8637 | } |
| 8461 | } | 8638 | } |
| 8462 | | 8639 | |
| ... | @@ -8738,6 +8915,33 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index, have_ | ... | @@ -8738,6 +8915,33 @@ fn nodeMayNeedMemoryLocation(tree: *const Ast, start_node: Ast.Node.Index, have_ |
| 8738 | } | 8915 | } |
| 8739 | } | 8916 | } |
| 8740 | | 8917 | |
| | 8918 | fn nodeMayAppendToErrorTrace(tree: *const Ast, start_node: Ast.Node.Index) bool { |
| | 8919 | const node_tags = tree.nodes.items(.tag); |
| | 8920 | const node_datas = tree.nodes.items(.data); |
| | 8921 | |
| | 8922 | var node = start_node; |
| | 8923 | while (true) { |
| | 8924 | switch (node_tags[node]) { |
| | 8925 | // These don't have the opportunity to call any runtime functions. |
| | 8926 | .error_value, |
| | 8927 | .identifier, |
| | 8928 | .@"comptime", |
| | 8929 | => return false, |
| | 8930 | |
| | 8931 | // Forward the question to the LHS sub-expression. |
| | 8932 | .grouped_expression, |
| | 8933 | .@"try", |
| | 8934 | .@"nosuspend", |
| | 8935 | .unwrap_optional, |
| | 8936 | => node = node_datas[node].lhs, |
| | 8937 | |
| | 8938 | // Anything that does not eval to an error is guaranteed to pop any |
| | 8939 | // additions to the error trace, so it effectively does not append. |
| | 8940 | else => return nodeMayEvalToError(tree, start_node) != .never, |
| | 8941 | } |
| | 8942 | } |
| | 8943 | } |
| | 8944 | |
| 8741 | fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.EvalToError { | 8945 | fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.EvalToError { |
| 8742 | const node_tags = tree.nodes.items(.tag); | 8946 | const node_tags = tree.nodes.items(.tag); |
| 8743 | const node_datas = tree.nodes.items(.data); | 8947 | const node_datas = tree.nodes.items(.data); |
| ... | @@ -9472,7 +9676,7 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { | ... | @@ -9472,7 +9676,7 @@ fn nodeUsesAnonNameStrategy(tree: *const Ast, node: Ast.Node.Index) bool { |
| 9472 | /// Assumes nothing stacked on `gz`. | 9676 | /// Assumes nothing stacked on `gz`. |
| 9473 | fn rvalue( | 9677 | fn rvalue( |
| 9474 | gz: *GenZir, | 9678 | gz: *GenZir, |
| 9475 | rl: ResultLoc, | 9679 | ri: ResultInfo, |
| 9476 | raw_result: Zir.Inst.Ref, | 9680 | raw_result: Zir.Inst.Ref, |
| 9477 | src_node: Ast.Node.Index, | 9681 | src_node: Ast.Node.Index, |
| 9478 | ) InnerError!Zir.Inst.Ref { | 9682 | ) InnerError!Zir.Inst.Ref { |
| ... | @@ -9487,7 +9691,7 @@ fn rvalue( | ... | @@ -9487,7 +9691,7 @@ fn rvalue( |
| 9487 | break :r raw_result; | 9691 | break :r raw_result; |
| 9488 | }; | 9692 | }; |
| 9489 | if (gz.endsWithNoReturn()) return result; | 9693 | if (gz.endsWithNoReturn()) return result; |
| 9490 | switch (rl) { | 9694 | switch (ri.rl) { |
| 9491 | .none, .coerced_ty => return result, | 9695 | .none, .coerced_ty => return result, |
| 9492 | .discard => { | 9696 | .discard => { |
| 9493 | // Emit a compile error for discarding error values. | 9697 | // Emit a compile error for discarding error values. |
| ... | @@ -9513,7 +9717,7 @@ fn rvalue( | ... | @@ -9513,7 +9717,7 @@ fn rvalue( |
| 9513 | } | 9717 | } |
| 9514 | return indexToRef(gop.value_ptr.*); | 9718 | return indexToRef(gop.value_ptr.*); |
| 9515 | }, | 9719 | }, |
| 9516 | .ty, .ty_shift_operand => |ty_inst| { | 9720 | .ty => |ty_inst| { |
| 9517 | // Quickly eliminate some common, unnecessary type coercion. | 9721 | // Quickly eliminate some common, unnecessary type coercion. |
| 9518 | const as_ty = @as(u64, @enumToInt(Zir.Inst.Ref.type_type)) << 32; | 9722 | const as_ty = @as(u64, @enumToInt(Zir.Inst.Ref.type_type)) << 32; |
| 9519 | const as_comptime_int = @as(u64, @enumToInt(Zir.Inst.Ref.comptime_int_type)) << 32; | 9723 | const as_comptime_int = @as(u64, @enumToInt(Zir.Inst.Ref.comptime_int_type)) << 32; |
| ... | @@ -9574,7 +9778,7 @@ fn rvalue( | ... | @@ -9574,7 +9778,7 @@ fn rvalue( |
| 9574 | => return result, // type of result is already correct | 9778 | => return result, // type of result is already correct |
| 9575 | | 9779 | |
| 9576 | // Need an explicit type coercion instruction. | 9780 | // Need an explicit type coercion instruction. |
| 9577 | else => return gz.addPlNode(rl.zirTag(), src_node, Zir.Inst.As{ | 9781 | else => return gz.addPlNode(ri.zirTag(), src_node, Zir.Inst.As{ |
| 9578 | .dest_type = ty_inst, | 9782 | .dest_type = ty_inst, |
| 9579 | .operand = result, | 9783 | .operand = result, |
| 9580 | }), | 9784 | }), |
| ... | @@ -10268,8 +10472,8 @@ const GenZir = struct { | ... | @@ -10268,8 +10472,8 @@ const GenZir = struct { |
| 10268 | label: ?Label = null, | 10472 | label: ?Label = null, |
| 10269 | break_block: Zir.Inst.Index = 0, | 10473 | break_block: Zir.Inst.Index = 0, |
| 10270 | continue_block: Zir.Inst.Index = 0, | 10474 | continue_block: Zir.Inst.Index = 0, |
| 10271 | /// Only valid when setBreakResultLoc is called. | 10475 | /// Only valid when setBreakResultInfo is called. |
| 10272 | break_result_loc: AstGen.ResultLoc = undefined, | 10476 | break_result_info: AstGen.ResultInfo = undefined, |
| 10273 | /// When a block has a pointer result location, here it is. | 10477 | /// When a block has a pointer result location, here it is. |
| 10274 | rl_ptr: Zir.Inst.Ref = .none, | 10478 | rl_ptr: Zir.Inst.Ref = .none, |
| 10275 | /// When a block has a type result location, here it is. | 10479 | /// When a block has a type result location, here it is. |
| ... | @@ -10371,7 +10575,7 @@ const GenZir = struct { | ... | @@ -10371,7 +10575,7 @@ const GenZir = struct { |
| 10371 | fn finishCoercion( | 10575 | fn finishCoercion( |
| 10372 | as_scope: *GenZir, | 10576 | as_scope: *GenZir, |
| 10373 | parent_gz: *GenZir, | 10577 | parent_gz: *GenZir, |
| 10374 | rl: ResultLoc, | 10578 | ri: ResultInfo, |
| 10375 | src_node: Ast.Node.Index, | 10579 | src_node: Ast.Node.Index, |
| 10376 | result: Zir.Inst.Ref, | 10580 | result: Zir.Inst.Ref, |
| 10377 | dest_type: Zir.Inst.Ref, | 10581 | dest_type: Zir.Inst.Ref, |
| ... | @@ -10397,7 +10601,7 @@ const GenZir = struct { | ... | @@ -10397,7 +10601,7 @@ const GenZir = struct { |
| 10397 | as_scope.instructions_top = GenZir.unstacked_top; | 10601 | as_scope.instructions_top = GenZir.unstacked_top; |
| 10398 | // as_scope now unstacked, can add new instructions to parent_gz | 10602 | // as_scope now unstacked, can add new instructions to parent_gz |
| 10399 | const casted_result = try parent_gz.addBin(.as, dest_type, result); | 10603 | const casted_result = try parent_gz.addBin(.as, dest_type, result); |
| 10400 | return rvalue(parent_gz, rl, casted_result, src_node); | 10604 | return rvalue(parent_gz, ri, casted_result, src_node); |
| 10401 | } else { | 10605 | } else { |
| 10402 | // implicitly move all as_scope instructions to parent_gz | 10606 | // implicitly move all as_scope instructions to parent_gz |
| 10403 | as_scope.instructions_top = GenZir.unstacked_top; | 10607 | as_scope.instructions_top = GenZir.unstacked_top; |
| ... | @@ -10440,7 +10644,7 @@ const GenZir = struct { | ... | @@ -10440,7 +10644,7 @@ const GenZir = struct { |
| 10440 | return gz.astgen.tree.firstToken(gz.decl_node_index); | 10644 | return gz.astgen.tree.firstToken(gz.decl_node_index); |
| 10441 | } | 10645 | } |
| 10442 | | 10646 | |
| 10443 | fn setBreakResultLoc(gz: *GenZir, parent_rl: AstGen.ResultLoc) void { | 10647 | fn setBreakResultInfo(gz: *GenZir, parent_ri: AstGen.ResultInfo) void { |
| 10444 | // Depending on whether the result location is a pointer or value, different | 10648 | // Depending on whether the result location is a pointer or value, different |
| 10445 | // ZIR needs to be generated. In the former case we rely on storing to the | 10649 | // ZIR needs to be generated. In the former case we rely on storing to the |
| 10446 | // pointer to communicate the result, and use breakvoid; in the latter case | 10650 | // pointer to communicate the result, and use breakvoid; in the latter case |
| ... | @@ -10449,32 +10653,32 @@ const GenZir = struct { | ... | @@ -10449,32 +10653,32 @@ const GenZir = struct { |
| 10449 | // the scenario where the result location is not consumed. In this case | 10653 | // the scenario where the result location is not consumed. In this case |
| 10450 | // we emit ZIR for the block break instructions to have the result values, | 10654 | // we emit ZIR for the block break instructions to have the result values, |
| 10451 | // and then rvalue() on that to pass the value to the result location. | 10655 | // and then rvalue() on that to pass the value to the result location. |
| 10452 | switch (parent_rl) { | 10656 | switch (parent_ri.rl) { |
| 10453 | .ty, .ty_shift_operand, .coerced_ty => |ty_inst| { | 10657 | .ty, .coerced_ty => |ty_inst| { |
| 10454 | gz.rl_ty_inst = ty_inst; | 10658 | gz.rl_ty_inst = ty_inst; |
| 10455 | gz.break_result_loc = parent_rl; | 10659 | gz.break_result_info = parent_ri; |
| 10456 | }, | 10660 | }, |
| 10457 | | 10661 | |
| 10458 | .discard, .none, .ref => { | 10662 | .discard, .none, .ref => { |
| 10459 | gz.rl_ty_inst = .none; | 10663 | gz.rl_ty_inst = .none; |
| 10460 | gz.break_result_loc = parent_rl; | 10664 | gz.break_result_info = parent_ri; |
| 10461 | }, | 10665 | }, |
| 10462 | | 10666 | |
| 10463 | .ptr => |ptr_res| { | 10667 | .ptr => |ptr_res| { |
| 10464 | gz.rl_ty_inst = .none; | 10668 | gz.rl_ty_inst = .none; |
| 10465 | gz.break_result_loc = .{ .ptr = .{ .inst = ptr_res.inst } }; | 10669 | gz.break_result_info = .{ .rl = .{ .ptr = .{ .inst = ptr_res.inst } } }; |
| 10466 | }, | 10670 | }, |
| 10467 | | 10671 | |
| 10468 | .inferred_ptr => |ptr| { | 10672 | .inferred_ptr => |ptr| { |
| 10469 | gz.rl_ty_inst = .none; | 10673 | gz.rl_ty_inst = .none; |
| 10470 | gz.rl_ptr = ptr; | 10674 | gz.rl_ptr = ptr; |
| 10471 | gz.break_result_loc = .{ .block_ptr = gz }; | 10675 | gz.break_result_info = .{ .rl = .{ .block_ptr = gz }, .ctx = parent_ri.ctx }; |
| 10472 | }, | 10676 | }, |
| 10473 | | 10677 | |
| 10474 | .block_ptr => |parent_block_scope| { | 10678 | .block_ptr => |parent_block_scope| { |
| 10475 | gz.rl_ty_inst = parent_block_scope.rl_ty_inst; | 10679 | gz.rl_ty_inst = parent_block_scope.rl_ty_inst; |
| 10476 | gz.rl_ptr = parent_block_scope.rl_ptr; | 10680 | gz.rl_ptr = parent_block_scope.rl_ptr; |
| 10477 | gz.break_result_loc = .{ .block_ptr = gz }; | 10681 | gz.break_result_info = .{ .rl = .{ .block_ptr = gz }, .ctx = parent_ri.ctx }; |
| 10478 | }, | 10682 | }, |
| 10479 | } | 10683 | } |
| 10480 | } | 10684 | } |
| ... | @@ -11157,6 +11361,46 @@ const GenZir = struct { | ... | @@ -11157,6 +11361,46 @@ const GenZir = struct { |
| 11157 | }); | 11361 | }); |
| 11158 | } | 11362 | } |
| 11159 | | 11363 | |
| | 11364 | fn addSaveErrRetIndex( |
| | 11365 | gz: *GenZir, |
| | 11366 | cond: union(enum) { |
| | 11367 | always: void, |
| | 11368 | if_of_error_type: Zir.Inst.Ref, |
| | 11369 | }, |
| | 11370 | ) !Zir.Inst.Index { |
| | 11371 | return gz.addAsIndex(.{ |
| | 11372 | .tag = .save_err_ret_index, |
| | 11373 | .data = .{ .save_err_ret_index = .{ |
| | 11374 | .operand = if (cond == .if_of_error_type) cond.if_of_error_type else .none, |
| | 11375 | } }, |
| | 11376 | }); |
| | 11377 | } |
| | 11378 | |
| | 11379 | const BranchTarget = union(enum) { |
| | 11380 | ret, |
| | 11381 | block: Zir.Inst.Index, |
| | 11382 | }; |
| | 11383 | |
| | 11384 | fn addRestoreErrRetIndex( |
| | 11385 | gz: *GenZir, |
| | 11386 | bt: BranchTarget, |
| | 11387 | cond: union(enum) { |
| | 11388 | always: void, |
| | 11389 | if_non_error: Zir.Inst.Ref, |
| | 11390 | }, |
| | 11391 | ) !Zir.Inst.Index { |
| | 11392 | return gz.addAsIndex(.{ |
| | 11393 | .tag = .restore_err_ret_index, |
| | 11394 | .data = .{ .restore_err_ret_index = .{ |
| | 11395 | .block = switch (bt) { |
| | 11396 | .ret => .none, |
| | 11397 | .block => |b| Zir.indexToRef(b), |
| | 11398 | }, |
| | 11399 | .operand = if (cond == .if_non_error) cond.if_non_error else .none, |
| | 11400 | } }, |
| | 11401 | }); |
| | 11402 | } |
| | 11403 | |
| 11160 | fn addBreak( | 11404 | fn addBreak( |
| 11161 | gz: *GenZir, | 11405 | gz: *GenZir, |
| 11162 | tag: Zir.Inst.Tag, | 11406 | tag: Zir.Inst.Tag, |
| ... | @@ -11624,10 +11868,10 @@ const GenZir = struct { | ... | @@ -11624,10 +11868,10 @@ const GenZir = struct { |
| 11624 | return new_index; | 11868 | return new_index; |
| 11625 | } | 11869 | } |
| 11626 | | 11870 | |
| 11627 | fn addRet(gz: *GenZir, rl: ResultLoc, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void { | 11871 | fn addRet(gz: *GenZir, ri: ResultInfo, operand: Zir.Inst.Ref, node: Ast.Node.Index) !void { |
| 11628 | switch (rl) { | 11872 | switch (ri.rl) { |
| 11629 | .ptr => |ptr_res| _ = try gz.addUnNode(.ret_load, ptr_res.inst, node), | 11873 | .ptr => |ptr_res| _ = try gz.addUnNode(.ret_load, ptr_res.inst, node), |
| 11630 | .ty, .ty_shift_operand => _ = try gz.addUnNode(.ret_node, operand, node), | 11874 | .ty => _ = try gz.addUnNode(.ret_node, operand, node), |
| 11631 | else => unreachable, | 11875 | else => unreachable, |
| 11632 | } | 11876 | } |
| 11633 | } | 11877 | } |